From: Vincent Torri Date: Sun, 2 Dec 2012 22:35:45 +0000 (+0000) Subject: merge: add escape ecore, fix several bugs X-Git-Tag: submit/efl/20131015.063327~3172 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7d6010b12c47a20e492da808e3192c3f87dab619;p=platform%2Fupstream%2Fefl.git merge: add escape ecore, fix several bugs SVN revision: 79995 --- diff --git a/AUTHORS b/AUTHORS index 17b645d05f..63915c70e4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -10,6 +10,11 @@ Daniel Stenberg (inet_pton and inet_ntop functions) The MinGW and MinGW-w64 teams (POSIX printf family functions) Keith Marshall (realpath on Windows XP). See http://sourceforge.net/tracker/?func=detail&atid=302435&aid=1294010&group_id=2435 +Escape +------ + +Youness Alaoui (KaKaRoTo) + Eina ---- diff --git a/COPYING b/COPYING index 4cbd1f8642..32df97fe80 100644 --- a/COPYING +++ b/COPYING @@ -2,8 +2,9 @@ EFL comes with several licences. Listed are the library/probject name and the license file covering it. evil: licenses/COPYING.BSD +escape: licenses/COPYING.GPL eet: licenses/COPYING.BSD eina: licenses/COPYING.LGPL eo: licenses/COPYING.BSD evas: licenses/COPYING.BSD -embryo: licenses/COPYING.BSD +embryo: licenses/COPYING.SMALL diff --git a/Makefile.am b/Makefile.am index d0f7c55ac0..b59b22074f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,12 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src data doc +if HAVE_PO + +SUBDIRS += po + +endif + MAINTAINERCLEANFILES = \ Makefile.in \ aclocal.m4 \ @@ -53,6 +59,7 @@ old/NEWS.eet \ old/README.eet \ spec/efl.spec \ pc/evil.pc \ +pc/escape.pc \ pc/eina.pc \ pc/eet.pc \ pc/eo.pc \ @@ -65,10 +72,27 @@ pc/evas-software-buffer.pc \ pc/evas-software-x11.pc \ pc/evas-software-gdi.pc \ pc/evas-software-ddraw.pc \ -pc/evas-direct3d.pc \ pc/evas-psl1ght.pc \ pc/evas-wayland-shm.pc \ pc/evas-wayland-egl.pc \ +pc/ecore.pc \ +pc/ecore-con.pc \ +pc/ecore-ipc.pc \ +pc/ecore-file.pc \ +pc/ecore-input.pc \ +pc/ecore-input-evas.pc \ +pc/ecore-cocoa.pc \ +pc/ecore-directfb.pc \ +pc/ecore-fb.pc \ +pc/ecore-psl1ght.pc \ +pc/ecore-sdl.pc \ +pc/ecore-wayland.pc \ +pc/ecore-win32.pc \ +pc/ecore-wince.pc \ +pc/ecore-x.pc \ +pc/ecore-imf.pc \ +pc/ecore-imf-evas.pc \ +pc/ecore-evas.pc \ pc/embryo.pc pkgconfigdir = $(libdir)/pkgconfig @@ -78,11 +102,24 @@ if HAVE_WINDOWS pkgconfig_DATA += pc/evil.pc endif +if HAVE_PS3 +pkgconfig_DATA += pc/escape.pc +endif + pkgconfig_DATA += \ pc/eina.pc \ pc/eo.pc \ pc/eet.pc \ pc/evas.pc \ +pc/ecore.pc \ +pc/ecore-con.pc \ +pc/ecore-ipc.pc \ +pc/ecore-file.pc \ +pc/ecore-input.pc \ +pc/ecore-input-evas.pc \ +pc/ecore-imf.pc \ +pc/ecore-imf-evas.pc \ +pc/ecore-evas.pc \ pc/embryo.pc if BUILD_ENGINE_SOFTWARE_X11 @@ -121,10 +158,6 @@ if BUILD_ENGINE_SOFTWARE_DDRAW pkgconfig_DATA += pc/evas-software-ddraw.pc endif -if BUILD_ENGINE_DIRECT3D -pkgconfig_DATA += pc/evas-direct3d.pc -endif - if BUILD_ENGINE_PSL1GHT pkgconfig_DATA += pc/evas-psl1ght.pc endif @@ -137,6 +170,42 @@ if BUILD_ENGINE_WAYLAND_EGL pkgconfig_DATA += pc/evas-wayland-egl.pc endif +if HAVE_ECORE_COCOA +pkgconfig_DATA += pc/ecore-cocoa.pc +endif + +if HAVE_ECORE_DIRECTFB +pkgconfig_DATA += pc/ecore-directfb.pc +endif + +if HAVE_ECORE_FB +pkgconfig_DATA += pc/ecore-fb.pc +endif + +if HAVE_PS3 +pkgconfig_DATA += pc/ecore-psl1ght.pc +endif + +if HAVE_ECORE_SDL +pkgconfig_DATA += pc/ecore-sdl.pc +endif + +if HAVE_ECORE_WAYLAND +pkgconfig_DATA += pc/ecore-wayland.pc +endif + +if HAVE_WIN32 +pkgconfig_DATA += pc/ecore-win32.pc +endif + +if HAVE_WINCE +pkgconfig_DATA += pc/ecore-wince.pc +endif + +if HAVE_ECORE_X +pkgconfig_DATA += pc/ecore-x.pc +endif + .PHONY: doc benchmark examples install-examples diff --git a/configure.ac b/configure.ac index e2d1b852a4..7b035be665 100644 --- a/configure.ac +++ b/configure.ac @@ -34,8 +34,7 @@ AH_BOTTOM([ #endif /* EFL_CONFIG_H__ */ ]) -AC_GNU_SOURCE -AC_SYS_LARGEFILE +AC_USE_SYSTEM_EXTENSIONS AM_INIT_AUTOMAKE([1.6 dist-bzip2]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -76,7 +75,7 @@ esac # TODO: add some build "profile" (server, full, etc...) AC_ARG_ENABLE([coverage], - [AC_HELP_STRING([--enable-coverage], [enable unit testing coverage. @<:@default==disabled@:>@])], + [AC_HELP_STRING([--enable-coverage], [enable unit testing coverage. @<:@default=disabled@:>@])], [ if test "x${enableval}" = "xyes" ; then want_coverage="yes" @@ -94,7 +93,21 @@ requirements_libs_eina="" requirements_libs_eo="" requirements_libs_eet="" requirements_libs_evas="" -#requirements_libs_ecore="" +requirements_libs_ecore="" +requirements_libs_ecore_con="" +requirements_libs_ecore_ipc="" +requirements_libs_ecore_file="" +requirements_libs_ecore_input="" +requirements_libs_ecore_cocoa="" +requirements_libs_ecore_directfb="" +requirements_libs_ecore_fb="" +requirements_libs_ecore_psl1ght="" +requirements_libs_ecore_sdl="" +requirements_libs_ecore_wayland="" +requirements_libs_ecore_win32="" +requirements_libs_ecore_wince="" +requirements_libs_ecore_x="" +requirements_libs_ecore_evas="" requirements_libs_embryo="" #requirements_libs_eio="" #requirements_libs_edje="" @@ -105,27 +118,25 @@ requirements_libs_embryo="" #requirements_libs_ethumb="" #requirements_libs_elementary="" -requirements_libs_deps_evil="" -requirements_libs_deps_eina="" -requirements_libs_deps_eo="" -requirements_libs_deps_eet="" -requirements_libs_deps_evas="" -#requirements_libs_deps_ecore="" -requirements_libs_deps_embryo="" -#requirements_libs_deps_eio="" -#requirements_libs_deps_edje="" -#requirements_libs_deps_efreet="" -#requirements_libs_deps_e_dbus="" -#requirements_libs_deps_eeze="" -#requirements_libs_deps_emotion="" -#requirements_libs_deps_ethumb="" -#requirements_libs_deps_elementary="" - requirements_pc_eina="" requirements_pc_eo="" requirements_pc_eet="" requirements_pc_evas="" -#requirements_pc_ecore="" +requirements_pc_ecore="" +requirements_pc_ecore_con="" +requirements_pc_ecore_ipc="" +requirements_pc_ecore_file="" +requirements_pc_ecore_input="" +requirements_pc_ecore_cocoa="" +requirements_pc_ecore_directfb="" +requirements_pc_ecore_fb="" +requirements_pc_ecore_psl1ght="" +requirements_pc_ecore_sdl="" +requirements_pc_ecore_wayland="" +requirements_pc_ecore_win32="" +requirements_pc_ecore_wince="" +requirements_pc_ecore_x="" +requirements_pc_ecore_evas="" requirements_pc_embryo="" #requirements_pc_eio="" #requirements_pc_edje="" @@ -140,7 +151,12 @@ requirements_pc_deps_eina="" requirements_pc_deps_eo="" requirements_pc_deps_eet="" requirements_pc_deps_evas="" -#requirements_pc_deps_ecore="" +requirements_pc_deps_ecore="" +requirements_pc_deps_ecore_con="" +requirements_pc_deps_ecore_fb="" +requirements_pc_deps_ecore_sdl="" +requirements_pc_deps_ecore_wayland="" +requirements_pc_deps_ecore_evas="" requirements_pc_deps_embryo="" #requirements_pc_deps_eio="" #requirements_pc_deps_edje="" @@ -156,7 +172,21 @@ AC_SUBST([requirements_libs_eina]) AC_SUBST([requirements_libs_eo]) AC_SUBST([requirements_libs_eet]) AC_SUBST([requirements_libs_evas]) -#AC_SUBST([requirements_libs_ecore]) +AC_SUBST([requirements_libs_ecore]) +AC_SUBST([requirements_libs_ecore_con]) +AC_SUBST([requirements_libs_ecore_ipc]) +AC_SUBST([requirements_libs_ecore_file]) +AC_SUBST([requirements_libs_ecore_input]) +AC_SUBST([requirements_libs_ecore_cocoa]) +AC_SUBST([requirements_libs_ecore_directfb]) +AC_SUBST([requirements_libs_ecore_fb]) +AC_SUBST([requirements_libs_ecore_psl1ght]) +AC_SUBST([requirements_libs_ecore_sdl]) +AC_SUBST([requirements_libs_ecore_wayland]) +AC_SUBST([requirements_libs_ecore_win32]) +AC_SUBST([requirements_libs_ecore_wince]) +AC_SUBST([requirements_libs_ecore_x]) +AC_SUBST([requirements_libs_ecore_evas]) AC_SUBST([requirements_libs_embryo]) #AC_SUBST([requirements_libs_eio]) #AC_SUBST([requirements_libs_edje]) @@ -171,7 +201,21 @@ AC_SUBST([requirements_pc_eina]) AC_SUBST([requirements_pc_eo]) AC_SUBST([requirements_pc_eet]) AC_SUBST([requirements_pc_evas]) -#AC_SUBST([requirements_pc_ecore]) +AC_SUBST([requirements_pc_ecore]) +AC_SUBST([requirements_pc_ecore_con]) +AC_SUBST([requirements_pc_ecore_ipc]) +AC_SUBST([requirements_pc_ecore_file]) +AC_SUBST([requirements_pc_ecore_input]) +AC_SUBST([requirements_pc_ecore_cocoa]) +AC_SUBST([requirements_pc_ecore_directfb]) +AC_SUBST([requirements_pc_ecore_fb]) +AC_SUBST([requirements_pc_ecore_psl1ght]) +AC_SUBST([requirements_pc_ecore_sdl]) +AC_SUBST([requirements_pc_ecore_wayland]) +AC_SUBST([requirements_pc_ecore_win32]) +AC_SUBST([requirements_pc_ecore_wince]) +AC_SUBST([requirements_pc_ecore_x]) +AC_SUBST([requirements_pc_ecore_evas]) AC_SUBST([requirements_pc_embryo]) #AC_SUBST([requirements_pc_eio]) #AC_SUBST([requirements_pc_edje]) @@ -189,6 +233,7 @@ AC_CANONICAL_HOST have_wince="no" have_win32="no" have_windows="no" +have_ps3="no" case "$host_os" in cegcc*) AC_MSG_ERROR([ceGCC compiler is not supported anymore. Exiting...]) @@ -221,6 +266,12 @@ case "$host_os" in ;; esac +case "$host_vendor" in + ps3*) + have_ps3="yes" + ;; +esac + AC_SUBST([MODULE_ARCH]) AC_DEFINE_UNQUOTED([MODULE_ARCH], ["${MODULE_ARCH}"], ["Module architecture"]) AC_DEFINE_UNQUOTED([SHARED_LIB_SUFFIX], ["${MODULE_EXT}"], [Suffix for shared objects]) @@ -229,6 +280,7 @@ AC_DEFINE_UNQUOTED([SHARED_LIB_SUFFIX], ["${MODULE_EXT}"], [Suffix for shared ob AM_CONDITIONAL([HAVE_WINCE], [test "x${have_wince}" = "xyes"]) AM_CONDITIONAL([HAVE_WIN32], [test "x${have_win32}" = "xyes"]) AM_CONDITIONAL([HAVE_WINDOWS], [test "x${have_windows}" = "xyes"]) +AM_CONDITIONAL([HAVE_PS3], [test "x${have_ps3}" = "xyes"]) #### Checks for programs @@ -238,14 +290,32 @@ AM_CONDITIONAL([HAVE_WINDOWS], [test "x${have_windows}" = "xyes"]) if test "x${have_windows}" = "xyes" ; then lt_cv_deplibs_check_method='pass_all' fi -AC_LIBTOOL_WIN32_DLL -define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl -AC_PROG_LIBTOOL +LT_INIT([win32-dll]) version_info="lt_cur:lt_rev:lt_age" AC_SUBST([version_info]) release_info="v_rel" AC_SUBST([release_info]) +### gettext + +AM_GNU_GETTEXT_VERSION([0.17]) + +m4_ifdef([AM_GNU_GETTEXT], [ +AM_GNU_GETTEXT([external]) +po_makefile_in=po/Makefile.in +have_po="yes" +], +[ +have_po="no" +]) +AC_SUBST([LTLIBINTL]) + +if test "x${POSUB}" = "x" ; then + have_po="no" +fi + +AM_CONDITIONAL([HAVE_PO], [test "x${have_po}" = "xyes"]) + ### compilers # rw_PROG_OBJC_WORKS @@ -277,10 +347,22 @@ rw_PROG_OBJC_WORKS AM_PROG_AS AC_PROG_CXX AC_LANG(C) -AC_PROG_CPP -AC_PROG_CC +AC_PROG_CC_C99 AM_PROG_CC_C_O +if test "x${ac_cv_prog_cc_c99}" = "xno" ; then + AC_MSG_ERROR([ecore requires a c99-capable compiler]) +fi + +have_gnu_objc=${ac_cv_objc_compiler_gnu} + +#echo $ac_cv_prog_CXX +#if test "x${ac_cv_prog_CXX}" = "x" ; then +# AC_MSG_ERROR([C++ compiler needed. Exiting...]) +#fi + +AC_SYS_LARGEFILE + # pkg-config PKG_PROG_PKG_CONFIG @@ -337,6 +419,7 @@ AC_HEADER_TIME AC_CHECK_HEADERS([ \ execinfo.h \ +errno.h \ inttypes.h \ libgen.h \ mcheck.h \ @@ -465,8 +548,6 @@ AC_DEFINE([HAVE_EVIL], [1], [Set to 1 if Evil package is installed]) ### Checks for header files -AC_CHECK_HEADERS([errno.h]) - ### Checks for types ### Checks for structures @@ -497,6 +578,42 @@ fi #### End of Evil +#### Escape + +if test "x${have_ps3}" = "xyes" ; then + +AC_MSG_NOTICE([Escape checks]) + +### Additional options to configure + +### Default values + +### Checks for programs + +### Checks for libraries + +ESCAPE_LIBS="-llv2" +requirements_libs_escape="${ESCAPE_LIBS}" + +AC_SUBST([ESCAPE_LIBS]) + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +fi + +#### End of Evil + + #### Eina AC_MSG_NOTICE([Eina checks]) @@ -563,17 +680,15 @@ esac # Escape library for compilation on Playstation 3 case "$host_vendor" in - ps3*) -# TODO: add back whenever escape is merged into efl single tree -# PKG_CHECK_EXISTS([escape]) -# AC_DEFINE([HAVE_ESCAPE], [1], [Set to 1 if Escape package is installed]) -# requirements_pc_eina="${requirements_pc_eina} escape" + ps3*) + AC_DEFINE([HAVE_ESCAPE], [1], [Set to 1 if Escape package is installed]) + requirements_pc_eina="${requirements_pc_eina} escape >= ${PACKAGE_VERSION}" ;; esac # Exotic library for compilation on Coyote -# TODO: add back whenever escape is merged into efl single tree +# TODO: add back whenever exotic is merged into efl single tree #PKG_CHECK_EXISTS([exotic], # [ # enable_exotic="yes" @@ -745,7 +860,6 @@ case "$build_crypto" in AC_PATH_GENERIC([libgcrypt], [], [:], [AC_MSG_ERROR([libgcrypt required but not found])]) requirements_libs_eet="${LIBGCRYPT_LIBS} ${requirements_libs_eet}" - requirements_libs_deps_eet="${LIBGCRYPT_LIBS} ${requirements_libs_deps_eet}" # TODO: do we need this? can't we just bump required version? # Specific GNUTLS improvement @@ -782,10 +896,12 @@ case "$build_crypto" in ;; openssl) - PKG_CHECK_MODULES([OPENSSL], [openssl]) - AC_DEFINE([HAVE_OPENSSL], [1], [Have Openssl support]) - requirements_pc_eet="openssl ${requirements_pc_eet}" - requirements_pc_deps_eet="openssl ${requirements_pc_deps_eet}" + PKG_CHECK_EXISTS([openssl], + [ + AC_DEFINE([HAVE_OPENSSL], [1], [Have Openssl support]) + requirements_pc_eet="openssl ${requirements_pc_eet}" + requirements_pc_deps_eet="openssl ${requirements_pc_deps_eet}" + ]) ;; esac @@ -816,15 +932,13 @@ PKG_CHECK_MODULES([EET], [${requirements_pc_deps_eet}]) case "$host_os" in mingw32ce*) requirements_libs_eet="${requirements_libs_eet} -lws2" - requirements_libs_deps_eet="${requirements_libs_deps_eet} -lws2" ;; mingw*) requirements_libs_eet="${requirements_libs_eet} -lws2_32" - requirements_libs_deps_eet="${requirements_libs_deps_eet} -lws2_32" ;; esac -EET_LIBS="${EET_LIBS} ${requirements_libs_deps_eet}" +EET_LIBS="${EET_LIBS} ${requirements_libs_eet}" ### Checks for header files @@ -905,7 +1019,7 @@ AC_MSG_NOTICE([Evas checks]) # a requirement is selected, but not met. use_strict="no" AC_ARG_ENABLE([strict], - [AC_HELP_STRING([--enable-strict], [enable strict checking mode. @<:@default==disabled@:>@])], + [AC_HELP_STRING([--enable-strict], [enable strict checking mode. @<:@default=disabled@:>@])], [use_strict="yes"], [use_strict="no"]) @@ -1204,7 +1318,6 @@ want_evas_engine_gl_xlib="no" want_evas_engine_gl_xcb="no" want_evas_engine_gl_sdl="no" want_evas_engine_gl_cocoa="no" -want_evas_engine_direct3d="no" want_evas_engine_fb="no" want_evas_engine_directfb="no" want_evas_engine_psl1ght="no" @@ -1255,7 +1368,7 @@ case "$host_os" in esac EFL_CHECK_FUNC([DLSYM], [dlsym]) -requirements_libs_deps_evas="${requirements_libs_deps_evas} ${DLSYM_LIBS}" +requirements_libs_evas="${requirements_libs_evas} ${DLSYM_LIBS}" if test "x${efl_func_dlsym}" = "xno" ; then want_evas_engine_gl_xlib="no" @@ -1385,7 +1498,6 @@ fi ## Engines EVAS_CHECK_ENGINE([buffer], [${want_evas_engine_buffer}], [yes], [Buffer]) -EVAS_CHECK_ENGINE([direct3d], [${want_evas_engine_direct3d}], [no], [Direct3D]) EVAS_CHECK_ENGINE([directfb], [${want_evas_engine_directfb}], [no], [DirectFB]) EVAS_CHECK_ENGINE([fb], [${want_evas_engine_fb}], [no], [Framebuffer]) EVAS_CHECK_ENGINE([gl-cocoa], [${want_evas_engine_gl_cocoa}], [no], [OpenGL Cocoa]) @@ -1606,7 +1718,7 @@ AM_CONDITIONAL([BUILD_SAVER_JPEG], [test "x${have_evas_image_saver_jpeg}" = "xye PKG_CHECK_MODULES([EVAS], [${requirements_pc_deps_evas}]) -EVAS_LIBS="${EVAS_LIBS} ${requirements_libs_deps_evas}" +EVAS_LIBS="${EVAS_LIBS} ${requirements_libs_evas}" ### Checks for header files @@ -1854,136 +1966,2367 @@ fi #### End of Embryo -AC_CONFIG_FILES([ -Makefile -data/Makefile -doc/Makefile -doc/Doxyfile -src/Makefile -src/benchmarks/Makefile -src/benchmarks/eina/Makefile -src/benchmarks/eo/Makefile -src/examples/Makefile -src/examples/eina/Makefile -src/examples/eet/Makefile -src/examples/eo/Makefile -src/examples/evas/Makefile -src/lib/eina/eina_config.h -spec/efl.spec -pc/evil.pc -pc/eina.pc -pc/eet.pc -pc/eo.pc -pc/embryo.pc -pc/evas-direct3d.pc -pc/evas-directfb.pc -pc/evas-fb.pc -pc/evas-opengl-x11.pc -pc/evas-opengl-sdl.pc -pc/evas-opengl-cocoa.pc -pc/evas-psl1ght.pc -pc/evas-software-buffer.pc -pc/evas-software-x11.pc -pc/evas-software-gdi.pc -pc/evas-software-ddraw.pc -pc/evas-software-sdl.pc -pc/evas-wayland-shm.pc -pc/evas-wayland-egl.pc -pc/evas.pc -]) +#### Ecore -AC_OUTPUT +AC_MSG_NOTICE([Ecore checks]) +### Additional options to configure -#### Info +# glib + +AC_ARG_WITH([glib], + [AC_HELP_STRING([--with-glib=yes|no|always], + [add glib support. @<:@default=enabled@:>@])], + [ + if test "x${withval}" = "xyes" ; then + with_glib="yes" + else + if test "x${withval}" = "xalways" ; then + with_glib="always" + else + with_glib="no" + fi + fi + ], + [with_glib="yes"]) + +AC_ARG_ENABLE([g-main-loop], + [AC_HELP_STRING([--enable-g-main-loop], + [enable ecore_main_loop based on g_main_loop. @<:@default=disabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_g_main_loop="yes" + else + want_g_main_loop="no" + fi + ], + [want_g_main_loop="no"]) + +# thread safety + +AC_ARG_ENABLE([thread-safety], + [AC_HELP_STRING([--enable-thread-safety], + [enable thread safety. @<:@default=disabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_thread_safety="yes" + else + want_thread_safety="no" + fi + ], + [want_thread_safety="no"]) + +# epoll + +AC_ARG_ENABLE([epoll], + [AC_HELP_STRING([--disable-epoll], + [disable epoll support. @<:@default=enabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_epoll="yes" + else + want_epoll="no" + fi + ], + [want_epoll="yes"]) + +### Default values + +case "$host_os" in + mingw32*) + with_glib="no" + ;; +esac + +want_glib="no" +if test "x${with_glib}" = "xyes" || test "x${with_glib}" = "xalways" ; then + want_glib="yes" +fi + +if test "x${want_thread_safety}" = "xyes" ; then + AC_DEFINE([HAVE_THREAD_SAFETY], [1], [Define to enable thread safety]) +fi + +want_ecore_timer_dump="no" +if test "x${build_profile}" = "xdebug" && test "x${ac_cv_func_backtrace}" = "xyes"; then + want_ecore_timer_dump="yes" + AC_DEFINE([WANT_ECORE_TIMER_DUMP], [1], [Want Ecore_Timer dump infrastructure]) +fi + +### Checks for programs + +### Checks for libraries + +## Compatibility layers + +# Evil library for compilation on Windows -echo -echo -echo -echo "------------------------------------------------------------------------" -echo "$PACKAGE_NAME $PACKAGE_VERSION" -echo "------------------------------------------------------------------------" -echo -echo "Configuration Options Summary:" -echo -echo " OS...................: ${host_os}" if test "x${have_windows}" = "xyes" ; then - echo " Windows version......: ${_efl_windows_version}" + requirements_pc_ecore="${requirements_pc_ecore} evil >= ${PACKAGE_VERSION}" fi -echo " Build Profile........: ${build_profile}" -echo " Threads Type.........: ${efl_have_threads}" -echo " spinlocks..........: ${efl_have_posix_threads_spinlock}" -echo " barrier............: ${efl_have_pthread_barrier}" -echo " affinity...........: ${efl_have_setaffinity}" -echo " Cryptographic System.: ${build_crypto}" -echo -echo "Evas:" -echo -echo " Engines:" -echo " Software Memory Buffer.....: $have_evas_engine_buffer" -echo " Software X11...............: $have_evas_engine_software_x11 (Xlib: $have_evas_engine_software_xlib) (XCB: $have_evas_engine_software_xcb)" -echo $ECHO_N " OpenGL X11.................: $have_evas_engine_gl_x11 (Xlib: $have_evas_engine_gl_xlib) (XCB: $have_evas_engine_gl_xcb) $ECHO_C" -if test "x$have_evas_engine_gl_x11" = "xyes"; then - echo "(GLES: $gl_flavor_gles)" -else - echo + +# Escape library for compilation on PS3 + +if test "x${have_ps3}" = "xyes" ; then + requirements_pc_ecore="${requirements_pc_ecore} escape >= ${PACKAGE_VERSION}" fi -echo " Software GDI...............: $have_evas_engine_software_gdi" -echo " Software DirectDraw........: $have_evas_engine_software_ddraw" -echo " Direct3d...................: $have_evas_engine_direct3d" -echo " OpenGL SDL.................: $have_evas_engine_gl_sdl $ECHO_C" -if test "x$have_evas_engine_gl_sdl" = "xyes"; then - echo "(GLES: $gl_flavor_gles)" -else - echo + +# Eina, Eo libraries + +requirements_pc_ecore="eo >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore}" + +# glib + +have_glib="no" +if test "x${want_glib}" = "xyes" ; then + PKG_CHECK_EXISTS([glib-2.0], [have_glib="yes"], [have_glib="no"]) fi -echo " OpenGL Cocoa...............: $have_evas_engine_gl_cocoa" -echo " Software Framebuffer.......: $have_evas_engine_fb" -echo " DirectFB...................: $have_evas_engine_directfb" -echo " PSL1GHT....................: $have_evas_engine_psl1ght" -echo " Wayland Shm................: $have_evas_engine_wayland_shm" -echo " Wayland Egl................: $have_evas_engine_wayland_egl" -echo -echo " Image Loaders:" -echo " JPEG region decode......: $have_jpeg_region" -echo " WEBP....................: $have_evas_image_loader_webp" -echo " GIF.....................: $have_evas_image_loader_gif" -echo " TIFF....................: $have_evas_image_loader_tiff" -echo " SVG.....................: $have_evas_image_loader_svg" -echo -echo " Font Searching Systems:" -echo " Fontconfig..............: $have_fontconfig" -echo -echo " Font Rendering Helpers:" -echo " Fribidi.................: $have_fribidi" -echo " Harfbuzz................: $have_harfbuzz" -# FIXME: add non freetype2 font engine support -# FIXME: make freetype2 optional -echo -echo " CPU Specific Extensions:" -echo " MMX/SSE.................: $build_cpu_mmx" -echo " SSE3....................: $build_cpu_sse3" -echo " ALTIVEC.................: $build_cpu_altivec" -echo " NEON....................: $build_cpu_neon" -echo -echo " Features:" -echo " Cache Server 2..........: $want_evas_cserve2" -echo " Threaded Pipe Rendering.: $build_pipe_render" -echo -echo " Optional pixman rendering path:" -echo " Pixman..................: $have_pixman" -echo " Pixman Fonts............: $have_pixman_font" -echo " Pixman Rects............: $have_pixman_rect" -echo " Pixman Lines............: $have_pixman_line" -echo " Pixman Polygons.........: $have_pixman_poly" -echo " Pixman Images...........: $have_pixman_image" -echo " Pixman Image ScaleSample: $have_pixman_image_scale_sample" -echo -echo " Conversion Options:" -echo " Smaller Dither Mask.....: $conv_small_dither" -echo " Line Dither Mask........: $conv_line_dither" -echo " No Dither Mask for 16bpp: $conv_no_dither" -echo " Tiled 32BPP rotate......: $have_tile_rotate" + +if test "x${want_glib}" = "xyes" && test "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_pc_ecore="glib-2.0 ${requirements_pc_ecore}" + requirements_pc_deps_ecore="glib-2.0 ${requirements_pc_deps_ecore}" +fi + +if test "x${have_glib}" = "xno"; then + want_g_main_loop="no" +fi + +if test "x${with_glib}" = "xalways" && test "x${want_g_main_loop}" = "xyes"; then + AC_MSG_ERROR([--with-glib set to always and --enable-glib-main-loop are mutually exclusive]) +fi + +want_glib_integration_always=no +if test "x${with_glib}" = "xalways" ; then + want_glib_integration_always="yes" + AC_DEFINE([GLIB_INTEGRATION_ALWAYS], [1], [Always integrate glib if support compiled]) +fi + +if test "x${want_g_main_loop}" = "xyes" ; then + AC_DEFINE([USE_G_MAIN_LOOP], [1], [Use g_main_loop in ecore]) +fi + +if ! test "x${requirements_pc_deps_ecore}" = "x" ; then + PKG_CHECK_MODULES([ECORE], [${requirements_pc_deps_ecore}]) +fi + +case "$host_os" in + mingw32ce*) + requirements_libs_ecore="${requirements_libs_ecore} -lws2" + ;; + mingw*) + requirements_libs_ecore="${requirements_libs_ecore} -lws2_32" + ;; +esac + +### Checks for header files + +AC_HEADER_SYS_WAIT + +AC_CHECK_HEADERS([ \ +features.h \ +langinfo.h \ +locale.h \ +signal.h \ +sys/time.h \ +sys/prctl.h \ +sys/resource.h \ +sys/select.h \ +sys/timerfd.h \ +]) + +if test "x${want_epoll}" = "xyes" ; then + AC_CHECK_HEADERS([sys/epoll.h]) +fi + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +## ecore + +# isfinite + +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include + ]], + [[ +int i = isfinite(0); + ]])], + [ + AC_DEFINE(HAVE_ISFINITE, 1, [Define to 1 if you have `isfinite', as a function or macro.]) + have_isfinite="yes" + ], + [have_isfinite="no"]) + +AC_MSG_CHECKING([for isfinite]) +AC_MSG_RESULT([${have_isfinite}]) + +# mallinfo, timerfd_create, clock_gettime + +AC_CHECK_FUNCS_ONCE([mallinfo timerfd_create clock_gettime]) + +if ! test "x${ac_cv_func_clock_gettime}" = "xyes" ; then + AC_CHECK_LIB([rt], [clock_gettime], + [ + requirements_libs_ecore="${requirements_libs_ecore} -lrt" + AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Have clock_gettime()]) + ]) +fi + +ECORE_LIBS="${ECORE_LIBS} ${LTLIBINTL} ${requirements_libs_ecore}" + +### Check availability + +#### End of Ecore + + +#### Ecore_Con + +AC_MSG_NOTICE([Ecore_Con checks]) + +### Additional options to configure + +AC_ARG_ENABLE([ipv6], + [AC_HELP_STRING([--disable-ipv6], + [disable ipv6 functionality @<:@default=detect@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_ipv6="yes" + else + want_ipv6="no" + fi], + [want_ipv6="auto"]) + +AC_ARG_ENABLE([curl], + [AC_HELP_STRING([--disable-curl], [disable curl support. @<:@default=enabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_curl="yes" + else + want_curl="no" + fi + ], + [want_curl="yes"]) + +AC_ARG_WITH([tls], + [AC_HELP_STRING([--with-tls=TLS], + [select Transport Layer Security, one of: gnutls, openssl, none. + @<:@default=gnutls@:>@])], + [with_tls=${withval}], + [with_tls="gnutls"]) + +case "${with_tls}" in + gnutls|openssl|none) + ;; + *) + AC_MSG_ERROR([Unknown Transport Layer Security --with-tls=${with_tls}]) + ;; +esac + +AC_ARG_ENABLE([local-sockets], + [AC_HELP_STRING([--disable-local-sockets], [disable local sockets.])], + [ + if test "x${enableval}" = "xyes" ; then + want_ecore_con_local_sockets="yes" + else + want_ecore_con_local_sockets="no" + fi + ], + [want_ecore_con_local_sockets="yes"]) + +AC_ARG_ENABLE([abstract-sockets], + [AC_HELP_STRING([--disable-abstract-sockets], [disable abstract sockets.])], + [ + if test "x${enableval}" = "xyes" ; then + want_ecore_con_abstract_sockets="yes" + else + want_ecore_con_abstract_sockets="no" + fi + ], + [want_ecore_con_abstract_sockets="yes"]) + +### Default values + + +case "$host_os" in + mingw32ce*) + with_tls="none" + want_curl="no" + want_cares="no" + want_ecore_con_local_sockets="no" + want_ecore_con_abstract_sockets="no" + ;; + mingw*) + want_cares="yes" + want_ecore_con_abstract_sockets="no" + ;; + darwin*) + want_ecore_con_abstract_sockets="no" + ;; + *) + want_cares="no" + ;; +esac + +case "$host_vendor" in + ps3*) + want_ecore_con_local_sockets="no" + ;; +esac + +if test "x${want_ecore_con_local_sockets}" = "xyes" ; then + AC_DEFINE([HAVE_LOCAL_SOCKETS], [1], [Have local sockets support]) +fi + +if test "x${want_ecore_con_abstract_sockets}" = "xyes" ; then + AC_DEFINE([HAVE_ABSTRACT_SOCKETS], [1], [Have abstract sockets namespace]) +fi + +### Checks for programs + +have_gnutls="no" +if test "x${with_tls}" = "xgnutls" ; then + AC_PATH_GENERIC([libgcrypt], [], [have_gnutls="yes"], [have_gnutls="no"]) +fi + +### Checks for libraries + +# Evil library for compilation on Windows +case "$host_os" in + mingw*) + requirements_pc_ecore_con="evil >= ${PACKAGE_VERSION} ${requirements_pc_ecore_con}" + ;; +esac + +# Eina, Eo, Eet, Ecore + +requirements_pc_ecore_con="ecore >= ${PACKAGE_VERSION} eet >= ${PACKAGE_VERSION} eo >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_con}" + +# gnuTLS + +if test "x${have_gnutls}" = "xyes" ; then + PKG_CHECK_EXISTS([gnutls >= 2.10.2], + [ + have_gnutls="yes" + AC_DEFINE([USE_GNUTLS], [1], [Use GnuTLS]) + requirements_pc_ecore_con="gnutls >= 2.10.2 ${requirements_pc_ecore_con}" + requirements_pc_deps_ecore_con="gnutls >= 2.10.2 ${requirements_pc_deps_ecore_con}" + ], + [have_gnutls="no"]) +fi + +# openssl + +have_openssl="no" +if test "x${with_tls}" = "xopenssl" ; then + PKG_CHECK_EXISTS([openssl], + [ + have_openssl="yes" + AC_DEFINE([USE_OPENSSL], [1], [Use OpenSSL]) + requirements_pc_ecore_con="openssl ${requirements_pc_ecore_con}" + requirements_pc_deps_ecore_con="openssl ${requirements_pc_deps_ecore_con}" + ], + [have_openssl="no"]) +fi + +# cURL + +have_curl="no" +if test "x${want_curl}" = "xyes" ; then + PKG_CHECK_EXISTS([libcurl], + [ + have_curl="yes" + AC_DEFINE([HAVE_CURL], [1], [Downloading with CURL]) + requirements_pc_ecore_con="libcurl ${requirements_pc_ecore_con}" + requirements_pc_deps_ecore_con="libcurl ${requirements_pc_deps_ecore_con}" + ], + [have_curl="no"]) +fi + +# c-ares + +have_cares="no" +if test "x${want_cares}" = "xyes" ; then + PKG_CHECK_EXISTS([libcares >= 1.6.1], + [ + have_cares="yes" + AC_DEFINE([HAVE_CARES], [1], [Build Ecore_Con_Info with c-ares support]) + requirements_pc_ecore_con="libcares >= 1.6.1 ${requirements_pc_ecore_con}" + requirements_pc_deps_ecore_con="libcares >= 1.6.1 ${requirements_pc_deps_ecore_con}" + ], + [have_cares="no"]) +fi + +AM_CONDITIONAL([HAVE_CARES], [test "x${have_cares}" = "xyes"]) + +# FIXME: to remove + +AC_DEFINE(ECORE_HAVE_EET, 1, [Define if Ecore_Con Eet_Connection helper is supported]) +AM_CONDITIONAL([ECORE_HAVE_EET], [true]) + +PKG_CHECK_MODULES([ECORE_CON], [${requirements_pc_deps_ecore_con}]) + +case "$host_os" in + mingw32ce*) + requirements_libs_ecore_con="${requirements_libs_ecore_con} -lws2" + ;; + mingw*) + requirements_libs_ecore_con="${requirements_libs_ecore_con} -lws2_32" + ;; +esac + +ECORE_CON_CFLAGS="${ECORE_CON_CFLAGS} ${LIBGCRYPT_CFLAGS}" +ECORE_CON_LIBS="${ECORE_CON_LIBS} ${LIBGCRYPT_LIBS}" +requirements_libs_ecore_con="${requirements_libs_ecore_con} ${LIBGCRYPT_LIBS}" + +### Checks for header files + +AC_CHECK_HEADERS([sys/socket.h]) +AC_CHECK_HEADERS([net/if.h], [], [], +[ +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +]) +AC_CHECK_HEADERS([sys/un.h], [], [], +[ +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +]) +AC_CHECK_HEADERS([arpa/inet.h arpa/nameser.h netinet/tcp.h netinet/in.h ws2tcpip.h netdb.h]) + +if test "x${ac_cv_header_netdb_h}" = "xno" && test "x${have_windows}" = "xno"; then + AC_MSG_ERROR([netdb.h is requested to have Ecore_Con. Exiting...]) +fi + +### Checks for types + +have_ipv6="no" +if test "x${want_ipv6}" != "xno" ; then + AC_CHECK_TYPES([struct ipv6_mreq], + [have_ipv6="yes"], + [have_ipv6="no"], + [[ +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_WS2TCPIP_H +# include +#endif + ]]) +fi + +if test "x${have_ipv6}" = "xyes" ; then + AC_DEFINE([HAVE_IPV6], 1, [Define if IPV6 is supported]) +fi + +AM_CONDITIONAL([HAVE_IPV6], [test "x${have_ipv6}" = "xyes"]) + +### Checks for structures + +### Checks for compiler characteristics + +EFL_CHECK_COMPILER_FLAGS([ECORE_CON], [-Wno-override-init -Wno-initializer-overrides]) + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_Con + + +#### Ecore_Ipc + +AC_MSG_NOTICE([Ecore_Ipc checks]) + +### Default values + +### Additional options to configure + +### Checks for programs + +### Checks for libraries + +# Eina, Ecore, Ecore_Con + +requirements_pc_ecore_ipc="ecore_con >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_ipc}" + +### Checks for header files + +AC_CHECK_HEADERS([winsock2.h]) + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_Ipc + + +#### Ecore_File + +AC_MSG_NOTICE([Ecore_File checks]) + +### Additional options to configure + +AC_ARG_ENABLE([poll], + [AC_HELP_STRING([--disable-poll], + [disable poll in the ecore_file module. @<:@default=enabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_poll="yes" + else + want_poll="no" + fi + ], + [want_poll="yes"]) + +AC_ARG_ENABLE([inotify], + [AC_HELP_STRING([--disable-inotify], + [disable inotify in the ecore_file module. @<:@default=enabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_inotify="yes" + else + want_inotify="no" + fi + ], + [want_inotify="yes"]) + +AC_ARG_ENABLE([atfile-source], + [AC_HELP_STRING([--disable-atfile-source], + [disable use of atfile source functions as openat and mkdirat @<:@default=detect@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + have_atfile_source="yes" + else + have_atfile_source="no" + fi], + [have_atfile_source=auto]) + +### Default values + +have_poll="no" +if test "x${want_poll}" = "xyes" ; then + AC_DEFINE([HAVE_POLL], [1], [File monitoring with polling]) + have_poll="yes" +fi + +have_notify_win32="no" + +case "$host_os" in + mingw32ce*) + ;; + mingw32*) + have_notify_win32="yes" + AC_DEFINE([HAVE_NOTIFY_WIN32], [1], [File monitoring with Windows notification]) + ;; +esac + +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 + +# FIXME: remove that +AC_DEFINE([BUILD_ECORE_CON], [1], [Ecore_Con is supported]) + +### Checks for programs + +### Checks for libraries + +# Escape library for compilation on PS3 + +if test "x${have_ps3}" = "xyes" ; then + requirements_pc_ecore_file="${requirements_pc_ecore_file} escape >= ${PACKAGE_VERSION}" +fi + +# Eina, Ecore, Ecore_Con + +requirements_pc_ecore_file="ecore_con >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_file}" + +### Checks for header files + +have_inotify="no" +if test "x${want_inotify}" = "xyes" ; then + AC_CHECK_HEADER([sys/inotify.h], + [ + AC_DEFINE([HAVE_INOTIFY], [1], [File monitoring with Inotify]) + have_inotify="yes" + ], + [have_inotify="no"]) +fi + +AC_MSG_CHECKING([whether inotify is to be used for filemonitoring]) +AC_MSG_RESULT(${have_inotify}) + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_File + + +#### Ecore_Input + +AC_MSG_NOTICE([Ecore_Input checks]) + +### Additional options to configure + +### Default values + +### Checks for programs + +### Checks for libraries + +## Eina, Ecore (ecore_input) + +requirements_pc_ecore_input="ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_input}" + +## Eina, Evas, Ecore, Ecore_Input (ecore_input_evas) + +requirements_pc_ecore_input_evas="ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} evas >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_input_evas}" + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_Input + + +#### Ecore_Cocoa + +AC_MSG_NOTICE([Ecore_Cocoa checks]) + +### Additional options to configure + +### Default values + +have_ecore_cocoa="no" +case "$host_os" in + darwin*) + have_ecore_cocoa="yes" + ;; +esac + +### Checks for programs + +### Checks for libraries + +## Eina, Ecore, Ecore_Input + +requirements_pc_ecore_cocoa="ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_cocoa}" + +### Checks for header files + +ECORE_COCOA_LIBS="" +if test "x${have_ecore_cocoa}" = "xyes" ; then + m4_ifdef([AC_PROG_OBJC], + [ + if test "x${have_gnu_objc}" = "xyes" ; then + AC_LANG_PUSH([Objective C]) + LIBS_save="$LIBS" + LIBS="$LIBS -framework Cocoa" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include + ]], + [[ +NSWindow *window; +window = [[NSWindow alloc] + initWithContentRect:NSMakeRect(0, 0, 1, 1) + styleMask:(NSTitledWindowMask) + backing:NSBackingStoreBuffered + defer:NO + screen:nil + ]; + ]])], + [ + have_ecore_cocoa="yes" + ECORE_COCOA_LIBS="-framework Cocoa" + requirements_libs_ecore_cocoa="-framework Cocoa" + ], + [have_ecore_cocoa="no"]) + LIBS="$LIBS_save" + AC_MSG_CHECKING([whether Cocoa framework is supported]) + AC_MSG_RESULT([${have_ecore_cocoa}]) + AC_LANG_POP([Objective C]) + fi + ]) +fi +AC_SUBST([ECORE_COCOA_LIBS]) + +AM_CONDITIONAL([HAVE_ECORE_COCOA], [test "x${have_ecore_cocoa}" = "xyes"]) + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_Cocoa + + +#### Ecore_DirectFB + +AC_MSG_NOTICE([Ecore_DirectFB checks]) + +### Additional options to configure + +### Default values + +### Checks for programs + +### Checks for libraries + +## Eina, Ecore + +requirements_pc_ecore_directfb="ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_directfb}" + +## DirectFB + +PKG_CHECK_MODULES([ECORE_DIRECTFB], + [directfb >= 0.9.16], + [ + have_ecore_directfb="yes" + requirements_pc_ecore_directfb="directfb >= 0.9.16 ${requirements_pc_ecore_directfb}" + ], + [have_ecore_directfb="no"]) + +AM_CONDITIONAL([HAVE_ECORE_DIRECTFB], [test "x${have_ecore_directfb}" = "xyes"]) + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_Directfb + + +#### Ecore_FB + +AC_MSG_NOTICE([Ecore_FB checks]) + +### Additional options to configure + +### Default values + +want_tslib="no" +case "$host_os" in + mingw*|darwin*) + ;; + *) + want_tslib="yes" + ;; +esac + +### Checks for programs + +### Checks for libraries + +## Eina, Ecore + +requirements_pc_ecore_fb="ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_fb}" + +## tslib + +PKG_CHECK_EXISTS([tslib-1.0], + [ + have_tslib="yes" + AC_DEFINE([HAVE_TSLIB], [1], [Build Ecore_FB Touchscreen Code]) + requirements_pc_ecore_fb="tslib-1.0 ${requirements_pc_ecore_fb}" + requirements_pc_deps_ecore_fb="tslib-1.0 ${requirements_pc_deps_ecore_fb}" + ], + [have_tslib="no"]) + +if test "x${have_tslib}" = "xno" ; then + PKG_CHECK_EXISTS([tslib], + [ + have_tslib="yes" + AC_DEFINE([HAVE_TSLIB], [1], [Build Ecore_FB Touchscreen Code]) + requirements_pc_ecore_fb="tslib ${requirements_pc_ecore_fb}" + requirements_pc_deps_ecore_fb="tslib-1.0 ${requirements_pc_deps_ecore_fb}" + ], + [have_tslib="no"]) +fi + +if test "x${have_tslib}" = "xno" ; then + AC_CHECK_HEADER([tslib.h], [have_tslib="yes"], [have_tslib="no"]) + + if test "x${have_tslib}" = "xyes" ; then + AC_CHECK_LIB([ts], [ts_open], + [ + have_tslib="yes" + AC_DEFINE([HAVE_TSLIB], [1], [Build Ecore_FB Touchscreen Code]) + requirements_libs_ecore_fb="-lts ${requirements_libs_ecore_fb}" + ], + [have_tslib="no"]) + fi + + if test "x${have_tslib}" = "xno" ; then + AC_CHECK_LIB([tslib], [ts_open], + [ + have_tslib="yes" + AC_DEFINE([HAVE_TSLIB], [1], [Build Ecore_FB Touchscreen Code]) + requirements_libs_ecore_fb="-ltslib ${requirements_libs_ecore_fb}" + ], + [have_tslib="no"]) + fi +fi + +if test "x${requirements_pc_deps_ecore_fb}" = "x" ; then + ECORE_FB_LIBS=${requirements_libs_ecore_fb} + AC_SUBST([ECORE_FB_LIBS]) +else + PKG_CHECK_MODULES([ECORE_FB], [${requirements_pc_deps_ecore_fb}]) +fi + +### Checks for header files + +have_ecore_fb="no" +AC_CHECK_HEADER([linux/fb.h], + [AC_CHECK_HEADER([linux/input.h], [have_ecore_fb="yes"], [have_ecore_fb="no"])]) + +AM_CONDITIONAL([HAVE_ECORE_FB], [test "x${have_ecore_fb}" = "xyes"]) + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_FB + + +#### Ecore_Psl1ght + +if test "x${have_ps3}" = "xyes" ; then + +AC_MSG_NOTICE([Ecore_Psl1ght checks]) + +### Additional options to configure + +### Default values + +### Checks for programs + +### Checks for libraries + +## Escape, Eina, Ecore, Ecore_Input + +requirements_pc_ecore_psl1ght="ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} escape >= ${PACKAGE_VERSION} ${requirements_pc_ecore_psl1ght}" + +requirements_libs_ecore_psl1ght="-lio -lsysutil -lgem -lcamera -lspurs" + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +fi + +#### End of Ecore_Psl1ght + + +#### Ecore_SDL + +AC_MSG_NOTICE([Ecore_SDL checks]) + +### Additional options to configure + +### Default values + +### Checks for programs + +### Checks for libraries + +# Escape library for compilation on PS3 + +if test "x${have_ps3}" = "xyes" ; then + requirements_pc_ecore_sdl="${requirements_pc_ecore_sdl} escape >= ${PACKAGE_VERSION}" +fi + +## Eina, Ecore + +requirements_pc_ecore_sdl="ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_sdl}" + +## SDL + +PKG_CHECK_MODULES([ECORE_SDL], + [sdl >= 1.2.0], + [ + have_ecore_sdl="yes" + requirements_pc_ecore_sdl="sdl >= 1.2.0 ${requirements_pc_ecore_sdl}" + ], + [have_ecore_sdl="no"]) + +if test "x${have_ecore_sdl}" = "xno" ; then + AC_PATH_GENERIC([sdl], [], + [ + have_ecore_sdl="yes" + requirements_libs_ecore_sdl="${SDL_LIBS} ${requirements_libs_ecore_sdl}" + ECORE_SDL_CFLAGS=${SDL_CFLAGS} + ECORE_SDL_LIBS=${SDL_LIBS} + ], + [have_ecore_sdl="no"]) +fi + +if test "x${have_ecore_sdl}" = "xyes" ; then + PKG_CHECK_EXISTS([sdl >= 1.3.0], + [AC_DEFINE(BUILD_ECORE_EVAS_SDL_130, 1, [Support for SVN SDL])]) +fi + +AM_CONDITIONAL([HAVE_ECORE_SDL], [test "x${have_ecore_sdl}" = "xyes"]) + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_SDL + + +#### Ecore_Wayland + +AC_MSG_NOTICE([Ecore_Wayland checks]) + +### Additional options to configure + +### Default values + +### Checks for programs + +### Checks for libraries + +## Evil, Eina, Ecore, Ecore_Input + +requirements_pc_ecore_wayland="ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} evil >= ${PACKAGE_VERSION} ${requirements_pc_ecore_wayland}" + +## Wayland + +PKG_CHECK_MODULES([ECORE_WAYLAND], + [wayland-client wayland-cursor xkbcommon], + [ + have_ecore_wayland="yes" + requirements_pc_ecore_wayland="wayland-client wayland-cursor xkbcommon ${requirements_pc_ecore_wayland}" + ], + [have_ecore_wayland="no"]) + +AM_CONDITIONAL([HAVE_ECORE_WAYLAND], [test "x${have_ecore_wayland}" = "xyes"]) + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_Wayland + + +#### Ecore_Win32 + +if test "x${have_win32}" = "xyes" ; then + +AC_MSG_NOTICE([Ecore_Win32 checks]) + +### Additional options to configure + +### Default values + +### Checks for programs + +### Checks for libraries + +## Evil, Eina, Ecore, Ecore_Input + +requirements_pc_ecore_win32="ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} evil >= ${PACKAGE_VERSION} ${requirements_pc_ecore_win32}" + +ECORE_WIN32_LIBS="-lole32 -lgdi32" +requirements_libs_ecore_win32="-lole32 -lgdi32 ${requirements_libs_ecore_win32}" +AC_SUBST([ECORE_WIN32_LIBS]) + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +fi + +#### End of Ecore_Win32 + + +#### Ecore_WinCE + +if test "x${have_wince}" = "xyes" ; then + +AC_MSG_NOTICE([Ecore_WinCE checks]) + +### Additional options to configure + +### Default values + +### Checks for programs + +### Checks for libraries + +## Evil, Eina, Ecore, Ecore_Input + +requirements_pc_ecore_wince="ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} evil >= ${PACKAGE_VERSION} ${requirements_pc_ecore_wince}" + + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +fi + +#### End of Ecore_WinCE + + +#### Ecore_X + +AC_MSG_NOTICE([Ecore_X checks]) + +### Additional options to configure + +# FIXME: recycle that with evas +AC_ARG_WITH([ecore-x-backend], + [AC_HELP_STRING([--ecore-x-backend=BACKEND], + [use the predefined x11 backends, one of: xlib, xcb and none. @<:@default=xlib@:>@])], + [ecore_x_backend=${withval}], + [ecore_x_backend="xlib"]) + +case "${ecore_x_backend}" in + xlib) + have_ecore_x_xlib="yes" + ;; + xcb) + have_ecore_x_xcb="yes" + ;; + none) + have_ecore_x_xcb="no" + have_ecore_x_xlib="no" + ;; + *) + AC_MSG_ERROR([Unknown x11 backend --with-ecore-x-backend=${ecore_x_backend}]) + ;; +esac + +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], + [want_ecore_x_composite="yes"]) + +AC_ARG_ENABLE(ecore-x-cursor, + [AC_HELP_STRING([--disable-ecore-x-cursor], + [disable the ecore_x support for Xcursor library. @<:@default=detect@:>@])], + [want_ecore_x_cursor=$enableval], + [want_ecore_x_cursor="yes"]) + +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], + [want_ecore_x_damage="yes"]) + +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], + [want_ecore_x_dpms="yes"]) + +AC_ARG_ENABLE(ecore-x-dri, + [AC_HELP_STRING([--disable-ecore-x-dri], + [disable the ecore_x support for DRI extension. @<:@default=detect@:>@])], + [want_ecore_x_dri=$enableval], + [want_ecore_x_dri="yes"]) + +AC_ARG_ENABLE(ecore-x-gesture, + [AC_HELP_STRING([--enable-ecore-x-gesture], + [enable the ecore_x support for Xgesture extension. @<:@default=detect@:>@])], + [want_ecore_x_gesture=$enableval], + [want_ecore_x_gesture="yes"]) + +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], + [want_ecore_x_input="yes"]) + +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], + [want_ecore_x_randr="yes"]) + +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], + [want_ecore_x_render="yes"]) + +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], + [want_ecore_x_screensaver="yes"]) + +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], + [want_ecore_x_shape="yes"]) + +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], + [want_ecore_x_sync="yes"]) + +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], + [want_ecore_x_xfixes="yes"]) + +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], + [want_ecore_x_xinerama="yes"]) + +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], + [want_ecore_x_xprint="yes"]) + +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], + [want_ecore_x_xtest="yes"]) + +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"]) + +### Default values + +have_ecore_x="no" +use_Xcursor="no" + +AC_MSG_CHECKING([which X11 backend is to be built]) +AC_MSG_RESULT([${ecore_x_backend}]) + +### Checks for programs + +### Checks for libraries + +## Eina, Ecore, Ecore_Input + +requirements_pc_ecore_x="ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_x}" + +## Xlib +if test "x${have_ecore_x_xlib}" = "xyes" ; then + AC_PATH_XTRA +fi + +## XCB + +### Checks for header files + +AC_CHECK_DECL([MAXHOSTNAMELEN], [FOUND_MAXHOSTNAMELEN=yes]) + +if test "x${FOUND_MAXHOSTNAMELEN}" != "xyes" ; then + FOUND_MAXHOSTNAMELEN="not found" + + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ +#include + ]], + [[ +int h = MAXHOSTNAMELEN; + ]]) + ], + [ + FOUND_MAXHOSTNAMELEN="sys/param.h" + AC_DEFINE([NEED_SYS_PARAM_H], [1], [Define to 1 if you need to define MAXHOSTNAMELEN]) + ]) + + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM( + [[ +#include + ]], + [[ +int h = MAXHOSTNAMELEN; + ]]) + ], + [ + FOUND_MAXHOSTNAMELEN="netdb.h" + AC_DEFINE([NEED_NETDB_H], [1], [Define to 1 if you need to define MAXHOSTNAMELEN]) + ]) + + AC_MSG_CHECKING([for header that defines MAXHOSTNAMELEN]) + AC_MSG_RESULT([$FOUND_MAXHOSTNAMELEN]) +fi + +## Xlib +if test "x${have_ecore_x_xlib}" = "xyes" ; then + AC_CHECK_HEADERS([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$want_ecore_x_cursor" = "xyes"; then + CFLAGS_save="${CFLAGS}" + CFLAGS="$x_cflags $x_includes" + AC_CHECK_HEADER([X11/Xcursor/Xcursor.h], + [use_Xcursor="yes"], + [use_Xcursor="no"], + [#include ]) + CFLAGS="$CFLAGS_save" + fi +fi + +## XCB +if test "x${have_ecore_x_xcb}" = "xyes" ; then + KEYSYMDEFDIR=`$PKG_CONFIG --variable=includedir xproto`/X11 + FILES="keysymdef.h XF86keysym.h Sunkeysym.h DECkeysym.h HPkeysym.h" + for i in $FILES; do + if test -f "$KEYSYMDEFDIR/$i"; then + KEYSYMDEFS="$KEYSYMDEFS $KEYSYMDEFDIR/$i" + elif test "x$i" = "xkeysymdef.h"; then + AC_MSG_ERROR([Cannot find keysymdef.h]) + fi + done + AC_MSG_CHECKING([keysym definitions]) + AC_MSG_RESULT([$KEYSYMDEFS]) + AC_SUBST([KEYSYMDEFS]) +fi + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +## Xlib + +if test "x${have_ecore_x_xlib}" = "xyes" ; then + AC_CHECK_LIB([X11], [XCreateImage], [have_ecore_x_xlib="yes"], [have_ecore_x_xlib="no"]) +fi + +if test "x${have_ecore_x_xlib}" = "xyes" ; then + AC_CHECK_LIB([Xext], [XShmCreateImage], [have_ecore_x_xlib="yes"], [have_ecore_x_xlib="no"]) + have_ecore_x="yes" +fi + +if test "x${have_ecore_x_xlib}" = "xyes" && test "x$want_ecore_x_cursor" = "xyes" ; then + AC_CHECK_LIB([Xcursor], + [XcursorImageLoadCursor], + [ + use_Xcursor="yes" + AC_DEFINE([ECORE_XCURSOR], 1, [Build support for Xcursor]) + Xcursor_libs="-lXcursor" + ], + [use_Xcursor="no"], + [$x_libs -lXrender]) + ECORE_X_CFLAGS="${ECORE_X_CFLAGS} $x_cflags $x_includes" + ECORE_X_LIBS="${ECORE_X_LIBS} ${Xcursor_libs}" +fi + +if test "x${have_ecore_x_xlib}" = "xyes" ; then + 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([Xgesture], [gesture.h], [Xgesture], [XGestureQueryExtension], [$want_ecore_x_gesture]) + 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]) + + AC_DEFINE([HAVE_ECORE_X_XLIB], [1], [Defined to 1 if Xlib is enabled.]) +fi + +## XCB + +# FIXME: remove OLD_XCB_VERSION support + +if test "x${have_ecore_x_xcb}" = "xyes" ; then + + PKG_CHECK_EXISTS([x11-xcb xcb xcb-shm xcb-event xcb-icccm >= 0.3.8 xcb-util >= 0.3.8 xcb-image xcb-keysyms >= 0.3.8], + [ + have_ecore_x_xcb="yes" + have_ecore_x="yes" + requirements_pc_ecore_x="${requirements_pc_ecore_x} x11-xcb xcb xcb-shm xcb-event xcb-icccm >= 0.3.8 xcb-util >= 0.3.8 xcb-image xcb-keysyms >= 0.3.8" + requirements_pc_deps_ecore_x="${requirements_pc_deps_ecore_x} x11-xcb xcb xcb-shm xcb-event xcb-icccm >= 0.3.8 xcb-util >= 0.3.8 xcb-image xcb-keysyms >= 0.3.8" + ], + [AC_MSG_ERROR([Ecore_X with XCB backend enabled but XCB not available. Exiting...])]) +fi + +if test "x${have_ecore_x_xcb}" = "xyes" ; then + if test "x${have_pixman}" = "xyes" ; then + requirements_pc_ecore_x="${requirements_pc_ecore_x} pixman-1" + requirements_pc_deps_ecore_x="${requirements_pc_deps_ecore_x} pixman-1" + fi + + if test "x$want_ecore_x_composite" != "xno"; then + PKG_CHECK_EXISTS([xcb-composite], + [ + have_ecore_x_xcb_composite="yes" + requirements_pc_ecore_x="xcb-composite ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-composite ${requirements_pc_deps_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_EXISTS([xcb-damage], + [ + have_ecore_x_xcb_damage="yes" + requirements_pc_ecore_x="xcb-damage ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-damage ${requirements_pc_deps_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_EXISTS([xcb-dpms], + [ + have_ecore_x_xcb_dpms="yes" + requirements_pc_ecore_x="xcb-dpms ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-dpms ${requirements_pc_deps_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_EXISTS([xcb-randr], + [ + have_ecore_x_xcb_randr="yes" + requirements_pc_ecore_x="xcb-randr ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-randr ${requirements_pc_deps_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_EXISTS([xcb-render], + [ + have_ecore_x_xcb_render="yes" + requirements_pc_ecore_x="xcb-render ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-render ${requirements_pc_deps_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_EXISTS([xcb-screensaver], + [ + have_ecore_x_xcb_screensaver="yes" + requirements_pc_ecore_x="xcb-screensaver ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-screensaver ${requirements_pc_deps_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_EXISTS([xcb-shape], + [ + have_ecore_x_xcb_shape="yes" + requirements_pc_ecore_x="xcb-shape ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-shape ${requirements_pc_deps_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_gesture" != "xno"; then + PKG_CHECK_EXISTS([xcb-gesture], + [ + have_ecore_x_xcb_gesture="yes" + requirements_pc_ecore_x="xcb-gesture ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-gesture ${requirements_pc_deps_ecore_x}" + AC_DEFINE([ECORE_XCB_XGESTURE], [1], [Build support for XCB xgesture]) + ], + [have_ecore_x_xcb_gesture="no"]) + else + have_ecore_x_xcb_gesture="no" + AC_MSG_NOTICE([gesture extension explicitly disabled]) + fi + + if test "x$want_ecore_x_sync" != "xno"; then + PKG_CHECK_EXISTS([xcb-sync], + [ + have_ecore_x_xcb_sync="yes" + requirements_pc_ecore_x="xcb-sync ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-sync ${requirements_pc_deps_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_EXISTS([xcb-xfixes], + [ + have_ecore_x_xcb_xfixes="yes" + requirements_pc_ecore_x="xcb-xfixes ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-xfixes ${requirements_pc_deps_ecore_x}" + AC_DEFINE([ECORE_XCB_XFIXES], [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_EXISTS([xcb-xinerama], + [ + have_ecore_x_xcb_xinerama="yes" + requirements_pc_ecore_x="xcb-xinerama ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-xinerama ${requirements_pc_deps_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_EXISTS([xcb-xprint], + [ + have_ecore_x_xcb_xprint="yes" + requirements_pc_ecore_x="xcb-xprint ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-xprint ${requirements_pc_deps_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_EXISTS([xcb-xtest], + [ + have_ecore_x_xcb_xtest="yes" + requirements_pc_ecore_x="xcb-xtest ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-xtest ${requirements_pc_deps_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 + +# input extension disabled currently in xcb as xcb-input has some issues + want_ecore_x_input="no" + if test "x$want_ecore_x_input" != "xno"; then + PKG_CHECK_EXISTS([xcb-xinput], + [ + have_ecore_x_xcb_xinput="yes" + requirements_pc_ecore_x="xcb-xinput ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-xinput ${requirements_pc_deps_ecore_x}" + AC_DEFINE([ECORE_XCB_XINPUT], [1], [Build support for XCB input]) + ], + [have_ecore_x_xcb_xinput="no"]) + else + have_ecore_x_xcb_xinput="no" + AC_MSG_NOTICE([input extension explicitly disabled]) + fi + + if test "x$want_ecore_x_cursor" != "xno"; then + PKG_CHECK_EXISTS([xcb-render xcb-renderutil], + [ + have_ecore_x_xcb_cursor="yes" + requirements_pc_ecore_x="xcb-render xcb-renderutil ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-render xcb-renderutil ${requirements_pc_deps_ecore_x}" + AC_DEFINE([ECORE_XCB_CURSOR], [1], [Build support for XCB cursor]) + ], + [have_ecore_x_xcb_cursor="no"]) + else + have_ecore_x_xcb_cursor="no" + AC_MSG_NOTICE([cursor extension explicitly disabled]) + fi + +# dri extension disabled currently in xcb + want_ecore_x_dri="no" + if test "x$want_ecore_x_dri" != "xno"; then + PKG_CHECK_EXISTS([xcb-dri2], + [ + have_ecore_x_xcb_dri="yes" + requirements_pc_ecore_x="xcb-dri2 ${requirements_pc_ecore_x}" + requirements_pc_deps_ecore_x="xcb-dri2 ${requirements_pc_deps_ecore_x}" + AC_DEFINE([ECORE_XCB_DRI], [1], [Build support for XCB dri]) + ], + [have_ecore_x_xcb_dri="no"]) + else + have_ecore_x_xcb_dri="no" + AC_MSG_NOTICE([dri extension explicitly disabled]) + fi + + PKG_CHECK_MODULES([ECORE_X], [${requirements_pc_deps_ecore_x}]) + EFL_CHECK_FUNCS([ECORE_X], [dlopen iconv]) + AC_DEFINE([HAVE_ECORE_X_XCB], [1], [Defined to 1 if XCB is enabled.]) + have_ecore_x_xcb_define="-DHAVE_ECORE_X_XCB" + AC_SUBST([have_ecore_x_xcb_define]) +fi + +requirements_libs_ecore_x="${requirements_libs_ecore_x} ${ECORE_X_LIBS}" + +AC_SUBST([ECORE_X_CFLAGS]) +AC_SUBST([ECORE_X_LIBS]) + +AM_CONDITIONAL([HAVE_ECORE_X_XLIB], [test "x${have_ecore_x_xlib}" = "xyes"]) +AM_CONDITIONAL([HAVE_ECORE_X_XCB], [test "x${have_ecore_x_xcb}" = "xyes"]) +AM_CONDITIONAL([HAVE_ECORE_X], [test "x${have_ecore_x}" = "xyes"]) + +#### End of Ecore_X + + +#### Ecore_Imf + +AC_MSG_NOTICE([Ecore_Imf checks]) + +### Additional options to configure + +### Default values + +want_ecore_imf="yes" +want_ecore_imf_xim="no" +want_ecore_imf_scim="no" +want_ecore_imf_ibus="no" + +case "$host_os" in + mingw32ce*) + want_ecore_imf="no" + ;; + mingw*) + want_ecore_imf="yes" + ;; + darwin*) + want_ecore_imf="yes" + ;; + *) + want_ecore_imf="yes" + want_ecore_imf_xim="yes" + want_ecore_imf_scim="yes" + want_ecore_imf_ibus="yes" + ;; +esac + +### Checks for programs + +### Checks for libraries + +# Escape library for compilation on PS3 + +if test "x${have_ps3}" = "xyes" ; then + requirements_pc_ecore_imf="${requirements_pc_ecore_imf} escape >= ${PACKAGE_VERSION}" + requirements_pc_ecore_imf_evas="${requirements_pc_ecore_imf_evas} escape >= ${PACKAGE_VERSION}" +fi + +## Eina, Ecore (ecore_imf) + +requirements_pc_ecore_imf="ecore >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_imf}" + +## Eina, Evas, Ecore, Ecore_Imf (ecore_imf_evas) + +requirements_pc_ecore_imf_evas="ecore_imf >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} evas >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_imf_evas}" + +## modules + +# ibus + +have_ecore_imf_ibus="no" +if test "x${want_ecore_imf_ibus}" = "xyes" && test "x${have_glib}" = "xyes" ; then + PKG_CHECK_MODULES([IBUS], + [ibus-1.0 >= 1.4], + [ + have_ecore_imf_ibus="yes" + AC_DEFINE([BUILD_ECORE_IMF_IBUS], [1], [Ecore Imf IBUS Support]) + ], + [have_ecore_imf_ibus="no"]) + IBUS_CFLAGS="${GLIB_CFLAGS} ${IBUS_CFLAGS}"² + IBUS_LIBS="${GLIB_LIBS} ${IBUS_LIBS}" +fi + +AM_CONDITIONAL([BUILD_ECORE_IMF_IBUS], [test "x${have_ecore_imf_ibus}" = "xyes"]) + +# scim + +if test "x${want_ecore_imf_scim}" = "xyes" ; then + PKG_CHECK_MODULES([SCIM], + [scim], + [ + have_ecore_imf_scim="yes" + AC_DEFINE([BUILD_ECORE_IMF_SCIM], [1], [Ecore Imf SCIM Support]) + ], + [have_ecore_imf_scim="no"]) +fi + +AM_CONDITIONAL([BUILD_ECORE_IMF_SCIM], [test "x${have_ecore_imf_scim}" = "xyes"]) + +# xim + +have_ecore_imf_xim="no" +if test "x${want_xim}" = "xyes" && test "x${want_ecore_imf_xim}" = "xyes" ; then + have_ecore_imf_xim="yes" + AC_DEFINE([ENABLE_XIM], [1], [Enable X Input Method]) +fi + +AM_CONDITIONAL([BUILD_ECORE_IMF_XIM], [test "x${have_ecore_imf_xim}" = "xyes"]) + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_Imf + + +#### Ecore_Evas + +AC_MSG_NOTICE([Ecore_Evas checks]) + +### Additional options to configure + +### Default values + +have_ecore_evas="yes" + +want_ecore_evas_software_buffer="yes" +want_ecore_evas_software_x11="no" +want_ecore_evas_opengl_x11="no" +want_ecore_evas_software_xcb="no" +want_ecore_evas_software_gdi="no" +want_ecore_evas_software_ddraw="no" +want_ecore_evas_software_sdl="no" +want_ecore_evas_gl_sdl="no" +want_ecore_evas_gl_cocoa="no" +want_ecore_evas_directfb="no" +want_ecore_evas_fb="no" +want_ecore_evas_ews="yes" +want_ecore_evas_extn="yes" +want_ecore_evas_wayland_shm="no" +want_ecore_evas_wayland_egl="no" + +case "$host_os" in + mingw32ce*) + want_ecore_evas_extn="no" + ;; + mingw*) + want_ecore_evas_software_gdi="yes" + want_ecore_evas_software_ddraw="yes" + want_ecore_evas_software_sdl="yes" + want_ecore_evas_gl_sdl="yes" + ;; + darwin*) + want_ecore_evas_software_sdl="yes" + want_ecore_evas_gl_sdl="yes" + want_ecore_evas_gl_cocoa="yes" + ;; + *) + want_ecore_evas_software_x11="yes" + want_ecore_evas_opengl_x11="yes" + want_ecore_evas_software_xcb="no" + want_ecore_evas_software_sdl="yes" + want_ecore_evas_gl_sdl="yes" + want_ecore_evas_gl_cocoa="no" + want_ecore_evas_directfb="yes" + want_ecore_evas_fb="yes" + want_ecore_evas_wayland_shm="yes" + want_ecore_evas_wayland_egl="yes" + ;; +esac + +### Checks for programs + +### Checks for libraries + +## Eina, Evas, Ecore, Ecore_Input + +requirements_pc_ecore_evas="ecore-input-evas >= ${PACKAGE_VERSION} ecore-input >= ${PACKAGE_VERSION} ecore >= ${PACKAGE_VERSION} evas >= ${PACKAGE_VERSION} eina >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}" + +## modules + +# ecore_evas_buffer + +ECORE_EVAS_CHECK_MODULE_FULL([software-buffer], + [${have_evas_engine_buffer}], + [${want_ecore_evas_software_buffer}], + [Software Buffer], + [yes]) + +# ecore_evas_cocoa + +ECORE_EVAS_CHECK_MODULE_FULL([opengl-cocoa], + [${have_evas_engine_gl_cocoa}], + [${want_ecore_evas_gl_cocoa}], + [OpenGL Cocoa], + [${have_ecore_cocoa}], + [requirements_pc_ecore_evas="ecore-cocoa >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}"]) + +# ecore_evas_directfb + +ECORE_EVAS_CHECK_MODULE_FULL([directfb], + [${have_evas_engine_directfb}], + [${want_ecore_evas_directfb}], + [DirectFB], + [${have_ecore_directfb}], + [requirements_pc_ecore_evas="ecore-directfb >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}"]) + +# ecore_evas_ews + +ECORE_EVAS_CHECK_MODULE_FULL([ews], + [${have_evas_engine_buffer}], + [${want_ecore_evas_ews}], + [Ecore Evas Single Process Windowing System], + [yes], []) + +# ecore_evas_extn + +have_extn="yes" +if test "x${have_ecore_ipc}" = "xno" || \ + test "x${have_ecore_evas_software_buffer}" = "xno" || \ + test "x${have_shm_open}" = "xno" ; then + have_extn="no" +fi + +dnl THIS IS SPECIAL - dont use normal ECORE_EVAS_CHECK_MODULE +have_ecore_evas_extn="no" +if test "x${want_ecore_evas_extn}" = "xyes" && \ + test "x${have_extn}" = "xyes" && \ + test "x${have_ecore_evas}" = "xyes"; then + have_ecore_evas_extn="yes" + AC_DEFINE([BUILD_ECORE_EVAS_EXTN], [1], [Support for Extn Engine in Ecore_Evas]) + requirements_pc_ecore_evas="ecore-ipc >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}" +fi + +# ecore_evas_fb + +ECORE_EVAS_CHECK_MODULE_FULL([fb], + [${have_evas_engine_fb}], + [${want_ecore_evas_fb}], + [Linux Framebuffer], + [${have_ecore_fb}], + [requirements_pc_ecore_evas="ecore-fb >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}"]) + +# ecore_evas_psl1ght + +ECORE_EVAS_CHECK_MODULE_FULL([psl1ght], + [${have_evas_engine_psl1ght}], + [${want_ecore_evas_psl1ght}], + [PSL1GHT], + [${have_ecore_psl1ght}], + [requirements_pc_ecore_evas="ecore-psl1ght >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}"]) + +# ecore_evas_sdl + +ECORE_EVAS_CHECK_MODULE_FULL([software-sdl], + [${have_evas_engine_software_sdl}], + [${want_ecore_evas_software_sdl}], + [Software SDL], + [${have_ecore_sdl}], + [requirements_ecore_evas="ecore-sdl >= ${PACKAGE_VERSION} ${requirements_ecore_evas}"]) + +ECORE_EVAS_CHECK_MODULE_FULL([opengl-sdl], + [${have_evas_engine_gl_sdl}], + [${want_ecore_evas_gl_sdl}], + [OpenGL SDL], + [${have_ecore_sdl}], + [requirements_ecore_evas="ecore-sdl >= ${PACKAGE_VERSION} ${requirements_ecore_evas}"]) + +# ecore_evas_wayland + +ECORE_EVAS_CHECK_MODULE_FULL([wayland-shm], + [wayland-shm], + [${want_ecore_evas_wayland_shm}], + [Wayland Shm], + [${have_ecore_wayland}], + [requirements_pc_ecore_evas="ecore-wayland >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}"]) + +ECORE_EVAS_CHECK_MODULE_FULL([wayland-egl], + [wayland-egl egl >= 7.10], + [${want_ecore_evas_wayland_egl}], + [Wayland Egl], + [${have_ecore_wayland}], + [ + PKG_CHECK_MODULES([WAYLAND_EGL], [wayland-egl], [have_wayland_egl="yes"], [have_wayland_egl="no"]) + if test "x${have_wayland_egl}" = "xyes" ; then + requirements_pc_ecore_evas="wayland-egl egl >= 7.10 ecore-wayland >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}" + requirements_pc_deps_ecore_evas="wayland-egl egl >= 7.10 ecore-wayland >= ${PACKAGE_VERSION} ${requirements_pc_deps_ecore_evas}" + fi + ]) + +# ecore_evas_win32 +ECORE_EVAS_CHECK_MODULE_FULL([software-gdi], + [${have_evas_engine_software_gdi}], + [${want_ecore_evas_software_gdi}], + [Software GDI], + [${have_win32}]) + +ECORE_EVAS_CHECK_MODULE_FULL([software-ddraw], + [${have_evas_engine_software_ddraw}], + [${want_ecore_evas_software_ddraw}], + [Software DirectDraw], + [${have_win32}]) + +if test "x${have_ecore_evas_software_gdi}" = "xyes" || \ + test "x${have_ecore_evas_software_ddraw}" = "xyes" ; then + AC_DEFINE(BUILD_ECORE_EVAS_WIN32, 1, [Support for Win32 Engine in Ecore_Evas]) + requirements_pc_ecore_evas="ecore-win32 >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}" +fi + +# ecore_evas_x11 + +ECORE_EVAS_CHECK_MODULE_FULL([software-x11], + [${have_evas_engine_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}" = "xstatic"; then + have_ecore_evas_software_xlib="yes" + fi + if test "x${have_ecore_evas_software_xlib}" = "xyes" && test "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" = "xstatic"; then + have_ecore_evas_software_xcb="yes" + fi + if test "x$have_ecore_evas_software_xcb" = "xyes" && test "x${have_ecore_x_xcb}" = "xyes" ; then + AC_DEFINE([BUILD_ECORE_EVAS_SOFTWARE_XCB], [1], [Evas Software XCB Engine Support]) + fi +fi + +# ecore_evas_opengl_x11 + +ECORE_EVAS_CHECK_MODULE_FULL([opengl-x11], + [${have_evas_engine_gl_x11}], + [${want_ecore_evas_opengl_x11}], + [OpenGL Xlib], + [${have_ecore_x}]) + +have_ecore_evas_opengl_xlib="no" +have_ecore_evas_opengl_xcb="no" +if test "x${have_ecore_evas_opengl_x11}" = "xyes" || test "x${have_ecore_evas_opengl_x11}" = "xstatic" ; then + have_ecore_evas_opengl_xlib=`${PKG_CONFIG} --variable=Xlib evas-opengl-x11` + if test "x${have_ecore_evas_opengl_xlib}" = "xyes" ; then + AC_DEFINE([BUILD_ECORE_EVAS_OPENGL_XLIB], [1], [OpenGL Xlib rendering backend]) + fi + +# opengl does not work with xcb (yet) + have_ecore_evas_opengl_xcb=`${PKG_CONFIG} --variable=XCB evas-opengl-x11` + if test "x${have_ecore_evas_opengl_xcb}" = "xstatic"; then + have_ecore_evas_opengl_xcb="yes" + fi + if test "x${have_ecore_evas_opengl_xcb}" = "xyes" && test "x${have_ecore_x_xcb}" = "xyes" ; then + PKG_CHECK_MODULES([XCB_X11], + [x11-xcb], + [ + have_ecore_x_opengl_xcb="yes" + requirements_ecore_x="x11-xcb ${requirements_ecore_x}" + AC_DEFINE([BUILD_ECORE_X_OPENGL_XCB], [1], [Build support for XCB-based OpenGL]) + AC_DEFINE([BUILD_ECORE_EVAS_OPENGL_XCB], [1], [OpenGL XCB rendering backend]) + ], + [have_ecore_x_opengl_xcb="no"]) + else + have_ecore_x_opengl_xcb="no" + AC_MSG_NOTICE(["XCB-based OpenGL explicitly disabled"]) + fi +fi + +if test "x$have_ecore_evas_software_x11" = "xyes" || \ + test "x$have_ecore_evas_opengl_x11" = "xyes" || \ + test "x$have_ecore_evas_software_xcb" = "xyes"; then + AC_DEFINE([BUILD_ECORE_EVAS_X11], [1], [Support for X Window Engines in Ecore_Evas]) + requirements_pc_ecore_evas="ecore-x >= ${PACKAGE_VERSION} ${requirements_pc_ecore_evas}" +fi + +if test "x${requirements_pc_deps_ecore_evas}" = "x" ; then + ECORE_EVAS_CFLAGS="" + ECORE_EVAS_LIBS="" + AC_SUBST([ECORE_EVAS_CFLAGS]) + AC_SUBST([ECORE_EVAS_LIBS]) +else + PKG_CHECK_MODULES([ECORE_EVAS], [${requirements_pc_deps_ecore_evas}]) +fi + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +#### End of Ecore_Evas + + +AC_CONFIG_FILES([ +Makefile +data/Makefile +doc/Makefile +doc/Doxyfile +src/Makefile +src/benchmarks/Makefile +src/benchmarks/eina/Makefile +src/benchmarks/eo/Makefile +src/examples/Makefile +src/examples/eina/Makefile +src/examples/eet/Makefile +src/examples/eo/Makefile +src/examples/evas/Makefile +src/lib/eina/eina_config.h +spec/efl.spec +pc/evil.pc +pc/eina.pc +pc/eet.pc +pc/eo.pc +pc/evas-directfb.pc +pc/evas-fb.pc +pc/evas-opengl-x11.pc +pc/evas-opengl-sdl.pc +pc/evas-opengl-cocoa.pc +pc/evas-psl1ght.pc +pc/evas-software-buffer.pc +pc/evas-software-x11.pc +pc/evas-software-gdi.pc +pc/evas-software-ddraw.pc +pc/evas-software-sdl.pc +pc/evas-wayland-shm.pc +pc/evas-wayland-egl.pc +pc/evas.pc +pc/ecore.pc +pc/ecore-con.pc +pc/ecore-ipc.pc +pc/ecore-file.pc +pc/ecore-input.pc +pc/ecore-input-evas.pc +pc/ecore-cocoa.pc +pc/ecore-directfb.pc +pc/ecore-fb.pc +pc/ecore-sdl.pc +pc/ecore-win32.pc +pc/ecore-wince.pc +pc/ecore-x.pc +pc/ecore-evas.pc +pc/ecore-imf.pc +pc/ecore-imf-evas.pc +pc/embryo.pc +$po_makefile_in +]) + +AC_OUTPUT + + +#### Info + +echo +echo +echo +echo "------------------------------------------------------------------------" +echo "$PACKAGE_NAME $PACKAGE_VERSION" +echo "------------------------------------------------------------------------" +echo +echo "Configuration Options Summary:" +echo +echo " OS...................: ${host_os}" +if test "x${have_windows}" = "xyes" ; then + echo " Windows version......: ${_efl_windows_version}" +fi +echo " Build Profile........: ${build_profile}" +echo " Threads Type.........: ${efl_have_threads}" +echo " spinlocks..........: ${efl_have_posix_threads_spinlock}" +echo " barrier............: ${efl_have_pthread_barrier}" +echo " affinity...........: ${efl_have_setaffinity}" +echo " Cryptographic System.: ${build_crypto}" +echo + +echo "Evas:" +echo +echo " Engines:" +echo " Software Memory Buffer.....: $have_evas_engine_buffer" +echo " Software X11...............: $have_evas_engine_software_x11 (Xlib: $have_evas_engine_software_xlib) (XCB: $have_evas_engine_software_xcb)" +echo $ECHO_N " OpenGL X11.................: $have_evas_engine_gl_x11 (Xlib: $have_evas_engine_gl_xlib) (XCB: $have_evas_engine_gl_xcb) $ECHO_C" +if test "x$have_evas_engine_gl_x11" = "xyes"; then + echo "(GLES: $gl_flavor_gles)" +else + echo +fi +echo " Software GDI...............: $have_evas_engine_software_gdi" +echo " Software DirectDraw........: $have_evas_engine_software_ddraw" +echo $ECHO_N " OpenGL SDL.................: $have_evas_engine_gl_sdl $ECHO_C" +if test "x$have_evas_engine_gl_sdl" = "xyes"; then + echo "(GLES: $gl_flavor_gles)" +else + echo +fi +echo " OpenGL Cocoa...............: $have_evas_engine_gl_cocoa" +echo " Software Framebuffer.......: $have_evas_engine_fb" +echo " DirectFB...................: $have_evas_engine_directfb" +echo " PSL1GHT....................: $have_evas_engine_psl1ght" +echo " Wayland Shm................: $have_evas_engine_wayland_shm" +echo " Wayland Egl................: $have_evas_engine_wayland_egl" +echo +echo " Image Loaders:" +echo " JPEG region decode......: $have_jpeg_region" +echo " WEBP....................: $have_evas_image_loader_webp" +echo " GIF.....................: $have_evas_image_loader_gif" +echo " TIFF....................: $have_evas_image_loader_tiff" +echo " SVG.....................: $have_evas_image_loader_svg" +echo +echo " Font Searching Systems:" +echo " Fontconfig..............: $have_fontconfig" +echo +echo " Font Rendering Helpers:" +echo " Fribidi.................: $have_fribidi" +echo " Harfbuzz................: $have_harfbuzz" +# FIXME: add non freetype2 font engine support +# FIXME: make freetype2 optional +echo +echo " CPU Specific Extensions:" +echo " MMX/SSE.................: $build_cpu_mmx" +echo " SSE3....................: $build_cpu_sse3" +echo " ALTIVEC.................: $build_cpu_altivec" +echo " NEON....................: $build_cpu_neon" +echo +echo " Features:" +echo " Cache Server 2..........: $want_evas_cserve2" +echo " Threaded Pipe Rendering.: $build_pipe_render" +echo +echo " Optional pixman rendering path:" +echo " Pixman..................: $have_pixman" +echo " Pixman Fonts............: $have_pixman_font" +echo " Pixman Rects............: $have_pixman_rect" +echo " Pixman Lines............: $have_pixman_line" +echo " Pixman Polygons.........: $have_pixman_poly" +echo " Pixman Images...........: $have_pixman_image" +echo " Pixman Image ScaleSample: $have_pixman_image_scale_sample" +echo +echo " Conversion Options:" +echo " Smaller Dither Mask.....: $conv_small_dither" +echo " Line Dither Mask........: $conv_line_dither" +echo " No Dither Mask for 16bpp: $conv_no_dither" +echo " Tiled 32BPP rotate......: $have_tile_rotate" +echo + +echo "Ecore:" +echo " Thread safety..............: $want_thread_safety" +echo " GLib support...............: $with_glib" +echo " Use g_main_loop............: $want_g_main_loop" +echo " Gathering memory statistic.: $ac_cv_func_mallinfo" +echo " Gathering timer allocation.: $want_ecore_timer_dump" +echo + +echo "Ecore_Con:" +if test "x${have_gnutls}" = "xyes" || test "x${have_openssl}" = "xyes" ; then +echo " TLS........................: $with_tls" +else +echo " TLS........................: no" +fi +echo " IPv6.......................: $have_ipv6" +echo " CURL.......................: $have_curl" +echo " Local Sockets..............: $want_ecore_con_local_sockets" +if test "x$want_ecore_con_local_sockets" = "xyes" ; then +echo " Abstract Sockets...........: $want_ecore_con_abstract_sockets" +fi +if test "x$have_cares" = "xyes" ; then +echo " Resolver...................: c-ares" +elif test "x$have_ipv6" = "xyes" ; then +echo " Resolver...................: dns.c" +else +echo " Resolver...................: fork" +fi +echo + +echo "Ecore_Ipc:" +echo " TLS........................: $with_tls" +echo + +echo "Ecore_File:" +echo " Inotify....................: $have_inotify" +echo " Windows notification.......: $have_notify_win32" +echo " Poll.......................: $have_poll" +echo " CURL.......................: $have_curl" +echo + +echo "Ecore_IMF....................: $have_ecore_imf" +echo " XIM........................: $have_ecore_imf_xim" +echo " SCIM.......................: $have_ecore_imf_scim" +echo " IBUS.......................: $have_ecore_imf_ibus" +echo "Ecore_IMF_Evas...............: $have_ecore_imf_evas" +echo + +echo "Ecore 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 " Xgesture...................: $have_ecore_x_xcb_gesture" + 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 " Xgesture...................: $use_xgesture" + 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_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_wince" +echo " Ecore_PSL1GHT..............: $have_ps3" +echo " Ecore_Wayland..............: $have_ecore_wayland" + +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 + if test "x${have_ecore_evas_opengl_x11}" = "xyes" ; then + echo " OpenGL X11.................: $have_ecore_evas_opengl_x11 (Xlib=${have_ecore_evas_opengl_xlib}) (XCB=${have_ecore_evas_opengl_xcb})" + else + echo " OpenGL X11.................: $have_ecore_evas_opengl_x11" + fi + echo " Software GDI...............: $have_ecore_evas_software_gdi" + echo " Software DirectDraw........: $have_ecore_evas_software_ddraw" + echo " Software SDL...............: $have_ecore_evas_software_sdl" + echo " OpenGL SDL.................: $have_ecore_evas_opengl_sdl" + echo " OpenGL Cocoa...............: $have_ecore_evas_opengl_cocoa" + echo " DirectFB...................: $have_ecore_evas_directfb" + echo " PSL1GHT....................: $have_ecore_evas_psl1ght" + echo " Software Framebuffer.......: $have_ecore_evas_fb" + echo " Sing.Proc. Windowing System: $have_ecore_evas_ews" + echo " Wayland Shm................: $have_ecore_evas_wayland_shm" + echo " Wayland Egl................: $have_ecore_evas_wayland_egl" + echo " Extn (Plug/socket Extn)....: $have_ecore_evas_extn" +#fi echo echo "Tests..................: ${_efl_enable_tests}" if test "x${_efl_enable_tests}" = "xyes"; then diff --git a/legacy/ecore/ecore-cocoa.pc.in b/legacy/ecore/ecore-cocoa.pc.in deleted file mode 100644 index 91fc4ee0ac..0000000000 --- a/legacy/ecore/ecore-cocoa.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-con.pc.in b/legacy/ecore/ecore-con.pc.in deleted file mode 100644 index 9b188aa4e4..0000000000 --- a/legacy/ecore/ecore-con.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-directfb.pc.in b/legacy/ecore/ecore-directfb.pc.in deleted file mode 100644 index 9eb104a10f..0000000000 --- a/legacy/ecore/ecore-directfb.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-evas.pc.in b/legacy/ecore/ecore-evas.pc.in deleted file mode 100644 index 155abbe974..0000000000 --- a/legacy/ecore/ecore-evas.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-fb.pc.in b/legacy/ecore/ecore-fb.pc.in deleted file mode 100644 index 4e70c48c77..0000000000 --- a/legacy/ecore/ecore-fb.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-file.pc.in b/legacy/ecore/ecore-file.pc.in deleted file mode 100644 index 833ff1e06f..0000000000 --- a/legacy/ecore/ecore-file.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-imf-evas.pc.in b/legacy/ecore/ecore-imf-evas.pc.in deleted file mode 100644 index 23451c80e5..0000000000 --- a/legacy/ecore/ecore-imf-evas.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-imf.pc.in b/legacy/ecore/ecore-imf.pc.in deleted file mode 100644 index cc155ed29a..0000000000 --- a/legacy/ecore/ecore-imf.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-input-evas.pc.in b/legacy/ecore/ecore-input-evas.pc.in deleted file mode 100644 index f95325c79d..0000000000 --- a/legacy/ecore/ecore-input-evas.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-input.pc.in b/legacy/ecore/ecore-input.pc.in deleted file mode 100644 index b670b71ccb..0000000000 --- a/legacy/ecore/ecore-input.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-ipc.pc.in b/legacy/ecore/ecore-ipc.pc.in deleted file mode 100644 index d66f404687..0000000000 --- a/legacy/ecore/ecore-ipc.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-psl1ght.pc.in b/legacy/ecore/ecore-psl1ght.pc.in deleted file mode 100644 index e81f4e8366..0000000000 --- a/legacy/ecore/ecore-psl1ght.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: ecore-psl1ght -Description: E core library, PSL1GHT module -@pkgconfig_requires_private@: @requirements_ecore_psl1ght@ -Version: @VERSION@ -Libs: -L${libdir} -lecore_psl1ght -Libs.private: -lio -lsysutil -lgem -lcamera -lspurs -Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-sdl.pc.in b/legacy/ecore/ecore-sdl.pc.in deleted file mode 100644 index 78170c1c41..0000000000 --- a/legacy/ecore/ecore-sdl.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-wayland.pc.in b/legacy/ecore/ecore-wayland.pc.in deleted file mode 100644 index f4f5cf3a0a..0000000000 --- a/legacy/ecore/ecore-wayland.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: ecore-wayland -Description: E core library, Wayland module -@pkgconfig_requires_private@: @requirements_ecore_wayland@ -Version: @VERSION@ -Libs: -L${libdir} -lecore_wayland -Libs.private: -lwayland-client -Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-win32.pc.in b/legacy/ecore/ecore-win32.pc.in deleted file mode 100644 index ac5ab32bb9..0000000000 --- a/legacy/ecore/ecore-win32.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -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: @WIN32_LIBS@ -Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-wince.pc.in b/legacy/ecore/ecore-wince.pc.in deleted file mode 100644 index c937e8871a..0000000000 --- a/legacy/ecore/ecore-wince.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -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}/ecore-@VMAJ@ diff --git a/legacy/ecore/ecore-x.pc.in b/legacy/ecore/ecore-x.pc.in deleted file mode 100644 index a02b42ba54..0000000000 --- a/legacy/ecore/ecore-x.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -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}/ecore-@VMAJ@ @have_ecore_x_xcb_define@ diff --git a/legacy/ecore/ecore.pc.in b/legacy/ecore/ecore.pc.in deleted file mode 100644 index db67e7a7b5..0000000000 --- a/legacy/ecore/ecore.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -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 @EINA_LIBS@ -Libs.private: -lm -Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/legacy/ecore/m4/check_x_extension.m4 b/legacy/ecore/m4/check_x_extension.m4 deleted file mode 100644 index a15120c7ef..0000000000 --- a/legacy/ecore/m4/check_x_extension.m4 +++ /dev/null @@ -1,40 +0,0 @@ -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 ] - ) - 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]) -]) diff --git a/legacy/ecore/m4/ecore_check_module.m4 b/legacy/ecore/m4/ecore_check_module.m4 deleted file mode 100644 index 01c4e0eb60..0000000000 --- a/legacy/ecore/m4/ecore_check_module.m4 +++ /dev/null @@ -1,97 +0,0 @@ -dnl use: ECORE_CHECK_MODULE(Foo, default-enabled, description[, dependency[, 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_FULL(foo-bar, evas-module, want, description, backend[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) -AC_DEFUN([ECORE_EVAS_CHECK_MODULE_FULL], -[ -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="$3" - -AC_ARG_ENABLE(ecore-evas-$1, - [AC_HELP_STRING( - [--enable-ecore-evas-$1], - [enable $4 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 $4 support is to be built]) -AC_MSG_RESULT([${want_module}]) - -if test "x$5" = "xyes" && \ - test "x$have_ecore_evas" = "xyes" && \ - test "x$want_module" = "xyes" ; then - PKG_CHECK_EXISTS([evas-$2], - [ - AC_DEFINE([BUILD_ECORE_EVAS_]m4_defn([UP]), [1], [Support for $4 Engine in Ecore_Evas]) - have_ecore_evas_[]m4_defn([DOWN])="yes" - ]) -fi - -AC_MSG_CHECKING([whether ecore_evas $4 support is built]) -AC_MSG_RESULT([$have_ecore_evas_]m4_defn([DOWN])) - -AS_IF([test "x$have_ecore_evas_[]m4_defn([DOWN])" = "xyes"], [$6], [$7]) - -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], -[ECORE_EVAS_CHECK_MODULE_FULL([$1], [$1], [$2], [$3], [$4], [$5], [$6])]) diff --git a/legacy/ecore/po/Makevars b/legacy/ecore/po/Makevars deleted file mode 100644 index 22837aba49..0000000000 --- a/legacy/ecore/po/Makevars +++ /dev/null @@ -1,41 +0,0 @@ -# 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 = diff --git a/legacy/ecore/po/POTFILES.in b/legacy/ecore/po/POTFILES.in deleted file mode 100644 index 5014aa2e92..0000000000 --- a/legacy/ecore/po/POTFILES.in +++ /dev/null @@ -1 +0,0 @@ -src/lib/ecore/ecore_getopt.c diff --git a/legacy/ecore/po/cs.po b/legacy/ecore/po/cs.po deleted file mode 100644 index db049a6ea2..0000000000 --- a/legacy/ecore/po/cs.po +++ /dev/null @@ -1,174 +0,0 @@ -# ecore czech translation -# quaker66@gmail.com -# Vít Pelčák , 2011. -msgid "" -msgstr "" -"Project-Id-Version: ecore\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2011-10-23 01:28+0100\n" -"Last-Translator: Daniel Kolesa \n" -"Language-Team: Czech \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 1.2\n" -"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" - -#: src/lib/ecore/ecore_getopt.c:95 -msgid "Version:" -msgstr "Verze:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Použití:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [volby]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Copyright:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Licence:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Typ: " - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Výchozí: " - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Možnosti: " - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Volby:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "CHYBA: neznámá volba --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "CHYBA: neznámá volba -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "CHYBA: " - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "hodnota nemá nastaven pointer.\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "neznámá boolean hodnota %s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "neznámý číselný formát %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "neznámá volba \"%s\". Možné hodnoty jsou: " - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "chybějící parametr k připojení.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "nemůžu parsovat hodnotu.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "chybějící parametr.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "chybějící callback funkce!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "nebyla definována verze.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "nebyl definován copyright.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "nebyla definována licence.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "CHYBA: neznámá volba --%s, ignoruji.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, c-format -msgid "ERROR: option --%s requires an argument!\n" -msgstr "CHYBA: volba --%s vyžaduje argument!\n" - -#: src/lib/ecore/ecore_getopt.c:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "CHYBA: neznámá volba -%c, ignoruji.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, c-format -msgid "ERROR: option -%c requires an argument!\n" -msgstr "CHYBA: volba -%c vyžaduje argument!\n" - -#: src/lib/ecore/ecore_getopt.c:1793 -msgid "ERROR: no parser provided.\n" -msgstr "CHYBA: nebyl poskytnut parser.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "CHYBA: nebyly poskytnuty hodnoty.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "CHYBA: nebyly poskytnuty argumenty.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "CHYBA: nalezeny neplatné volby." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr " Viz --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr " Viz -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "CHYBA: neplatná hodnota geometrie '%s'\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "CHYBA: neplatná hodnota velikosti '%s'\n" diff --git a/legacy/ecore/po/de.po b/legacy/ecore/po/de.po deleted file mode 100644 index 4a16766e17..0000000000 --- a/legacy/ecore/po/de.po +++ /dev/null @@ -1,175 +0,0 @@ -# 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 , 2009. -# Fabian Nowak , 2010. -# -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: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2010-01-03 21:52+GMT\n" -"Last-Translator: Fabian Nowak \n" -"Language-Team: German \n" -"Language: de\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:95 -msgid "Version:" -msgstr "Version:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Aufruf:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [Optionen]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Copyright:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Lizenz:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Typ: " - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Standard: " - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Auswahlmöglichkeiten: " - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Optionen:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "FEHLER: Unbekannte Option --%s\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "FEHLER: Unbekannte Option -%c\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "FEHLER: " - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "kein Zeiger auf Wert gesetzt\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "unbekannter boolescher Wert %s\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "ungültiges Zahlenformat %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "ungültige Auswahl \"%s\". Gültige Werte sind: " - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "fehlender Parameter zum Anhängen.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "Wert kann nicht ausgewertet werden.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "fehlender Parameter.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "fehlende Rückruffunktion!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "es wurde keine Version angegeben.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "es wurde kein Copyright angegeben.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "es wurde keine Lizenz angegeben.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "FEHLER: Unbekannte Option --%s, ignoriert\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, 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:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "FEHLER: Unbekannte Option -%c, ignoriert\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, 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:1793 -msgid "ERROR: no parser provided.\n" -msgstr "FEHLER: Kein Parser bereitgestellt.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "FEHLER: Keine Werte bereitgestellt.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "FEHLER: Keine Argumente bereitgestellt.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "FEHLER: Ungültige Optionen gefunden." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr " Siehe --%s\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr " Siehe -%c\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "FEHLER: Falscher Geometriewert \"%s\"\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "FEHLER: Falscher Größenwert \"%s\"\n" diff --git a/legacy/ecore/po/el.po b/legacy/ecore/po/el.po deleted file mode 100644 index 882f77c859..0000000000 --- a/legacy/ecore/po/el.po +++ /dev/null @@ -1,209 +0,0 @@ -# Greek translation for Ecore. -# This file is put in the public domain. -# ragecryx , 2009. -# George Rizopoulos 20 11 -# Alex-P. Natsios 2012 -# Efstathios Iosifidis , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: Ecore\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2012-12-01 18:25+0200\n" -"Last-Translator: Efstathios Iosifidis \n" -"Language-Team: Ελληνικά, Σύγχρονα \n" -"Language: \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-Generator: Gtranslator 2.91.5\n" - -#: src/lib/ecore/ecore_getopt.c:95 -msgid "Version:" -msgstr "Έκδοση:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Χρήση:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [επιλογές]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Πνευματικά δικαιώματα:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Άδεια:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Τύπος: " - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Προκαθορισμένο: " - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Επιλογές:" - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Επιλογές:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "ΣΦΑΛΜΑ: άγνωστη επιλογή --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "ΣΦΑΛΜΑ: άγνωστη επιλογή -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "ΣΦΑΛΜΑ: " - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "η τιμή δεν έχει καθορισμένο τον δείκτη.\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "άγνωστη τιμή boolean %s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "μη έγκυρη μορφή αριθμού %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "μη έγκυρη επιλογή \"%s\". Οι έγκυρες τιμές είναι: " - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "απούσα παράμετρος για προσάρτηση.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "αδυναμία ανάλυσης τιμών.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "απούσα παράμετρος.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "απούσα λειτουργία επανάκλησης!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "δεν έχει οριστεί έκδοση.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "δεν έχουν οριστεί πνευματικά δικαιώματα.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "δεν έχει οριστεί άδεια.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "ΣΦΑΛΜΑ: άγνωστη επιλογή --%s, αγνοήθηκε.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, c-format -msgid "ERROR: option --%s requires an argument!\n" -msgstr "ΣΦΑΛΜΑ: η επιλογή --%s απαιτεί μια παράμετρο!\n" - -#: src/lib/ecore/ecore_getopt.c:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "ΣΦΑΛΜΑ: άγνωστη επιλογή -%c, αγνοήθηκε.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, c-format -msgid "ERROR: option -%c requires an argument!\n" -msgstr "ΣΦAΛΜΑ: η επιλογή -%c απαιτεί μία παράμετρο!\n" - -#: src/lib/ecore/ecore_getopt.c:1793 -msgid "ERROR: no parser provided.\n" -msgstr "ΣΦΑΛΜΑ: δεν παρέχεται αναλυτής.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "ΣΦΑΛΜΑ: δεν έχουν δοθεί τιμές.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "ΣΦΑΛΜΑ:δεν έχουν δοθεί παράμετροι.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "ΣΦΑΛΜΑ: βρέθηκαν μη έγκυρες επιλογές." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr " Δείτε --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr " Δείτε -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "ΣΦΑΛΜΑ: μη έγκυρη γεωμετρική τιμή '%s'\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "ΣΦΑΛΜΑ: μη έγκυρη τιμή μεγέθους '%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" diff --git a/legacy/ecore/po/es.po b/legacy/ecore/po/es.po deleted file mode 100644 index 3e4c0e3d53..0000000000 --- a/legacy/ecore/po/es.po +++ /dev/null @@ -1,181 +0,0 @@ -# Spanish translation for ecore. -# Copyright (C) YEAR Enlightenment development team -# This file is distributed under the same license as the PACKAGE package. -# Aníbal Garrido , 2012. - -msgid "" -msgstr "" -"Project-Id-Version: ecore\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-11-08 02:06+0100\n" -"PO-Revision-Date: 2012-11-08 02:06+0100\n" -"Last-Translator: Aníbal Garrido \n" -"Language-Team: Enlightenment Team\n" -"Language: es\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:95 -msgid "Version:" -msgstr "Versión:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Uso:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [opciones]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Copyright:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Licencia:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Tipo:" - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Predeterminado" - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Elecciones:" - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Opciones:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "ERROR: opción desconocida --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "ERROR: opción desconocida -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "ERROR: " - -#: src/lib/ecore/ecore_getopt.c:931 -#: src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 -#: src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 -#: src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 -#: src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "no se definió el valor.\n" - -#: src/lib/ecore/ecore_getopt.c:963 -#: src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "valor booleano desconocido %s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 -#: src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "formato numérico inválido %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "Elección inválida \"%s\". Los valores válidos son:" - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "faltan los parámetros a anexar.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "incapaz de procesar el valor.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "parámetro ausente.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "¡función de invocación desaparecida!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "no se definió la versión.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "no se definió el copyright.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "no se definió la licencia.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "ERROR: opción desconocida --%s, ignorada.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, c-format -msgid "ERROR: option --%s requires an argument!\n" -msgstr "ERROR: opción --%s ¡requiere un argumento!\n" - -#: src/lib/ecore/ecore_getopt.c:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "ERROR: opción desconocida -%c, ignorada.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, c-format -msgid "ERROR: option -%c requires an argument!\n" -msgstr "ERROR: opción -%c ¡requiere un argumento!\n" - -#: src/lib/ecore/ecore_getopt.c:1793 -msgid "ERROR: no parser provided.\n" -msgstr "ERROR: no se proporcionó ningún procesador.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "ERROR: no se proporcionó ningún valor.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "ERROR: no se proporcionó ningún argumento.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "ERROR: encontradas opciones inválidas." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr " Vea --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr " Vea -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "ERROR: valor geométrico incorrecto '%s'\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "ERROR: valor del tamaño incorrecto '%s'\n" - diff --git a/legacy/ecore/po/fr.po b/legacy/ecore/po/fr.po deleted file mode 100644 index 4858bc0b54..0000000000 --- a/legacy/ecore/po/fr.po +++ /dev/null @@ -1,208 +0,0 @@ -# French translation for Ecore. -# This file is put in the public domain. -# batden , 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: Ecore\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2010-07-11 11:01+0400\n" -"Last-Translator: batden \n" -"Language-Team: Enlightenment French Team \n" -"Language: \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:95 -msgid "Version:" -msgstr "Version :" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Usage :" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [options]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Copyright :" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Licence :" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Type : " - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Par défaut :" - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Choix :" - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Options :\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "ERREUR : option inconnue --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "ERREUR : option inconnue -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "ERREUR :" - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "la valeur n'a aucun pointeur défini.\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "valeur booléenne inconnue %s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "format du nombre non valide %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "choix non valide « %s ». Les valeurs valides sont : " - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "paramètre manquant à ajouter.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "analyse de la valeur impossible.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "paramètre manquant.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "fonction de rappel manquante !\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "aucune version n'est définie.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "aucun copyright n'est défini.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "aucune licence n'est définie.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, 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:1502 -#, 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:1544 -#, 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:1582 -#, 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:1793 -msgid "ERROR: no parser provided.\n" -msgstr "ERREUR : aucun analyseur n'est fourni.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "ERREUR : aucune valeur n'est fournie.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "ERREUR : aucun argument n'est fourni.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "ERREUR : options non valides détectées." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr " Voir --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr " Voir -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "ERREUR : valeur géométrique incorrecte « %s »\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, 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" diff --git a/legacy/ecore/po/gl.po b/legacy/ecore/po/gl.po deleted file mode 100644 index 33ba338459..0000000000 --- a/legacy/ecore/po/gl.po +++ /dev/null @@ -1,180 +0,0 @@ -# Galician translation of ecore -# This file is put in the public domain. -# Aníbal Garrido , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: ecore\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 09:50+0200\n" -"PO-Revision-Date: 2012-10-16 09:53+0200\n" -"Last-Translator: Aníbal Garrido \n" -"Language-Team: http://trasno.net/ \n" -"Language: gl\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:95 -msgid "Version:" -msgstr "Versión:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Uso:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [opcións]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Dereitos de autor:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Licenza" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Tipo:" - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Predeterminado:" - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Eleccións:" - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Opcións:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "ERRO: opción descoñecida --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "ERRO: opción descoñecida -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "ERRO: " - -#: src/lib/ecore/ecore_getopt.c:931 -#: src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 -#: src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 -#: src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 -#: src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "non se definiu o valor.\n" - -#: src/lib/ecore/ecore_getopt.c:963 -#: src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "valor booleano descoñecido %s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 -#: src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "formato numérico inválido %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "Elección inválida \"%s\". Os valores válidos son:" - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "faltan os parámetros a anexar.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "incapaz de procesar o valor.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "parámetro ausente.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "Función de invocación desaparecida!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "non se definiu a versión.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "non se definiron os dereitos de autor.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "non se definiu a licenza.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "ERRO: opción descoñecida --%s, ignorada.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, c-format -msgid "ERROR: option --%s requires an argument!\n" -msgstr "ERRO: opción --%s require un argumento!\n" - -#: src/lib/ecore/ecore_getopt.c:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "ERRO: opción descoñecida -%c, ignorada.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, c-format -msgid "ERROR: option -%c requires an argument!\n" -msgstr "ERRO: opción -%c require un argumento!\n" - -#: src/lib/ecore/ecore_getopt.c:1793 -msgid "ERROR: no parser provided.\n" -msgstr "ERRO: non se forneceu ningún procesador.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "ERRO: non se forneceu ningún valor.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "ERRO: non se forneceu ningún argumento.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "ERRO: atopadas opcións inválidas." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr " Consulte --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr " Consulte -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "ERRO: valor xeométrico incorrecto '%s'\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "ERRO: valor do tamaño incorrecto '%s'\n" - diff --git a/legacy/ecore/po/it.po b/legacy/ecore/po/it.po deleted file mode 100644 index eb48e55e8d..0000000000 --- a/legacy/ecore/po/it.po +++ /dev/null @@ -1,204 +0,0 @@ -# Italian translation for Ecore. -# This file is put in the public domain. -# Massimo Maiurana , 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: Ecore\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2009-10-27 19:36+0100\n" -"Last-Translator: quaker66 \n" -"Language-Team: none\n" -"Language: \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:95 -msgid "Version:" -msgstr "Versione:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Uso:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [opzioni]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Copyright:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Licenza:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Tipo: " - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Predefinito:" - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Scelte:" - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Opzioni:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "ERRORE: opzione sconosciuta --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "ERRORE: opzione sconosciuta -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "ERRORE:" - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "il valore non ha puntatori impostati.\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "valore booleano sconosciuto %s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "formato numero non valido %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "scelta non valida \"%s\". I valori ammessi sono: " - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "parametro da appendere mancante.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "impossibile il parsing del valore.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "parametro mancante.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "funzione callback mancante!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "nessuna versione definita.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "nessun copyright definito.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "nessuna licenza definita.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "ERRORE: opzione sconosciuta --%s, ignorata.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, 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:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "ERRORE: opzione sconosciuta -%c, ignorata.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, 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:1793 -msgid "ERROR: no parser provided.\n" -msgstr "ERRORE: nessun parser fornito.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "ERRORE: nessun valore fornito.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "ERRORE: nessun argomento fornito.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "ERRORE: trovate opzioni non valide." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr " Vedere --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr " Vedere -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "ERRORE: valore geometrico non corretto '%s'\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, 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" diff --git a/legacy/ecore/po/ko.po b/legacy/ecore/po/ko.po deleted file mode 100644 index db5f21e3f7..0000000000 --- a/legacy/ecore/po/ko.po +++ /dev/null @@ -1,179 +0,0 @@ -# Korean translation for the Enlightenment ecore. -# Copyright (C) 2000-2012 Enlightenment development team -# This file is distributed under the same license as the Enlightenment package. -# Seong-ho Cho , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: Enlightenment Ecore 1.7.0\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2012-08-30 22:50+0900\n" -"Last-Translator: Seong-ho Cho \n" -"Language-Team: Enlightenment-Intl \n" -"Language: ko\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Poedit-Language: Korean\n" -"X-Poedit-Country: KOREA, REPUBLIC OF\n" -"X-Poedit-SourceCharset: utf-8\n" - -#: src/lib/ecore/ecore_getopt.c:95 -msgid "Version:" -msgstr "버전:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "사용법:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s <옵션>\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "저작권 정보:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "라이선스:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "형식: " - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "기본값: " - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "선택: " - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "옵션:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "오류: 알 수 없는 옵션 --%s 입니다.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "오류: 알 수 없는 옵션 -%c 입니다.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "오류: " - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "값에 포인터 집합이 없습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "알 수 없는 부울린 값 %s 입니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "잘못된 숫자 형식 %s 입니다\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "잘못된 선택 \"%s\" 입니다. 유효한 값은 다음과 같습니다: " - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "붙일 매개변수가 빠졌습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "값을 해석할 수 없습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "매개변수가 빠졌습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "콜백 함수가 빠졌습니다!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "정의한 버전이 없습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "정의한 저작권 정보가 없습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "정의한 라이선스가 없습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "오류: 알 수 없는 --%s 옵션을 무시합니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, c-format -msgid "ERROR: option --%s requires an argument!\n" -msgstr "오류: --%s 옵션에 인자가 필요합니다!\n" - -#: src/lib/ecore/ecore_getopt.c:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "오류: 알 수 없는 -%c 옵션을 무시합니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, c-format -msgid "ERROR: option -%c requires an argument!\n" -msgstr "오류: -%c 옵션에 인자가 필요합니다!\n" - -#: src/lib/ecore/ecore_getopt.c:1793 -msgid "ERROR: no parser provided.\n" -msgstr "오류: 해석 프로그램이 존재하지 않습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "오류: 값이 존재하지 않습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "인자가 존재하지 않습니다.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "오류: 잘못된 옵션이 있습니다." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr " --%s을(를) 참조하십시오.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr " -%c을(를) 참조하십시오.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "오류: '%s' 값의 좌표가 올바르지 않습니다\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "오류: '%s' 값의 크기가 올바르지 않습니다\n" diff --git a/legacy/ecore/po/nl.po b/legacy/ecore/po/nl.po deleted file mode 100644 index 7e4d79013a..0000000000 --- a/legacy/ecore/po/nl.po +++ /dev/null @@ -1,175 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# This file is put in the public domain. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: Ecore\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2011-09-03 15:48+0100\n" -"Last-Translator: Heimen Stoffels \n" -"Language-Team: \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: NL\n" -"X-Poedit-Country: Nederland\n" - -#: src/lib/ecore/ecore_getopt.c:95 -msgid "Version:" -msgstr "Versie:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Gebruik:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [opties]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Copyright:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Licentie:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Type:" - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Standaard:" - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Keuzes:" - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Opties:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "FOUT: onbekende optie --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "FOUT: onbekende optie -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "FOUT:" - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "waarde heeft geen pointer ingsteld.\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "onbekende boolean-waarde %s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "ongeldig nummerformaat %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "ongeldige keuze \"%s\". Geldige waardes zijn:" - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "parameter om toe te wijzen ontbreekt.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "kon waarde niet doorvoeren.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "paramater ontbreekt.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "ontbrekende terugroep-functie!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "geen versie was gedefinieerd.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "geen copyright was gedefinieerd.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "geen licentie was gedefinieerd.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "FOUT: onbekende optie --%s, genegeerd.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, c-format -msgid "ERROR: option --%s requires an argument!\n" -msgstr "FOUT: optie --%s vereist een argument!\n" - -#: src/lib/ecore/ecore_getopt.c:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "FOUT: onbekende opties -%c, genegeerd.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, c-format -msgid "ERROR: option -%c requires an argument!\n" -msgstr "FOUT: optie -%c vereist een argument!\n" - -#: src/lib/ecore/ecore_getopt.c:1793 -msgid "ERROR: no parser provided.\n" -msgstr "FOUT: geen doorvoerder beschikbaar gesteld.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "FOUT: geen waarden beschikbaar gesteld.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "FOUT: geen argumenten beschibaar gesteld.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "FOUT: ongeldige opties gevonden." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr "Zie --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr "Zie -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "Fout: foutieve wiskundige waarde '%s'\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "FOUT: foutieve grootte-waarden '%s'\n" diff --git a/legacy/ecore/po/pt.po b/legacy/ecore/po/pt.po deleted file mode 100644 index 859652c7b1..0000000000 --- a/legacy/ecore/po/pt.po +++ /dev/null @@ -1,176 +0,0 @@ -# Portuguese translation for ecore -# This file is distributed under the same license as the enlightenment package. -# Sérgio Marques , 2010 -# -msgid "" -msgstr "" -"Project-Id-Version: ecore\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2012-08-23 00:30+0100\n" -"Last-Translator: Sérgio Marques \n" -"Language-Team: \n" -"Language: \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: Portuguese\n" -"X-Poedit-Country: Portugal\n" - -#: src/lib/ecore/ecore_getopt.c:95 -msgid "Version:" -msgstr "Versão:" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Utilização:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s [opções]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Direitos de autor:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Licença:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Tipo:" - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Padrão:" - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Escolhas:" - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Opções:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "ERRO: opção desconhecida --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "ERRO: opção desconhecida -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "ERRO: " - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "o valor não está definido.\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "valor booleano desconhecido %s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "formato numérico inválido %s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "escolha inválida \"%s\". O valores possíveis são:" - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "faltam os parâmetros a anexar.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "incapaz de processar o valor.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "parâmetro em falta.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "função de invocação em falta!\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "nenhuma versão definida.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "direitos de autor não definidos.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "licença não definida.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "ERRO: opção desconhecida --%s, ignorada.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, c-format -msgid "ERROR: option --%s requires an argument!\n" -msgstr "ERRO: a opção --%s requer um argumento!\n" - -#: src/lib/ecore/ecore_getopt.c:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "ERRO: opção desconhecida --%c, ignorada.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, c-format -msgid "ERROR: option -%c requires an argument!\n" -msgstr "ERRO: a opção --%c requer um argumento!\n" - -#: src/lib/ecore/ecore_getopt.c:1793 -msgid "ERROR: no parser provided.\n" -msgstr "ERRO: nenhum processador fornecido.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "ERRO: nenhum valor fornecido.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "ERRO: nenhum argumento fornecido.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "ERRO: encontradas opções inválidas." - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr "Consulte --%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr "Consulte -%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "ERRO: valor geométrico incorreto \"%s\"\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "ERRO: tamanho incorreto \"%s\"\n" diff --git a/legacy/ecore/po/sl.po b/legacy/ecore/po/sl.po deleted file mode 100644 index c138f5cec9..0000000000 --- a/legacy/ecore/po/sl.po +++ /dev/null @@ -1,175 +0,0 @@ -# Slovenian translation of ecore. -# This file is put in the public domain. -# r1to , 2011. -# , fuzzy -# -# -msgid "" -msgstr "" -"Project-Id-Version: ecore 1.0\n" -"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-10-16 11:52+0900\n" -"PO-Revision-Date: 2011-02-24 16:54+0100\n" -"Last-Translator: r1to \n" -"Language-Team: Slovenian \n" -"Language: sl\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:95 -msgid "Version:" -msgstr "Različica" - -#: src/lib/ecore/ecore_getopt.c:104 -msgid "Usage:" -msgstr "Uporaba:" - -#: src/lib/ecore/ecore_getopt.c:109 -#, c-format -msgid "%s [options]\n" -msgstr "%s·[možnosti]\n" - -#: src/lib/ecore/ecore_getopt.c:264 -msgid "Copyright:" -msgstr "Avtorstvo:" - -#: src/lib/ecore/ecore_getopt.c:276 -msgid "License:" -msgstr "Licenca:" - -#: src/lib/ecore/ecore_getopt.c:457 -msgid "Type: " -msgstr "Vrsta:·" - -#: src/lib/ecore/ecore_getopt.c:533 -msgid "Default: " -msgstr "Privzeto:·" - -#: src/lib/ecore/ecore_getopt.c:560 -msgid "Choices: " -msgstr "Izbire:·" - -#: src/lib/ecore/ecore_getopt.c:661 -msgid "Options:\n" -msgstr "Možnosti:\n" - -#: src/lib/ecore/ecore_getopt.c:788 -#, c-format -msgid "ERROR: unknown option --%s.\n" -msgstr "NAPAKA:·Neznana možnost·--%s.\n" - -#: src/lib/ecore/ecore_getopt.c:790 -#, c-format -msgid "ERROR: unknown option -%c.\n" -msgstr "NAPAKA:·neznana možnost·-%c.\n" - -#: src/lib/ecore/ecore_getopt.c:848 -msgid "ERROR: " -msgstr "NAPAKA:" - -#: src/lib/ecore/ecore_getopt.c:931 src/lib/ecore/ecore_getopt.c:1068 -#: src/lib/ecore/ecore_getopt.c:1084 src/lib/ecore/ecore_getopt.c:1099 -#: src/lib/ecore/ecore_getopt.c:1116 src/lib/ecore/ecore_getopt.c:1163 -#: src/lib/ecore/ecore_getopt.c:1283 src/lib/ecore/ecore_getopt.c:1324 -msgid "value has no pointer set.\n" -msgstr "vrednost nima nastavljenega kazalnika.\n" - -#: src/lib/ecore/ecore_getopt.c:963 src/lib/ecore/ecore_getopt.c:1183 -#, c-format -msgid "unknown boolean value %s.\n" -msgstr "neznana Boolova vrednost·%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1014 src/lib/ecore/ecore_getopt.c:1271 -#, c-format -msgid "invalid number format %s\n" -msgstr "napačen·format Å¡tevila·%s\n" - -#: src/lib/ecore/ecore_getopt.c:1129 -#, c-format -msgid "invalid choice \"%s\". Valid values are: " -msgstr "napačna izbira·\"%s\".·Pravilne izbire so:·" - -#: src/lib/ecore/ecore_getopt.c:1157 -msgid "missing parameter to append.\n" -msgstr "manjka·parameter·za dodajo.\n" - -#: src/lib/ecore/ecore_getopt.c:1261 -msgid "could not parse value.\n" -msgstr "vrednosti ni bilo možno razčleniti.\n" - -#: src/lib/ecore/ecore_getopt.c:1318 -msgid "missing parameter.\n" -msgstr "manjkajoči·parameter.\n" - -#: src/lib/ecore/ecore_getopt.c:1331 -msgid "missing callback function!\n" -msgstr "manjkajoča povratno-zasilna funkcija !\n" - -#: src/lib/ecore/ecore_getopt.c:1360 -msgid "no version was defined.\n" -msgstr "definirana ni bila nobena različica.\n" - -#: src/lib/ecore/ecore_getopt.c:1377 -msgid "no copyright was defined.\n" -msgstr "definirano ni bilo nobeno avtorstvo.\n" - -#: src/lib/ecore/ecore_getopt.c:1394 -msgid "no license was defined.\n" -msgstr "definirana ni bila nobena licenca.\n" - -#: src/lib/ecore/ecore_getopt.c:1469 -#, c-format -msgid "ERROR: unknown option --%s, ignored.\n" -msgstr "NAPAKA:·neznana možnost·--%s,·prezrto.\n" - -#: src/lib/ecore/ecore_getopt.c:1502 -#, c-format -msgid "ERROR: option --%s requires an argument!\n" -msgstr "NAPAKA:·možnost·--%s·zahteva argument!\n" - -#: src/lib/ecore/ecore_getopt.c:1544 -#, c-format -msgid "ERROR: unknown option -%c, ignored.\n" -msgstr "NAPAKA:·neznana možnost·-%c,·prezrto.\n" - -#: src/lib/ecore/ecore_getopt.c:1582 -#, c-format -msgid "ERROR: option -%c requires an argument!\n" -msgstr "NAPAKA:·možnost·-%c zahteva argument!\n" - -#: src/lib/ecore/ecore_getopt.c:1793 -msgid "ERROR: no parser provided.\n" -msgstr "NAPAKA:·ni podan razčlenjevalnik.\n" - -#: src/lib/ecore/ecore_getopt.c:1798 -msgid "ERROR: no values provided.\n" -msgstr "NAPAKA::·ni podanih vrednosti.\n" - -#: src/lib/ecore/ecore_getopt.c:1807 -msgid "ERROR: no arguments provided.\n" -msgstr "NAPAKA::·ni podanih argumentov.\n" - -#: src/lib/ecore/ecore_getopt.c:1833 -msgid "ERROR: invalid options found." -msgstr "NAPAKA::·najdene nepravilne možnosti" - -#: src/lib/ecore/ecore_getopt.c:1839 -#, c-format -msgid " See --%s.\n" -msgstr "·Glej·--%s.\n" - -#: src/lib/ecore/ecore_getopt.c:1841 -#, c-format -msgid " See -%c.\n" -msgstr "·Glej·-%c.\n" - -#: src/lib/ecore/ecore_getopt.c:1887 -#, c-format -msgid "ERROR: incorrect geometry value '%s'\n" -msgstr "NAPAKA::·nepravilna geometrijska vrednost·'%s'\n" - -#: src/lib/ecore/ecore_getopt.c:1919 -#, c-format -msgid "ERROR: incorrect size value '%s'\n" -msgstr "NAPAKA::·nepravilna vrednost velikosti·'%s'\n" diff --git a/legacy/ecore/src/lib/ecore/Ecore.h b/legacy/ecore/src/lib/ecore/Ecore.h deleted file mode 100644 index 5a02211526..0000000000 --- a/legacy/ecore/src/lib/ecore/Ecore.h +++ /dev/null @@ -1,2954 +0,0 @@ -/** - @brief Ecore Library Public API Calls - - These routines are used for Ecore Library interaction - */ - -/** - - @mainpage Ecore - - @version 1.7 - @date 2000-2012 - - Please see the @ref authors page for contact details. - - @section intro Introduction - - Ecore is a library of convenience functions. A brief explanation of how to use - it can be found in @ref Ecore_Main_Loop_Page. - - The Ecore library provides the following modules: - @li @ref Ecore_Main_Loop_Group - @li @ref Ecore_File_Group - @li @ref Ecore_Con_Group - @li @ref Ecore_Evas_Group - @li @ref Ecore_FB_Group - @li @ref Ecore_IMF_Lib_Group - @li @ref Ecore_IMF_Context_Group - @li @ref Ecore_IMF_Context_Module_Group - @li @ref Ecore_IMF_Evas_Group - @li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink - @li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink - @li @ref Ecore_Win32_Group - @li @ref Ecore_WinCE_Group - - For more info on Ecore usage, there are these @ref Examples. - - @section compiling How to compile using Ecore? - pkgconfig (.pc) files are installed for every ecore module. - Thus, to compile using any of them, you can use something like the following: - -@verbatim -gcc *.c $(pkg-config ecore ecore-$x ecore-$y [...] --cflags --libs) -@endverbatim - - @section install How is it installed? - - Suggested configure options for ecore for a Linux desktop X display - with OpenGL and Software support, communication (networking) and - IPC (inter process communication): - -@verbatim -./configure \ - --enable-ecore-con \ - --enable-ecore-ipc \ - --enable-ecore-file \ - --enable-ecore-input \ - --enable-ecore-input-evas \ - --enable-ecore-x \ - --enable-ecore-evas \ - --enable-ecore-evas-software-buffer \ - --enable-ecore-evas-software-x11 \ - --enable-ecore-evas-opengl-x11 -make -sudo make install -@endverbatim - - */ - -/** - @page authors Authors - @author Carsten Haitzler - @author Tom Gilbert - @author Burra - @author Chris Ross - @author Term - @author Tilman Sauerbeck - @author Ibukun Olumuyiwa - @author Yuri - @author Nicholas Curran - @author Howell Tam - @author Nathan Ingersoll - @author Andrew Elcock - @author Kim Woelders - @author Sebastian Dransfeld - @author Simon Poole - @author Jorge Luis Zapata Muga - @author dan sinclair - @author Michael 'Mickey' Lauer - @author David 'onefang' Seikel - @author Hisham 'CodeWarrior' Mardam Bey - @author Brian 'rephorm' Mattern - @author Tim Horton - @author Arnaud de Turckheim 'quarium' - @author Matt Barclay - @author Peter Wehrfritz - @author Albin "Lutin" Tonnerre - @author Vincent Torri - @author Lars Munch - @author Andre Dieb - @author Mathieu Taillefumier - @author Rui Miguel Silva Seabra - @author Samsung Electronics - @author Samsung SAIT - @author Nicolas Aguirre - @author Brett Nash - @author Mike Blumenkrantz - @author Leif Middelschulte - @author Mike McCormack - @author Sangho Park - @author Jihoon Kim - @author PnB - @author Daniel Juyung Seo - @author Christopher 'devilhorns' Michael - @author ChunEon Park - @author xlopez@igalia.com - @author Rafael Antognolli - @author Kim Yunhan - @author Youness Alaoui - @author Bluezery - @author Doyoun Kang - @author Haifeng Deng - @author Jérémy Zurcher - @author Vikram Narayanan - - Please contact to get in - contact with the developers and maintainers. - */ - -/** - * @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 from embedded systems all the way up to large and - * powerful multi-cpu workstations. The main loop has a number of primitives to - * be used with its main loop. It serializes all the primitives and allows for - * great responsiveness without the need for threads(or any other concurrency). - * - * @subsection timers Timers - * - * Timers serve two main purposes: doing something at a specified time and - * repeatedly doing something with a set interval. - * @see Ecore_Timer_Group - * - * @subsection pollers Pollers - * - * Pollers allow for polling to be centralized into a single place therefore - * alleviating the need for different parts of the program to wake up at - * different times to do polling, thereby making the code simpler and more - * efficient. - * @see Ecore_Poller_Group - * - * @subsection idler Idlers - * - * There are three types of idlers, enterers, idlers(proper) and exiters, they - * are called, respectively, when the program is about to enter an idle state, - * when the program is idle and when the program is leaving an idle state. Idler - * enterers are usually a good place to update the program state. Proper idlers - * are the appropriate place to do heavy computational tasks thereby using what - * would otherwise be wasted CPU cycles. Exiters are the perfect place to do - * anything your program should do just before processing events(also timers, - * poolers, file descriptor handlers and animators) - * @see Ecore_Idle_Group - * - * @subsection fd_handler File descriptor handlers - * - * File descriptor handlers allow you to monitor when there is data available to - * read on file descriptors, when writing will not block or if there was an - * error. Any valid file descriptor can be used with this API, regardless of if - * was gotten with an OS specific API or from ecore. - * @see Ecore_FD_Handler_Group - * - * @subsection animators Animators - * - * Ecore provides a facility called animators, so named since the intended use - * was in animations, that facilitates knowing what percentage of a given - * interval has elapsed. This is perfect for performing animations, but is not - * limited to that use, it can, for example, also be used to create a progress - * bar. - * @see Ecore_Animator_Group - * - * @subsection ev_handlers Event handlers - * - * Event handlers are, arguably, the most important feature of the ecore main - * loop, they are what allows the programmer to easily handle user interaction. - * Events however are not only things the user does, events can represent - * anything for which a type is created. - * @see Ecore_Event_Group - * - * All of these primitives are discussed in more detail in their respective - * pages linked above. - * - * Here is a diagram of the main loop flow of a simple program: - * - * @image html prog_flow.png - * @image latex prog_flow.eps width=\textwidth - * - * - * - * @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 - * - * 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 doesn'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_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 abstraction - 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 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. - */ - -#ifndef _ECORE_H -#define _ECORE_H - -#ifdef _MSC_VER -# include -#endif - -#include - -/* This include has been added to support Eo in Ecore */ -#include - -#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 */ - -#ifdef _WIN32 -# include -#elif defined (__FreeBSD__) || defined (__OpenBSD__) -# include -# include -#elif defined (__ANDROID__) -# include -#else -# include -# if !defined (EXOTIC_NO_SIGNAL) -# include -# endif -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup Ecore_Init_Group Ecore initialization, shutdown functions and reset on fork. - * - * @{ - */ - -EAPI int ecore_init(void); -EAPI int ecore_shutdown(void); -/** - * @} - */ - -/** - * @defgroup Ecore_Main_Loop_Group Ecore main loop - * - * This group discusses functions that are acting on Ecore's main loop itself or - * on events and infrastructure directly linked to it. Most programs only need - * to start and end the main loop, the rest of the function discussed here are - * meant to be used in special situations, and with great care. - * - * For details on the usage of ecore's main loop and how it interacts with other - * ecore facilities see: @ref Ecore_Main_Loop_Page. - * - * @{ - */ - -#define ECORE_VERSION_MAJOR 1 -#define ECORE_VERSION_MINOR 8 - -typedef struct _Ecore_Version -{ - int major; - int minor; - int micro; - int revision; -} Ecore_Version; - -EAPI extern Ecore_Version *ecore_version; - -#define ECORE_CALLBACK_CANCEL EINA_FALSE /**< Return value to remove a callback */ -#define ECORE_CALLBACK_RENEW EINA_TRUE /**< Return value to keep a callback */ - -#define ECORE_CALLBACK_PASS_ON EINA_TRUE /**< Return value to pass event to next handler */ -#define ECORE_CALLBACK_DONE EINA_FALSE /**< Return value to stop event handling */ - -/** - * @typedef Ecore_Task_Cb Ecore_Task_Cb - * A callback run for a task (timer, idler, poller, animator, etc) - */ -typedef Eina_Bool (*Ecore_Task_Cb)(void *data); - -/** - * @typedef Ecore_Select_Function - * A function which can be used to replace select() in the main loop - */ -typedef int (*Ecore_Select_Function)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); - -EAPI void ecore_main_loop_iterate(void); - -EAPI void ecore_main_loop_select_func_set(Ecore_Select_Function func); -EAPI Ecore_Select_Function 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); - -/** - * @typedef Ecore_Cb Ecore_Cb - * A generic callback called as a hook when a certain point in - * execution is reached. - */ -typedef void (*Ecore_Cb)(void *data); - -/** - * @typedef Ecore_Data_Cb Ecore_Data_Cb - * A callback which is used to return data to the main function - */ -typedef void *(*Ecore_Data_Cb)(void *data); - -/** - * Add a function to be called by ecore_fork_reset() - * - * This queues @p func to be called (and passed @p data as its argument) when - * ecore_fork_reset() is called. This allows other libraries and subsystems - * to also reset their internal state after a fork. - * - * @since 1.7 - */ -EAPI Eina_Bool ecore_fork_reset_callback_add(Ecore_Cb func, const void *data); - -/** - * This removes the callback specified - * - * This deletes the callback added by ecore_fork_reset_callback_add() using - * the function and data pointer to specify which to remove. - * - * @since 1.7 - */ -EAPI Eina_Bool ecore_fork_reset_callback_del(Ecore_Cb func, const void *data); - -/** - * Reset the ecore internal state after a fork - * - * Ecore maintains internal data that can be affected by the fork() system call - * which creates a duplicate of the current process. This also duplicates - * file descriptors which is problematic in that these file descriptors still - * point to their original sources. This function makes ecore reset internal - * state (e.g. pipes used for signalling between threads) so they function - * correctly afterwards. - * - * It is highly suggested that you call this function after any fork() - * system call inside the child process if you intend to use ecore features - * after this point and not call any exec() family functions. Not doing so - * will cause possible misbehaviour. - * - * @since 1.7 - */ -EAPI void ecore_fork_reset(void); - -/** - * @brief Call callback asynchronously in the main loop. - * @since 1.1.0 - * - * @param callback The callback to call in the main loop - * @param data The data to give to that call back - * - * For all calls that need to happen in the main loop (most EFL functions do), - * this helper function provides the infrastructure needed to do it safely - * by avoiding dead lock, race condition and properly wake up the main loop. - * - * Remember after that function call, you should never touch again the @p data - * in the thread, it is owned by the main loop and your callback should take - * care of freeing it if necessary. - */ -EAPI void ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, void *data); - -/** - * @brief Call callback synchronously in the main loop. - * @since 1.1.0 - * - * @param callback The callback to call in the main loop - * @param data The data to give to that call back - * @return the value returned by the callback in the main loop - * - * For all calls that need to happen in the main loop (most EFL functions do), - * this helper function provides the infrastructure needed to do it safely - * by avoiding dead lock, race condition and properly wake up the main loop. - * - * Remember this function will block until the callback is executed in the - * main loop. It can take time and you have no guaranty about the timeline. - */ -EAPI void *ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, void *data); - -/** - * @brief This function suspend the main loop in a know state - * @since 1.1.0 - * - * @result the number of time ecore_thread_main_loop_begin() has been called - * in this thread, if the main loop was suspended correctly. If not, it return @c -1. - * - * This function suspend the main loop in a know state, this let you - * use any EFL call you want after it return. Be carefully, the main loop - * is blocked until you call ecore_thread_main_loop_end(). This is - * the only sane way to achieve pseudo thread safety. - * - * Notice that until the main loop is blocked, the thread is blocked - * and their is noway around that. - * - * We still advise you, when possible, to use ecore_main_loop_thread_safe_call_async() - * as it will not block the thread nor the main loop. - */ -EAPI int ecore_thread_main_loop_begin(void); - -/** - * @brief Unlock the main loop. - * @since 1.1.0 - * - * @result the number of time ecore_thread_main_loop_end() need to be called before - * the main loop is unlocked again. @c -1 will be returned if you are trying to unlock - * when there wasn't enough call to ecore_thread_main_loop_begin(). - * - * After a call to ecore_thread_main_loop_begin(), you need to absolutely - * call ecore_thread_main_loop_end(), or you application will stay frozen. - */ -EAPI int ecore_thread_main_loop_end(void); - -/** - * @} - */ - -/** - * @defgroup Ecore_Event_Group Ecore Event functions - * - * Ecore events provide two main features that are of use to those using ecore: - * creating events and being notified of events. Those two will usually be used - * in different contexts, creating events is mainly done by libraries wrapping - * some system functionality while being notified of events is mainly a - * necessity of applications. - * - * For a program to be notified of events it's interested in it needs to have a - * function to process the event and to register that function as the callback - * to the event, that's all: - * @code - * ecore_event_handler_add(EVENT_TYPE, _my_event_handler, some_data); - * ... - * static Eina_Bool - * _my_event_handler(void *data, int type, void *event) - * { - * //data is some_data - * //event is provided by whoever created the event - * //Do really cool stuff with event - * } - * @endcode - * - * One very important thing to note here is the @c EVENT_TYPE, to register a - * handler for an event you must know its type before hand. Ecore provides - * the following events which are emitted in response to POSIX - * signals(https://en.wikipedia.org/wiki/Signal_%28computing%29): - * @li @b ECORE_EVENT_SIGNAL_USER - * @li @b ECORE_EVENT_SIGNAL_HUP - * @li @b ECORE_EVENT_SIGNAL_POWER - * @li @b ECORE_EVENT_SIGNAL_EXIT - * - * @warning Don't override these using the @c signal or @c sigaction calls. - * These, however, aren't the only signals one can handle. Many - * libraries(including ecore modules) have their own signals that can be - * listened for and handled, to do that one only needs to know the type of the - * event. This information can be found on the documentation of the library - * emitting the signal, so, for example, for events related to windowing one - * would look in @ref Ecore_Evas_Group. - * - * Examples of libraries that integrate into ecore's main loop by providing - * events are @ref Ecore_Con_Group, @ref Ecore_Evas_Group and @ref - * Ecore_Exe_Group, amongst others. This usage can be divided into two parts, - * setup and adding events. The setup is very simple, all that needs doing is - * getting a type id for the event: - * @code - * int MY_EV_TYPE = ecore_event_type_new(); - * @endcode - * @note This variable should be declared in the header since it'll be needed by - * anyone wishing to register a handler to your event. - * - * The complexity of adding of an event to the queue depends on whether that - * event sends uses @c event, if it doesn't it a one-liner: - * @code - * ecore_event_add(MY_EV_TYPE, NULL, NULL, NULL); - * @endcode - * The usage when an @c event is needed is not that much more complex and can be - * seen in @ref ecore_event_add. - * - * Examples that deals with events: - * @li @ref ecore_event_example_01_c - * @li @ref ecore_event_example_02_c - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -#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 - -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_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 Ecore_Filter_Cb - * A callback used for filtering events from the main loop. - */ -typedef Eina_Bool (*Ecore_Filter_Cb)(void *data, void *loop_data, int type, void *event); - -/** - * @typedef Ecore_End_Cb Ecore_End_Cb - * This is the callback which is called at the end of a function, - * usually for cleanup purposes. - */ -typedef void (*Ecore_End_Cb)(void *user_data, void *func_data); - -/** - * @typedef Ecore_Event_Handler_Cb Ecore_Event_Handler_Cb - * A callback used by the main loop to handle events of a specified - * type. - */ -typedef Eina_Bool (*Ecore_Event_Handler_Cb)(void *data, int type, void *event); - -struct _Ecore_Event_Signal_User /** User signal event */ -{ - int number; /**< The signal number. Either 1 or 2 */ - void *ext_data; /**< Extension data - not used */ - -#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) - siginfo_t data; /**< Signal info */ -#endif -}; - -struct _Ecore_Event_Signal_Hup /** Hup signal event */ -{ - void *ext_data; /**< Extension data - not used */ - -#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) - siginfo_t data; /**< Signal info */ -#endif -}; - -struct _Ecore_Event_Signal_Exit /** Exit request event */ -{ - Eina_Bool interrupt : 1; /**< Set if the exit request was an interrupt signal*/ - Eina_Bool quit : 1; /**< set if the exit request was a quit signal */ - Eina_Bool terminate : 1; /**< Set if the exit request was a terminate signal */ - void *ext_data; /**< Extension data - not used */ - -#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) - siginfo_t data; /**< Signal info */ -#endif -}; - -struct _Ecore_Event_Signal_Power /** Power event */ -{ - void *ext_data; /**< Extension data - not used */ - -#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) - siginfo_t data; /**< Signal info */ -#endif -}; - -struct _Ecore_Event_Signal_Realtime /** Realtime event */ -{ - int num; /**< The realtime signal's number */ - -#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) - siginfo_t data; /**< Signal info */ -#endif -}; - -/** - * @brief 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 @c 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_PASS_ON), It will keep being called as per normal, for - * each handler set up for that event type. If it returns 0 (or - * ECORE_CALLBACK_DONE), 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, Ecore_Event_Handler_Cb func, const void *data); -/** - * @brief 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 @c 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); -/** - * @brief Add an event to the event queue. - * @param type The event type to add to the end of the event queue - * @param ev The data structure passed as @c event to event handlers - * @param func_free The function to be called to free @a ev - * @param data The data pointer to be passed to the free function - * @return A Handle for that event on success, otherwise NULL - * - * If it succeeds, an event of type @a type will be added to the queue for - * processing by event handlers added by ecore_event_handler_add(). The @a ev - * parameter will be passed as the @c event parameter of the handler. When the - * event is no longer needed, @a func_free will be called and passed @a ev for - * cleaning up. If @p func_free is NULL, free() will be called with the private - * structure pointer. - */ -EAPI Ecore_Event *ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data); -/** - * @brief 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 parameter 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); -/** - * @brief Get the data associated with an #Ecore_Event_Handler - * @param eh The event handler - * @return The data - * - * This function returns the data previously associated with @p eh by - * ecore_event_handler_add(). - */ -EAPI void *ecore_event_handler_data_get(Ecore_Event_Handler *eh); -/** - * @brief Set the data associated with an #Ecore_Event_Handler - * @param eh The event handler - * @param data The data to associate - * @return The previous data - * - * This function sets @p data to @p eh and returns the old data pointer - * which was previously associated with @p eh by ecore_event_handler_add(). - */ -EAPI void *ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data); -/** - * @brief 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); -/** - * @brief 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 queue has been filtered - * @param data Data to pass to the filter functions - * @return A filter handle on success, @c NULL otherwise. - * - * Adds a callback to filter events from the event queue. Filters are called on - * the queue just before Event handler processing to try and remove redundant - * events. Just as processing is about to start @a func_start is called and - * passed the @a data pointer, the return value of this functions is passed to - * @a func_filter as loop_data. @a func_filter is also passed @a data and the - * event type and event structure. If this @a func_filter returns - * @c EINA_FALSE, the event is removed from the queue, if it returns - * @c EINA_TRUE, the event is kept. When processing is finished @p func_end is - * called and is passed the loop_data(returned by @c func_start) and @p data - * pointer to clean up. - */ -EAPI Ecore_Event_Filter *ecore_event_filter_add(Ecore_Data_Cb func_start, Ecore_Filter_Cb func_filter, Ecore_End_Cb func_end, const void *data); -/** - * @brief Delete an event filter. - * @param ef The event filter handle - * @return The data set for the filter on success, @c NULL otherwise. - * - * Delete a filter that has been added by its @p ef handle. - */ -EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef); -/** - * @brief Return the current event type being handled. - * @return The current event type being handled if inside a handler callback, - * ECORE_EVENT_NONE otherwise - * - * If the program is currently inside an Ecore event handler callback this - * will return the type of the current event being processed. - * - * 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); -/** - * @brief Return the current event type pointer handled. - * @return The current event pointer being handled if inside a handler callback, - * @c NULL otherwise. - * - * If the program is currently inside an Ecore event handler callback this - * will return the pointer of the current event being processed. - * - * 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); - -/** - * @} - */ - -/** - * @defgroup Ecore_Exe_Group Process Spawning Functions - * - * This module is responsible for managing portable processes using Ecore. - * With this module you're able to spawn processes and you also can pause, - * quit your spawned processes. - * An interaction between your process and those spawned is possible - * using pipes or signals. - * - * Example - * @li @ref Ecore_exe_simple_example_c - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -/** Inherit priority from parent process */ -#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 consistent 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_Exe_Flags - * Flags for executing a child with its stdin and/or stdout piped back. - */ -enum _Ecore_Exe_Flags /* flags for executing a child with its stdin and/or stdout piped back */ -{ - ECORE_EXE_NONE = 0, /**< No exe flags at all */ - 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 split 1 line per Ecore_Exe_Event_Data_Line */ - ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16, /**< Errors are buffered until a newline and split 1 line per Ecore_Exe_Event_Data_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 */ - ECORE_EXE_TERM_WITH_PARENT = 512 /**< Makes child receive SIGTERM when parent dies. */ -}; -typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags; - -/** - * @enum _Ecore_Exe_Win32_Priority - * Defines the priority of the proccess. - */ -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; - -typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */ - -/** - * @typedef Ecore_Exe_Cb Ecore_Exe_Cb - * A callback to run with the associated @ref Ecore_Exe, usually - * for cleanup purposes. - */ -typedef void (*Ecore_Exe_Cb)(void *data, const Ecore_Exe *exe); - -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 */ - -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 @c NULL if not found */ - int exit_signal; /** < The signal that caused the process to exit */ - Eina_Bool exited : 1; /** < set to 1 if the process exited of its own accord */ - Eina_Bool signalled : 1; /** < set to 1 id the process exited due to uncaught signal */ - void *ext_data; /**< Extension data - not used */ -#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) - siginfo_t data; /**< Signal info */ -#endif -}; - -struct _Ecore_Exe_Event_Data_Line /**< Lines from a child process */ -{ - char *line; /**< The bytes of a line of buffered data */ - int size; /**< The size of the line buffer in bytes */ -}; - -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 received */ - 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 @c NULL */ -}; - -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, Ecore_Exe_Cb func); -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 void *ecore_exe_data_set(Ecore_Exe *exe, void *data); -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); - -/** - * @} - */ - -/** - * @defgroup Ecore_FD_Handler_Group File Descriptor Handling Functions - * - * @brief Functions that deal with file descriptor handlers. - * - * File descriptor handlers facilitate reading, writing and checking for errors - * without blocking the program or doing expensive pooling. This can be used to - * monitor a socket, pipe, or other stream for which an FD can be had. - * - * @warning File descriptor handlers can't be used to monitor for file creation, - * modification or deletion, see @ref Ecore_File_Group for this. - * - * One common FD to be monitored is the standard input(stdin), monitoring it for - * reading requires a single call: - * @code - * static Eina_Bool - * _my_cb_func(void *data, Ecore_Fd_Handler *handler) - * { - * char c; - * scanf("%c", &c); //Guaranteed not to block - * ... do stuff with c ... - * } - * ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ, _my_cb_func, NULL, NULL, NULL); - * @endcode - * - * When using a socket, pipe or other stream it's important to remember that - * errors may occur and as such to monitor not only for reading/writing but also - * for errors using the @ref ECORE_FD_ERROR flag. - * - * Example of use of a file descriptor handler: - * @li @ref ecore_fd_handler_example_c - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; /**< A handle for Fd handlers */ - -/** - * @enum _Ecore_Fd_Handler_Flags - * What to monitor the file descriptor for: reading, writing or error. - */ -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; - -/** - * @typedef Ecore_Fd_Cb Ecore_Fd_Cb - * A callback used by an @ref Ecore_Fd_Handler. - */ -typedef Eina_Bool (*Ecore_Fd_Cb)(void *data, Ecore_Fd_Handler *fd_handler); - -/** - * @typedef Ecore_Fd_Prep_Cb Ecore_Fd_Prep_Cb - * A callback used by an @ref Ecore_Fd_Handler. - */ -typedef void (*Ecore_Fd_Prep_Cb)(void *data, Ecore_Fd_Handler *fd_handler); - -/** - * @typedef Ecore_Win32_Handle_Cb Ecore_Win32_Handle_Cb - * A callback used by an @ref Ecore_Win32_Handler. - */ -typedef Eina_Bool (*Ecore_Win32_Handle_Cb)(void *data, Ecore_Win32_Handler *wh); - -/** - * @brief Adds a callback for activity on the given file descriptor. - * - * @param fd The file descriptor to watch. - * @param flags To monitor it for reading use @c ECORE_FD_READ, for writing @c - * ECORE_FD_WRITE, and for error @c ECORE_FD_ERROR. Values by |(ored). - * @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. May be @c NULL. - * @param buf_data The data to pass to the @p buf_func function. - * @return A fd handler handle on success, @c NULL otherwise. - * - * @a func will be called during the execution of @ref Ecore_Main_Loop_Page - * when the file descriptor is available for reading, writing, or there has been - * an error(depending on the given @a flags). - * - * When @a func returns ECORE_CALLBACK_CANCEL, it indicates that the - * handler should be marked for deletion (identical to calling @ref - * ecore_main_fd_handler_del). - * - * @warning @a buf_func is meant for @b internal use only and should be @b - * avoided. - * - * The return value of @a buf_func has a different meaning, when it returns - * ECORE_CALLBACK_CANCEL, it indicates that @a func @b shouldn't be called, and - * when it returns ECORE_CALLBACK_RENEW it indicates @a func should be called. - * The return value of @a buf_func will not cause the FD handler to be deleted. - * - * @a 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 @a buf_func. This is a - * most annoying hack, only ecore_x uses it, so refer to that for an example. - * - * @warning This function should @b not be used for monitoring "normal" files, like text files. - * - */ -EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, Ecore_Fd_Cb buf_func, const void *buf_data); - -/** - * @brief Adds a callback for activity on the given file descriptor. - * - * @param fd The file descriptor to watch. - * @param flags To monitor it for reading use @c ECORE_FD_READ, for writing @c - * ECORE_FD_WRITE, and for error @c ECORE_FD_ERROR. Values by |(ored). - * @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. May be @c NULL. - * @param buf_data The data to pass to the @p buf_func function. - * @return A fd handler handle on success, @c NULL otherwise. - * - * This function is identical to ecore_main_fd_handler_add, except that it supports regular files. - * @warning This function should ONLY be called with ECORE_FD_ERROR, otherwise it will call the fd - * handler constantly. - * @warning Do not use this function unless you know what you are doing. - * - * @since 1.7 - */ -EAPI Ecore_Fd_Handler *ecore_main_fd_handler_file_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, Ecore_Fd_Cb buf_func, const void *buf_data); - -/** - * @brief Set the prepare callback with data for a given #Ecore_Fd_Handler - * - * @param fd_handler The fd handler - * @param func The prep function - * @param data The data to pass to the prep function - * - * This function will be called prior to any fd handler's callback function - * (even the other fd handlers), before entering the main loop select function. - * - * @note Once a prepare callback is set for a fd handler, it cannot be changed. - * You need to delete the fd handler and create a new one, to set another - * callback. - * @note You probably don't need this function. It is only necessary for very - * uncommon cases that need special behavior. - */ -EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data); -/** - * @brief Marks an FD handler for deletion. - * @param fd_handler The FD handler. - * @return The data pointer set using @ref ecore_main_fd_handler_add, for - * @a fd_handler on success, @c NULL otherwise. - * This function marks an fd handler to be deleted during an iteration of the - * main loop. It does NOT close the associated fd! - * - * @warning If the underlying fd is already closed ecore may complain if the - * main loop is using epoll internally, and also in some rare cases this may - * cause crashes and instability. Remember to delete your fd handlers before the - * fds they listen to are closed. - */ -EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); -/** - * @brief 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. - */ -EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler); -/** - * @brief Gets which flags are active on an 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 EINA_TRUE if any of the given flags are active, @c EINA_FALSE - * otherwise. - */ -EAPI Eina_Bool ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); -/** - * @brief 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. - */ -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, Ecore_Win32_Handle_Cb func, const void *data); -EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler); - -/** - * @} - */ - -/** - * @defgroup Ecore_Poller_Group Ecore Poll functions - * - * Ecore poller provides infrastructure for the creation of pollers. Pollers - * are, in essence, callbacks that share a single timer per type. Because not - * all pollers need to be called at the same frequency the user may specify the - * frequency in ticks(each expiration of the shared timer is called a tick, in - * ecore poller parlance) for each added poller. Ecore pollers should only be - * used when the poller doesn't have specific requirements on the exact times - * to poll. - * - * This architecture means that the main loop is only woken up once to handle - * all pollers of that type, 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 in situations where power usage is a concern. - * - * For now only 1 core poller type is supported: ECORE_POLLER_CORE, the default - * interval for ECORE_POLLER_CORE is 0.125(or 1/8th) second. - * - * The creation of a poller is extremely simple and only requires one line: - * @code - * ecore_poller_add(ECORE_POLLER_CORE, 1, my_poller_function, NULL); - * @endcode - * This sample creates a poller to call @c my_poller_function at every tick with - * @c NULL as data. - * - * Example: - * @li @ref ecore_poller_example_c - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -/** - * @enum _Ecore_Poller_Type - * Defines the frequency of ticks for the poller. - */ -enum _Ecore_Poller_Type /* Poller types */ -{ - ECORE_POLLER_CORE = 0 /**< The core poller interval */ -}; -typedef enum _Ecore_Poller_Type Ecore_Poller_Type; - -/* - * @since 1.8 - */ - -typedef Eo Ecore_Poller; /**< A handle for pollers */ - -#define ECORE_POLLER_CLASS ecore_poller_class_get() -const Eo_Class *ecore_poller_class_get(void) EINA_CONST; -extern EAPI Eo_Op ECORE_POLLER_BASE_ID; - -enum -{ - ECORE_POLLER_SUB_ID_CONSTRUCTOR, - ECORE_POLLER_SUB_ID_INTERVAL_SET, - ECORE_POLLER_SUB_ID_INTERVAL_GET, - ECORE_POLLER_SUB_ID_LAST, -}; - -#define ECORE_POLLER_ID(sub_id) (ECORE_POLLER_BASE_ID + sub_id) - -/** - * @def ecore_poller_constructor - * @since 1.8 - * - * Contructor with parameters for Ecore Poller. - * - * @param[in] type - * @param[in] interval - * @param[in] func - * @param[in] data - * - */ -#define ecore_poller_constructor(type, interval, func, data) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Poller_Type, type), EO_TYPECHECK(int, interval), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * @def ecore_poller_interval_set - * @since 1.8 - * - * Changes the polling interval rate of poller. - * - * @param[in] interval - * @param[out] ret - * - * @see ecore_poller_poller_interval_set - */ -#define ecore_poller_interval_set(interval, ret) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_SET), EO_TYPECHECK(int, interval), EO_TYPECHECK(Eina_Bool *, ret) - -/** - * @def ecore_poller_interval_get - * @since 1.8 - * - * Gets the polling interval rate of poller. - * - * @param[out] ret - * - * @see ecore_poller_poller_interval_get - */ -#define ecore_poller_interval_get(ret) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_GET), EO_TYPECHECK(int *, ret) - - -/** - * @brief Sets the time(in seconds) between ticks for the given poller type. - * @param type The poller type to adjust. - * @param poll_time The time(in seconds) between ticks of the timer. - * - * This will adjust the time between ticks of the given timer 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, double poll_time); -/** - * @brief Gets the time(in seconds) between ticks for the given poller type. - * @param type The poller type to query. - * @return The time in seconds between ticks of the poller timer. - * - * This will get the time between ticks of the specified poller timer. - */ -EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type); -/** - * @brief Changes the polling interval rate of @p poller. - * @param poller The Ecore_Poller to change the interval of. - * @param interval The tick interval to set; must be a power of 2 and <= 32768. - * @return Returns true on success, false on failure. - * - * This allows the changing of a poller's polling interval. It is useful when - * you want to alter a poll rate without deleting and re-creating a poller. - */ -EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval); -/** - * @brief Gets the polling interval rate of @p poller. - * @param poller The Ecore_Poller to change the interval of. - * @return Returns the interval, in ticks, that @p poller polls at. - * - * This returns a poller's polling interval, or 0 on error. - */ -EAPI int ecore_poller_poller_interval_get(Ecore_Poller *poller); -/** - * @brief Creates a poller to call the given function at a particular tick interval. - * @param type The ticker type to attach the poller to. Must be ECORE_POLLER_CORE. - * @param interval The poll interval. - * @param func The poller function. - * @param data Data to pass to @a func when it is called. - * @return A poller object on success, @c NULL otherwise. - * - * This function adds @a func as a poller callback that will be called every @a - * interval ticks together with other pollers of type @a type. @a func will be - * passed the @p data pointer as a parameter. - * - * The @p interval must be between 1 and 32768 inclusive, and must be a power of - * 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768). The exact tick in which @a func - * will be called is undefined, as only the interval between calls can be - * defined. Ecore will endeavor to keep pollers synchronized and to call as - * many in 1 wakeup event as possible. If @a interval is not a power of two, the - * closest power of 2 greater than @a interval will be used. - * - * When the poller @p func is called, it must return a value of either - * ECORE_CALLBACK_RENEW(or 1) or ECORE_CALLBACK_CANCEL(or 0). 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, int interval, Ecore_Task_Cb func, const void *data); -/** - * @brief 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 on success, @c NULL otherwise. - * - * @note @a 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 deleted). - */ -EAPI void *ecore_poller_del(Ecore_Poller *poller); - -/** - * @} - */ - -/** - * @defgroup Ecore_Animator_Group Ecore Animator functions - * - * @brief Ecore animators are a helper to simplify creating - * animations. - * - * Creating an animation is as simple as saying for how long it - * should be run and having a callback that does the animation, - * something like this: - * @code - * static Eina_Bool - * _do_animation(void *data, double pos) - * { - * evas_object_move(data, 100 * pos, 100 * pos); - * ... do some more animating ... - * } - * ... - *ecore_animator_timeline_add(2, _do_animation, my_evas_object); - * @endcode - * In the sample above we create an animation to move - * @c my_evas_object from position (0,0) to (100,100) in 2 seconds. - * - * If your animation will run for an unspecified amount of time you - * can use ecore_animator_add(), which is like using - *ecore_timer_add() with the interval being the - * @ref ecore_animator_frametime_set "framerate". Note that this has - * tangible benefits to creating a timer for each animation in terms - * of performance. - * - * For a more detailed example that show several animation see - * @ref tutorial_ecore_animator. - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -/* - * @since 1.8 - */ -typedef Eo Ecore_Animator; /**< A handle for animators */ -#define ECORE_ANIMATOR_CLASS ecore_animator_class_get() -const Eo_Class *ecore_animator_class_get(void) EINA_CONST; - -extern EAPI Eo_Op ECORE_ANIMATOR_BASE_ID; - -enum -{ - ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR, - ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR, - ECORE_ANIMATOR_SUB_ID_LAST -}; - -#define ECORE_ANIMATOR_ID(sub_id) (ECORE_ANIMATOR_BASE_ID + sub_id) - -/** - * @def ecore_animator_constructor - * @since 1.8 - * - * Contructor. - * - * @param[in] func - * @param[in] data - * - */ -#define ecore_animator_constructor(func, data) ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * @def ecore_animator_timeline_constructor - * @since 1.8 - * - * Contructor. - * - * @param[in] runtime - * @param[in] func - * @param[in] data - * - */ -#define ecore_animator_timeline_constructor(runtime, func, data) ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR), EO_TYPECHECK(double, runtime), EO_TYPECHECK(Ecore_Timeline_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * @enum _Ecore_Pos_Map - * Defines the position mappings for the animation. - */ -enum _Ecore_Pos_Map /* Position mappings */ -{ - ECORE_POS_MAP_LINEAR, /**< Linear 0.0 -> 1.0 */ - ECORE_POS_MAP_ACCELERATE, /**< Start slow then speed up */ - ECORE_POS_MAP_DECELERATE, /**< Start fast then slow down */ - ECORE_POS_MAP_SINUSOIDAL, /**< Start slow, speed up then slow down at end */ - ECORE_POS_MAP_ACCELERATE_FACTOR, /**< Start slow then speed up, v1 being a power factor, 0.0 being linear, 1.0 being normal accelerate, 2.0 being much more pronounced accelerate (squared), 3.0 being cubed, etc. */ - ECORE_POS_MAP_DECELERATE_FACTOR, /**< Start fast then slow down, v1 being a power factor, 0.0 being linear, 1.0 being normal decelerate, 2.0 being much more pronounced decelerate (squared), 3.0 being cubed, etc. */ - ECORE_POS_MAP_SINUSOIDAL_FACTOR, /**< Start slow, speed up then slow down at end, v1 being a power factor, 0.0 being linear, 1.0 being normal sinusoidal, 2.0 being much more pronounced sinusoidal (squared), 3.0 being cubed, etc. */ - ECORE_POS_MAP_DIVISOR_INTERP, /**< Start at gradient * v1, interpolated via power of v2 curve */ - ECORE_POS_MAP_BOUNCE, /**< Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1 */ - ECORE_POS_MAP_SPRING /**< Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1 */ -}; -typedef enum _Ecore_Pos_Map Ecore_Pos_Map; - -/** - * @enum _Ecore_Animator_Source - * Defines the timing sources for animators. - */ -enum _Ecore_Animator_Source /* Timing sources for animators */ -{ - ECORE_ANIMATOR_SOURCE_TIMER, /**< The default system clock/timer based animator that ticks every "frametime" seconds */ - ECORE_ANIMATOR_SOURCE_CUSTOM /**< A custom animator trigger that you need to call ecore_animator_trigger() to make it tick */ -}; -typedef enum _Ecore_Animator_Source Ecore_Animator_Source; - -/** - * @typedef Ecore_Timeline_Cb Ecore_Timeline_Cb - * A callback run for a task (animators with runtimes) - */ -typedef Eina_Bool (*Ecore_Timeline_Cb)(void *data, double pos); - -/** - * @brief Add an animator to call @p func at every animation 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 - * - * This function adds a animator and returns its handle on success and @c NULL - * on failure. The function @p func will be called every N seconds where N is - * the @p 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. - * - * @note The default @p frametime value is 1/30th of a second. - * - * @see ecore_animator_timeline_add() - * @see ecore_animator_frametime_set() - */ -EAPI Ecore_Animator *ecore_animator_add(Ecore_Task_Cb func, const void *data); -/** - * @brief Add a animator that runs for a limited time - * - * @param runtime The time to run in seconds - * @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 - * - * This function is just like ecore_animator_add() except the animator only - * runs for a limited time specified in seconds by @p runtime. Once the - * runtime the animator has elapsed (animator finished) it will automatically - * be deleted. The callback function @p func can return ECORE_CALLBACK_RENEW - * to keep the animator running or ECORE_CALLBACK_CANCEL ro stop it and have - * it be deleted automatically at any time. - * - * The @p func will ALSO be passed a position parameter that will be in value - * from 0.0 to 1.0 to indicate where along the timeline (0.0 start, 1.0 end) - * the animator run is at. If the callback wishes not to have a linear - * transition it can "map" this value to one of several curves and mappings - * via ecore_animator_pos_map(). - * - * @note The default @p frametime value is 1/30th of a second. - * - * @see ecore_animator_add() - * @see ecore_animator_pos_map() - * @since 1.1.0 - */ -EAPI Ecore_Animator *ecore_animator_timeline_add(double runtime, Ecore_Timeline_Cb func, const void *data); -/** - * @brief Delete the specified animator from the animator list. - * - * @param animator The animator to delete - * @return The data pointer set for the animator on add - * - * Delete the specified @p animator 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 @c 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); -/** - * @brief Suspend the specified animator. - * - * @param animator The animator to delete - * - * The specified @p animator will be temporarily removed from the set of - * animators that are executed during main loop. - * - * @warning Freezing an animator doesn't freeze accounting of how long that - * animator has been running. Therefore if the animator was created with - *ecore_animator_timeline_add() the @p pos argument given to the callback - * will increase as if the animator hadn't been frozen and the animator may - * have it's execution halted if @p runtime elapsed. - */ -EAPI void ecore_animator_freeze(Ecore_Animator *animator); -/** - * @brief Restore execution of the specified animator. - * - * @param animator The animator to delete - * - * The specified @p animator will be put back in the set of animators that are - * executed during main loop. - */ -EAPI void ecore_animator_thaw(Ecore_Animator *animator); -/** - * @brief 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) between animator ticks. - * At every tick the callback of every existing animator will be called. - * - * @warning Too small a value may cause performance issues and too high a - * value may cause your animation to seem "jerky". - * - * @note The default @p frametime value is 1/30th of a second. - */ -EAPI void ecore_animator_frametime_set(double frametime); -/** - * @brief Get the animator call interval in seconds. - * - * @return The time in second in between animator ticks. - * - * This function retrieves the time in seconds between animator ticks. - * - * @see ecore_animator_frametime_set() - */ -EAPI double ecore_animator_frametime_get(void); -/** - * @brief Maps an input position from 0.0 to 1.0 along a timeline to a - * position in a different curve. - * - * @param pos The input position to map - * @param map The mapping to use - * @param v1 A parameter use by the mapping (pass 0.0 if not used) - * @param v2 A parameter use by the mapping (pass 0.0 if not used) - * @return The mapped value - * - * Takes an input position (0.0 to 1.0) and maps to a new position (normally - * between 0.0 and 1.0, but it may go above/below 0.0 or 1.0 to show that it - * has "overshot" the mark) using some interpolation (mapping) algorithm. - * - * This function useful to create non-linear animations. It offers a variety - * of possible animation curves to be used: - * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos - * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up - * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down - * @li ECORE_POS_MAP_SINUSOIDAL - Start slow, speed up then slow down at end - * @li ECORE_POS_MAP_ACCELERATE_FACTOR - Start slow then speed up, v1 being a - * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_ACCELERATE, 2.0 - * being much more pronounced accelerate (squared), 3.0 being cubed, etc. - * @li ECORE_POS_MAP_DECELERATE_FACTOR - Start fast then slow down, v1 being a - * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_DECELERATE, 2.0 - * being much more pronounced decelerate (squared), 3.0 being cubed, etc. - * @li ECORE_POS_MAP_SINUSOIDAL_FACTOR - Start slow, speed up then slow down - * at end, v1 being a power factor, 0.0 being linear, 1.0 being - * ECORE_POS_MAP_SINUSOIDAL, 2.0 being much more pronounced sinusoidal - * (squared), 3.0 being cubed, etc. - * @li ECORE_POS_MAP_DIVISOR_INTERP - Start at gradient * v1, interpolated via - * power of v2 curve - * @li ECORE_POS_MAP_BOUNCE - Start at 0.0 then "drop" like a ball bouncing to - * the ground at 1.0, and bounce v2 times, with decay factor of v1 - * @li ECORE_POS_MAP_SPRING - Start at 0.0 then "wobble" like a spring rest - * position 1.0, and wobble v2 times, with decay factor of v1 - * @note When not listed v1 and v2 have no effect. - * - * @image html ecore-pos-map.png - * @image latex ecore-pos-map.eps width=\textwidth - * - * One way to use this would be: - * @code - * double pos; // input position in a timeline from 0.0 to 1.0 - * double out; // output position after mapping - * int x1, y1, x2, y2; // x1 & y1 are start position, x2 & y2 are end position - * int x, y; // x & y are the calculated position - * - * out = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 1.8, 7); - * x = (x1 * out) + (x2 * (1.0 - out)); - * y = (y1 * out) + (y2 * (1.0 - out)); - * move_my_object_to(myobject, x, y); - * @endcode - * This will make an animation that bounces 7 each times diminishing by a - * factor of 1.8. - * - * @see _Ecore_Pos_Map - * - * @since 1.1.0 - */ -EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2); -/** - * @brief Set the source of animator ticks for the mainloop - * - * @param source The source of animator ticks to use - * - * This sets the source of animator ticks. When an animator is active the - * mainloop will "tick" over frame by frame calling all animators that are - * registered until none are. The mainloop will tick at a given rate based - * on the animator source. The default source is the system clock timer - * source - ECORE_ANIMATOR_SOURCE_TIMER. This source uses the system clock - * to tick over every N seconds (specified by ecore_animator_frametime_set(), - * with the default being 1/30th of a second unless set otherwise). You can - * set a custom tick source by setting the source to - * ECORE_ANIMATOR_SOURCE_CUSTOM and then drive it yourself based on some input - * tick source (like another application via ipc, some vertical blanking - * interrupt interrupt etc.) using - *ecore_animator_custom_source_tick_begin_callback_set() and - *ecore_animator_custom_source_tick_end_callback_set() to set the functions - * that will be called to start and stop the ticking source, which when it - * gets a "tick" should call ecore_animator_custom_tick() to make the "tick" over 1 - * frame. - */ -EAPI void ecore_animator_source_set(Ecore_Animator_Source source); -/** - * @brief Get the animator source currently set. - * - * @return The current animator source - * - * This gets the current animator source. - * - * @see ecore_animator_source_set() - */ -EAPI Ecore_Animator_Source ecore_animator_source_get(void); -/** - * @brief Set the function that begins a custom animator tick source - * - * @param func The function to call when ticking is to begin - * @param data The data passed to the tick begin function as its parameter - * - * The Ecore Animator infrastructure handles tracking if animators are needed - * or not and which ones need to be called and when, but when the tick source - * is custom, you have to provide a tick source by calling - *ecore_animator_custom_tick() to indicate a frame tick happened. In order - * to allow the source of ticks to be dynamically enabled or disabled as - * needed, the @p func when set is called to enable the tick source to - * produce tick events that call ecore_animator_custom_tick(). If @p func - * is @c NULL then no function is called to begin custom ticking. - * - * @see ecore_animator_source_set() - * @see ecore_animator_custom_source_tick_end_callback_set() - * @see ecore_animator_custom_tick() - */ -EAPI void ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data); -/** - * @brief Set the function that ends a custom animator tick source - * - * @param func The function to call when ticking is to end - * @param data The data passed to the tick end function as its parameter - * - * This function is a matching pair to the function set by - * ecore_animator_custom_source_tick_begin_callback_set() and is called - * when ticking is to stop. If @p func is @c NULL then no function will be - * called to stop ticking. For more information please see - * ecore_animator_custom_source_tick_begin_callback_set(). - * - * @see ecore_animator_source_set() - * @see ecore_animator_custom_source_tick_begin_callback_set() - * @see ecore_animator_custom_tick() - */ -EAPI void ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data); -/** - * @brief Trigger a custom animator tick - * - * When animator source is set to ECORE_ANIMATOR_SOURCE_CUSTOM, then calling - * this function triggers a run of all animators currently registered with - * Ecore as this indicates a "frame tick" happened. This will do nothing if - * the animator source(set by ecore_animator_source_set()) is not set to - * ECORE_ANIMATOR_SOURCE_CUSTOM. - * - * @see ecore_animator_source_set() - * @see ecore_animator_custom_source_tick_begin_callback_set - * @see ecore_animator_custom_source_tick_end_callback_set()() - */ -EAPI void ecore_animator_custom_tick(void); - -/** - * @} - */ - -/** - * @defgroup Ecore_Time_Group Ecore time functions - * - * These are function to retrieve time in a given format. - * - * Examples: - * @li @ref ecore_time_functions_example_c - * @{ - */ -EAPI double ecore_time_get(void); -EAPI double ecore_time_unix_get(void); -EAPI double ecore_loop_time_get(void); - -/** - * @} - */ - -/** - * @defgroup Ecore_Timer_Group Ecore Timer functions - * - * Ecore provides very flexible timer functionality. The basic usage of timers, - * to call a certain function at a certain interval can be achieved with a - * single line: - * @code - * Eina_Bool my_func(void *data) { - * do_funky_stuff_with_data(data); - * return EINA_TRUE; - * } - * ecore_timer_add(interval_in_seconds, my_func, data_given_to_function); - * @endcode - * @note If the function was to be executed only once simply return - * @c EINA_FALSE instead. - * - * An example that shows the usage of a lot of these: - * @li @ref ecore_timer_example_c - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -/* - * @since 1.8 - */ -typedef Eo Ecore_Timer; /**< A handle for timers */ - -#define ECORE_TIMER_CLASS ecore_timer_class_get() -const Eo_Class *ecore_timer_class_get(void) EINA_CONST; -extern EAPI Eo_Op ECORE_TIMER_BASE_ID; - -enum -{ - ECORE_TIMER_SUB_ID_CONSTRUCTOR, - ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR, - ECORE_TIMER_SUB_ID_INTERVAL_SET, - ECORE_TIMER_SUB_ID_INTERVAL_GET, - ECORE_TIMER_SUB_ID_DELAY, - ECORE_TIMER_SUB_ID_RESET, - ECORE_TIMER_SUB_ID_PENDING_GET, - ECORE_TIMER_SUB_ID_LAST, -}; - -#define ECORE_TIMER_ID(sub_id) (ECORE_TIMER_BASE_ID + sub_id) - -/** - * @def ecore_timer_constructor - * @since 1.8 - * - * Contructor. - * - * @param[in] in - * @param[in] func - * @param[in] data - * - */ -#define ecore_timer_constructor(in, func, data) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(double, in), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * @def ecore_timer_loop_constructor - * @since 1.8 - * - * Contructor. - * - * @param[in] in - * @param[in] func - * @param[in] data - * - */ -#define ecore_timer_loop_constructor(in, func, data) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR), EO_TYPECHECK(double, in), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * @def ecore_obj_timer_interval_set - * @since 1.8 - * - * Change the interval the timer ticks of. - * - * @param[in] in - * - * @see ecore_timer_interval_set - */ -#define ecore_obj_timer_interval_set(in) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_SET), EO_TYPECHECK(double, in) - -/** - * @def ecore_obj_timer_interval_get - * @since 1.8 - * - * Get the interval the timer ticks on. - * - * @param[out] ret - * - * @see ecore_timer_interval_get - */ -#define ecore_obj_timer_interval_get(ret) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_GET), EO_TYPECHECK(double *, ret) - -/** - * @def ecore_obj_timer_delay - * @since 1.8 - * - * Add some delay for the next occurrence of a timer. - * - * @param[in] add - * - * @see ecore_timer_delay - */ -#define ecore_obj_timer_delay(add) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_DELAY), EO_TYPECHECK(double, add) - -/** - * @def ecore_obj_timer_reset - * @since 1.8 - * - * Reset a timer to its full interval. - * - * @see ecore_timer_reset - */ -#define ecore_obj_timer_reset() ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_RESET) - -/** - * @def ecore_obj_timer_pending_get - * @since 1.8 - * - * Get the pending time regarding a timer. - * - * @param[out] ret - * - * @see ecore_timer_pending_get - */ -#define ecore_obj_timer_pending_get(ret) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_PENDING_GET), EO_TYPECHECK(double *, ret) - -EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data); -EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, 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 void ecore_timer_reset(Ecore_Timer *timer); -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 char *ecore_timer_dump(void); - -/** - * @} - */ - -/** - * @defgroup Ecore_Idle_Group Ecore Idle functions - * - * The idler functionality in Ecore allows for callbacks to be called when the - * program isn't handling @ref Ecore_Event_Group "events", @ref Ecore_Timer_Group - * "timers" or @ref Ecore_FD_Handler_Group "fd handlers". - * - * There are three types of idlers: Enterers, Idlers(proper) and Exiters. They - * are called, respectively, when the program is about to enter an idle state, - * when the program is in an idle state and when the program has just left an - * idle state and will begin processing @ref Ecore_Event_Group "events", @ref - * Ecore_Timer_Group "timers" or @ref Ecore_FD_Handler_Group "fd handlers". - * - * 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. - * - * Exiter callbacks are called when the main loop wakes up from an idle state. - * - * 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. - * - * @note Idle state doesn't mean that the @b program is idle, but - * that the main loop is idle. It doesn't have any timers, - * events, fd handlers or anything else to process (which in most - * event driven programs also means that the @b program is - * idle too, but it's not a rule). The program itself may be doing - * a lot of processing in the idler, or in another thread, for - * example. - * - * Example with functions that deal with idle state: - * - * @li @ref ecore_idler_example_c - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -/* - * @since 1.8 - */ -typedef Eo Ecore_Idler; /**< A handle for idlers */ -#define ECORE_IDLER_CLASS ecore_idler_class_get() -const Eo_Class *ecore_idler_class_get(void) EINA_CONST; - -extern EAPI Eo_Op ECORE_IDLER_BASE_ID; - -enum -{ - ECORE_IDLER_SUB_ID_CONSTRUCTOR, - ECORE_IDLER_SUB_ID_LAST -}; - -#define ECORE_IDLER_ID(sub_id) (ECORE_IDLER_BASE_ID + sub_id) - -/** - * @def ecore_idler_constructor - * @since 1.8 - * - * Contructor. - * - * @param[in] func - * @param[in] data - * - */ -#define ecore_idler_constructor(func, data) ECORE_IDLER_ID(ECORE_IDLER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * - */ - -typedef Eo Ecore_Idle_Enterer; /**< A handle for idle enterers */ -#define ECORE_IDLE_ENTERER_CLASS ecore_idle_enterer_class_get() -const Eo_Class *ecore_idle_enterer_class_get(void) EINA_CONST; - -extern EAPI Eo_Op ECORE_IDLE_ENTERER_BASE_ID; - -enum -{ - ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR, - ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR, - ECORE_IDLE_ENTERER_SUB_ID_LAST -}; - -#define ECORE_IDLE_ENTERER_ID(sub_id) (ECORE_IDLE_ENTERER_BASE_ID + sub_id) - -/** - * @def ecore_idle_enterer_after_constructor - * @since 1.8 - * - * Contructor. Will insert the handler at the end of the list. - * - * @param[in] func - * @param[in] data - * - */ -#define ecore_idle_enterer_after_constructor(func, data) ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * @def ecore_idle_enterer_before_constructor - * @since 1.8 - * - * Contructor. Will insert the handler at the beginning of the list. - * - * @param[in] func - * @param[in] data - * - */ -#define ecore_idle_enterer_before_constructor(func, data) ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * - */ - -/* - * @since 1.8 - */ -typedef Eo Ecore_Idle_Exiter; /**< A handle for idle exiters */ -#define ECORE_IDLE_EXITER_CLASS ecore_idle_exiter_class_get() -const Eo_Class *ecore_idle_exiter_class_get(void) EINA_CONST; - -extern EAPI Eo_Op ECORE_IDLE_EXITER_BASE_ID; - -enum -{ - ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR, - ECORE_IDLE_EXITER_SUB_ID_LAST -}; - -#define ECORE_IDLE_EXITER_ID(sub_id) (ECORE_IDLE_EXITER_BASE_ID + sub_id) - -/** - * @def ecore_idle_exiter_constructor - * @since 1.8 - * - * Contructor. - * - * @param[in] func - * @param[in] data - * - */ -#define ecore_idle_exiter_constructor(func, data) ECORE_IDLE_EXITER_ID(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) - -/** - * 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, @c NULL otherwise. - * - * Add an idler handle to the event loop, returning a handle on - * success and @c NULL otherwise. The function @p func will be called - * repeatedly while no other events are ready to be processed, as - * long as it returns @c 1 (or ECORE_CALLBACK_RENEW). A return of @c 0 - * (or ECORE_CALLBACK_CANCEL) deletes the idler. - * - * Idlers are useful for progressively prossessing data without blocking. - */ -EAPI Ecore_Idler *ecore_idler_add(Ecore_Task_Cb func, const void *data); - -/** - * 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, @c NULL - * otherwise. - */ -EAPI void *ecore_idler_del(Ecore_Idler *idler); - -EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data); -EAPI Ecore_Idle_Enterer *ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data); -EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer); - -EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data); -EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter); - -/** - * @} - */ - -/** - * @defgroup Ecore_Thread_Group Ecore Thread functions - * - * Facilities to run heavy tasks in different threads to avoid blocking - * the main loop. - * - * The EFL is, for the most part, not thread safe. This means that if you - * have some task running in another thread and you have, for example, an - * Evas object to show the status progress of this task, you cannot update - * the object from within the thread. This can only be done from the main - * thread, the one running the main loop. This problem can be solved - * by running a thread that sends messages to the main one using an - * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other - * things like cancelling the thread, your code grows in complexity and gets - * much harder to maintain. - * - * Ecore Thread is here to solve that problem. It is @b not a simple wrapper - * around standard POSIX threads (or the equivalent in other systems) and - * it's not meant to be used to run parallel tasks throughout the entire - * duration of the program, especially when these tasks are performance - * critical, as Ecore manages these tasks using a pool of threads based on - * system configuration. - * - * What Ecore Thread does, is make it a lot easier to dispatch a worker - * function to perform some heavy task and then get the result once it - * completes, without blocking the application's UI. In addition, cancelling - * and rescheduling comes practically for free and the developer needs not - * worry about how many threads are launched, since Ecore will schedule - * them according to the number of processors the system has and maximum - * amount of concurrent threads set for the application. - * - * At the system level, Ecore will start a new thread on an as-needed basis - * until the maximum set is reached. When no more threads can be launched, - * new worker functions will be queued in a waiting list until a thread - * becomes available. This way, system threads will be shared throughout - * different worker functions, but running only one at a time. At the same - * time, a worker function that is rescheduled may be run on a different - * thread the next time. - * - * The ::Ecore_Thread handler has two meanings, depending on what context - * it is on. The one returned when starting a worker with any of the - * functions ecore_thread_run() or ecore_thread_feedback_run() is an - * identifier of that specific instance of the function and can be used from - * the main loop with the ecore_thread_cancel() and ecore_thread_check() - * functions. This handler must not be shared with the worker function - * function running in the thread. This same handler will be the one received - * on the @c end, @c cancel and @c feedback callbacks. - * - * The worker function, that's the one running in the thread, also receives - * an ::Ecore_Thread handler that can be used with ecore_thread_cancel() and - *ecore_thread_check(), sharing the flag with the main loop. But this - * handler is also associated with the thread where the function is running. - * This has strong implications when working with thread local data. - * - * There are two kinds of worker threads Ecore handles: simple, or short, - * workers and feedback workers. - * - * The first kind is for simple functions that perform a - * usually small but time consuming task. Ecore will run this function in - * a thread as soon as one becomes available and notify the calling user of - * its completion once the task is done. - * - * The following image shows the flow of a program running four tasks on - * a pool of two threads. - * - * @image html ecore_thread.png - * @image rtf ecore_thread.png - * @image latex ecore_thread.eps width=\textwidth - * - * For larger tasks that may require continuous communication with the main - * program, the feedback workers provide the same functionality plus a way - * for the function running in the thread to send messages to the main - * thread. - * - * The next diagram omits some details shown in the previous one regarding - * how threads are spawned and tasks are queued, but illustrates how feedback - * jobs communicate with the main loop and the special case of threads - * running out of pool. - * - * @image html ecore_thread_feedback.png - * @image rtf ecore_thread_feedback.png - * @image latex ecore_thread_feedback.eps width=\textwidth - * - * See an overview example in @ref ecore_thread_example_c. - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -typedef struct _Ecore_Thread Ecore_Thread; /**< A handle for threaded jobs */ - -/** - * @typedef Ecore_Thread_Cb Ecore_Thread_Cb - * A callback used by Ecore_Thread helper. - */ -typedef void (*Ecore_Thread_Cb)(void *data, Ecore_Thread *thread); -/** - * @typedef Ecore_Thread_Notify_Cb Ecore_Thread_Notify_Cb - * A callback used by the main loop to receive data sent by an - * @ref Ecore_Thread_Group. - */ -typedef void (*Ecore_Thread_Notify_Cb)(void *data, Ecore_Thread *thread, void *msg_data); - -/** - * Schedule a task to run in a parallel thread to avoid locking the main loop - * - * @param func_blocking The function that should run in another thread. - * @param func_end Function to call from main loop when @p func_blocking - * completes its task successfully (may be NULL) - * @param func_cancel Function to call from main loop if the thread running - * @p func_blocking is cancelled or fails to start (may be NULL) - * @param data User context data to pass to all callbacks. - * @return A new thread handler, or @c NULL on failure. - * - * This function will try to create a new thread to run @p func_blocking in, - * or if the maximum number of concurrent threads has been reached, will - * add it to the pending list, where it will wait until a thread becomes - * available. The return value will be an ::Ecore_Thread handle that can - * be used to cancel the thread before its completion. - * - * @note This function should always return immediately, but in the rare - * case that Ecore is built with no thread support, @p func_blocking will - * be called here, actually blocking the main loop. - * - * Once a thread becomes available, @p func_blocking will be run in it until - * it finishes, then @p func_end is called from the thread containing the - * main loop to inform the user of its completion. While in @p func_blocking, - * no functions from the EFL can be used, except for those from Eina that are - * marked to be thread-safe. Even for the latter, caution needs to be taken - * if the data is shared across several threads. - * - * @p func_end will be called from the main thread when @p func_blocking ends, - * so here it's safe to use anything from the EFL freely. - * - * The thread can also be cancelled before its completion calling - *ecore_thread_cancel(), either from the main thread or @p func_blocking. - * In this case, @p func_cancel will be called, also from the main thread - * to inform of this happening. If the thread could not be created, this - * function will be called and it's @c thread parameter will be NULL. It's - * also safe to call any EFL function here, as it will be running in the - * main thread. - * - * Inside @p func_blocking, it's possible to call ecore_thread_reschedule() - * to tell Ecore that this function should be called again. - * - * Be aware that no assumptions can be made about the order in which the - * @p func_end callbacks for each task will be called. Once the function is - * running in a different thread, it's the OS that will handle its running - * schedule, and different functions may take longer to finish than others. - * Also remember that just starting several tasks together doesn't mean they - * will be running at the same time. Ecore will schedule them based on the - * number of threads available for the particular system it's running in, - * so some of the jobs started may be waiting until another one finishes - * before it can execute its own @p func_blocking. - * - * @see ecore_thread_feedback_run() - * @see ecore_thread_cancel() - * @see ecore_thread_reschedule() - * @see ecore_thread_max_set() - */ -EAPI Ecore_Thread *ecore_thread_run(Ecore_Thread_Cb func_blocking, Ecore_Thread_Cb func_end, Ecore_Thread_Cb func_cancel, const void *data); -/** - * Launch a thread to run a task that can talk back to the main thread - * - * @param func_heavy The function that should run in another thread. - * @param func_notify Function that receives the data sent from the thread - * @param func_end Function to call from main loop when @p func_heavy - * completes its task successfully - * @param func_cancel Function to call from main loop if the thread running - * @p func_heavy is cancelled or fails to start - * @param data User context data to pass to all callback. - * @param try_no_queue If you want to run outside of the thread pool. - * @return A new thread handler, or @c NULL on failure. - * - * See ecore_thread_run() for a general description of this function. - * - * The difference with the above is that ecore_thread_run() is meant for - * tasks that don't need to communicate anything until they finish, while - * this function is provided with a new callback, @p func_notify, that will - * be called from the main thread for every message sent from @p func_heavy - * with ecore_thread_feedback(). - * - * Like with ecore_thread_run(), a new thread will be launched to run - * @p func_heavy unless the maximum number of simultaneous threads has been - * reached, in which case the function will be scheduled to run whenever a - * running task ends and a thread becomes free. But if @p try_no_queue is - * set, Ecore will first try to launch a thread outside of the pool to run - * the task. If it fails, it will revert to the normal behaviour of using a - * thread from the pool as if @p try_no_queue had not been set. - * - * Keep in mind that Ecore handles the thread pool based on the number of - * CPUs available, but running a thread outside of the pool doesn't count for - * this, so having too many of them may have drastic effects over the - * program's performance. - * - * @see ecore_thread_feedback() - * @see ecore_thread_run() - * @see ecore_thread_cancel() - * @see ecore_thread_reschedule() - * @see ecore_thread_max_set() - */ -EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, Ecore_Thread_Notify_Cb func_notify, - Ecore_Thread_Cb func_end, Ecore_Thread_Cb func_cancel, - const void *data, Eina_Bool try_no_queue); -/** - * Cancel a running thread. - * - * @param thread The thread to cancel. - * @return Will return @c EINA_TRUE if the thread has been cancelled, - * @c EINA_FALSE if it is pending. - * - * This function can be called both in the main loop or in the running thread. - * - * This function cancels a running thread. If @p thread can be immediately - * cancelled (it's still pending execution after creation or rescheduling), - * then the @c cancel callback will be called, @p thread will be freed and - * the function will return @c EINA_TRUE. - * - * If the thread is already running, then this function returns @c EINA_FALSE - * after marking the @p thread as pending cancellation. For the thread to - * actually be terminated, it needs to return from the user function back - * into Ecore control. This can happen in several ways: - * @li The function ends and returns normally. If it hadn't been cancelled, - * @c func_end would be called here, but instead @c func_cancel will happen. - * @li The function returns after requesting to be rescheduled with - * ecore_thread_reschedule(). - * @li The function is prepared to leave early by checking if - * ecore_thread_check() returns @c EINA_TRUE. - * - * The user function can cancel itself by calling ecore_thread_cancel(), but - * it should always use the ::Ecore_Thread handle passed to it and never - * share it with the main loop thread by means of shared user data or any - * other way. - * - * @p thread will be freed and should not be used again if this function - * returns @c EINA_TRUE or after the @c func_cancel callback returns. - * - * @see ecore_thread_check() - */ -EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread); -/** - * Checks if a thread is pending cancellation - * - * @param thread The thread to test. - * @return @c EINA_TRUE if the thread is pending cancellation, - * @c EINA_FALSE if it is not. - * - * This function can be called both in the main loop or in the running thread. - * - * When ecore_thread_cancel() is called on an already running task, the - * thread is marked as pending cancellation. This function returns @c EINA_TRUE - * if this mark is set for the given @p thread and can be used from the - * main loop thread to check if a still active thread has been cancelled, - * or from the user function running in the thread to check if it should - * stop doing what it's doing and return early, effectively cancelling the - * task. - * - * @see ecore_thread_cancel() - */ -EAPI Eina_Bool ecore_thread_check(Ecore_Thread *thread); -/** - * Sends data from the worker thread to the main loop - * - * @param thread The current ::Ecore_Thread context to send data from - * @param msg_data Data to be transmitted to the main loop - * @return @c EINA_TRUE if @p msg_data was successfully sent to main loop, - * @c EINA_FALSE if anything goes wrong. - * - * You should use this function only in the @c func_heavy call. - * - * Only the address to @p msg_data will be sent and once this function - * returns @c EINA_TRUE, the job running in the thread should never touch the - * contents of it again. The data sent should be malloc()'ed or something - * similar, as long as it's not memory local to the thread that risks being - * overwritten or deleted once it goes out of scope or the thread finishes. - * - * Care must be taken that @p msg_data is properly freed in the @c func_notify - * callback set when creating the thread. - * - * @see ecore_thread_feedback_run() - */ -EAPI Eina_Bool ecore_thread_feedback(Ecore_Thread *thread, const void *msg_data); -/** - * Asks for the function in the thread to be called again at a later time - * - * @param thread The current ::Ecore_Thread context to rescheduled - * @return @c EINA_TRUE if the task was successfully rescheduled, - * @c EINA_FALSE if anything goes wrong. - * - * This function should be called only from the same function represented - * by @p thread. - * - * Calling this function will mark the thread for a reschedule, so as soon - * as it returns, it will be added to the end of the list of pending tasks. - * If no other tasks are waiting or there are sufficient threads available, - * the rescheduled task will be launched again immediately. - * - * This should never return @c EINA_FALSE, unless it was called from the wrong - * thread or with the wrong arguments. - * - * The @c func_end callback set when the thread is created will not be - * called until the function in the thread returns without being rescheduled. - * Similarly, if the @p thread is cancelled, the reschedule will not take - * effect. - */ -EAPI Eina_Bool ecore_thread_reschedule(Ecore_Thread *thread); -/** - * Gets the number of active threads running jobs - * - * @return Number of active threads running jobs - * - * This returns the number of threads currently running jobs of any type - * through the Ecore_Thread API. - * - * @note Jobs started through the ecore_thread_feedback_run() function with - * the @c try_no_queue parameter set to @c EINA_TRUE will not be accounted for - * in the return of this function unless the thread creation fails and it - * falls back to using one from the pool. - */ -EAPI int ecore_thread_active_get(void); -/** - * Gets the number of short jobs waiting for a thread to run - * - * @return Number of pending threads running "short" jobs - * - * This returns the number of tasks started with ecore_thread_run() that are - * pending, waiting for a thread to become available to run them. - */ -EAPI int ecore_thread_pending_get(void); -/** - * Gets the number of feedback jobs waiting for a thread to run - * - * @return Number of pending threads running "feedback" jobs - * - * This returns the number of tasks started with ecore_thread_feedback_run() - * that are pending, waiting for a thread to become available to run them. - */ -EAPI int ecore_thread_pending_feedback_get(void); -/** - * Gets the total number of pending jobs - * - * @return Number of pending threads running jobs - * - * Same as the sum of ecore_thread_pending_get() and - *ecore_thread_pending_feedback_get(). - */ -EAPI int ecore_thread_pending_total_get(void); -/** - * Gets the maximum number of threads that can run simultaneously - * - * @return Max possible number of Ecore_Thread's running concurrently - * - * This returns the maximum number of Ecore_Thread's that may be running at - * the same time. If this number is reached, new jobs started by either - *ecore_thread_run() or ecore_thread_feedback_run() will be added to the - * respective pending queue until one of the running threads finishes its - * task and becomes available to run a new one. - * - * By default, this will be the number of available CPUs for the - * running program (as returned by eina_cpu_count()), or 1 if this value - * could not be fetched. - * - * @see ecore_thread_max_set() - * @see ecore_thread_max_reset() - */ -EAPI int ecore_thread_max_get(void); -/** - * Sets the maximum number of threads allowed to run simultaneously - * - * @param num The new maximum - * - * This sets a new value for the maximum number of concurrently running - * Ecore_Thread's. It @b must an integer between 1 and (16 * @c x), where @c x - * is the number for CPUs available. - * - * @see ecore_thread_max_get() - * @see ecore_thread_max_reset() - */ -EAPI void ecore_thread_max_set(int num); -/** - * Resets the maximum number of concurrently running threads to the default - * - * This resets the value returned by ecore_thread_max_get() back to its - * default. - * - * @see ecore_thread_max_get() - * @see ecore_thread_max_set() - */ -EAPI void ecore_thread_max_reset(void); -/** - * Gets the number of threads available for running tasks - * - * @return The number of available threads - * - * Same as doing ecore_thread_max_get() - ecore_thread_active_get(). - * - * This function may return a negative number only in the case the user - * changed the maximum number of running threads while other tasks are - * running. - */ -EAPI int ecore_thread_available_get(void); -/** - * Adds some data to a hash local to the thread - * - * @param thread The thread context the data belongs to - * @param key The name under which the data will be stored - * @param value The data to add - * @param cb Function to free the data when removed from the hash - * @param direct If true, this will not copy the key string (like - * eina_hash_direct_add()) - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. - * - * Ecore Thread has a mechanism to share data across several worker functions - * that run on the same system thread. That is, the data is stored per - * thread and for a worker function to have access to it, it must be run - * by the same thread that stored the data. - * - * When there are no more workers pending, the thread will be destroyed - * along with the internal hash and any data left in it will be freed with - * the @p cb function given. - * - * This set of functions is useful to share things around several instances - * of a function when that thing is costly to create and can be reused, but - * may only be used by one function at a time. - * - * For example, if you have a program doing requisitions to a database, - * these requisitions can be done in threads so that waiting for the - * database to respond doesn't block the UI. Each of these threads will - * run a function, and each function will be dependent on a connection to - * the database, which may not be able to handle more than one request at - * a time so for each running function you will need one connection handle. - * The options then are: - * @li Each function opens a connection when it's called, does the work and - * closes the connection when it finishes. This may be costly, wasting a lot - * of time on resolving hostnames, negotiating permissions and allocating - * memory. - * @li Open the connections in the main loop and pass it to the threads - * using the data pointer. Even worse, it's just as costly as before and now - * it may even be kept with connections open doing nothing until a thread - * becomes available to run the function. - * @li Have a way to share connection handles, so that each instance of the - * function can check if an available connection exists, and if it doesn't, - * create one and add it to the pool. When no more connections are needed, - * they are all closed. - * - * The last option is the most efficient, but it requires a lot of work to - * implement properly. Using thread local data helps to achieve the same - * result while avoiding doing all the tracking work on your code. The way - * to use it would be, at the worker function, to ask for the connection - * with ecore_thread_local_data_find() and if it doesn't exist, then open - * a new one and save it with ecore_thread_local_data_add(). Do the work and - * forget about the connection handle, when everything is done the function - * just ends. The next worker to run on that thread will check if a - * connection exists and find that it does, so the process of opening a - * new one has been spared. When no more workers exist, the thread is - * destroyed and the callback used when saving the connection will be called - * to close it. - * - * This function adds the data @p value to the thread data under the given - * @p key. - * No other value in the hash may have the same @p key. If you need to - * change the value under a @p key, or you don't know if one exists already, - * you can use ecore_thread_local_data_set(). - * - * Neither @p key nor @p value may be @c NULL and @p key will be copied in the - * hash, unless @p direct is set, in which case the string used should not - * be freed until the data is removed from the hash. - * - * The @p cb function will be called when the data in the hash needs to be - * freed, be it because it got deleted with ecore_thread_local_data_del() or - * because @p thread was terminated and the hash destroyed. This parameter - * may be NULL, in which case @p value needs to be manually freed after - * removing it from the hash with either ecore_thread_local_data_del() or - * ecore_thread_local_data_set(), but it's very unlikely that this is what - * you want. - * - * This function, and all of the others in the @c ecore_thread_local_data - * family of functions, can only be called within the worker function running - * in the thread. Do not call them from the main loop or from a thread - * other than the one represented by @p thread. - * - * @see ecore_thread_local_data_set() - * @see ecore_thread_local_data_find() - * @see ecore_thread_local_data_del() - */ -EAPI Eina_Bool ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, - Eina_Free_Cb cb, Eina_Bool direct); -/** - * Sets some data in the hash local to the given thread - * - * @param thread The thread context the data belongs to - * @param key The name under which the data will be stored - * @param value The data to add - * @param cb Function to free the data when removed from the hash - * - * If no data exists in the hash under the @p key, this function adds - * @p value in the hash under the given @p key and returns NULL. - * The key itself is copied. - * - * If the hash already contains something under @p key, the data will be - * replaced by @p value and the old value will be returned. - * - * @c NULL will also be returned if either @p key or @p value are @c NULL, or - * if an error occurred. - * - * This function, and all of the others in the @c ecore_thread_local_data - * family of functions, can only be called within the worker function running - * in the thread. Do not call them from the main loop or from a thread - * other than the one represented by @p thread. - * - * @see ecore_thread_local_data_add() - * @see ecore_thread_local_data_del() - * @see ecore_thread_local_data_find() - */ -EAPI void *ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb); -/** - * Gets data stored in the hash local to the given thread - * - * @param thread The thread context the data belongs to - * @param key The name under which the data is stored - * @return The value under the given key, or @c NULL on error. - * - * Finds and return the data stored in the shared hash under the key @p key. - * - * This function, and all of the others in the @c ecore_thread_local_data - * family of functions, can only be called within the worker function running - * in the thread. Do not call them from the main loop or from a thread - * other than the one represented by @p thread. - * - * @see ecore_thread_local_data_add() - * @see ecore_thread_local_data_wait() - */ -EAPI void *ecore_thread_local_data_find(Ecore_Thread *thread, const char *key); -/** - * Deletes from the thread's hash the data corresponding to the given key - * - * @param thread The thread context the data belongs to - * @param key The name under which the data is stored - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. - * - * If there's any data stored associated with @p key in the global hash, - * this function will remove it from it and return @c EINA_TRUE. If no data - * exists or an error occurs, it returns @c EINA_FALSE. - * - * If the data was added to the hash with a free function, then it will - * also be freed after removing it from the hash, otherwise it requires - * to be manually freed by the user, which means that if no other reference - * to it exists before calling this function, it will result in a memory - * leak. - * - * This function, and all of the others in the @c ecore_thread_local_data - * family of functions, can only be called within the worker function running - * in the thread. Do not call them from the main loop or from a thread - * other than the one represented by @p thread. - * - * @see ecore_thread_local_data_add() - */ -EAPI Eina_Bool ecore_thread_local_data_del(Ecore_Thread *thread, const char *key); - -/** - * Adds some data to a hash shared by all threads - * - * @param key The name under which the data will be stored - * @param value The data to add - * @param cb Function to free the data when removed from the hash - * @param direct If true, this will not copy the key string (like - * eina_hash_direct_add()) - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. - * - * Ecore Thread keeps a hash that can be used to share data across several - * threads, including the main loop one, without having to manually handle - * mutexes to do so safely. - * - * This function adds the data @p value to this hash under the given @p key. - * No other value in the hash may have the same @p key. If you need to - * change the value under a @p key, or you don't know if one exists already, - * you can use ecore_thread_global_data_set(). - * - * Neither @p key nor @p value may be @c NULL and @p key will be copied in the - * hash, unless @p direct is set, in which case the string used should not - * be freed until the data is removed from the hash. - * - * The @p cb function will be called when the data in the hash needs to be - * freed, be it because it got deleted with ecore_thread_global_data_del() or - * because Ecore Thread was shut down and the hash destroyed. This parameter - * may be NULL, in which case @p value needs to be manually freed after - * removing it from the hash with either ecore_thread_global_data_del() or - *ecore_thread_global_data_set(). - * - * Manually freeing any data that was added to the hash with a @p cb function - * is likely to produce a segmentation fault, or any other strange - * happenings, later on in the program. - * - * @see ecore_thread_global_data_del() - * @see ecore_thread_global_data_set() - * @see ecore_thread_global_data_find() - */ -EAPI Eina_Bool ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct); -/** - * Sets some data in the hash shared by all threads - * - * @param key The name under which the data will be stored - * @param value The data to add - * @param cb Function to free the data when removed from the hash - * - * If no data exists in the hash under the @p key, this function adds - * @p value in the hash under the given @p key and returns NULL. - * The key itself is copied. - * - * If the hash already contains something under @p key, the data will be - * replaced by @p value and the old value will be returned. - * - * @c NULL will also be returned if either @p key or @p value are @c NULL, or - * if an error occurred. - * - * @see ecore_thread_global_data_add() - * @see ecore_thread_global_data_del() - * @see ecore_thread_global_data_find() - */ -EAPI void *ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb); -/** - * Gets data stored in the hash shared by all threads - * - * @param key The name under which the data is stored - * @return The value under the given key, or @c NULL on error. - * - * Finds and return the data stored in the shared hash under the key @p key. - * - * Keep in mind that the data returned may be used by more than one thread - * at the same time and no reference counting is done on it by Ecore. - * Freeing the data or modifying its contents may require additional - * precautions to be considered, depending on the application's design. - * - * @see ecore_thread_global_data_add() - * @see ecore_thread_global_data_wait() - */ -EAPI void *ecore_thread_global_data_find(const char *key); -/** - * Deletes from the shared hash the data corresponding to the given key - * - * @param key The name under which the data is stored - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. - * - * If there's any data stored associated with @p key in the global hash, - * this function will remove it from it and return @c EINA_TRUE. If no data - * exists or an error occurs, it returns @c EINA_FALSE. - * - * If the data was added to the hash with a free function, then it will - * also be freed after removing it from the hash, otherwise it requires - * to be manually freed by the user, which means that if no other reference - * to it exists before calling this function, it will result in a memory - * leak. - * - * Note, also, that freeing data that other threads may be using will result - * in a crash, so appropriate care must be taken by the application when - * that possibility exists. - * - * @see ecore_thread_global_data_add() - */ -EAPI Eina_Bool ecore_thread_global_data_del(const char *key); -/** - * Gets data stored in the shared hash, or wait for it if it doesn't exist - * - * @param key The name under which the data is stored - * @param seconds The amount of time in seconds to wait for the data. - * @return The value under the given key, or @c NULL on error. - * - * Finds and return the data stored in the shared hash under the key @p key. - * - * If there's nothing in the hash under the given @p key, the function - * will block and wait up to @p seconds seconds for some other thread to - * add it with either ecore_thread_global_data_add() or - * ecore_thread_global_data_set(). If after waiting there's still no data - * to get, @c NULL will be returned. - * - * If @p seconds is 0, then no waiting will happen and this function works - * like ecore_thread_global_data_find(). If @p seconds is less than 0, then - * the function will wait indefinitely. - * - * Keep in mind that the data returned may be used by more than one thread - * at the same time and no reference counting is done on it by Ecore. - * Freeing the data or modifying its contents may require additional - * precautions to be considered, depending on the application's design. - * - * @see ecore_thread_global_data_add() - * @see ecore_thread_global_data_find() - */ -EAPI void *ecore_thread_global_data_wait(const char *key, double seconds); - -/** - * @} - */ - -/** - * @defgroup Ecore_Pipe_Group Pipe wrapper - * - * These functions wrap the pipe / write / read functions to easily - * integrate its use into ecore's main loop. - * - * The ecore_pipe_add() function creates file descriptors (sockets - * on Windows) and attach a 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(). - * - * For examples see here: - * @li @ref tutorial_ecore_pipe_gstreamer_example - * @li @ref tutorial_ecore_pipe_simple_example - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -typedef struct _Ecore_Pipe Ecore_Pipe; /**< A handle for pipes */ - -/** - * @typedef Ecore_Pipe_Cb Ecore_Pipe_Cb - * The callback that data written to the pipe is sent to. - */ -typedef void (*Ecore_Pipe_Cb)(void *data, void *buffer, unsigned int nbyte); - -EAPI Ecore_Pipe *ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data); -EAPI void *ecore_pipe_del(Ecore_Pipe *p); -EAPI Eina_Bool 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 void ecore_pipe_thaw(Ecore_Pipe *p); -EAPI void ecore_pipe_freeze(Ecore_Pipe *p); -EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait); - -/** - * @} - */ - -/** - * @defgroup Ecore_Job_Group Ecore Job functions - * - * You can queue jobs that are to be done by the main loop when the - * current event is dealt with. - * - * Jobs are processed by the main loop similarly to events. They - * also will be executed in the order in which they were added. - * - * A good use for them is when you don't want to execute an action - * immediately, but want to give the control back to the main loop - * so that it will call your job callback when jobs start being - * processed (and if there are other jobs added before yours, they - * will be processed first). This also gives the chance to other - * actions in your program to cancel the job before it is started. - * - * Examples of using @ref Ecore_Job : - * @li @ref ecore_job_example_c - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -/* - * @since 1.8 - */ -typedef Eo Ecore_Job; /**< A job handle */ -#define ECORE_JOB_CLASS ecore_job_class_get() -const Eo_Class *ecore_job_class_get(void) EINA_CONST; - -extern EAPI Eo_Op ECORE_JOB_BASE_ID; - -enum -{ - ECORE_JOB_SUB_ID_CONSTRUCTOR, - ECORE_JOB_SUB_ID_LAST -}; - -#define ECORE_JOB_ID(sub_id) (ECORE_JOB_BASE_ID + sub_id) - -/** - * @def ecore_job_constructor - * @since 1.8 - * - * Contructor. - * - * @param[in] func - * @param[in] data - * - */ -#define ecore_job_constructor(func, data) ECORE_JOB_ID(ECORE_JOB_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Cb, func), EO_TYPECHECK(const void *, data) - -EAPI Ecore_Job *ecore_job_add(Ecore_Cb func, const void *data); -EAPI void *ecore_job_del(Ecore_Job *job); - -/** - * @} - */ - -/** - * @defgroup Ecore_Application_Group Ecore Application functions - * - * @{ - */ - -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); - -/** - * @} - */ - -/** - * @defgroup Ecore_Throttle_Group Ecore Throttle functions - * - * @ingroup Ecore_Main_Loop_Group - * - * @{ - */ - -EAPI void ecore_throttle_adjust(double amount); -EAPI double ecore_throttle_get(void); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif -#endif diff --git a/legacy/ecore/src/lib/ecore/Ecore_Getopt.h b/legacy/ecore/src/lib/ecore/Ecore_Getopt.h deleted file mode 100644 index 0a11787d4d..0000000000 --- a/legacy/ecore/src/lib/ecore/Ecore_Getopt.h +++ /dev/null @@ -1,419 +0,0 @@ -#ifndef _ECORE_GETOPT_H -#define _ECORE_GETOPT_H - -#include -#include - -#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; - Eina_Bool boolv; - short shortv; - int intv; - long longv; - unsigned short ushortv; - unsigned int uintv; - unsigned long ulongv; - double doublev; - } def; -}; - -struct _Ecore_Getopt_Desc_Callback -{ - Eina_Bool (*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 */ - Eina_Bool 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 Eina_Bool - 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 Eina_Bool -ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser, - const Ecore_Getopt_Desc *desc, - const char *str, - void *data, - Ecore_Getopt_Value *storage); -EAPI Eina_Bool -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 */ diff --git a/legacy/ecore/src/lib/ecore/ecore.c b/legacy/ecore/src/lib/ecore/ecore.c deleted file mode 100644 index 433294cbb4..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore.c +++ /dev/null @@ -1,878 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_LOCALE_H -# include -#endif - -#ifdef HAVE_LANGINFO_H -# include -#endif - -#ifdef HAVE_SYS_MMAN_H -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#if HAVE_MALLINFO -#include - - -static Ecore_Version _version = { VERS_MAJ, VERS_MIN, VERS_MIC, VERS_REV }; -EAPI Ecore_Version *ecore_version = &_version; - -#define KEEP_MAX(Global, Local) \ - if (Global < (Local)) \ - Global = Local; - -static Eina_Bool _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 - -Eo *_ecore_parent = NULL; - -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; - -typedef struct _Ecore_Safe_Call Ecore_Safe_Call; -struct _Ecore_Safe_Call -{ - union { - Ecore_Cb async; - Ecore_Data_Cb sync; - } cb; - void *data; - - Eina_Lock m; - Eina_Condition c; - - int current_id; - - Eina_Bool sync : 1; - Eina_Bool suspend : 1; -}; - -static void _ecore_main_loop_thread_safe_call(Ecore_Safe_Call *order); -static void _thread_safe_cleanup(void *data); -static void _thread_callback(void *data, - void *buffer, - unsigned int nbyte); -static Eina_List *_thread_cb = NULL; -static Ecore_Pipe *_thread_call = NULL; -static Eina_Lock _thread_safety; -static const int wakeup = 42; - -static int _thread_loop = 0; -static Eina_Lock _thread_mutex; -static Eina_Condition _thread_cond; -static Eina_Lock _thread_feedback_mutex; -static Eina_Condition _thread_feedback_cond; - -static Eina_Lock _thread_id_lock; -static int _thread_id = -1; -static int _thread_id_max = 0; -static int _thread_id_update = 0; - -Eina_Lock _ecore_main_loop_lock; -int _ecore_main_lock_count; - -/** OpenBSD does not define CODESET - * FIXME ?? - */ - -#ifndef CODESET -# define CODESET "INVALID" -#endif - -/** - * @addtogroup Ecore_Init_Group - * - * @{ - */ - -/** - * 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 - * - * 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; - - eo_init(); - -#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(); - if (!ecore_mempool_init()) goto shutdown_mempool; - _ecore_main_loop_init(); - _ecore_signal_init(); -#ifndef HAVE_EXOTIC - _ecore_exe_init(); -#endif - _ecore_thread_init(); - _ecore_glib_init(); - _ecore_job_init(); - _ecore_time_init(); - - eina_lock_new(&_thread_mutex); - eina_condition_new(&_thread_cond, &_thread_mutex); - eina_lock_new(&_thread_feedback_mutex); - eina_condition_new(&_thread_feedback_cond, &_thread_feedback_mutex); - _thread_call = _ecore_pipe_add(_thread_callback, NULL); - eina_lock_new(&_thread_safety); - - eina_lock_new(&_thread_id_lock); - - eina_lock_new(&_ecore_main_loop_lock); - -#if HAVE_MALLINFO - if (getenv("ECORE_MEM_STAT")) - { - _ecore_memory_pid = getpid(); - ecore_animator_add(_ecore_memory_statistic, NULL); - } -#endif - -#if defined(GLIB_INTEGRATION_ALWAYS) - if (_ecore_glib_always_integrate) ecore_main_loop_glib_integrate(); -#endif - _ecore_parent = eo_add(ECORE_PARENT_CLASS, NULL); - - return _ecore_init_count; - -shutdown_mempool: - ecore_mempool_shutdown(); -shutdown_log_dom: - eina_shutdown(); -shutdown_evil: -#ifdef HAVE_EVIL - evil_shutdown(); -#endif - - eo_shutdown(); - - return --_ecore_init_count; -} - -/** - * Shut down connections, signal handlers sockets etc. - * - * @return 0 if ecore shuts down, greater than 0 otherwise. - * 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) -{ - Ecore_Pipe *p; - /* - * take a lock here because _ecore_event_shutdown() does callbacks - */ - _ecore_lock(); - if (_ecore_init_count <= 0) - { - ERR("Init count not greater than 0 in shutdown."); - _ecore_unlock(); - return 0; - } - if (--_ecore_init_count != 0) - goto unlock; - - if (_ecore_fps_debug) _ecore_fps_debug_shutdown(); - _ecore_poller_shutdown(); - _ecore_animator_shutdown(); - _ecore_glib_shutdown(); - _ecore_job_shutdown(); - _ecore_thread_shutdown(); - - /* this looks horrible - a hack for now, but something to note. as - * we delete the _thread_call pipe a thread COULD be doing - * ecore_pipe_write() or what not to it at the same time - we - * must ensure all possible users of this _thread_call are finished - * and exited before we delete it here */ - /* - * ok - this causes other valgrind complaints regarding glib aquiring - * locks internally. so fix bug a or bug b. let's leave the original - * bug in then and leave this as a note for now - */ - /* - * It should be fine now as we do wait for thread to shutdown before - * we try to destroy the pipe. - */ - p = _thread_call; - _thread_call = NULL; - _ecore_pipe_wait(p, 1, 0.1); - _ecore_pipe_del(p); - eina_lock_free(&_thread_safety); - eina_condition_free(&_thread_cond); - eina_lock_free(&_thread_mutex); - eina_condition_free(&_thread_feedback_cond); - eina_lock_free(&_thread_feedback_mutex); - eina_lock_free(&_thread_id_lock); - - -#ifndef HAVE_EXOTIC - _ecore_exe_shutdown(); -#endif - _ecore_idle_enterer_shutdown(); - _ecore_idle_exiter_shutdown(); - _ecore_idler_shutdown(); - _ecore_timer_shutdown(); - _ecore_event_shutdown(); - _ecore_main_shutdown(); - _ecore_signal_shutdown(); - _ecore_main_loop_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 - ecore_mempool_shutdown(); - eina_log_domain_unregister(_ecore_log_dom); - _ecore_log_dom = -1; - eina_shutdown(); -#ifdef HAVE_EVIL - evil_shutdown(); -#endif - - eo_unref(_ecore_parent); - eo_shutdown(); -unlock: - _ecore_unlock(); - - return _ecore_init_count; -} - -struct _Ecore_Fork_Cb -{ - Ecore_Cb func; - void *data; - Eina_Bool delete_me : 1; -}; - -typedef struct _Ecore_Fork_Cb Ecore_Fork_Cb; - -static int fork_cbs_walking = 0; -static Eina_List *fork_cbs = NULL; - -EAPI Eina_Bool -ecore_fork_reset_callback_add(Ecore_Cb func, const void *data) -{ - Ecore_Fork_Cb *fcb; - - fcb = calloc(1, sizeof(Ecore_Fork_Cb)); - if (!fcb) return EINA_FALSE; - fcb->func = func; - fcb->data = (void *)data; - fork_cbs = eina_list_append(fork_cbs, fcb); - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_fork_reset_callback_del(Ecore_Cb func, const void *data) -{ - Eina_List *l; - Ecore_Fork_Cb *fcb; - - EINA_LIST_FOREACH(fork_cbs, l, fcb) - { - if ((fcb->func == func) && (fcb->data == data)) - { - if (!fork_cbs_walking) - { - fork_cbs = eina_list_remove_list(fork_cbs, l); - free(fcb); - } - else - fcb->delete_me = EINA_TRUE; - return EINA_TRUE; - } - } - return EINA_FALSE; -} - -EAPI void -ecore_fork_reset(void) -{ - Eina_List *l, *ln; - Ecore_Fork_Cb *fcb; - - eina_lock_take(&_thread_safety); - - ecore_pipe_del(_thread_call); - _thread_call = ecore_pipe_add(_thread_callback, NULL); - /* If there was something in the pipe, trigger a wakeup again */ - if (_thread_cb) ecore_pipe_write(_thread_call, &wakeup, sizeof (int)); - - eina_lock_release(&_thread_safety); - - // should this be done withing the eina lock stuff? - - fork_cbs_walking++; - EINA_LIST_FOREACH(fork_cbs, l, fcb) - { - fcb->func(fcb->data); - } - fork_cbs_walking--; - - EINA_LIST_FOREACH_SAFE(fork_cbs, l, ln, fcb) - { - if (fcb->delete_me) - { - fork_cbs = eina_list_remove_list(fork_cbs, l); - free(fcb); - } - } -} - -/** - * @} - */ - -EAPI void -ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, - void *data) -{ - Ecore_Safe_Call *order; - - if (!callback) return; - - if (eina_main_loop_is()) - { - callback(data); - return; - } - - order = malloc(sizeof (Ecore_Safe_Call)); - if (!order) return; - - order->cb.async = callback; - order->data = data; - order->sync = EINA_FALSE; - order->suspend = EINA_FALSE; - - _ecore_main_loop_thread_safe_call(order); -} - -EAPI void * -ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, - void *data) -{ - Ecore_Safe_Call *order; - void *ret; - - if (!callback) return NULL; - - if (eina_main_loop_is()) - { - return callback(data); - } - - order = malloc(sizeof (Ecore_Safe_Call)); - if (!order) return NULL; - - order->cb.sync = callback; - order->data = data; - eina_lock_new(&order->m); - eina_condition_new(&order->c, &order->m); - order->sync = EINA_TRUE; - order->suspend = EINA_FALSE; - - _ecore_main_loop_thread_safe_call(order); - - eina_lock_take(&order->m); - eina_condition_wait(&order->c); - eina_lock_release(&order->m); - - ret = order->data; - - order->sync = EINA_FALSE; - order->cb.async = _thread_safe_cleanup; - order->data = order; - - _ecore_main_loop_thread_safe_call(order); - - return ret; -} - -EAPI int -ecore_thread_main_loop_begin(void) -{ - Ecore_Safe_Call *order; - - if (eina_main_loop_is()) - { - return ++_thread_loop; - } - - order = malloc(sizeof (Ecore_Safe_Call)); - if (!order) return -1; - - eina_lock_take(&_thread_id_lock); - order->current_id = ++_thread_id_max; - if (order->current_id < 0) - { - _thread_id_max = 0; - order->current_id = ++_thread_id_max; - } - eina_lock_release(&_thread_id_lock); - - eina_lock_new(&order->m); - eina_condition_new(&order->c, &order->m); - order->suspend = EINA_TRUE; - - _ecore_main_loop_thread_safe_call(order); - - eina_lock_take(&order->m); - while (order->current_id != _thread_id) - eina_condition_wait(&order->c); - eina_lock_release(&order->m); - - eina_main_loop_define(); - - _thread_loop = 1; - - return EINA_TRUE; -} - -EAPI int -ecore_thread_main_loop_end(void) -{ - int current_id; - - if (_thread_loop == 0) - { - ERR("the main loop is not locked ! No matching call to ecore_thread_main_loop_begin()."); - return -1; - } - - /* until we unlock the main loop, this thread has the main loop id */ - if (!eina_main_loop_is()) - { - ERR("Not in a locked thread !"); - return -1; - } - - _thread_loop--; - if (_thread_loop > 0) - return _thread_loop; - - current_id = _thread_id; - - eina_lock_take(&_thread_mutex); - _thread_id_update = _thread_id; - eina_condition_broadcast(&_thread_cond); - eina_lock_release(&_thread_mutex); - - eina_lock_take(&_thread_feedback_mutex); - while (current_id == _thread_id && _thread_id != -1) - eina_condition_wait(&_thread_feedback_cond); - eina_lock_release(&_thread_feedback_mutex); - - return 0; -} - -EAPI void -ecore_print_warning(const char *function EINA_UNUSED, - const char *sparam EINA_UNUSED) -{ - 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 EINA_UNUSED) -{ - 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 ""; - } -} - -/* 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[PATH_MAX]; - 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 = 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 *buf2 = (char *)&zero; - ssize_t todo = sizeof(unsigned int); - - while (todo > 0) - { - ssize_t r = write(_ecore_fps_debug_fd, buf2, todo); - if (r > 0) - { - todo -= r; - buf2 += 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 Eina_Bool -_ecore_memory_statistic(EINA_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 ECORE_CALLBACK_RENEW; -} - -#endif - -static void -_ecore_main_loop_thread_safe_call(Ecore_Safe_Call *order) -{ - Eina_Bool count; - - eina_lock_take(&_thread_safety); - - count = _thread_cb ? 0 : 1; - _thread_cb = eina_list_append(_thread_cb, order); - if (count) ecore_pipe_write(_thread_call, &wakeup, sizeof (int)); - - eina_lock_release(&_thread_safety); -} - -static void -_thread_safe_cleanup(void *data) -{ - Ecore_Safe_Call *call = data; - - eina_condition_free(&call->c); - eina_lock_free(&call->m); -} - -void -_ecore_main_call_flush(void) -{ - Ecore_Safe_Call *call; - Eina_List *callback; - - eina_lock_take(&_thread_safety); - callback = _thread_cb; - _thread_cb = NULL; - eina_lock_release(&_thread_safety); - - EINA_LIST_FREE(callback, call) - { - if (call->suspend) - { - eina_lock_take(&_thread_mutex); - - eina_lock_take(&call->m); - _thread_id = call->current_id; - eina_condition_broadcast(&call->c); - eina_lock_release(&call->m); - - while (_thread_id_update != _thread_id) - eina_condition_wait(&_thread_cond); - eina_lock_release(&_thread_mutex); - - eina_main_loop_define(); - - eina_lock_take(&_thread_feedback_mutex); - - _thread_id = -1; - - eina_condition_broadcast(&_thread_feedback_cond); - eina_lock_release(&_thread_feedback_mutex); - - _thread_safe_cleanup(call); - free(call); - } - else if (call->sync) - { - call->data = call->cb.sync(call->data); - eina_condition_broadcast(&call->c); - } - else - { - call->cb.async(call->data); - free(call); - } - } -} - -static void -_thread_callback(void *data EINA_UNUSED, - void *buffer EINA_UNUSED, - unsigned int nbyte EINA_UNUSED) -{ - _ecore_main_call_flush(); -} - -static const Eo_Class_Description parent_class_desc = { - EO_VERSION, - "ecore_parent", - EO_CLASS_TYPE_REGULAR, - EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), - NULL, - 0, - NULL, - NULL -}; - -EO_DEFINE_CLASS(ecore_parent_class_get, &parent_class_desc, EO_BASE_CLASS, NULL); diff --git a/legacy/ecore/src/lib/ecore/ecore_alloc.c b/legacy/ecore/src/lib/ecore/ecore_alloc.c deleted file mode 100644 index bec66ef0d5..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_alloc.c +++ /dev/null @@ -1,132 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -typedef struct _Ecore_Mempool Ecore_Mempool; -struct _Ecore_Mempool -{ - const char *name; - Eina_Mempool *mp; - size_t size; -}; - -#define GENERIC_ALLOC_FREE(TYPE, Type) \ - extern size_t _ecore_sizeof_##TYPE; \ - Ecore_Mempool Type##_mp = { #TYPE, NULL, 0 }; \ - TYPE * \ - Type##_calloc(unsigned int num) \ - { \ - return eina_mempool_calloc(Type##_mp.mp, \ - num * _ecore_sizeof_##TYPE); \ - } \ - void \ - Type##_mp_free(TYPE *e) \ - { \ - eina_mempool_free(Type##_mp.mp, e); \ - } - -//GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator); -GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler); -GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter); -GENERIC_ALLOC_FREE(Ecore_Event, ecore_event); -//GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter); -//GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer); -//GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler); -//GENERIC_ALLOC_FREE(Ecore_Job, ecore_job); -//GENERIC_ALLOC_FREE(Ecore_Timer, ecore_timer); -//GENERIC_ALLOC_FREE(Ecore_Poller, ecore_poller); -GENERIC_ALLOC_FREE(Ecore_Pipe, ecore_pipe); -GENERIC_ALLOC_FREE(Ecore_Fd_Handler, ecore_fd_handler); -#ifdef _WIN32 -GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler); -#endif - -static Ecore_Mempool *mempool_array[] = { -// &ecore_animator_mp, - &ecore_event_handler_mp, - &ecore_event_filter_mp, - &ecore_event_mp, -// &ecore_idle_exiter_mp, -// &ecore_idle_enterer_mp, -// &ecore_idler_mp, -// &ecore_job_mp, -// &ecore_timer_mp, -// &ecore_poller_mp, - &ecore_pipe_mp, - &ecore_fd_handler_mp, -#ifdef _WIN32 - &ecore_win32_handler_mp -#endif -}; - -Eina_Bool -ecore_mempool_init(void) -{ - const char *choice; - unsigned int i; - -#define MP_SIZE_INIT(TYPE, Type) \ - Type##_mp.size = _ecore_sizeof_##TYPE - -// MP_SIZE_INIT(Ecore_Animator, ecore_animator); - MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler); - MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter); - MP_SIZE_INIT(Ecore_Event, ecore_event); -// MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter); -// MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer); -// MP_SIZE_INIT(Ecore_Idler, ecore_idler); -// MP_SIZE_INIT(Ecore_Job, ecore_job); -// MP_SIZE_INIT(Ecore_Timer, ecore_timer); -// MP_SIZE_INIT(Ecore_Poller, ecore_poller); - MP_SIZE_INIT(Ecore_Pipe, ecore_pipe); - MP_SIZE_INIT(Ecore_Fd_Handler, ecore_fd_handler); -#ifdef _WIN32 - MP_SIZE_INIT(Ecore_Win32_Handler, ecore_win32_handler); -#endif -#undef MP_SIZE_INIT - - choice = getenv("EINA_MEMPOOL"); - if ((!choice) || (!choice[0])) - choice = "chained_mempool"; - - for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) - { - retry: - mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 16); - if (!mempool_array[i]->mp) - { - if (!(!strcmp(choice, "pass_through"))) - { - ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice); - choice = "pass_through"; - goto retry; - } - else - { - ERR("Impossible to allocate mempool '%s' !", choice); - return EINA_FALSE; - } - } - } - return EINA_TRUE; -} - -void -ecore_mempool_shutdown(void) -{ - unsigned int i; - - for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) - { - eina_mempool_del(mempool_array[i]->mp); - mempool_array[i]->mp = NULL; - } -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_anim.c b/legacy/ecore/src/lib/ecore/ecore_anim.c deleted file mode 100644 index c06d139add..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_anim.c +++ /dev/null @@ -1,633 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#define MY_CLASS ECORE_ANIMATOR_CLASS - -#define MY_CLASS_NAME "ecore_animator" - -#define ECORE_ANIMATOR_CHECK(obj) \ - if (!eo_isa((obj), ECORE_ANIMATOR_CLASS)) \ - return - -EAPI Eo_Op ECORE_ANIMATOR_BASE_ID = EO_NOOP; - -struct _Ecore_Animator_Private_Data -{ - EINA_INLIST; - Ecore_Animator *obj; - - Ecore_Task_Cb func; - void *data; - - double start, run; - Ecore_Timeline_Cb run_func; - void *run_data; - - Eina_Bool delete_me : 1; - Eina_Bool suspended : 1; - Eina_Bool just_added : 1; -}; - -typedef struct _Ecore_Animator_Private_Data Ecore_Animator_Private_Data; - -static Eina_Bool _ecore_animator_run(void *data); -static Eina_Bool _ecore_animator(void *data); - -static int animators_delete_me = 0; -static Ecore_Animator_Private_Data *animators = NULL; -static double animators_frametime = 1.0 / 30.0; - -static Ecore_Animator_Source src = ECORE_ANIMATOR_SOURCE_TIMER; -static Ecore_Timer *timer = NULL; -static int ticking = 0; -static Ecore_Cb begin_tick_cb = NULL; -static const void *begin_tick_data = NULL; -static Ecore_Cb end_tick_cb = NULL; -static const void *end_tick_data = NULL; - -static void -_begin_tick(void) -{ - if (ticking) return; - ticking = 1; - switch (src) - { - case ECORE_ANIMATOR_SOURCE_TIMER: - 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); - } - break; - - case ECORE_ANIMATOR_SOURCE_CUSTOM: - if (begin_tick_cb) begin_tick_cb((void *)begin_tick_data); - break; - - default: - break; - } -} - -static void -_end_tick(void) -{ - if (!ticking) return; - ticking = 0; - switch (src) - { - case ECORE_ANIMATOR_SOURCE_TIMER: - if (timer) - { - _ecore_timer_del(timer); - timer = NULL; - } - break; - - case ECORE_ANIMATOR_SOURCE_CUSTOM: - if (end_tick_cb) end_tick_cb((void *)end_tick_data); - break; - - default: - break; - } -} - -static Eina_Bool -_do_tick(void) -{ - Ecore_Animator_Private_Data *animator; - - EINA_INLIST_FOREACH(animators, animator) - { - animator->just_added = EINA_FALSE; - } - EINA_INLIST_FOREACH(animators, animator) - { - if ((!animator->delete_me) && - (!animator->suspended) && - (!animator->just_added)) - { - if (!_ecore_call_task_cb(animator->func, animator->data)) - { - animator->delete_me = EINA_TRUE; - animators_delete_me++; - } - } - else animator->just_added = EINA_FALSE; - } - if (animators_delete_me) - { - Ecore_Animator_Private_Data *l; - for (l = animators; l; ) - { - animator = l; - l = (Ecore_Animator_Private_Data *)EINA_INLIST_GET(l)->next; - if (animator->delete_me) - { - animators = (Ecore_Animator_Private_Data *) - eina_inlist_remove(EINA_INLIST_GET(animators), - EINA_INLIST_GET(animator)); - - eo_parent_set(animator->obj, NULL); - if (eo_destructed_is(animator->obj)) - eo_manual_free(animator->obj); - else - eo_manual_free_set(animator->obj, EINA_FALSE); - - animators_delete_me--; - if (animators_delete_me == 0) break; - } - } - } - if (!animators) - { - _end_tick(); - return ECORE_CALLBACK_CANCEL; - } - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_ecore_animator_add(Ecore_Animator *obj, - Ecore_Animator_Private_Data *animator, - Ecore_Task_Cb func, - const void *data) -{ - if (EINA_UNLIKELY(!eina_main_loop_is())) - { - eo_error_set(obj); - EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); - } - - animator->obj = obj; - eo_do_super(obj, eo_constructor()); - eo_manual_free_set(obj, EINA_TRUE); - - if (!func) - { - eo_error_set(obj); - ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); - return EINA_FALSE; - } - - animator->func = func; - animator->data = (void *)data; - animator->just_added = EINA_TRUE; - animators = (Ecore_Animator_Private_Data *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator)); - _begin_tick(); - return EINA_TRUE; -} - -static void -_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) -{ - eo_error_set(obj); - ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); -} - -EAPI Ecore_Animator * -ecore_animator_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Animator *animator = NULL; - - animator = eo_add_custom(MY_CLASS, _ecore_parent, - ecore_animator_constructor(func, data)); - eo_unref(animator); - return animator; -} - -static void -_animator_constructor(Eo *obj, void *_pd, va_list *list) -{ - Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); - const void *data = va_arg(*list, const void *); - - _ecore_lock(); - Ecore_Animator_Private_Data *animator = _pd; - _ecore_animator_add(obj, animator, func, data); - _ecore_unlock(); -} - -EAPI Ecore_Animator * -ecore_animator_timeline_add(double runtime, - Ecore_Timeline_Cb func, - const void *data) -{ - Ecore_Animator *animator; - animator = eo_add_custom(MY_CLASS, _ecore_parent, - ecore_animator_timeline_constructor(runtime, func, data)); - eo_unref(animator); - return animator; -} - -static void -_animator_timeline_constructor(Eo *obj, void *_pd, va_list *list) -{ - _ecore_lock(); - double runtime = va_arg(*list, double); - if (runtime <= 0.0) runtime = 0.0; - Ecore_Timeline_Cb func = va_arg(*list, Ecore_Timeline_Cb); - const void *data = va_arg(*list, const void *); - - Ecore_Animator_Private_Data *animator = _pd; - if (!_ecore_animator_add(obj, animator, _ecore_animator_run, NULL)) goto unlock; - - animator->data = obj; - animator->run_func = func; - animator->run_data = (void *)data; - animator->start = ecore_loop_time_get(); - animator->run = runtime; - -unlock: - _ecore_unlock(); -} - -static double -_pos_map_sin(double in) -{ - return eina_f32p32_double_to(eina_f32p32_sin(eina_f32p32_double_from(in))); -} - -#if 0 -static double -_pos_map_cos(double in) -{ - return eina_f32p32_double_to(eina_f32p32_cos(eina_f32p32_double_from(in))); -} -#endif - -static double -_pos_map_accel_factor(double pos, - double v1) -{ - int i, fact = (int)v1; - double p, o1 = pos, o2, v; - p = 1.0 - _pos_map_sin((M_PI / 2.0) + ((pos * M_PI) / 2.0)); - o2 = p; - for (i = 0; i < fact; i++) - { - o1 = o2; - o2 = o2 * p; - } - v = v1 - (double)fact; - pos = (v * o2) + ((1.0 - v) * o1); - return pos; -} - -static double -_pos_map_pow(double pos, - double divis, - int p) -{ - double v = 1.0; - int i; - for (i = 0; i < p; i++) v *= pos; - return ((pos * divis) * (1.0 - v)) + (pos * v); -} - -static double -_pos_map_spring(double pos, - int bounces, - double decfac) -{ - int segnum, segpos, b1, b2; - double len, decay, decpos, p2; - if (bounces < 0) bounces = 0; - p2 = _pos_map_pow(pos, 0.5, 3); - len = (M_PI / 2.0) + ((double)bounces * M_PI); - segnum = (bounces * 2) + 1; - segpos = 2 * (((int)(p2 * segnum) + 1) / 2); - b1 = segpos; - b2 = segnum + 1; - if (b1 < 0) b1 = 0; - decpos = (double)b1 / (double)b2; - decay = _pos_map_accel_factor(1.0 - decpos, decfac); - return _pos_map_sin((M_PI / 2.0) + (p2 * len)) * decay; -} - -#define DBL_TO(Fp) eina_f32p32_double_to(Fp) -#define DBL_FROM(D) eina_f32p32_double_from(D) -#define INT_FROM(I) eina_f32p32_int_from(I) -#define SIN(Fp) eina_f32p32_sin(Fp) -#define COS(Fp) eina_f32p32_cos(Fp) -#define ADD(A, B) eina_f32p32_add(A, B) -#define SUB(A, B) eina_f32p32_sub(A, B) -#define MUL(A, B) eina_f32p32_mul(A, B) - -EAPI double -ecore_animator_pos_map(double pos, - Ecore_Pos_Map map, - double v1, - double v2) -{ - /* purely functional - locking not required */ - if (pos > 1.0) pos = 1.0; - else if (pos < 0.0) - pos = 0.0; - switch (map) - { - case ECORE_POS_MAP_LINEAR: - return pos; - - case ECORE_POS_MAP_ACCELERATE: - /* pos = 1 - sin(Pi / 2 + pos * Pi / 2); */ - pos = DBL_TO(SUB(INT_FROM(1), SIN(ADD((EINA_F32P32_PI >> 1), MUL(DBL_FROM(pos), (EINA_F32P32_PI >> 1)))))); - return pos; - - case ECORE_POS_MAP_DECELERATE: - /* pos = sin(pos * Pi / 2); */ - pos = DBL_TO(SIN(MUL(DBL_FROM(pos), (EINA_F32P32_PI >> 1)))); - return pos; - - case ECORE_POS_MAP_SINUSOIDAL: - /* pos = (1 - cos(pos * Pi)) / 2 */ - pos = DBL_TO((SUB(INT_FROM(1), COS(MUL(DBL_FROM(pos), EINA_F32P32_PI)))) >> 1); - return pos; - - case ECORE_POS_MAP_ACCELERATE_FACTOR: - pos = _pos_map_accel_factor(pos, v1); - return pos; - - case ECORE_POS_MAP_DECELERATE_FACTOR: - pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v1); - return pos; - - case ECORE_POS_MAP_SINUSOIDAL_FACTOR: - if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v1) / 2.0; - else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v1) / 2.0); - return pos; - - case ECORE_POS_MAP_DIVISOR_INTERP: - pos = _pos_map_pow(pos, v1, (int)v2); - return pos; - - case ECORE_POS_MAP_BOUNCE: - pos = _pos_map_spring(pos, (int)v2, v1); - if (pos < 0.0) pos = -pos; - pos = 1.0 - pos; - return pos; - - case ECORE_POS_MAP_SPRING: - pos = 1.0 - _pos_map_spring(pos, (int)v2, v1); - return pos; - - default: - return pos; - } - return pos; -} - -EAPI void * -ecore_animator_del(Ecore_Animator *obj) -{ - void *data = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - Ecore_Animator_Private_Data *animator = eo_data_get(obj, MY_CLASS); - _ecore_lock(); - - if (animator->delete_me) - { - data = animator->data; - goto unlock; - } - animator->delete_me = EINA_TRUE; - animators_delete_me++; - if (animator->run_func) - data = animator->run_data; - else - data = animator->data; -unlock: - _ecore_unlock(); - return data; -} - -static void -_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Animator_Private_Data *pd = _pd; - - pd->delete_me = EINA_TRUE; - animators_delete_me++; - - eo_do_super(obj, eo_destructor()); -} - -EAPI void -ecore_animator_frametime_set(double frametime) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - if (frametime < 0.0) frametime = 0.0; - if (animators_frametime == frametime) goto unlock; - animators_frametime = frametime; - _end_tick(); - if (animators) _begin_tick(); -unlock: - _ecore_unlock(); -} - -EAPI double -ecore_animator_frametime_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); - return animators_frametime; -} - -EAPI void -ecore_animator_freeze(Ecore_Animator *animator) -{ - ECORE_ANIMATOR_CHECK(animator); - eo_do(animator, eo_event_freeze()); -} - -static void -_ecore_animator_freeze(Eo *obj EINA_UNUSED, void *_pd, - va_list *list EINA_UNUSED) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - Ecore_Animator_Private_Data *animator = _pd; - - if (animator->delete_me) goto unlock; - animator->suspended = EINA_TRUE; -unlock: - _ecore_unlock(); -} - -EAPI void -ecore_animator_thaw(Ecore_Animator *animator) -{ - ECORE_ANIMATOR_CHECK(animator); - eo_do(animator, eo_event_thaw()); -} - -static void -_ecore_animator_thaw(Eo *obj EINA_UNUSED, void *_pd, - va_list *list EINA_UNUSED) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - Ecore_Animator_Private_Data *animator = _pd; - - _ecore_lock(); - if (animator->delete_me) goto unlock; - animator->suspended = EINA_FALSE; -unlock: - _ecore_unlock(); -} - -EAPI void -ecore_animator_source_set(Ecore_Animator_Source source) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - src = source; - _end_tick(); - if (animators) _begin_tick(); - _ecore_unlock(); -} - -EAPI Ecore_Animator_Source -ecore_animator_source_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - return src; -} - -EAPI void -ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, - const void *data) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - begin_tick_cb = func; - begin_tick_data = data; - _end_tick(); - if (animators) _begin_tick(); - _ecore_unlock(); -} - -EAPI void -ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, - const void *data) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - end_tick_cb = func; - end_tick_data = data; - _end_tick(); - if (animators) _begin_tick(); - _ecore_unlock(); -} - -EAPI void -ecore_animator_custom_tick(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - if (src == ECORE_ANIMATOR_SOURCE_CUSTOM) _do_tick(); - _ecore_unlock(); -} - -void -_ecore_animator_shutdown(void) -{ - _end_tick(); - while (animators) - { - Ecore_Animator_Private_Data *animator; - - animator = animators; - animators = (Ecore_Animator_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators)); - - eo_parent_set(animator->obj, NULL); - if (eo_destructed_is(animator->obj)) - eo_manual_free(animator->obj); - else - eo_manual_free_set(animator->obj, EINA_FALSE); - } -} - -static Eina_Bool -_ecore_animator_run(void *data) -{ - Ecore_Animator *obj = data; - Ecore_Animator_Private_Data *animator = eo_data_get(obj, MY_CLASS); - - double pos = 0.0, t; - Eina_Bool run_ret; - - t = ecore_loop_time_get(); - if (animator->run > 0.0) - { - pos = (t - animator->start) / animator->run; - if (pos > 1.0) pos = 1.0; - else if (pos < 0.0) - pos = 0.0; - } - run_ret = animator->run_func(animator->run_data, pos); - if (t >= (animator->start + animator->run)) run_ret = EINA_FALSE; - return run_ret; -} - -static Eina_Bool -_ecore_animator(void *data EINA_UNUSED) -{ - Eina_Bool r; - _ecore_lock(); - r = _do_tick(); - _ecore_unlock(); - return r; -} - -static void -_class_constructor(Eo_Class *klass) -{ - const Eo_Op_Func_Description func_desc[] = { - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE), _ecore_animator_freeze), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW), _ecore_animator_thaw), - - EO_OP_FUNC(ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR), _animator_constructor), - EO_OP_FUNC(ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR), _animator_timeline_constructor), - EO_OP_FUNC_SENTINEL - }; - - eo_class_funcs_set(klass, func_desc); -} - -static const Eo_Op_Description op_desc[] = { - EO_OP_DESCRIPTION(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR, "Add an animator to call func at every animation tick during main loop execution."), - EO_OP_DESCRIPTION(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR, "Add an animator that runs for a limited time"), - EO_OP_DESCRIPTION_SENTINEL -}; - -static const Eo_Class_Description class_desc = { - EO_VERSION, - MY_CLASS_NAME, - EO_CLASS_TYPE_REGULAR, - EO_CLASS_DESCRIPTION_OPS(&ECORE_ANIMATOR_BASE_ID, op_desc, ECORE_ANIMATOR_SUB_ID_LAST), - NULL, - sizeof(Ecore_Animator_Private_Data), - _class_constructor, - NULL -}; - -EO_DEFINE_CLASS(ecore_animator_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/legacy/ecore/src/lib/ecore/ecore_app.c b/legacy/ecore/src/lib/ecore/ecore_app.c deleted file mode 100644 index 04df487d3c..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_app.c +++ /dev/null @@ -1,98 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef _MSC_VER -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -static int app_argc = 0; -static char **app_argv = NULL; - -/** - * @addtogroup Ecore_Application_Group - * - * @{ - */ - -/** - * 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) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - - 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) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - - 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) -{ - EINA_MAIN_LOOP_CHECK_RETURN; -#ifdef HAVE_EXECVP - 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); -#endif -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore/ecore_events.c b/legacy/ecore/src/lib/ecore/ecore_events.c deleted file mode 100644 index 2d8ac1f661..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_events.c +++ /dev/null @@ -1,648 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -static int inpurge = 0; - -struct _Ecore_Event_Handler -{ - EINA_INLIST; - ECORE_MAGIC; - int type; - Ecore_Event_Handler_Cb func; - void *data; - int references; - Eina_Bool delete_me : 1; -}; -GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Handler); - -struct _Ecore_Event_Filter -{ - EINA_INLIST; - ECORE_MAGIC; - Ecore_Data_Cb func_start; - Ecore_Filter_Cb func_filter; - Ecore_End_Cb func_end; - void *loop_data; - void *data; - int references; - Eina_Bool delete_me : 1; -}; -GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Filter); - -struct _Ecore_Event -{ - EINA_INLIST; - ECORE_MAGIC; - int type; - void *event; - Ecore_End_Cb func_free; - void *data; - int references; - Eina_Bool delete_me : 1; -}; -GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event); - -static int events_num = 0; -static Ecore_Event *events = NULL; -static Ecore_Event *event_current = NULL; -static Ecore_Event *purge_events = 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_Handler *event_handlers_add_list = NULL; - -static Ecore_Event_Filter *event_filters = NULL; -static Ecore_Event_Filter *event_filter_current = NULL; -static Ecore_Event *event_filter_event_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); - -EAPI Ecore_Event_Handler * -ecore_event_handler_add(int type, - Ecore_Event_Handler_Cb func, - const void *data) -{ - Ecore_Event_Handler *eh = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - - if (!func) goto unlock; - if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) goto unlock; - eh = ecore_event_handler_calloc(1); - if (!eh) goto unlock; - 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) - { - ecore_event_handler_mp_free(eh); - goto unlock; - } - event_handlers = new_handlers; - for (i = p_alloc_num; i < event_handlers_alloc_num; i++) - event_handlers[i] = NULL; - } - } - if (ecore_raw_event_type == type) - event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh)); - else if (type < event_handlers_alloc_num) - event_handlers[type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh)); - -unlock: - _ecore_unlock(); - return eh; -} - -EAPI void * -ecore_event_handler_del(Ecore_Event_Handler *event_handler) -{ - void *data = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER)) - { - ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER, - "ecore_event_handler_del"); - goto unlock; - } - data = _ecore_event_handler_del(event_handler); -unlock: - _ecore_unlock(); - - return data; -} - -EAPI void * -ecore_event_handler_data_get(Ecore_Event_Handler *eh) -{ - void *data = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER)) - { - ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_get"); - goto unlock; - } - data = eh->data; -unlock: - _ecore_unlock(); - return data; -} - -EAPI void * -ecore_event_handler_data_set(Ecore_Event_Handler *eh, - const void *data) -{ - void *old = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER)) - { - ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_set"); - goto unlock; - } - old = eh->data; - eh->data = (void *)data; -unlock: - _ecore_unlock(); - - return old; -} - -static void -_ecore_event_generic_free(void *data EINA_UNUSED, - void *event) -{ /* DO NOT MEMPOOL FREE THIS */ - free(event); -} - -EAPI Ecore_Event * -ecore_event_add(int type, - void *ev, - Ecore_End_Cb func_free, - void *data) -{ - Ecore_Event *event = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - -/* if (!ev) goto unlock; */ - if (type <= ECORE_EVENT_NONE) goto unlock; - if (type >= event_id_max) goto unlock; - if ((ev) && (!func_free)) func_free = _ecore_event_generic_free; - event = _ecore_event_add(type, ev, func_free, data); -unlock: - _ecore_unlock(); - return event; -} - -EAPI void * -ecore_event_del(Ecore_Event *event) -{ - void *data = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT)) - { - ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del"); - goto unlock; - } - EINA_SAFETY_ON_TRUE_GOTO(event->delete_me, unlock); - event->delete_me = 1; - data = event->data; -unlock: - _ecore_unlock(); - return data; -} - -EAPI int -ecore_event_type_new(void) -{ - int id; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - _ecore_lock(); - id = event_id_max++; - _ecore_unlock(); - - return id; -} - -EAPI Ecore_Event_Filter * -ecore_event_filter_add(Ecore_Data_Cb func_start, - Ecore_Filter_Cb func_filter, - Ecore_End_Cb func_end, - const void *data) -{ - Ecore_Event_Filter *ef = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - if (!func_filter) goto unlock; - ef = ecore_event_filter_calloc(1); - if (!ef) goto unlock; - 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)); -unlock: - _ecore_unlock(); - return ef; -} - -EAPI void * -ecore_event_filter_del(Ecore_Event_Filter *ef) -{ - void *data = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER)) - { - ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del"); - goto unlock; - } - EINA_SAFETY_ON_TRUE_GOTO(ef->delete_me, unlock); - ef->delete_me = 1; - event_filters_delete_me = 1; - data = ef->data; -unlock: - _ecore_unlock(); - - return data; -} - -EAPI int -ecore_event_current_type_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - return ecore_raw_event_type; -} - -EAPI void * -ecore_event_current_event_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - return ecore_raw_event_event; -} - -EAPI void * -_ecore_event_handler_del(Ecore_Event_Handler *event_handler) -{ - EINA_SAFETY_ON_TRUE_RETURN_VAL(event_handler->delete_me, NULL); - event_handler->delete_me = 1; - event_handlers_delete_list = eina_list_append(event_handlers_delete_list, event_handler); - return event_handler->data; -} - -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) ecore_event_handler_mp_free(eh); - } - } - EINA_LIST_FREE(event_handlers_delete_list, eh) - ecore_event_handler_mp_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); - ecore_event_filter_mp_free(ef); - } - event_filters_delete_me = 0; - event_filter_current = NULL; - event_filter_event_current = NULL; -} - -int -_ecore_event_exist(void) -{ - Ecore_Event *e; - EINA_INLIST_FOREACH(events, e) - if (!e->delete_me) return 1; - return 0; -} - -Ecore_Event * -_ecore_event_add(int type, - void *ev, - Ecore_End_Cb func_free, - void *data) -{ - Ecore_Event *e; - - e = ecore_event_calloc(1); - 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; - if (inpurge > 0) - { - purge_events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(e)); - events_num++; - } - else - { - 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) _ecore_call_end_cb(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); - ecore_event_mp_free(event); - events_num--; - return data; -} - -static void -_ecore_event_purge_deleted(void) -{ - Ecore_Event *itr = events; - - inpurge++; - while (itr) - { - Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next; - if ((!itr->references) && (itr->delete_me)) - _ecore_event_del(itr); - itr = next; - } - inpurge--; - while (purge_events) - { - Ecore_Event *e = purge_events; - purge_events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(purge_events)); - events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e)); - } -} - -static inline void -_ecore_event_filters_apply() -{ - 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 = _ecore_call_data_cb(ef->func_start, ef->data); - - if (!event_filter_event_current) - { - /* regular main loop, start from head */ - event_filter_event_current = events; - } - else - { - /* recursive main loop, continue from where we were */ - event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next; - } - - while (event_filter_event_current) - { - Ecore_Event *e = event_filter_event_current; - - if (!_ecore_call_filter_cb(ef->func_filter, ef->data, - ef->loop_data, e->type, e->event)) - { - ecore_event_del(e); - } - - if (event_filter_event_current) /* may have changed in recursive main loops */ - event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next; - } - if (ef->func_end) - _ecore_call_end_cb(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); - ecore_event_filter_mp_free(ef); - } - } - if (!deleted_in_use) - event_filters_delete_me = 0; - } -} - -void -_ecore_event_call(void) -{ - Eina_List *l, *l_next; - Ecore_Event_Handler *eh; - - _ecore_event_filters_apply(); - - if (!event_current) - { - /* regular main loop, start from head */ - event_current = events; - event_handler_current = NULL; - } - - while (event_current) - { - Ecore_Event *e = event_current; - int handle_count = 0; - - if (e->delete_me) - { - event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next; - continue; - } - - ecore_raw_event_type = e->type; - ecore_raw_event_event = e->event; - e->references++; - 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)) - { - eh = event_handler_current; - if (!eh->delete_me) - { - Eina_Bool ret; - - handle_count++; - - eh->references++; - ret = _ecore_call_handler_cb(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; - } - } - while (event_handlers_add_list) - { - eh = event_handlers_add_list; - event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh)); - event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh)); - } - /* 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--; - e->delete_me = 1; - - if (event_current) /* may have changed in recursive main loops */ - event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next; - } - - 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); - ecore_event_handler_mp_free(eh); - } -} - -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)); -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_exe.c b/legacy/ecore/src/lib/ecore/ecore_exe.c deleted file mode 100644 index 19bc39b008..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_exe.c +++ /dev/null @@ -1,1913 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_PRCTL_H -# include -#endif - -#ifdef HAVE_SYS_WAIT_H -# include -#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 existent 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 */ - - Ecore_Exe_Cb pre_free_cb; -}; - -/* 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 preceding 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 Eina_Bool _ecore_exe_data_generic_handler(void *data, - Ecore_Fd_Handler *fd_handler, - Ecore_Exe_Flags flags); -static Eina_Bool _ecore_exe_data_error_handler(void *data, - Ecore_Fd_Handler *fd_handler); -static Eina_Bool _ecore_exe_data_read_handler(void *data, - Ecore_Fd_Handler *fd_handler); -static Eina_Bool _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 EINA_UNUSED, - void *ev); -static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid); -static Eina_Bool _ecore_exe_make_sure_its_dead(void *data); -static Eina_Bool _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 EINA_UNUSED, - int line EINA_UNUSED) -{ - 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; -} - -/** - * @addtogroup Ecore_Exe_Group - * - * @{ - */ - -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 - * @ref ECORE_EXE_WIN32_PRIORITY_NORMAL priority, unless the calling - * process is in @ref ECORE_EXE_WIN32_PRIORITY_IDLE or - * @ref ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL priority. In that case, the - * child process inherits this priority. - * @li On other platforms, if set to @ref 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 @ref ECORE_EXE_PRIORITY_INHERIT on other OS. - */ -EAPI void -ecore_exe_run_priority_set(int pri) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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() - */ -EAPI int -ecore_exe_run_priority_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - return run_pri; -} - -/** - * Spawns a child process. - * - * This is now just a thin wrapper around ecore_exe_pipe_run() - * @note When you use this function you will have no permissions - * to write or read on the pipe that connects you with the spwaned process. - * If you need to do that use ecore_exe_pipe_run() with the - * appropriated flags. - * - * @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. - */ -EAPI Ecore_Exe * -ecore_exe_run(const char *exe_cmd, - const void *data) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - return ecore_exe_pipe_run(exe_cmd, 0, data); -} - -/** - * 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. - */ -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; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - if (!exe_cmd) return 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->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) - { -#ifdef PRIO_PROCESS - if ((run_pri >= -20) && (run_pri <= 19)) - setpriority(PRIO_PROCESS, 0, run_pri); -#else -#warning "Your OS/libc does not provide PRIO_PROCESS (and possibly setpriority())" -#warning "This is a POSIX-1.2001 standard and it is highly encouraged that you" -#warning "Have support for this" -#endif - } - /* 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 success */ - { - /* 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) - 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) - 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, - Ecore_Exe_Cb func) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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 receives 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 @c EINA_TRUE if successful, @c EINA_FALSE on failure. - */ -EAPI Eina_Bool -ecore_exe_send(Ecore_Exe *exe, - const void *data, - int size) -{ - void *buf; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) - { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_send"); - return EINA_FALSE; - } - - if (exe->close_stdin) - { - ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p", - exe, size, data); - return EINA_FALSE; - } - - 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 EINA_FALSE; - } - - buf = realloc(exe->write_data_buf, exe->write_data_size + size); - if (!buf) return EINA_FALSE; - - 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 EINA_TRUE; -} - -/** - * The stdin of the given child process will close when the write buffer is empty. - * - * @param exe The child process - */ -EAPI void -ecore_exe_close_stdin(Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI void -ecore_exe_auto_limits_set(Ecore_Exe *exe, - int start_bytes, - int end_bytes, - int start_lines, - int end_lines) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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 separate 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? - * @return The event data. - */ -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; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - 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 (i > last) /* Partial line left over, save it for next time. */ - { - if (count != 0) 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); - } - } - 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; - } - } - } - - 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. - */ -EAPI void -ecore_exe_tag_set(Ecore_Exe *exe, - const char *tag) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI const char * -ecore_exe_tag_get(const Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - 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. - */ -EAPI void * -ecore_exe_free(Ecore_Exe *exe) -{ - void *data; - int ok = 0; - int result; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - 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. - */ -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. - */ -EAPI pid_t -ecore_exe_pid_get(const Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - 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, @c NULL otherwise. This string is the - * pointer to the internal value and must not be modified in - * any way. - */ -EAPI const char * -ecore_exe_cmd_get(const Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - 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() - */ -EAPI void * -ecore_exe_data_get(const Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) - { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get"); - return NULL; - } - return exe->data; -} - -/** - * Sets the data attached to the given process handle. - * @param exe The given process handle. - * @param data The pointer to attach - * @return The data pointer previously attached to @p exe with - * ecore_exe_run(), ecore_exe_pipe_run(), or ecore_exe_data_set() - * @since 1.1 - */ -EAPI void * -ecore_exe_data_set(Ecore_Exe *exe, - void *data) -{ - void *ret; - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) - { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, __func__); - return NULL; - } - ret = exe->data; - exe->data = data; - return ret; -} - -/** - * Retrieves the flags attached to the given process handle. - * @param exe The given process handle. - * @return The flags attached to @p exe. - */ -EAPI Ecore_Exe_Flags -ecore_exe_flags_get(const Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) - { - ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get"); - return 0; - } - return exe->flags; -} - -/** - * Pauses the given process by sending it a @c SIGSTOP signal. - * @param exe Process handle to the given process. - */ -EAPI void -ecore_exe_pause(Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI void -ecore_exe_continue(Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI void -ecore_exe_interrupt(Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI void -ecore_exe_quit(Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI void -ecore_exe_terminate(Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI void -ecore_exe_kill(Ecore_Exe *exe) -{ - struct _ecore_exe_dead_exe *dead; - - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI void -ecore_exe_signal(Ecore_Exe *exe, - int num) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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. - */ -EAPI void -ecore_exe_hup(Ecore_Exe *exe) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - 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 independent 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 Eina_Bool -_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))) - { - if (dead->cmd) - INF("Sending KILL signal to allegedly dead %s (%d).", - dead->cmd, dead->pid); - else - INF("Sending KILL signal to allegedly 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 ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_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))) - { - 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 ECORE_CALLBACK_CANCEL; -} - -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; - } - } - -#ifdef HAVE_SYS_PRCTL_H - if ((flags & ECORE_EXE_TERM_WITH_PARENT)) - { - prctl(PR_SET_PDEATHSIG, SIGTERM); - } -#endif - - 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) /* Find users preferred shell. */ - { - shell = getenv("SHELL"); - if (!shell) - shell = "/bin/sh"; - } - errno = 0; - execl(shell, shell, "-c", exe_cmd, (char *)NULL); - } - else - { /* We can run this directly. */ - if (!args) - { - IF_FREE(buf); - IF_FREE(args); - ERR("arg[0] is NULL!"); - return; - } - errno = 0; - execvp(args[0], args); - } - - save_errno = errno; - IF_FREE(buf); - IF_FREE(args); - errno = save_errno; - return; -} - -static Eina_Bool -_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 ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_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 Eina_Bool -_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 Eina_Bool -_ecore_exe_data_write_handler(void *data, - Ecore_Fd_Handler *fd_handler EINA_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 ECORE_CALLBACK_RENEW; -} - -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 EINA_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 EINA_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 EINA_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; - } -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_exe_ps3.c b/legacy/ecore/src/lib/ecore/ecore_exe_ps3.c deleted file mode 100644 index 1ef1e81fcb..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_exe_ps3.c +++ /dev/null @@ -1,20 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_ESCAPE -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -void -_ecore_exe_init(void) -{ -} - -void -_ecore_exe_shutdown(void) -{ -} diff --git a/legacy/ecore/src/lib/ecore/ecore_exe_win32.c b/legacy/ecore/src/lib/ecore/ecore_exe_win32.c deleted file mode 100644 index 71557c3676..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_exe_win32.c +++ /dev/null @@ -1,1055 +0,0 @@ -/* - * 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 -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include - -#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; - - Ecore_Exe_Cb pre_free_cb; -}; - -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 Eina_Bool _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, - Ecore_Exe_Cb func) -{ - 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) 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 EINA_UNUSED, - int start_bytes EINA_UNUSED, - int end_bytes EINA_UNUSED, - int start_lines EINA_UNUSED, - int end_lines EINA_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 EINA_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 2048 - 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, sizeof(buf), &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 EINA_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 EINA_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 EINA_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 EINA_UNUSED, - void *ev) -{ - Ecore_Exe_Event_Data *e; - - e = (Ecore_Exe_Event_Data *)ev; - ecore_exe_event_data_free(e); -} - -static Eina_Bool -_ecore_exe_close_cb(void *data, - Ecore_Win32_Handler *wh EINA_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 EINA_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); -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_exe_wince.c b/legacy/ecore/src/lib/ecore/ecore_exe_wince.c deleted file mode 100644 index c07fcbe31b..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_exe_wince.c +++ /dev/null @@ -1,21 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -void -_ecore_exe_init(void) -{ -} - -void -_ecore_exe_shutdown(void) -{ -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_getopt.c b/legacy/ecore/src/lib/ecore/ecore_getopt.c deleted file mode 100644 index 42e43e8915..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_getopt.c +++ /dev/null @@ -1,1936 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include -#include -#include -#include -#include - -#ifdef ENABLE_NLS -# include -#else -# define gettext(x) (x) -# define dgettext(domain, x) (x) -#endif - -#define _(x) dgettext("ecore", x) - -#ifdef _WIN32_WCE -# include -#endif - -#ifdef HAVE_EXOTIC -# include -#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 EINA_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((unsigned char)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((int) 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; itr++) - { - used = _ecore_getopt_help_line - (fp, base, total, used, *itr, strlen(*itr)); - if (itr[1]) - 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 Eina_Bool -_ecore_getopt_desc_is_sentinel(const Ecore_Getopt_Desc *desc) -{ - return (desc->shortname == '\0') && (!desc->longname); -} - -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. - * - * @param fp The file the message will be printed on. - * @param parser The parser to be used. - */ -EAPI void -ecore_getopt_help(FILE *fp, - const Ecore_Getopt *parser) -{ - const char *var; - - EINA_MAIN_LOOP_CHECK_RETURN; - if (!parser) return; - - if (_argc < 1) - { - ecore_app_args_get(&_argc, &_argv); - if ((_argc > 0) && (_argv[0])) - 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 Eina_Bool -_ecore_getopt_parse_bool(const char *str, - Eina_Bool *v) -{ - if ((strcmp(str, "0") == 0) || - (strcasecmp(str, "f") == 0) || - (strcasecmp(str, "false") == 0) || - (strcasecmp(str, "no") == 0) || - (strcasecmp(str, "off") == 0) - ) - { - *v = EINA_FALSE; - return EINA_TRUE; - } - else if ((strcmp(str, "1") == 0) || - (strcasecmp(str, "t") == 0) || - (strcasecmp(str, "true") == 0) || - (strcasecmp(str, "yes") == 0) || - (strcasecmp(str, "on") == 0) - ) - { - *v = EINA_TRUE; - return EINA_TRUE; - } - - return EINA_FALSE; -} - -static Eina_Bool -_ecore_getopt_parse_long(const char *str, - long int *v) -{ - char *endptr = NULL; - *v = strtol(str, &endptr, 0); - return endptr > str; -} - -static Eina_Bool -_ecore_getopt_parse_double(const char *str, - double *v) -{ - char *endptr = NULL; - *v = strtod(str, &endptr); - return endptr > str; -} - -static Eina_Bool -_ecore_getopt_parse_store(const Ecore_Getopt *parser EINA_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; - Eina_Bool b; - - if (!value->ptrp) - { - _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); - return EINA_FALSE; - } - - 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 EINA_TRUE; - - case ECORE_GETOPT_TYPE_BOOL: - if (_ecore_getopt_parse_bool(arg_val, &b)) - { - *value->boolp = b; - return EINA_TRUE; - } - else - { - _ecore_getopt_desc_print_error - (desc, _("unknown boolean value %s.\n"), arg_val); - return EINA_FALSE; - } - - case ECORE_GETOPT_TYPE_SHORT: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->shortp = v; - return EINA_TRUE; - - case ECORE_GETOPT_TYPE_INT: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->intp = v; - return EINA_TRUE; - - case ECORE_GETOPT_TYPE_LONG: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->longp = v; - return EINA_TRUE; - - case ECORE_GETOPT_TYPE_USHORT: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->ushortp = v; - return EINA_TRUE; - - case ECORE_GETOPT_TYPE_UINT: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->uintp = v; - return EINA_TRUE; - - case ECORE_GETOPT_TYPE_ULONG: - if (!_ecore_getopt_parse_long(arg_val, &v)) - goto error; - *value->ulongp = v; - return EINA_TRUE; - - case ECORE_GETOPT_TYPE_DOUBLE: - if (!_ecore_getopt_parse_double(arg_val, &d)) - goto error; - *value->doublep = d; - break; - } - - return EINA_TRUE; - -error: - _ecore_getopt_desc_print_error - (desc, _("invalid number format %s\n"), arg_val); - return EINA_FALSE; - -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 EINA_TRUE; -} - -static Eina_Bool -_ecore_getopt_parse_store_const(const Ecore_Getopt *parser EINA_UNUSED, - const Ecore_Getopt_Desc *desc, - Ecore_Getopt_Value *val, - const char *arg_val EINA_UNUSED) -{ - if (!val->ptrp) - { - _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); - return EINA_FALSE; - } - - *val->ptrp = (void *)desc->action_param.store_const; - return EINA_TRUE; -} - -static Eina_Bool -_ecore_getopt_parse_store_true(const Ecore_Getopt *parser EINA_UNUSED, - const Ecore_Getopt_Desc *desc, - Ecore_Getopt_Value *val, - const char *arg_val EINA_UNUSED) -{ - if (!val->boolp) - { - _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); - return EINA_FALSE; - } - *val->boolp = EINA_TRUE; - return EINA_TRUE; -} - -static Eina_Bool -_ecore_getopt_parse_store_false(const Ecore_Getopt *parser EINA_UNUSED, - const Ecore_Getopt_Desc *desc, - Ecore_Getopt_Value *val, - const char *arg_val EINA_UNUSED) -{ - if (!val->boolp) - { - _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); - return EINA_FALSE; - } - *val->boolp = EINA_FALSE; - return EINA_TRUE; -} - -static Eina_Bool -_ecore_getopt_parse_choice(const Ecore_Getopt *parser EINA_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 EINA_FALSE; - } - - pchoice = desc->action_param.choices; - for (; *pchoice; pchoice++) - if (strcmp(*pchoice, arg_val) == 0) - { - *val->strp = (char *)*pchoice; - return EINA_TRUE; - } - - _ecore_getopt_desc_print_error - (desc, _("invalid choice \"%s\". Valid values are: "), arg_val); - - pchoice = desc->action_param.choices; - for (; *pchoice; pchoice++) - { - fputs(*pchoice, stderr); - if (pchoice[1]) - fputs(", ", stderr); - } - - fputs(".\n", stderr); - return EINA_FALSE; -} - -static Eina_Bool -_ecore_getopt_parse_append(const Ecore_Getopt *parser EINA_UNUSED, - const Ecore_Getopt_Desc *desc, - Ecore_Getopt_Value *val, - const char *arg_val) -{ - void *data; - long int v; - double d; - Eina_Bool b; - - if (!arg_val) - { - _ecore_getopt_desc_print_error - (desc, _("missing parameter to append.\n")); - return EINA_FALSE; - } - - if (!val->listp) - { - _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); - return EINA_FALSE; - } - - 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(Eina_Bool)); - if (data) - *(Eina_Bool *)data = b; - } - else - { - _ecore_getopt_desc_print_error(desc, _("unknown boolean value %s.\n"), arg_val); - return EINA_FALSE; - } - } - 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 EINA_FALSE; - } - } - - *val->listp = eina_list_append(*val->listp, data); - return EINA_TRUE; - -error: - _ecore_getopt_desc_print_error - (desc, _("invalid number format %s\n"), arg_val); - return EINA_FALSE; -} - -static Eina_Bool -_ecore_getopt_parse_count(const Ecore_Getopt *parser EINA_UNUSED, - const Ecore_Getopt_Desc *desc, - Ecore_Getopt_Value *val, - const char *arg_val EINA_UNUSED) -{ - if (!val->intp) - { - _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); - return EINA_FALSE; - } - - (*val->intp)++; - return EINA_TRUE; -} - -static Eina_Bool -_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 EINA_FALSE; - } - - if (!val->ptrp) - { - _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); - return EINA_FALSE; - } - } - - if (!cb->func) - { - _ecore_getopt_desc_print_error(desc, _("missing callback function!\n")); - return EINA_FALSE; - } - - return cb->func(parser, desc, arg_val, (void *)cb->data, val); -} - -static Eina_Bool -_ecore_getopt_parse_help(const Ecore_Getopt *parser, - const Ecore_Getopt_Desc *desc EINA_UNUSED, - Ecore_Getopt_Value *val, - const char *arg_val EINA_UNUSED) -{ - if (val->boolp) - (*val->boolp) = EINA_TRUE; - ecore_getopt_help(stdout, parser); - return EINA_TRUE; -} - -static Eina_Bool -_ecore_getopt_parse_version(const Ecore_Getopt *parser, - const Ecore_Getopt_Desc *desc, - Ecore_Getopt_Value *val, - const char *arg_val EINA_UNUSED) -{ - if (val->boolp) - (*val->boolp) = EINA_TRUE; - if (!parser->version) - { - _ecore_getopt_desc_print_error(desc, _("no version was defined.\n")); - return EINA_FALSE; - } - _ecore_getopt_version(stdout, parser); - return EINA_TRUE; -} - -static Eina_Bool -_ecore_getopt_parse_copyright(const Ecore_Getopt *parser, - const Ecore_Getopt_Desc *desc, - Ecore_Getopt_Value *val, - const char *arg_val EINA_UNUSED) -{ - if (val->boolp) - (*val->boolp) = EINA_TRUE; - if (!parser->copyright) - { - _ecore_getopt_desc_print_error(desc, _("no copyright was defined.\n")); - return EINA_FALSE; - } - _ecore_getopt_copyright(stdout, parser); - return EINA_TRUE; -} - -static Eina_Bool -_ecore_getopt_parse_license(const Ecore_Getopt *parser, - const Ecore_Getopt_Desc *desc, - Ecore_Getopt_Value *val, - const char *arg_val EINA_UNUSED) -{ - if (val->boolp) - (*val->boolp) = EINA_TRUE; - if (!parser->license) - { - _ecore_getopt_desc_print_error(desc, _("no license was defined.\n")); - return EINA_FALSE; - } - _ecore_getopt_license(stdout, parser); - return EINA_TRUE; -} - -static Eina_Bool -_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 EINA_FALSE; - } -} - -static Eina_Bool -_ecore_getopt_parse_arg_long(const Ecore_Getopt *parser, - Ecore_Getopt_Value *values, - int argc EINA_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; - Eina_Bool ret; - - desc = _ecore_getopt_parse_find_long(parser, arg); - if (!desc) - { - fprintf(stderr, _("ERROR: unknown option --%s, ignored.\n"), arg); - if (parser->strict) - return EINA_FALSE; - - (*idx)++; - return EINA_TRUE; - } - - (*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 EINA_FALSE; - return EINA_TRUE; - } - } - 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 EINA_FALSE; - - return EINA_TRUE; -} - -static Eina_Bool -_ecore_getopt_parse_arg_short(const Ecore_Getopt *parser, - Ecore_Getopt_Value *values, - int argc EINA_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; - Eina_Bool 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 EINA_FALSE; - - 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 EINA_FALSE; - return EINA_TRUE; - } - } - 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 EINA_FALSE; - } - - if (run) - (*idx)++; - - return EINA_TRUE; -} - -static Eina_Bool -_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 EINA_TRUE; - } - - 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 @c EINA_TRUE if there are duplicates, @c EINA_FALSE otherwise. - * @param parser The parser to be checked. - */ -EAPI Eina_Bool -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 EINA_TRUE; - } - } - - 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 EINA_TRUE; - } - } - } - return EINA_FALSE; -} - -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 @c 1 on value as a boolean - * (@c value->boolp) if it's not @c 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 @c -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 values 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. - */ -EAPI 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)) - ecore_app_args_get(&argc, &argv); - - if (argc < 1) - { - fputs(_("ERROR: no arguments provided.\n"), stderr); - return -1; - } - - if (argv[0]) - 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 @c NULL, so you can easily make your list head @c NULL. - */ -EAPI 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). - * - * @param parser This parameter isn't in use. - * @param desc This parameter isn't in use. - * @param str Geometry value - * @param data This parameter isn't in use. - * @param storage must be a pointer to @c Eina_Rectangle and will be used to - * store the four values passed in the given string. - * @return @c EINA_TRUE on success, @c EINA_FALSE on incorrect geometry value. - * - * @c callback_data value is ignored, you can safely use @c NULL. - */ -EAPI Eina_Bool -ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser EINA_UNUSED, - const Ecore_Getopt_Desc *desc EINA_UNUSED, - const char *str, - void *data EINA_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 EINA_FALSE; - } - - return EINA_TRUE; -} - -/** - * Helper ecore_getopt callback to parse geometry size (WxH). - * - * @param parser This parameter isn't in use. - * @param desc This parameter isn't in use. - * @param str size value - * @param data This parameter isn't in use. - * @param storage must be a pointer to @c Eina_Rectangle and will be used to - * store the two values passed in the given string and @c 0 in the x and y - * fields. - * @return @c EINA_TRUE on success, @c EINA_FALSE on incorrect size value. - * - * @c callback_data value is ignored, you can safely use @c NULL. - */ -EAPI Eina_Bool -ecore_getopt_callback_size_parse(const Ecore_Getopt *parser EINA_UNUSED, - const Ecore_Getopt_Desc *desc EINA_UNUSED, - const char *str, - void *data EINA_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 EINA_FALSE; - } - v->x = 0; - v->y = 0; - - return EINA_TRUE; -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_glib.c b/legacy/ecore/src/lib/ecore/ecore_glib.c deleted file mode 100644 index 5b73180951..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_glib.c +++ /dev/null @@ -1,346 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#ifdef HAVE_GLIB -# include - -static Eina_Bool _ecore_glib_active = EINA_FALSE; -static Ecore_Select_Function _ecore_glib_select_original; -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->events & G_IO_IN)) - { - itr->revents |= G_IO_IN; - ready--; - } - if (FD_ISSET(itr->fd, wfds) && (itr->events & G_IO_OUT)) - { - itr->revents |= G_IO_OUT; - ready--; - } - if (FD_ISSET(itr->fd, efds) && (itr->events & (G_IO_HUP | G_IO_ERR))) - { - 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; - GMutex *mutex; - GMainContext *ctx; - int ret; - - g_static_mutex_init(&lock); - mutex = g_static_mutex_get_mutex(&lock); - ctx = g_main_context_default(); - - if (g_main_context_acquire(ctx)) - { - if (mutex) 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); - - if (mutex) g_mutex_unlock(mutex); - g_main_context_release(ctx); - g_static_mutex_free(&lock); - - 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 -} - -/** - * @addtogroup Ecore_Main_Loop_Group - * - * @} - */ - -/** - * 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. - * - * Example of use: - * @code - * - * int main(void) - * { - * ecore_init(); - * ecore_main_loop_glib_integrate(); - * - * // some code here - * - * ecore_main_loop_begin(); - * - * ecore_shutdown(); - * - * return 0; - * } - * - * @endcode - * - * @note This is only available if Ecore was compiled with GLib support. - * @note You don't need to call this function if Ecore was compiled with - * --enable-glib-integration-always. - * - * @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 - ERR("No glib support"); - 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; -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore/ecore_idle_enterer.c b/legacy/ecore/src/lib/ecore/ecore_idle_enterer.c deleted file mode 100644 index 64956ad7b7..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_idle_enterer.c +++ /dev/null @@ -1,314 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#define MY_CLASS ECORE_IDLE_ENTERER_CLASS - -#define MY_CLASS_NAME "ecore_idle_enterer" - -EAPI Eo_Op ECORE_IDLE_ENTERER_BASE_ID = EO_NOOP; - -struct _Ecore_Idle_Enterer_Private_Data -{ - EINA_INLIST; - Ecore_Idle_Enterer *obj; - Ecore_Task_Cb func; - void *data; - int references; - Eina_Bool delete_me : 1; -}; -typedef struct _Ecore_Idle_Enterer_Private_Data Ecore_Idle_Enterer_Private_Data; - -static Ecore_Idle_Enterer_Private_Data *idle_enterers = NULL; -static Ecore_Idle_Enterer_Private_Data *idle_enterer_current = NULL; -static int idle_enterers_delete_me = 0; - -static void * -_ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer); - -/** - * @addtogroup Ecore_Idle_Group - * - * @{ - */ - -static Eina_Bool -_ecore_idle_enterer_add(Ecore_Idle_Enterer *obj, - Ecore_Idle_Enterer_Private_Data *ie, - Ecore_Task_Cb func, - const void *data) -{ - if (EINA_UNLIKELY(!eina_main_loop_is())) - { - eo_error_set(obj); - EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); - } - - ie->obj = obj; - eo_do_super(obj, eo_constructor()); - eo_manual_free_set(obj, EINA_TRUE); - - if (!func) - { - eo_error_set(obj); - ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); - return EINA_FALSE; - } - - ie->func = func; - ie->data = (void *)data; - return EINA_TRUE; -} - -/** - * 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. - * @note The function func will be called every time the main loop is entering - * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 - * (or ECORE_CALLBACK_CANCEL) deletes the idle enterer. - */ -EAPI Ecore_Idle_Enterer * -ecore_idle_enterer_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Idle_Enterer *ie = NULL; - ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_enterer_after_constructor(func, data)); - eo_unref(ie); - return ie; -} - -static void -_idle_enterer_after_constructor(Eo *obj, void *_pd, va_list *list) -{ - Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); - const void *data = va_arg(*list, const void *); - - _ecore_lock(); - Ecore_Idle_Enterer_Private_Data *ie = _pd; - if (!_ecore_idle_enterer_add(obj, ie, func, data)) goto unlock; - - idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie)); - -unlock: - _ecore_unlock(); -} - -/** - * 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. - * @note The function func will be called every time the main loop is entering - * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 - * (or ECORE_CALLBACK_CANCEL) deletes the idle enterer. - */ -EAPI Ecore_Idle_Enterer * -ecore_idle_enterer_before_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Idle_Enterer *ie = NULL; - ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_enterer_before_constructor(func, data)); - eo_unref(ie); - return ie; -} - -static void -_idle_enterer_before_constructor(Eo *obj, void *_pd, va_list *list) -{ - Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); - const void *data = va_arg(*list, const void *); - - _ecore_lock(); - Ecore_Idle_Enterer_Private_Data *ie = _pd; - if (!_ecore_idle_enterer_add(obj, ie, func, data)) goto unlock; - - idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie)); - -unlock: - _ecore_unlock(); -} - -static void -_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) -{ - eo_error_set(obj); - ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); -} - -/** - * 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. - */ -EAPI void * -ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer) -{ - void *data = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - - _ecore_lock(); - data = _ecore_idle_enterer_del(idle_enterer); - _ecore_unlock(); - return data; -} - -/** - * @} - */ - - -static void * -_ecore_idle_enterer_del(Ecore_Idle_Enterer *obj) -{ - Ecore_Idle_Enterer_Private_Data *idle_enterer = eo_data_get(obj, MY_CLASS); - - if (!idle_enterer) return NULL; - EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_enterer->delete_me, NULL); - idle_enterer->delete_me = 1; - idle_enterers_delete_me = 1; - return idle_enterer->data; -} - -static void -_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Idle_Enterer_Private_Data *idle_enterer = _pd; - - idle_enterer->delete_me = 1; - idle_enterers_delete_me = 1; - - eo_do_super(obj, eo_destructor()); -} - -void -_ecore_idle_enterer_shutdown(void) -{ - Ecore_Idle_Enterer_Private_Data *ie; - while ((ie = idle_enterers)) - { - idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers)); - - eo_parent_set(ie->obj, NULL); - if (eo_destructed_is(ie->obj)) - eo_manual_free(ie->obj); - else - eo_manual_free_set(ie->obj, EINA_FALSE); - } - 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_Private_Data *)EINA_INLIST_GET(idle_enterer_current)->next; - } - - while (idle_enterer_current) - { - Ecore_Idle_Enterer_Private_Data *ie = (Ecore_Idle_Enterer_Private_Data *)idle_enterer_current; - if (!ie->delete_me) - { - ie->references++; - if (!_ecore_call_task_cb(ie->func, ie->data)) - { - if (!ie->delete_me) _ecore_idle_enterer_del(ie->obj); - } - ie->references--; - } - if (idle_enterer_current) /* may have changed in recursive main loops */ - idle_enterer_current = - (Ecore_Idle_Enterer_Private_Data *)EINA_INLIST_GET(idle_enterer_current)->next; - } - if (idle_enterers_delete_me) - { - Ecore_Idle_Enterer_Private_Data *l; - int deleted_idler_enterers_in_use = 0; - - for (l = idle_enterers; l; ) - { - Ecore_Idle_Enterer_Private_Data *ie = l; - l = (Ecore_Idle_Enterer_Private_Data *)EINA_INLIST_GET(l)->next; - if (ie->delete_me) - { - if (ie->references) - { - deleted_idler_enterers_in_use++; - continue; - } - - idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie)); - - eo_parent_set(ie->obj, NULL); - if (eo_destructed_is(ie->obj)) - eo_manual_free(ie->obj); - else - eo_manual_free_set(ie->obj, EINA_FALSE); - } - } - if (!deleted_idler_enterers_in_use) - idle_enterers_delete_me = 0; - } -} - -int -_ecore_idle_enterer_exist(void) -{ - if (idle_enterers) return 1; - return 0; -} - -static void -_class_constructor(Eo_Class *klass) -{ - const Eo_Op_Func_Description func_desc[] = { - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), - - EO_OP_FUNC(ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR), _idle_enterer_after_constructor), - EO_OP_FUNC(ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR), _idle_enterer_before_constructor), - EO_OP_FUNC_SENTINEL - }; - - eo_class_funcs_set(klass, func_desc); -} - -static const Eo_Op_Description op_desc[] = { - EO_OP_DESCRIPTION(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR, "Add an idle enterer handler."), - EO_OP_DESCRIPTION(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR, "Add an idle enterer handler at the start of the list so it gets called earlier than others."), - EO_OP_DESCRIPTION_SENTINEL -}; -static const Eo_Class_Description class_desc = { - EO_VERSION, - MY_CLASS_NAME, - EO_CLASS_TYPE_REGULAR, - EO_CLASS_DESCRIPTION_OPS(&ECORE_IDLE_ENTERER_BASE_ID, op_desc, ECORE_IDLE_ENTERER_SUB_ID_LAST), - NULL, - sizeof(Ecore_Idle_Enterer_Private_Data), - _class_constructor, - NULL -}; - -EO_DEFINE_CLASS(ecore_idle_enterer_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/legacy/ecore/src/lib/ecore/ecore_idle_exiter.c b/legacy/ecore/src/lib/ecore/ecore_idle_exiter.c deleted file mode 100644 index 8fd20e7a0a..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_idle_exiter.c +++ /dev/null @@ -1,264 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#define MY_CLASS ECORE_IDLE_EXITER_CLASS - -#define MY_CLASS_NAME "ecore_idle_exiter" - -EAPI Eo_Op ECORE_IDLE_EXITER_BASE_ID = EO_NOOP; - -struct _Ecore_Idle_Exiter_Private_Data -{ - EINA_INLIST; - Ecore_Idle_Exiter *obj; - Ecore_Task_Cb func; - void *data; - int references; - Eina_Bool delete_me : 1; -}; - -typedef struct _Ecore_Idle_Exiter_Private_Data Ecore_Idle_Exiter_Private_Data; - -static Ecore_Idle_Exiter_Private_Data *idle_exiters = NULL; -static Ecore_Idle_Exiter_Private_Data *idle_exiter_current = NULL; -static int idle_exiters_delete_me = 0; - -static void * -_ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter); - -/** - * @addtogroup Ecore_Idle_Group - * - * @{ - */ - -/** - * 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. - * @note The function func will be called every time the main loop is exiting - * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 - * (or ECORE_CALLBACK_CANCEL) deletes the idle exiter. - */ -EAPI Ecore_Idle_Exiter * -ecore_idle_exiter_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Idle_Exiter *ie = NULL; - ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_exiter_constructor(func, data)); - eo_unref(ie); - return ie; -} - -static void -_idle_exiter_constructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); - const void *data = va_arg(*list, const void *); - - _ecore_lock(); - if (EINA_UNLIKELY(!eina_main_loop_is())) - { - eo_error_set(obj); - EINA_MAIN_LOOP_CHECK_RETURN; - } - - Ecore_Idle_Exiter_Private_Data *ie = _pd; - - ie->obj = obj; - eo_do_super(obj, eo_constructor()); - eo_manual_free_set(obj, EINA_TRUE); - - if (!func) - { - eo_error_set(obj); - ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); - return; - } - - ie->func = func; - ie->data = (void *)data; - - idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie)); - _ecore_unlock(); -} - -static void -_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) -{ - eo_error_set(obj); - ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); -} - -/** - * 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. - */ -EAPI void * -ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter) -{ - void *data; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - - _ecore_lock(); - data = _ecore_idle_exiter_del(idle_exiter); - _ecore_unlock(); - return data; -} - -/** - * @} - */ -static void * -_ecore_idle_exiter_del(Ecore_Idle_Exiter *obj) -{ - Ecore_Idle_Exiter_Private_Data *idle_exiter = eo_data_get(obj, MY_CLASS); - EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_exiter->delete_me, NULL); - idle_exiter->delete_me = 1; - idle_exiters_delete_me = 1; - return idle_exiter->data; -} - - -static void -_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Idle_Exiter_Private_Data *idle_exiter = _pd; - - idle_exiter->delete_me = 1; - idle_exiters_delete_me = 1; - - eo_do_super(obj, eo_destructor()); -} - -void -_ecore_idle_exiter_shutdown(void) -{ - Ecore_Idle_Exiter_Private_Data *ie; - while ((ie = idle_exiters)) - { - idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters)); - - eo_parent_set(ie->obj, NULL); - if (eo_destructed_is(ie->obj)) - eo_manual_free(ie->obj); - else - eo_manual_free_set(ie->obj, EINA_FALSE); - } - 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_Private_Data *)EINA_INLIST_GET(idle_exiter_current)->next; - } - - while (idle_exiter_current) - { - Ecore_Idle_Exiter_Private_Data *ie = (Ecore_Idle_Exiter_Private_Data *)idle_exiter_current; - if (!ie->delete_me) - { - ie->references++; - if (!_ecore_call_task_cb(ie->func, ie->data)) - { - if (!ie->delete_me) _ecore_idle_exiter_del(ie->obj); - } - ie->references--; - } - if (idle_exiter_current) /* may have changed in recursive main loops */ - idle_exiter_current = - (Ecore_Idle_Exiter_Private_Data *)EINA_INLIST_GET(idle_exiter_current)->next; - } - if (idle_exiters_delete_me) - { - Ecore_Idle_Exiter_Private_Data *l; - int deleted_idler_exiters_in_use = 0; - - for (l = idle_exiters; l; ) - { - Ecore_Idle_Exiter_Private_Data *ie = l; - - l = (Ecore_Idle_Exiter_Private_Data *)EINA_INLIST_GET(l)->next; - if (ie->delete_me) - { - if (ie->references) - { - deleted_idler_exiters_in_use++; - continue; - } - - idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie)); - - eo_parent_set(ie->obj, NULL); - if (eo_destructed_is(ie->obj)) - eo_manual_free(ie->obj); - else - eo_manual_free_set(ie->obj, EINA_FALSE); - } - } - if (!deleted_idler_exiters_in_use) - idle_exiters_delete_me = 0; - } -} - -int -_ecore_idle_exiter_exist(void) -{ - if (idle_exiters) return 1; - return 0; -} - -static void -_class_constructor(Eo_Class *klass) -{ - const Eo_Op_Func_Description func_desc[] = { - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), - - EO_OP_FUNC(ECORE_IDLE_EXITER_ID(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR), _idle_exiter_constructor), - EO_OP_FUNC_SENTINEL - }; - - eo_class_funcs_set(klass, func_desc); -} - -static const Eo_Op_Description op_desc[] = { - EO_OP_DESCRIPTION(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR, "Add an idle exiter handler."), - EO_OP_DESCRIPTION_SENTINEL -}; - -static const Eo_Class_Description class_desc = { - EO_VERSION, - MY_CLASS_NAME, - EO_CLASS_TYPE_REGULAR, - EO_CLASS_DESCRIPTION_OPS(&ECORE_IDLE_EXITER_BASE_ID, op_desc, ECORE_IDLE_EXITER_SUB_ID_LAST), - NULL, - sizeof(Ecore_Idle_Exiter_Private_Data), - _class_constructor, - NULL -}; - -EO_DEFINE_CLASS(ecore_idle_exiter_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/legacy/ecore/src/lib/ecore/ecore_idler.c b/legacy/ecore/src/lib/ecore/ecore_idler.c deleted file mode 100644 index 147b3c1880..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_idler.c +++ /dev/null @@ -1,247 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#define MY_CLASS ECORE_IDLER_CLASS - -#define MY_CLASS_NAME "ecore_idler" - -EAPI Eo_Op ECORE_IDLER_BASE_ID = EO_NOOP; - -struct _Ecore_Idler_Private_Data -{ - EINA_INLIST; - Ecore_Idler *obj; - Ecore_Task_Cb func; - void *data; - int references; - Eina_Bool delete_me : 1; -}; - -typedef struct _Ecore_Idler_Private_Data Ecore_Idler_Private_Data; -static Ecore_Idler_Private_Data *idlers = NULL; -static Ecore_Idler_Private_Data *idler_current = NULL; -static int idlers_delete_me = 0; - -static void * -_ecore_idler_del(Ecore_Idler *idler); - -EAPI Ecore_Idler * -ecore_idler_add(Ecore_Task_Cb func, - const void *data) -{ - Ecore_Idler *ie = NULL; - - _ecore_lock(); - - ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idler_constructor(func, data)); - eo_unref(ie); - - _ecore_unlock(); - return ie; -} - -static void -_idler_constructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); - const void *data = va_arg(*list, const void *); - - if (EINA_UNLIKELY(!eina_main_loop_is())) - { - eo_error_set(obj); - EINA_MAIN_LOOP_CHECK_RETURN; - } - - Ecore_Idler_Private_Data *ie = _pd; - - ie->obj = obj; - eo_do_super(obj, eo_constructor()); - eo_manual_free_set(obj, EINA_TRUE); - - if (!func) - { - eo_error_set(obj); - ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); - return; - } - - ie->func = func; - ie->data = (void *)data; - idlers = (Ecore_Idler_Private_Data *)eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie)); -} - - -static void -_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) -{ - eo_error_set(obj); - ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); -} - -EAPI void * -ecore_idler_del(Ecore_Idler *idler) -{ - void *data = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - - _ecore_lock(); - data = _ecore_idler_del(idler); - _ecore_unlock(); - return data; -} - -/** - * @} - */ - -/** - * @} - */ - -static void * -_ecore_idler_del(Ecore_Idler *obj) -{ - Ecore_Idler_Private_Data *idler = eo_data_get(obj, MY_CLASS); - EINA_SAFETY_ON_TRUE_RETURN_VAL(idler->delete_me, NULL); - idler->delete_me = 1; - idlers_delete_me = 1; - return idler->data; -} - -static void -_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Idler_Private_Data *idler = _pd; - - idler->delete_me = 1; - idlers_delete_me = 1; - - eo_do_super(obj, eo_destructor()); -} - -void -_ecore_idler_shutdown(void) -{ - Ecore_Idler_Private_Data *ie; - while ((ie = idlers)) - { - idlers = (Ecore_Idler_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers)); - - eo_parent_set(ie->obj, NULL); - if (eo_destructed_is(ie->obj)) - eo_manual_free(ie->obj); - else - eo_manual_free_set(ie->obj, EINA_FALSE); - } - idlers_delete_me = 0; - idler_current = NULL; -} - -int -_ecore_idler_all_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_Private_Data *)EINA_INLIST_GET(idler_current)->next; - } - - while (idler_current) - { - Ecore_Idler_Private_Data *ie = (Ecore_Idler_Private_Data *)idler_current; - if (!ie->delete_me) - { - ie->references++; - if (!_ecore_call_task_cb(ie->func, ie->data)) - { - if (!ie->delete_me) _ecore_idler_del(ie->obj); - } - ie->references--; - } - if (idler_current) /* may have changed in recursive main loops */ - idler_current = (Ecore_Idler_Private_Data *)EINA_INLIST_GET(idler_current)->next; - } - if (idlers_delete_me) - { - Ecore_Idler_Private_Data *l; - int deleted_idlers_in_use = 0; - for (l = idlers; l; ) - { - Ecore_Idler_Private_Data *ie = l; - l = (Ecore_Idler_Private_Data *)EINA_INLIST_GET(l)->next; - if (ie->delete_me) - { - if (ie->references) - { - deleted_idlers_in_use++; - continue; - } - - idlers = (Ecore_Idler_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie)); - - eo_parent_set(ie->obj, NULL); - if (eo_destructed_is(ie->obj)) - eo_manual_free(ie->obj); - else - eo_manual_free_set(ie->obj, EINA_FALSE); - } - } - 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; -} - -static void -_class_constructor(Eo_Class *klass) -{ - const Eo_Op_Func_Description func_desc[] = { - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), - - EO_OP_FUNC(ECORE_IDLER_ID(ECORE_IDLER_SUB_ID_CONSTRUCTOR), _idler_constructor), - EO_OP_FUNC_SENTINEL - }; - - eo_class_funcs_set(klass, func_desc); -} - -static const Eo_Op_Description op_desc[] = { - EO_OP_DESCRIPTION(ECORE_IDLER_SUB_ID_CONSTRUCTOR, "Add an idler handler."), - EO_OP_DESCRIPTION_SENTINEL -}; - -static const Eo_Class_Description class_desc = { - EO_VERSION, - MY_CLASS_NAME, - EO_CLASS_TYPE_REGULAR, - EO_CLASS_DESCRIPTION_OPS(&ECORE_IDLER_BASE_ID, op_desc, ECORE_IDLER_SUB_ID_LAST), - NULL, - sizeof(Ecore_Idler_Private_Data), - _class_constructor, - NULL -}; - -EO_DEFINE_CLASS(ecore_idler_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/legacy/ecore/src/lib/ecore/ecore_job.c b/legacy/ecore/src/lib/ecore/ecore_job.c deleted file mode 100644 index bc438b7209..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_job.c +++ /dev/null @@ -1,198 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#define MY_CLASS ECORE_JOB_CLASS - -#define MY_CLASS_NAME "ecore_job" - -EAPI Eo_Op ECORE_JOB_BASE_ID = EO_NOOP; - -static Eina_Bool _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; - -typedef struct _Ecore_Job_Private_Data Ecore_Job_Private_Data; - -struct _Ecore_Job_Private_Data -{ - Ecore_Event *event; - Ecore_Cb func; - 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; -} - -/** - * @addtogroup Ecore_Job_Group - * - * @{ - */ - -/** - * 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. - * @note Once the job has been executed, the job handle is invalid. - */ -EAPI Ecore_Job * -ecore_job_add(Ecore_Cb func, - const void *data) -{ - Ecore_Job *job = eo_add_custom(MY_CLASS, _ecore_parent, ecore_job_constructor(func, data)); - eo_unref(job); - return job; -} - -static void -_job_constructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Cb func = va_arg(*list, Ecore_Cb); - const void *data = va_arg(*list, const void *); - - if (EINA_UNLIKELY(!eina_main_loop_is())) - { - eo_error_set(obj); - EINA_MAIN_LOOP_CHECK_RETURN; - } - eo_do_super(obj, eo_constructor()); - eo_manual_free_set(obj, EINA_TRUE); - - if (!func) - { - eo_error_set(obj); - ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); - return; - } - - Ecore_Job_Private_Data *job = _pd; - - job->event = ecore_event_add(ecore_event_job_type, job, _ecore_job_event_free, obj); - if (!job->event) - { - eo_error_set(obj); - ERR("no event was assigned to object '%p' of class '%s'", obj, MY_CLASS_NAME); - return; - } - job->func = func; - job->data = (void *)data; -} - -static void -_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) -{ - eo_error_set(obj); - ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); -} - -/** - * 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. - */ -EAPI void * -ecore_job_del(Ecore_Job *obj) -{ - void *data; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - Ecore_Job_Private_Data *job = eo_data_get(obj, MY_CLASS); - data = job->data; - ecore_event_del(job->event); - eo_parent_set(obj, NULL); - return data; -} - -static void -_destructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) -{ - /*FIXME: check if ecore_event_del should be called from here*/ - eo_do_super(obj, eo_destructor()); -} - -/** - * @} - */ - -static Eina_Bool -_ecore_job_event_handler(void *data EINA_UNUSED, - int type EINA_UNUSED, - void *ev) -{ - Ecore_Job_Private_Data *job; - - job = ev; - job->func(job->data); - return ECORE_CALLBACK_CANCEL; -} - -static void -_ecore_job_event_free(void *data, - void *job EINA_UNUSED) -{ - eo_parent_set(data, NULL); - - Ecore_Job *obj = data; - - if (eo_destructed_is(obj)) - eo_manual_free(obj); - else - eo_manual_free_set(obj, EINA_FALSE); -} - -static void -_class_constructor(Eo_Class *klass) -{ - const Eo_Op_Func_Description func_desc[] = { - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), - EO_OP_FUNC(ECORE_JOB_ID(ECORE_JOB_SUB_ID_CONSTRUCTOR), _job_constructor), - EO_OP_FUNC_SENTINEL - }; - - eo_class_funcs_set(klass, func_desc); -} - -static const Eo_Op_Description op_desc[] = { - EO_OP_DESCRIPTION(ECORE_JOB_SUB_ID_CONSTRUCTOR, "Add a job to the event queue."), - EO_OP_DESCRIPTION_SENTINEL -}; -static const Eo_Class_Description class_desc = { - EO_VERSION, - MY_CLASS_NAME, - EO_CLASS_TYPE_REGULAR, - EO_CLASS_DESCRIPTION_OPS(&ECORE_JOB_BASE_ID, op_desc, ECORE_JOB_SUB_ID_LAST), - NULL, - sizeof(Ecore_Job_Private_Data), - _class_constructor, - NULL -}; - -EO_DEFINE_CLASS(ecore_job_class_get, &class_desc, EO_BASE_CLASS, NULL); diff --git a/legacy/ecore/src/lib/ecore/ecore_main.c b/legacy/ecore/src/lib/ecore/ecore_main.c deleted file mode 100644 index 9bed47a841..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_main.c +++ /dev/null @@ -1,2108 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef _WIN32 -# define WIN32_LEAN_AND_MEAN -# include -# undef WIN32_LEAN_AND_MEAN -# ifndef USER_TIMER_MINIMUM -# define USER_TIMER_MINIMUM 0x0a -# endif -#endif - -#ifdef __SUNPRO_C -# include -# include -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_TIME_H -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef _MSC_VER -# include -#endif - -#ifdef HAVE_ISFINITE -# define ECORE_FINITE(t) isfinite(t) -#else -# ifdef _MSC_VER -# define ECORE_FINITE(t) _finite(t) -# else -# define ECORE_FINITE(t) finite(t) -# endif -#endif - -//#define FIX_HZ 1 - -#ifdef FIX_HZ -# ifndef _MSC_VER -# include -# endif -# ifndef HZ -# define HZ 100 -# endif -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -#ifdef HAVE_SYS_EPOLL_H -# define HAVE_EPOLL 1 -# include -#else - -# define HAVE_EPOLL 0 -# define EPOLLIN 1 -# define EPOLLPRI 2 -# define EPOLLOUT 4 -# define EPOLLERR 8 - -#define EPOLL_CTL_ADD 1 -#define EPOLL_CTL_DEL 2 -#define EPOLL_CTL_MOD 3 - -typedef union epoll_data { - void *ptr; - int fd; - uint32_t u32; - uint64_t u64; -} epoll_data_t; - -struct epoll_event -{ - uint32_t events; - epoll_data_t data; -}; - -static inline int -epoll_create(int size EINA_UNUSED) -{ - return -1; -} - -static inline int -epoll_wait(int epfd EINA_UNUSED, - struct epoll_event *events EINA_UNUSED, - int maxevents EINA_UNUSED, - int timeout EINA_UNUSED) -{ - return -1; -} - -static inline int -epoll_ctl(int epfd EINA_UNUSED, - int op EINA_UNUSED, - int fd EINA_UNUSED, - struct epoll_event *event EINA_UNUSED) -{ - return -1; -} - -#endif - -#ifdef HAVE_SYS_TIMERFD_H -# include -#else -/* fallback code if we don't have real timerfd - reduces number of ifdefs */ -# ifndef CLOCK_MONOTONIC -# define CLOCK_MONOTONIC 0 /* bogus value */ -# endif -# ifndef TFD_NONBLOCK -# define TFD_NONBLOCK 0 /* bogus value */ -# endif -static inline int -timerfd_create(int clockid EINA_UNUSED, - int flags EINA_UNUSED) -{ - return -1; -} - -static inline int -timerfd_settime(int fd EINA_UNUSED, - int flags EINA_UNUSED, - const struct itimerspec *new_value EINA_UNUSED, - struct itimerspec *old_value EINA_UNUSED) -{ - return -1; -} - -#endif /* HAVE_SYS_TIMERFD_H */ - -#ifdef USE_G_MAIN_LOOP -# include -#endif - -#define NS_PER_SEC (1000.0 * 1000.0 * 1000.0) - -struct _Ecore_Fd_Handler -{ - EINA_INLIST; - ECORE_MAGIC; - Ecore_Fd_Handler *next_ready; - int fd; - Ecore_Fd_Handler_Flags flags; - Ecore_Fd_Cb func; - void *data; - Ecore_Fd_Cb buf_func; - void *buf_data; - Ecore_Fd_Prep_Cb prep_func; - 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; - Eina_Bool file : 1; -#if defined(USE_G_MAIN_LOOP) - GPollFD gfd; -#endif -}; -GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler); - -#ifdef _WIN32 -struct _Ecore_Win32_Handler -{ - EINA_INLIST; - ECORE_MAGIC; - HANDLE h; - Ecore_Win32_Handle_Cb func; - void *data; - int references; - Eina_Bool delete_me : 1; -}; -GENERIC_ALLOC_SIZE_DECLARE(Ecore_Win32_Handler); -#endif - -#ifndef USE_G_MAIN_LOOP -static int _ecore_main_select(double timeout); -#endif -static void _ecore_main_prepare_handlers(void); -static void _ecore_main_fd_handlers_cleanup(void); -#ifndef _WIN32 -# ifndef USE_G_MAIN_LOOP -static void _ecore_main_fd_handlers_bads_rem(void); -# endif -#endif -static void _ecore_main_fd_handlers_call(void); -static int _ecore_main_fd_handlers_buf_call(void); -#ifndef USE_G_MAIN_LOOP -static void _ecore_main_loop_iterate_internal(int once_only); -#endif - -#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 Eina_List *fd_handlers_with_prep = NULL; -static Eina_List *file_fd_handlers = NULL; -static Eina_List *fd_handlers_with_buffer = NULL; -static Eina_List *fd_handlers_to_delete = NULL; - -/* single linked list of ready fdhs, terminated by loop to self */ -static Ecore_Fd_Handler *fd_handlers_to_call; -static Ecore_Fd_Handler *fd_handlers_to_call_current; - -#ifdef _WIN32 -static Ecore_Win32_Handler *win32_handlers = NULL; -static Ecore_Win32_Handler *win32_handler_current = NULL; -static Eina_Bool win32_handlers_delete_me = EINA_FALSE; -#endif - -#ifdef _WIN32 -Ecore_Select_Function main_loop_select = _ecore_main_win32_select; -#else -# if !defined EXOTIC_NO_SELECT -# ifdef HAVE_SYS_SELECT_H -# include -# endif -Ecore_Select_Function main_loop_select = select; -# else -Ecore_Select_Function main_loop_select = NULL; -# endif -#endif - -#ifndef USE_G_MAIN_LOOP -static double t1 = 0.0; -static double t2 = 0.0; -#endif - -static int timer_fd = -1; -static int epoll_fd = -1; -static pid_t epoll_pid; - -#ifdef USE_G_MAIN_LOOP -static GPollFD ecore_epoll_fd; -static GPollFD ecore_timer_fd; -static GSource *ecore_glib_source; -static guint ecore_glib_source_id; -static GMainLoop *ecore_main_loop; -static gboolean ecore_idling; -static gboolean _ecore_glib_idle_enterer_called; -static gboolean ecore_fds_ready; -#endif - -static inline void -_ecore_fd_valid(void) -{ - if (HAVE_EPOLL && epoll_fd >= 0) - { - if (fcntl(epoll_fd, F_GETFD) < 0) - { - ERR("arghhh you caught me! report a backtrace to edevel!"); - pause(); - } - } -} - -static inline void -_ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh) -{ - /* check if this fdh is already in the list */ - if (fdh->next_ready) - return; - if (fdh->read_active || fdh->write_active || fdh->error_active) - { - /* - * make sure next_ready is non-null by pointing to ourselves - * use that to indicate this fdh is in the ready list - * insert at the head of the list to avoid trouble - */ - fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh; - fd_handlers_to_call = fdh; - } -} - -static inline int -_ecore_get_epoll_fd(void) -{ - if (epoll_pid && epoll_pid != getpid()) - { - /* forked! */ - _ecore_main_loop_shutdown(); - } - if (epoll_pid == 0 && epoll_fd < 0) - { - _ecore_main_loop_init(); - } - return epoll_fd; -} - -static inline int -_ecore_epoll_add(int efd, - int fd, - int events, - void *ptr) -{ - struct epoll_event ev; - - memset(&ev, 0, sizeof (ev)); - ev.events = events; - ev.data.ptr = ptr; - INF("adding poll on %d %08x", fd, events); - return epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev); -} - -static inline int -_ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh) -{ - int events = 0; - if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN; - if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT; - if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR | EPOLLPRI; - return events; -} - -#ifdef USE_G_MAIN_LOOP -static inline int -_gfd_events_from_fdh(Ecore_Fd_Handler *fdh) -{ - int events = 0; - if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN; - if (fdh->flags & ECORE_FD_WRITE) events |= G_IO_OUT; - if (fdh->flags & ECORE_FD_ERROR) events |= G_IO_ERR; - return events; -} - -#endif - -static inline int -_ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh) -{ - int r = 0; - - if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) - { - r = _ecore_epoll_add(_ecore_get_epoll_fd(), fdh->fd, - _ecore_poll_events_from_fdh(fdh), fdh); - } - else - { -#ifdef USE_G_MAIN_LOOP - fdh->gfd.fd = fdh->fd; - fdh->gfd.events = _gfd_events_from_fdh(fdh); - fdh->gfd.revents = 0; - INF("adding gpoll on %d %08x", fdh->fd, fdh->gfd.events); - g_source_add_poll(ecore_glib_source, &fdh->gfd); -#endif - } - return r; -} - -static inline void -_ecore_main_fdh_poll_del(Ecore_Fd_Handler *fdh) -{ - if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) - { - struct epoll_event ev; - int efd = _ecore_get_epoll_fd(); - - memset(&ev, 0, sizeof (ev)); - INF("removing poll on %d", fdh->fd); - /* could get an EBADF if somebody closed the FD before removing it */ - if ((epoll_ctl(efd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0)) - { - if (errno == EBADF) - { - WRN("fd %d was closed, can't remove from epoll - reinit!", - fdh->fd); - _ecore_main_loop_shutdown(); - _ecore_main_loop_init(); - } - else - { - ERR("Failed to delete epoll fd %d! (errno=%d)", fdh->fd, errno); - } - } - } - else - { -#ifdef USE_G_MAIN_LOOP - fdh->gfd.fd = fdh->fd; - fdh->gfd.events = _gfd_events_from_fdh(fdh); - fdh->gfd.revents = 0; - INF("adding gpoll on %d %08x", fdh->fd, fdh->gfd.events); - g_source_add_poll(ecore_glib_source, &fdh->gfd); -#endif - } -} - -static inline int -_ecore_main_fdh_poll_modify(Ecore_Fd_Handler *fdh) -{ - int r = 0; - if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) - { - struct epoll_event ev; - int efd = _ecore_get_epoll_fd(); - - memset(&ev, 0, sizeof (ev)); - ev.events = _ecore_poll_events_from_fdh(fdh); - ev.data.ptr = fdh; - INF("modifing epoll on %d to %08x", fdh->fd, ev.events); - r = epoll_ctl(efd, EPOLL_CTL_MOD, fdh->fd, &ev); - } - else - { -#ifdef USE_G_MAIN_LOOP - fdh->gfd.fd = fdh->fd; - fdh->gfd.events = _gfd_events_from_fdh(fdh); - fdh->gfd.revents = 0; - INF("modifing gpoll on %d to %08x", fdh->fd, fdh->gfd.events); -#endif - } - return r; -} - -static inline int -_ecore_main_fdh_epoll_mark_active(void) -{ - struct epoll_event ev[32]; - int i, ret; - int efd = _ecore_get_epoll_fd(); - - memset(&ev, 0, sizeof (ev)); - ret = epoll_wait(efd, ev, sizeof(ev) / sizeof(struct epoll_event), 0); - if (ret < 0) - { - if (errno == EINTR) return -1; - ERR("epoll_wait failed %d", errno); - return -1; - } - - for (i = 0; i < ret; i++) - { - Ecore_Fd_Handler *fdh; - - fdh = ev[i].data.ptr; - if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER)) - { - ECORE_MAGIC_FAIL(fdh, ECORE_MAGIC_FD_HANDLER, - "_ecore_main_fdh_epoll_mark_active"); - continue; - } - if (fdh->delete_me) - { - ERR("deleted fd in epoll"); - continue; - } - - if (ev[i].events & EPOLLIN) - fdh->read_active = EINA_TRUE; - if (ev[i].events & EPOLLOUT) - fdh->write_active = EINA_TRUE; - if (ev[i].events & EPOLLERR) - fdh->error_active = EINA_TRUE; - - _ecore_try_add_to_call_list(fdh); - } - - return ret; -} - -#ifdef USE_G_MAIN_LOOP - -static inline int -_ecore_main_fdh_glib_mark_active(void) -{ - Ecore_Fd_Handler *fdh; - int ret = 0; - - /* call the prepare callback for all handlers */ - EINA_INLIST_FOREACH(fd_handlers, fdh) - { - if (fdh->delete_me) - continue; - - if (fdh->gfd.revents & G_IO_IN) - fdh->read_active = EINA_TRUE; - if (fdh->gfd.revents & G_IO_OUT) - fdh->write_active = EINA_TRUE; - if (fdh->gfd.revents & G_IO_ERR) - fdh->error_active = EINA_TRUE; - - _ecore_try_add_to_call_list(fdh); - - if (fdh->gfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR)) ret++; - } - - return ret; -} - -/* like we are about to enter main_loop_select in _ecore_main_select */ -static gboolean -_ecore_main_gsource_prepare(GSource *source EINA_UNUSED, - gint *next_time) -{ - gboolean ready = FALSE; - - _ecore_lock(); - in_main_loop++; - - if (!ecore_idling && !_ecore_glib_idle_enterer_called) - { - _ecore_time_loop_time = ecore_time_get(); - _ecore_timer_expired_timers_call(_ecore_time_loop_time); - _ecore_timer_cleanup(); - - _ecore_idle_enterer_call(); - _ecore_throttle(); - _ecore_glib_idle_enterer_called = FALSE; - - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); - } - - _ecore_signal_received_process(); - - /* don't check fds if somebody quit */ - if (g_main_loop_is_running(ecore_main_loop)) - { - /* only set idling state in dispatch */ - if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist()) - { - if (_ecore_timers_exists()) - { - int r = -1; - double t = _ecore_timer_next_get(); - if (timer_fd >= 0 && t > 0.0) - { - struct itimerspec ts; - - ts.it_interval.tv_sec = 0; - ts.it_interval.tv_nsec = 0; - ts.it_value.tv_sec = t; - ts.it_value.tv_nsec = fmod(t * NS_PER_SEC, NS_PER_SEC); - - /* timerfd cannot sleep for 0 time */ - if (ts.it_value.tv_sec || ts.it_value.tv_nsec) - { - r = timerfd_settime(timer_fd, 0, &ts, NULL); - if (r < 0) - { - ERR("timer set returned %d (errno=%d)", r, errno); - close(timer_fd); - timer_fd = -1; - } - else - INF("sleeping for %ld s %06ldus", - ts.it_value.tv_sec, - ts.it_value.tv_nsec / 1000); - } - } - if (r == -1) - { - *next_time = ceil(t * 1000.0); - if (t == 0.0) - ready = TRUE; - } - } - else - *next_time = -1; - } - else - { - *next_time = 0; - if (_ecore_event_exist()) - ready = TRUE; - } - - if (fd_handlers_with_prep) - _ecore_main_prepare_handlers(); - } - else - ready = TRUE; - - in_main_loop--; - INF("leave, timeout = %d", *next_time); - _ecore_unlock(); - - /* ready if we're not running (about to quit) */ - return ready; -} - -static gboolean -_ecore_main_gsource_check(GSource *source EINA_UNUSED) -{ - gboolean ret = FALSE; - - _ecore_lock(); - in_main_loop++; - - /* check if old timers expired */ - if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist()) - { - if (timer_fd >= 0) - { - uint64_t count = 0; - int r = read(timer_fd, &count, sizeof count); - if (r == -1 && errno == EAGAIN) - ; - else if (r == sizeof count) - ret = TRUE; - else - { - /* unexpected things happened... fail back to old way */ - ERR("timer read returned %d (errno=%d)", r, errno); - close(timer_fd); - timer_fd = -1; - } - } - } - else - ret = TRUE; - - /* check if fds are ready */ - if (HAVE_EPOLL && epoll_fd >= 0) - ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active() > 0); - else - ecore_fds_ready = (_ecore_main_fdh_glib_mark_active() > 0); - _ecore_main_fd_handlers_cleanup(); - if (ecore_fds_ready) - ret = TRUE; - - /* check timers after updating loop time */ - if (!ret && _ecore_timers_exists()) - ret = (0.0 == _ecore_timer_next_get()); - - in_main_loop--; - _ecore_unlock(); - - return ret; -} - -/* like we just came out of main_loop_select in _ecore_main_select */ -static gboolean -_ecore_main_gsource_dispatch(GSource *source EINA_UNUSED, - GSourceFunc callback EINA_UNUSED, - gpointer user_data EINA_UNUSED) -{ - gboolean events_ready, timers_ready, idlers_ready; - double next_time; - - _ecore_lock(); - _ecore_time_loop_time = ecore_time_get(); - _ecore_timer_enable_new(); - next_time = _ecore_timer_next_get(); - - events_ready = _ecore_event_exist(); - timers_ready = _ecore_timers_exists() && (0.0 == next_time); - idlers_ready = _ecore_idler_exist(); - - in_main_loop++; - INF("enter idling=%d fds=%d events=%d timers=%d (next=%.2f) idlers=%d", - ecore_idling, ecore_fds_ready, events_ready, - timers_ready, next_time, idlers_ready); - - if (ecore_idling && events_ready) - { - _ecore_idle_exiter_call(); - ecore_idling = 0; - } - else if (!ecore_idling && !events_ready) - { - ecore_idling = 1; - } - - if (ecore_idling) - { - _ecore_idler_all_call(); - - events_ready = _ecore_event_exist(); - - if (ecore_fds_ready || events_ready || timers_ready) - { - _ecore_idle_exiter_call(); - ecore_idling = 0; - } - } - - /* process events */ - if (!ecore_idling) - { - _ecore_main_fd_handlers_call(); - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); - _ecore_signal_received_process(); - _ecore_event_call(); - _ecore_main_fd_handlers_cleanup(); - - _ecore_timer_expired_timers_call(_ecore_time_loop_time); - _ecore_timer_cleanup(); - - _ecore_idle_enterer_call(); - _ecore_throttle(); - _ecore_glib_idle_enterer_called = TRUE; - - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); - } - - in_main_loop--; - _ecore_unlock(); - - return TRUE; /* what should be returned here? */ -} - -static void -_ecore_main_gsource_finalize(GSource *source EINA_UNUSED) -{ -} - -static GSourceFuncs ecore_gsource_funcs = -{ - .prepare = _ecore_main_gsource_prepare, - .check = _ecore_main_gsource_check, - .dispatch = _ecore_main_gsource_dispatch, - .finalize = _ecore_main_gsource_finalize, -}; - -#endif - -void -_ecore_main_loop_init(void) -{ - epoll_fd = epoll_create(1); - if (epoll_fd < 0) - WRN("Failed to create epoll fd!"); - epoll_pid = getpid(); - - /* add polls on all our file descriptors */ - Ecore_Fd_Handler *fdh; - EINA_INLIST_FOREACH(fd_handlers, fdh) - { - if (fdh->delete_me) - continue; - _ecore_epoll_add(epoll_fd, fdh->fd, - _ecore_poll_events_from_fdh(fdh), fdh); - _ecore_main_fdh_poll_add(fdh); - } - - /* setup for the g_main_loop only integration */ -#ifdef USE_G_MAIN_LOOP - ecore_glib_source = g_source_new(&ecore_gsource_funcs, sizeof (GSource)); - if (!ecore_glib_source) - CRIT("Failed to create glib source for epoll!"); - else - { - g_source_set_priority(ecore_glib_source, G_PRIORITY_HIGH_IDLE + 20); - if (HAVE_EPOLL && epoll_fd >= 0) - { - /* epoll multiplexes fds into the g_main_loop */ - ecore_epoll_fd.fd = epoll_fd; - ecore_epoll_fd.events = G_IO_IN; - ecore_epoll_fd.revents = 0; - g_source_add_poll(ecore_glib_source, &ecore_epoll_fd); - } - - /* timerfd gives us better than millisecond accuracy in g_main_loop */ - timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); - if (timer_fd < 0) - WRN("failed to create timer fd!"); - else - { - ecore_timer_fd.fd = timer_fd; - ecore_timer_fd.events = G_IO_IN; - ecore_timer_fd.revents = 0; - g_source_add_poll(ecore_glib_source, &ecore_timer_fd); - } - - ecore_glib_source_id = g_source_attach(ecore_glib_source, NULL); - if (ecore_glib_source_id <= 0) - CRIT("Failed to attach glib source to default context"); - } -#endif -} - -void -_ecore_main_loop_shutdown(void) -{ -#ifdef USE_G_MAIN_LOOP - if (ecore_glib_source) - { - g_source_destroy(ecore_glib_source); - ecore_glib_source = NULL; - } -#endif - - if (epoll_fd >= 0) - { - close(epoll_fd); - epoll_fd = -1; - } - epoll_pid = 0; - - if (timer_fd >= 0) - { - close(timer_fd); - timer_fd = -1; - } -} - -void * -_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) -{ - if (fd_handler->delete_me) - { - ERR("fdh %p deleted twice", fd_handler); - return NULL; - } - - _ecore_main_fdh_poll_del(fd_handler); - fd_handler->delete_me = EINA_TRUE; - fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fd_handler); - if (fd_handler->prep_func && fd_handlers_with_prep) - fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler); - if (fd_handler->buf_func && fd_handlers_with_buffer) - fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler); - return fd_handler->data; -} - -/** - * @addtogroup Ecore_Main_Loop_Group - * - * @{ - */ - -/** - * Runs a single iteration of the main loop to process everything on the - * queue. - * - * It does everything that is already done inside an @c Ecore main loop, like - * checking for expired timers, idlers, etc. But it will do it only once and - * return, instead of keep watching for new events. - * - * DO NOT use this function unless you are the person God comes to ask for - * advice when He has trouble managing the Universe. - * - * @see ecore_main_loop_iterate_may_block() - */ -EAPI void -ecore_main_loop_iterate(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN; -#ifndef USE_G_MAIN_LOOP - _ecore_lock(); - _ecore_time_loop_time = ecore_time_get(); - _ecore_main_loop_iterate_internal(1); - _ecore_unlock(); -#else - g_main_context_iteration(NULL, 0); -#endif -} - -/** - * Runs a single iteration of the main loop to process everything on the - * queue with block/non-blocking status. - * - * @param may_block A flag if the main loop has a possibility of blocking. - * (@c EINA_TRUE = may block/@c EINA_FALSE = non block) - * - * This is an extension API for ecore_main_loop_iterate() with additional - * parameter. It does everything that is already done inside an - * @c Ecore main loop, like checking for expired timers, idlers, etc. But it - * will do it only once and return, instead of keep watching for new events. - * - * DO NOT use this function unless you are the person God comes to ask for - * advice when He has trouble managing the Universe. - * - * @see ecore_main_loop_iterate() - */ -EAPI int -ecore_main_loop_iterate_may_block(int may_block) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); -#ifndef USE_G_MAIN_LOOP - _ecore_lock(); - _ecore_time_loop_time = ecore_time_get(); -in_main_loop++; - _ecore_main_loop_iterate_internal(!may_block); -in_main_loop--; - _ecore_unlock(); - return _ecore_event_exist(); -#else - return g_main_context_iteration(NULL, may_block); -#endif -} - -/** - * Runs the application main loop. - * - * This function will not return until @ref ecore_main_loop_quit is called. It - * will check for expired timers, idlers, file descriptors being watched by fd - * handlers, etc. Once everything is done, before entering again on idle state, - * any callback set as @c Idle_Enterer will be called. - * - * Each main loop iteration is done by calling ecore_main_loop_iterate() - * internally. - * - * The polling (select) function used can be changed with - * ecore_main_loop_select_func_set(). - * - * The function used to check for file descriptors, events, and that has a - * timeout for the timers can be changed using - * ecore_main_loop_select_func_set(). - */ -EAPI void -ecore_main_loop_begin(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN; -#ifndef USE_G_MAIN_LOOP - _ecore_lock(); - in_main_loop++; - _ecore_time_loop_time = ecore_time_get(); - while (do_quit == 0) _ecore_main_loop_iterate_internal(0); - do_quit = 0; - in_main_loop--; - _ecore_unlock(); -#else - if (!do_quit) - { - if (!ecore_main_loop) - ecore_main_loop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(ecore_main_loop); - } - do_quit = 0; -#endif -} - -/** - * Quits the main loop once all the events currently on the queue have - * been processed. - * - * This function returns immediately, but will mark the ecore_main_loop_begin() - * function to return at the end of the current main loop iteration. - */ -EAPI void -ecore_main_loop_quit(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - do_quit = 1; -#ifdef USE_G_MAIN_LOOP - if (ecore_main_loop) - g_main_loop_quit(ecore_main_loop); -#endif -} - -/** - * 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. - * - * @param func The function to be used. - */ -EAPI void -ecore_main_loop_select_func_set(Ecore_Select_Function func) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - main_loop_select = func; -} - -/** - * Gets the select function set by ecore_select_func_set(), - * or the native select function if none was set. - * - */ -EAPI Ecore_Select_Function -ecore_main_loop_select_func_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - return main_loop_select; -} - -Ecore_Fd_Handler * -_ecore_main_fd_handler_add(int fd, - Ecore_Fd_Handler_Flags flags, - Ecore_Fd_Cb func, - const void *data, - Ecore_Fd_Cb buf_func, - const void *buf_data) -{ - Ecore_Fd_Handler *fdh = NULL; - - if ((fd < 0) || (flags == 0) || (!func)) return NULL; - - fdh = ecore_fd_handler_calloc(1); - if (!fdh) return NULL; - ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); - fdh->next_ready = NULL; - fdh->fd = fd; - fdh->flags = flags; - if (_ecore_main_fdh_poll_add(fdh) < 0) - { - int err = errno; - ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err)); - ecore_fd_handler_mp_free(fdh); - return NULL; - } - fdh->read_active = EINA_FALSE; - fdh->write_active = EINA_FALSE; - fdh->error_active = EINA_FALSE; - fdh->delete_me = EINA_FALSE; - fdh->func = func; - fdh->data = (void *)data; - fdh->buf_func = buf_func; - if (buf_func) - fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh); - 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; -} - -EAPI Ecore_Fd_Handler * -ecore_main_fd_handler_add(int fd, - Ecore_Fd_Handler_Flags flags, - Ecore_Fd_Cb func, - const void *data, - Ecore_Fd_Cb buf_func, - const void *buf_data) -{ - Ecore_Fd_Handler *fdh = NULL; - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - fdh = _ecore_main_fd_handler_add(fd, flags, func, data, buf_func, buf_data); - _ecore_unlock(); - return fdh; -} - -EAPI Ecore_Fd_Handler * -ecore_main_fd_handler_file_add(int fd, - Ecore_Fd_Handler_Flags flags, - Ecore_Fd_Cb func, - const void *data, - Ecore_Fd_Cb buf_func, - const void *buf_data) -{ - Ecore_Fd_Handler *fdh = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - - if ((fd < 0) || (flags == 0) || (!func)) goto unlock; - - fdh = ecore_fd_handler_calloc(1); - if (!fdh) goto unlock; - ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); - fdh->next_ready = NULL; - fdh->fd = fd; - fdh->flags = flags; - fdh->file = EINA_TRUE; - if (_ecore_main_fdh_poll_add(fdh) < 0) - { - int err = errno; - ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err)); - ecore_fd_handler_mp_free(fdh); - fdh = NULL; - goto unlock; - } - fdh->read_active = EINA_FALSE; - fdh->write_active = EINA_FALSE; - fdh->error_active = EINA_FALSE; - fdh->delete_me = EINA_FALSE; - fdh->func = func; - fdh->data = (void *)data; - fdh->buf_func = buf_func; - if (buf_func) - fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh); - fdh->buf_data = (void *)buf_data; - fd_handlers = (Ecore_Fd_Handler *) - eina_inlist_append(EINA_INLIST_GET(fd_handlers), - EINA_INLIST_GET(fdh)); - file_fd_handlers = eina_list_append(file_fd_handlers, fdh); -unlock: - _ecore_unlock(); - - return fdh; -} - -#ifdef _WIN32 -EAPI Ecore_Win32_Handler * -ecore_main_win32_handler_add(void *h, - Ecore_Win32_Handle_Cb func, - const void *data) -{ - Ecore_Win32_Handler *wh; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - if (!h || !func) return NULL; - - wh = ecore_win32_handler_calloc(1); - if (!wh) return NULL; - ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER); - wh->h = (HANDLE)h; - wh->delete_me = EINA_FALSE; - 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 EINA_UNUSED, - Ecore_Win32_Handle_Cb func EINA_UNUSED, - const void *data EINA_UNUSED) -{ - return NULL; -} - -#endif - -EAPI void * -ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) -{ - void *ret = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - - if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) - { - ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, - "ecore_main_fd_handler_del"); - goto unlock; - } - ret = _ecore_main_fd_handler_del(fd_handler); -unlock: - _ecore_unlock(); - return ret; -} - -#ifdef _WIN32 -EAPI void * -ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - 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 = EINA_TRUE; - win32_handlers_delete_me = EINA_TRUE; - return win32_handler->data; -} - -#else -EAPI void * -ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler EINA_UNUSED) -{ - return NULL; -} - -#endif - -EAPI void -ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, - Ecore_Fd_Prep_Cb func, - const void *data) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - - 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"); - goto unlock; - } - fd_handler->prep_func = func; - fd_handler->prep_data = (void *)data; - if ((!fd_handlers_with_prep) || - (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler)))) - /* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */ - fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler); -unlock: - _ecore_unlock(); -} - -EAPI int -ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler) -{ - int fd = -1; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1); - _ecore_lock(); - - 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"); - goto unlock; - } - fd = fd_handler->fd; -unlock: - _ecore_unlock(); - return fd; -} - -EAPI Eina_Bool -ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, - Ecore_Fd_Handler_Flags flags) -{ - int ret = EINA_FALSE; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); - _ecore_lock(); - - 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"); - goto unlock; - } - if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE; - if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE; - if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE; -unlock: - _ecore_unlock(); - return ret; -} - -EAPI void -ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, - Ecore_Fd_Handler_Flags flags) -{ - int ret; - - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - - 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"); - goto unlock; - } - fd_handler->flags = flags; - ret = _ecore_main_fdh_poll_modify(fd_handler); - if (ret < 0) - { - ERR("Failed to mod epoll fd %d: %s!", fd_handler->fd, strerror(ret)); - } -unlock: - _ecore_unlock(); -} - -/** - * @} - */ - -void -_ecore_main_shutdown(void) -{ - if (in_main_loop) - { - ERR("\n" - "*** ECORE WARNING: 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); - ecore_fd_handler_mp_free(fdh); - } - if (fd_handlers_with_buffer) - fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer); - if (fd_handlers_with_prep) - fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep); - if (fd_handlers_to_delete) - fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete); - if (file_fd_handlers) - file_fd_handlers = eina_list_free(file_fd_handlers); - - fd_handlers_to_call = NULL; - fd_handlers_to_call_current = NULL; - fd_handlers_to_delete = NULL; - 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); - ecore_win32_handler_mp_free(wh); - } - win32_handlers_delete_me = EINA_FALSE; - win32_handler_current = NULL; -#endif -} - -static void -_ecore_main_prepare_handlers(void) -{ - Ecore_Fd_Handler *fdh; - Eina_List *l, *l2; - - /* call the prepare callback for all handlers with prep functions */ - EINA_LIST_FOREACH_SAFE(fd_handlers_with_prep, l, l2, fdh) - { - if (!fdh) - { - fd_handlers_with_prep = eina_list_remove_list(l, fd_handlers_with_prep); - continue; - } - if (!fdh->delete_me && fdh->prep_func) - { - fdh->references++; - _ecore_call_prep_cb(fdh->prep_func, fdh->prep_data, fdh); - fdh->references--; - } - else - fd_handlers_with_prep = eina_list_remove_list(fd_handlers_with_prep, l); - } -} - -#ifndef USE_G_MAIN_LOOP -static int -_ecore_main_select(double timeout) -{ - struct timeval tv, *t; - fd_set rfds, wfds, exfds; - Ecore_Fd_Handler *fdh; - Eina_List *l; - int max_fd; - int ret; - - t = NULL; - if ((!ECORE_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 */ - if (fd_handlers_with_prep) - _ecore_main_prepare_handlers(); - - if (!HAVE_EPOLL || epoll_fd < 0) - { - 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; - } - } - } - } - else - { - /* polling on the epoll fd will wake when an fd in the epoll set is active */ - max_fd = _ecore_get_epoll_fd(); - FD_SET(max_fd, &rfds); - } - EINA_LIST_FOREACH(file_fd_handlers, l, 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 (fdh->fd > max_fd) max_fd = fdh->fd; - } - if (_ecore_signal_count_get()) return -1; - - _ecore_unlock(); - ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t); - _ecore_lock(); - - _ecore_time_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) - { - if (HAVE_EPOLL && epoll_fd >= 0) - _ecore_main_fdh_epoll_mark_active(); - else - { - EINA_INLIST_FOREACH(fd_handlers, fdh) - { - if (!fdh->delete_me) - { - if (FD_ISSET(fdh->fd, &rfds)) - fdh->read_active = EINA_TRUE; - if (FD_ISSET(fdh->fd, &wfds)) - fdh->write_active = EINA_TRUE; - if (FD_ISSET(fdh->fd, &exfds)) - fdh->error_active = EINA_TRUE; - _ecore_try_add_to_call_list(fdh); - } - } - } - EINA_LIST_FOREACH(file_fd_handlers, l, fdh) - { - if (!fdh->delete_me) - { - if (FD_ISSET(fdh->fd, &rfds)) - fdh->read_active = EINA_TRUE; - if (FD_ISSET(fdh->fd, &wfds)) - fdh->write_active = EINA_TRUE; - if (FD_ISSET(fdh->fd, &exfds)) - fdh->error_active = EINA_TRUE; - _ecore_try_add_to_call_list(fdh); - } - } - _ecore_main_fd_handlers_cleanup(); -#ifdef _WIN32 - _ecore_main_win32_handlers_cleanup(); -#endif - return 1; - } - return 0; -} - -#endif - -#ifndef _WIN32 -# ifndef USE_G_MAIN_LOOP -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 (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh)) - { - ERR("Fd function err returned 0, remove it"); - if (!fdh->delete_me) - { - fdh->delete_me = EINA_TRUE; - fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); - } - found++; - } - fdh->references--; - } - else - { - ERR("Problematic fd found at %d! setting it for delete", fdh->fd); - if (!fdh->delete_me) - { - fdh->delete_me = EINA_TRUE; - fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); - } - - 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 -#endif - -static void -_ecore_main_fd_handlers_cleanup(void) -{ - Ecore_Fd_Handler *fdh; - Eina_List *l, *l2; - - if (!fd_handlers_to_delete) return; - EINA_LIST_FOREACH_SAFE(fd_handlers_to_delete, l, l2, fdh) - { - if (!fdh) - { - fd_handlers_to_delete = eina_list_remove_list(l, fd_handlers_to_delete); - continue; - } - /* fdh->delete_me should be set for all fdhs at the start of the list */ - if (fdh->references) - continue; - if (fdh->buf_func && fd_handlers_with_buffer) - fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fdh); - if (fdh->prep_func && fd_handlers_with_prep) - fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh); - fd_handlers = (Ecore_Fd_Handler *) - eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh)); - if (fdh->file) - file_fd_handlers = eina_list_remove(file_fd_handlers, fdh); - ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); - ecore_fd_handler_mp_free(fdh); - fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l); - } -} - -#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); - ecore_win32_handler_mp_free(wh); - } - } - if (!deleted_in_use) win32_handlers_delete_me = EINA_FALSE; -} - -#endif - -static void -_ecore_main_fd_handlers_call(void) -{ - /* grab a new list */ - if (!fd_handlers_to_call_current) - { - fd_handlers_to_call_current = fd_handlers_to_call; - fd_handlers_to_call = NULL; - } - - while (fd_handlers_to_call_current) - { - Ecore_Fd_Handler *fdh = fd_handlers_to_call_current; - - if (!fdh->delete_me) - { - if ((fdh->read_active) || - (fdh->write_active) || - (fdh->error_active)) - { - fdh->references++; - if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh)) - { - if (!fdh->delete_me) - { - fdh->delete_me = EINA_TRUE; - fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); - } - } - fdh->references--; - _ecore_fd_valid(); - - fdh->read_active = EINA_FALSE; - fdh->write_active = EINA_FALSE; - fdh->error_active = EINA_FALSE; - } - } - - /* stop when we point to ourselves */ - if (fdh->next_ready == fdh) - { - fdh->next_ready = NULL; - fd_handlers_to_call_current = NULL; - break; - } - - fd_handlers_to_call_current = fdh->next_ready; - fdh->next_ready = NULL; - } -} - -static int -_ecore_main_fd_handlers_buf_call(void) -{ - Ecore_Fd_Handler *fdh; - Eina_List *l, *l2; - int ret; - - ret = 0; - EINA_LIST_FOREACH_SAFE(fd_handlers_with_buffer, l, l2, fdh) - { - if (!fdh) - { - fd_handlers_with_buffer = eina_list_remove_list(l, fd_handlers_with_buffer); - continue; - } - if ((!fdh->delete_me) && fdh->buf_func) - { - fdh->references++; - if (_ecore_call_fd_cb(fdh->buf_func, fdh->buf_data, fdh)) - { - ret |= _ecore_call_fd_cb(fdh->func, fdh->data, fdh); - fdh->read_active = EINA_TRUE; - _ecore_try_add_to_call_list(fdh); - } - fdh->references--; - } - else - fd_handlers_with_buffer = eina_list_remove_list(fd_handlers_with_buffer, l); - } - return ret; -} - -#ifndef USE_G_MAIN_LOOP - -enum { - SPIN_MORE, - SPIN_RESTART, - LOOP_CONTINUE -}; - -static int -_ecore_main_loop_spin_core(void) -{ - /* as we are spinning we need to update loop time per spin */ - _ecore_time_loop_time = ecore_time_get(); - /* call all idlers, which returns false if no more idelrs exist */ - if (!_ecore_idler_all_call()) return SPIN_RESTART; - /* sneaky - drop through or if checks - the first one to succeed - * drops through and returns "continue" so further ones dont run */ - if ((_ecore_main_select(0.0) > 0) || (_ecore_event_exist()) || - (_ecore_signal_count_get() > 0) || (do_quit)) - return LOOP_CONTINUE; - /* default - spin more */ - return SPIN_MORE; -} - -static int -_ecore_main_loop_spin_no_timers(void) -{ - /* if we have idlers we HAVE to spin and handle everything - * in a polling way - spin in a tight polling loop */ - for (;; ) - { - int action = _ecore_main_loop_spin_core(); - if (action != SPIN_MORE) return action; - /* if an idler has added a timer then we need to go through - * the start of the spin cycle again to handle cases properly */ - if (_ecore_timers_exists()) return SPIN_RESTART; - } - /* just contiune handling events etc. */ - return LOOP_CONTINUE; -} - -static int -_ecore_main_loop_spin_timers(void) -{ - /* if we have idlers we HAVE to spin and handle everything - * in a polling way - spin in a tight polling loop */ - for (;; ) - { - int action = _ecore_main_loop_spin_core(); - if (action != SPIN_MORE) return action; - /* if next timer expires now or in the past - stop spinning and - * continue the mainloop walk as our "select" timeout has - * expired now */ - if (_ecore_timer_next_get() <= 0.0) return LOOP_CONTINUE; - } - /* just contiune handling events etc. */ - return LOOP_CONTINUE; -} - -static void -_ecore_fps_marker_1(void) -{ - if (!_ecore_fps_debug) return; - t2 = ecore_time_get(); - if ((t1 > 0.0) && (t2 > 0.0)) _ecore_fps_debug_runtime_add(t2 - t1); -} - -static void -_ecore_fps_marker_2(void) -{ - if (!_ecore_fps_debug) return; - t1 = ecore_time_get(); -} - -static void -_ecore_main_loop_iterate_internal(int once_only) -{ - double next_time = -1.0; - - in_main_loop++; - /* expire any timers */ - _ecore_timer_expired_timers_call(_ecore_time_loop_time); - _ecore_timer_cleanup(); - - /* process signals into events .... */ - _ecore_signal_received_process(); - /* if as a result of timers/animators or signals we have accumulated - * events, then instantly handle them */ - if (_ecore_event_exist()) - { - /* but first conceptually enter an idle state */ - _ecore_idle_enterer_call(); - _ecore_throttle(); - /* now quickly poll to see which input fd's are active */ - _ecore_main_select(0.0); - /* allow newly queued timers to expire from now on */ - _ecore_timer_enable_new(); - /* go straight to processing the events we had queued */ - goto process_all; - } - - if (once_only) - { - /* in once_only mode we should quickly poll for inputs, signals - * if we got any events or signals, allow new timers to process. - * use bitwise or to force both conditions to be tested and - * merged together */ - if (_ecore_main_select(0.0) | _ecore_signal_count_get()) - { - _ecore_timer_enable_new(); - goto process_all; - } - } - else - { - /* call idle enterers ... */ - _ecore_idle_enterer_call(); - _ecore_throttle(); - } - - /* if these calls caused any buffered events to appear - deal with them */ - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); - - /* if there are any (buffered fd handling may generate them) - * then jump to processing them */ - if (_ecore_event_exist()) - { - _ecore_main_select(0.0); - _ecore_timer_enable_new(); - goto process_all; - } - - if (once_only) - { - /* in once_only mode enter idle here instead and then return */ - _ecore_idle_enterer_call(); - _ecore_throttle(); - _ecore_timer_enable_new(); - goto done; - } - - _ecore_fps_marker_1(); - - /* start of the sleeping or looping section */ -start_loop: /***************************************************************/ - /* any timers re-added as a result of these are allowed to go */ - _ecore_timer_enable_new(); - /* if we have been asked to quit the mainloop then exit at this point */ - if (do_quit) - { - _ecore_timer_enable_new(); - goto done; - } - if (!_ecore_event_exist()) - { - /* init flags */ - next_time = _ecore_timer_next_get(); - /* no idlers */ - if (!_ecore_idler_exist()) - { - /* sleep until timeout or forever (-1.0) waiting for on fds */ - _ecore_main_select(next_time); - } - else - { - int action = LOOP_CONTINUE; - - /* no timers - spin */ - if (next_time < 0) action = _ecore_main_loop_spin_no_timers(); - /* timers - spin */ - else action = _ecore_main_loop_spin_timers(); - if (action == SPIN_RESTART) goto start_loop; - } - } - _ecore_fps_marker_2(); - - /* actually wake up and deal with input, events etc. */ -process_all: /***********************************************************/ - - /* 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 */ - _ecore_main_fd_handlers_call(); - if (fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call(); - /* process signals into events .... */ - _ecore_signal_received_process(); - /* handle events ... */ - _ecore_event_call(); - _ecore_main_fd_handlers_cleanup(); - - if (once_only) - { - /* if in once_only mode handle idle exiting */ - _ecore_idle_enterer_call(); - _ecore_throttle(); - } - -done: /*******************************************************************/ - in_main_loop--; -} - -#endif - -#ifdef _WIN32 -static int -_ecore_main_win32_select(int nfds EINA_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 (readfds) - { - if (FD_ISSET(fdh->fd, readfds)) - network_event |= FD_READ; - } - if (writefds) - { - if (FD_ISSET(fdh->fd, writefds)) - network_event |= FD_WRITE; - } - if (exceptfds) - { - 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) - 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); - - if (readfds) - FD_ZERO(readfds); - if (writefds) - FD_ZERO(writefds); - if (exceptfds) - FD_ZERO(exceptfds); - - /* The result tells us the type of event we have. */ - if (result == WAIT_FAILED) - { - char *m; - - m = evil_last_error_get(); - ERR("%s", m); - free(m); - 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) && readfds) - FD_SET(sockets[result], readfds); - if ((network_event.lNetworkEvents & FD_WRITE) && writefds) - FD_SET(sockets[result], writefds); - if ((network_event.lNetworkEvents & FD_OOB) && exceptfds) - 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 = EINA_TRUE; - win32_handlers_delete_me = EINA_TRUE; - } - 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 diff --git a/legacy/ecore/src/lib/ecore/ecore_pipe.c b/legacy/ecore/src/lib/ecore/ecore_pipe.c deleted file mode 100644 index 3caf9781d0..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_pipe.c +++ /dev/null @@ -1,752 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#ifdef __SUNPRO_C -# include -#endif - -#ifdef HAVE_ISFINITE -# define ECORE_FINITE(t) isfinite(t) -#else -# ifdef _MSC_VER -# define ECORE_FINITE(t) _finite(t) -# else -# define ECORE_FINITE(t) finite(t) -# endif -#endif - -#define FIX_HZ 1 - -#ifdef FIX_HZ -# ifndef _MSC_VER -# include -# endif -# ifndef HZ -# define HZ 100 -# endif -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#ifdef HAVE_ESCAPE -# include -#endif - -#ifdef HAVE_EXOTIC -# include -#endif - -/* - * 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 - -# 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 -# include - -# 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 */ - -#include "Ecore.h" -#include "ecore_private.h" - -/* How of then we should retry to write to the pipe */ -#define ECORE_PIPE_WRITE_RETRY 6 - -struct _Ecore_Pipe -{ - ECORE_MAGIC; - int fd_read; - int fd_write; - Ecore_Fd_Handler *fd_handler; - const void *data; - Ecore_Pipe_Cb handler; - unsigned int len; - int handling; - size_t already_read; - void *passed_data; - int message; - Eina_Bool delete_me : 1; -}; -GENERIC_ALLOC_SIZE_DECLARE(Ecore_Pipe); - -static Eina_Bool _ecore_pipe_read(void *data, - Ecore_Fd_Handler *fd_handler); - -/** - * @addtogroup Ecore_Pipe_Group - * - * @{ - */ - -/** - * 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. - */ -EAPI Ecore_Pipe * -ecore_pipe_add(Ecore_Pipe_Cb handler, - const void *data) -{ - Ecore_Pipe *p; - - _ecore_lock(); - p = _ecore_pipe_add(handler, data); - _ecore_unlock(); - - 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 - */ -EAPI void * -ecore_pipe_del(Ecore_Pipe *p) -{ - void *r; - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - r = _ecore_pipe_del(p); - _ecore_unlock(); - return r; -} - -/** - * Close the read end of an Ecore_Pipe object created with ecore_pipe_add(). - * - * @param p The Ecore_Pipe object. - */ -EAPI void -ecore_pipe_read_close(Ecore_Pipe *p) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_close"); - goto out; - } - if (p->fd_handler) - { - _ecore_main_fd_handler_del(p->fd_handler); - p->fd_handler = NULL; - } - if (p->fd_read != PIPE_FD_INVALID) - { - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - } -out: - _ecore_unlock(); -} - -/** - * Stop monitoring if necessary the pipe for reading. See ecore_pipe_thaw() - * for monitoring it again. - * - * @param p The Ecore_Pipe object. - * @since 1.1 - */ -EAPI void -ecore_pipe_freeze(Ecore_Pipe *p) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_freeze"); - goto out; - } - if (p->fd_handler) - { - _ecore_main_fd_handler_del(p->fd_handler); - p->fd_handler = NULL; - } -out: - _ecore_unlock(); -} - -/** - * Start monitoring again the pipe for reading. See ecore_pipe_freeze() for - * stopping the monitoring activity. This will not work if - * ecore_pipe_read_close() was previously called on the same pipe. - * - * @param p The Ecore_Pipe object. - * @since 1.1 - */ -EAPI void -ecore_pipe_thaw(Ecore_Pipe *p) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_thaw"); - goto out; - } - if (!p->fd_handler && p->fd_read != PIPE_FD_INVALID) - { - p->fd_handler = ecore_main_fd_handler_add(p->fd_read, - ECORE_FD_READ, - _ecore_pipe_read, - p, - NULL, NULL); - } -out: - _ecore_unlock(); -} - -/** - * @brief Wait from another thread on the read side of a pipe. - * - * @param p The pipe to watch on. - * @param message_count The minimal number of message to wait before exiting. - * @param wait The amount of time in second to wait before exiting. - * @return the number of message catched during that wait call. - * @since 1.1 - * - * Negative value for @p wait means infite wait. - */ -EAPI int -ecore_pipe_wait(Ecore_Pipe *p, - int message_count, - double wait) -{ - int r; - _ecore_lock(); - r = _ecore_pipe_wait(p, message_count, wait); - _ecore_unlock(); - return r; -} - -/** - * Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). - * - * @param p The Ecore_Pipe object. - */ -EAPI void -ecore_pipe_write_close(Ecore_Pipe *p) -{ - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close"); - goto out; - } - if (p->fd_write != PIPE_FD_INVALID) - { - pipe_close(p->fd_write); - p->fd_write = PIPE_FD_INVALID; - } -out: - _ecore_unlock(); -} - -/** - * 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 @c EINA_TRUE on a successful write, @c EINA_FALSE on error. - */ -EAPI Eina_Bool -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; - Eina_Bool ok = EINA_FALSE; - - _ecore_lock(); - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write"); - goto out; - } - - if (p->delete_me) goto out; - - if (p->fd_write == PIPE_FD_INVALID) goto out; - - /* 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"); - goto out; - } - else if (ret == PIPE_FD_ERROR && errno == EPIPE) - { - pipe_close(p->fd_write); - p->fd_write = PIPE_FD_INVALID; - goto out; - } - else if (ret == PIPE_FD_ERROR && errno == EINTR) - /* try it again */ - ; - else - { - ERR("An unhandled error (ret: %zd errno: %d)" - "occurred while writing to the pipe the length", - ret, errno); - } - } - while (retry--); - - if (retry != ECORE_PIPE_WRITE_RETRY) goto out; - - /* 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)) - { - ok = EINA_TRUE; - goto out; - } - 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; - goto out; - } - else if (ret == PIPE_FD_ERROR && errno == EINTR) - /* try it again */ - ; - else - { - ERR("An unhandled error (ret: %zd errno: %d)" - "occurred while writing to the pipe the length", - ret, errno); - } - } - while (retry--); - -out: - _ecore_unlock(); - return ok; -} - -/** - * @} - */ - -/* Private functions */ -Ecore_Pipe * -_ecore_pipe_add(Ecore_Pipe_Cb handler, - const void *data) -{ - Ecore_Pipe *p = NULL; - int fds[2]; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - if (!handler) return NULL; - - p = ecore_pipe_calloc(1); - if (!p) return NULL; - - if (pipe(fds)) - { - ecore_pipe_mp_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; -} - -void * -_ecore_pipe_del(Ecore_Pipe *p) -{ - void *data = NULL; - - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_del"); - return NULL; - } - p->delete_me = EINA_TRUE; - if (p->handling > 0) return (void *)p->data; - if (p->fd_handler) _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; - ecore_pipe_mp_free(p); - return data; -} - -int -_ecore_pipe_wait(Ecore_Pipe *p, - int message_count, - double wait) -{ - struct timeval tv, *t; - fd_set rset; - double end = 0.0; - double timeout; - int ret; - int total = 0; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1); - if (p->fd_read == PIPE_FD_INVALID) - return -1; - - FD_ZERO(&rset); - FD_SET(p->fd_read, &rset); - - if (wait >= 0.0) - end = ecore_loop_time_get() + wait; - timeout = wait; - - while (message_count > 0 && (timeout > 0.0 || wait <= 0.0)) - { - if (wait >= 0.0) - { - /* finite() tests for NaN, too big, too small, and infinity. */ - if ((!ECORE_FINITE(timeout)) || (timeout == 0.0)) - { - tv.tv_sec = 0; - tv.tv_usec = 0; - } - 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; - } - else - { - t = NULL; - } - - ret = main_loop_select(p->fd_read + 1, &rset, NULL, NULL, t); - - if (ret > 0) - { - _ecore_pipe_read(p, NULL); - message_count -= p->message; - total += p->message; - p->message = 0; - } - else if (ret == 0) - { - break; - } - else if (errno != EINTR) - { - close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - break; - } - - if (wait >= 0.0) - timeout = end - ecore_loop_time_get(); - } - - return total; -} - -static void -_ecore_pipe_unhandle(Ecore_Pipe *p) -{ - p->handling--; - if (p->delete_me) - { - _ecore_pipe_del(p); - } -} - -static void -_ecore_pipe_handler_call(Ecore_Pipe *p, - unsigned char *buf, - size_t len) -{ - void *data = (void*) p->data; - if (!p->delete_me) - { - _ecore_unlock(); - p->handler(data, buf, len); - _ecore_lock(); - } -} - -static Eina_Bool -_ecore_pipe_read(void *data, - Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - Ecore_Pipe *p = (Ecore_Pipe *)data; - int i; - - p->handling++; - for (i = 0; i < 16; i++) - { - 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 */ - /* read amount ok - nothing more to do */ - if (ret == sizeof(p->len)) - ; - else if (ret > 0) - { - /* we got more data than we asked for - definite error */ - ERR("Only read %i bytes from the pipe, although" - " we need to read %i bytes.", - (int)ret, (int)sizeof(p->len)); - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_CANCEL; - } - else if (ret == 0) - { - /* we got no data */ - if (i == 0) - { - /* no data on first try through means an error */ - _ecore_pipe_handler_call(p, NULL, 0); - if (p->passed_data) free(p->passed_data); - p->passed_data = NULL; - p->already_read = 0; - p->len = 0; - p->message++; - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - p->fd_handler = NULL; - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_CANCEL; - } - else - { - /* no data after first loop try is ok */ - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_RENEW; - } - } -#ifndef _WIN32 - else if ((ret == PIPE_FD_ERROR) && - ((errno == EINTR) || (errno == EAGAIN))) - { - return ECORE_CALLBACK_RENEW; - } - else - { - ERR("An unhandled error (ret: %i errno: %i [%s])" - "occurred while reading from the pipe the length", - (int)ret, errno, strerror(errno)); - return ECORE_CALLBACK_RENEW; - } -#else - else /* ret == PIPE_FD_ERROR is the only other case on Windows */ - { - if (WSAGetLastError() != WSAEWOULDBLOCK) - { - _ecore_pipe_handler_call(p, NULL, 0); - if (p->passed_data) free(p->passed_data); - p->passed_data = NULL; - p->already_read = 0; - p->len = 0; - p->message++; - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - p->fd_handler = NULL; - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_CANCEL; - } - } -#endif - } - - /* if somehow we got less than or equal to 0 we got an errnoneous - * messages so call callback with null and len we got. this case should - * never happen */ - if (p->len == 0) - { - _ecore_pipe_handler_call(p, NULL, 0); - /* reset all values to 0 */ - if (p->passed_data) free(p->passed_data); - p->passed_data = NULL; - p->already_read = 0; - p->len = 0; - p->message++; - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_RENEW; - } - - /* we dont have a buffer to hold the data, so alloc it */ - if (!p->passed_data) - { - p->passed_data = malloc(p->len); - /* alloc failed - error case */ - if (!p->passed_data) - { - _ecore_pipe_handler_call(p, NULL, 0); - /* close the pipe */ - p->already_read = 0; - p->len = 0; - p->message++; - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - p->fd_handler = NULL; - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_CANCEL; - } - } - - /* 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 we read enough data to finish the message/buffer */ - if (ret == (ssize_t)(p->len - p->already_read)) - { - _ecore_pipe_handler_call(p, 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; - p->message++; - } - else if (ret > 0) - { - /* more data left to read */ - p->already_read += ret; - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_RENEW; - } - else if (ret == 0) - { - /* 0 bytes to read - could be more to read next select wake up */ - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_RENEW; - } -#ifndef _WIN32 - else if ((ret == PIPE_FD_ERROR) && - ((errno == EINTR) || (errno == EAGAIN))) - { - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_RENEW; - } - else - { - ERR("An unhandled error (ret: %zd errno: %d)" - "occurred while reading from the pipe the data", - ret, errno); - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_RENEW; - } -#else - else /* ret == PIPE_FD_ERROR is the only other case on Windows */ - { - if (WSAGetLastError() != WSAEWOULDBLOCK) - { - _ecore_pipe_handler_call(p, NULL, 0); - if (p->passed_data) free(p->passed_data); - p->passed_data = NULL; - p->already_read = 0; - p->len = 0; - p->message++; - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - p->fd_handler = NULL; - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_CANCEL; - } - else - break; - } -#endif - } - - _ecore_pipe_unhandle(p); - return ECORE_CALLBACK_RENEW; -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_poll.c b/legacy/ecore/src/lib/ecore/ecore_poll.c deleted file mode 100644 index 28be53857c..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_poll.c +++ /dev/null @@ -1,490 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#define MY_CLASS ECORE_POLLER_CLASS - -#define MY_CLASS_NAME "ecore_poller" - -EAPI Eo_Op ECORE_POLLER_BASE_ID = EO_NOOP; - -#define ECORE_POLLER_CHECK(obj) \ - if (!eo_isa((obj), ECORE_POLLER_CLASS)) \ - return - -struct _Ecore_Poller_Private_Data -{ - EINA_INLIST; - ECORE_MAGIC; - Ecore_Poller *obj; - int ibit; - unsigned char delete_me : 1; - Ecore_Task_Cb func; - void *data; -}; - -typedef struct _Ecore_Poller_Private_Data Ecore_Poller_Private_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_Private_Data *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 Eina_Bool _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 Eina_Bool -_ecore_poller_cb_timer(void *data EINA_UNUSED) -{ - int i; - Ecore_Poller_Private_Data *poller, *l; - int changes = 0; - - at_tick++; - last_tick = ecore_time_get(); - /* we have 16 counters - each increments every time the poller counter - * "ticks". it increments 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_Private_Data *)EINA_INLIST_GET(l)->next; - if (poller->delete_me) - { - pollers[i] = (Ecore_Poller_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller)); - - eo_parent_set(poller->obj, NULL); - if (eo_destructed_is(poller->obj)) - eo_manual_free(poller->obj); - else - eo_manual_free_set(poller->obj, EINA_FALSE); - - 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 implies keep running me" but we have been deleted - * anyway */ - if (!timer) return ECORE_CALLBACK_CANCEL; - - /* adjust interval */ - ecore_timer_interval_set(timer, poll_cur_interval); - return ECORE_CALLBACK_RENEW; -} - -EAPI void -ecore_poller_poll_interval_set(Ecore_Poller_Type type EINA_UNUSED, - double poll_time) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - - if (poll_time < 0.0) - { - ERR("Poll time %f less than zero, ignored", poll_time); - return; - } - - poll_interval = poll_time; - _ecore_poller_next_tick_eval(); -} - -EAPI double -ecore_poller_poll_interval_get(Ecore_Poller_Type type EINA_UNUSED) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); - return poll_interval; -} - -static void -_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) -{ - eo_error_set(obj); - ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); -} - -EAPI Ecore_Poller * -ecore_poller_add(Ecore_Poller_Type type EINA_UNUSED, - int interval, - Ecore_Task_Cb func, - const void *data) -{ - Ecore_Poller *poller; - poller = eo_add_custom(MY_CLASS, _ecore_parent, - ecore_poller_constructor(type, interval, func, data)); - eo_unref(poller); - return poller; -} - -static void -_poller_constructor(Eo *obj, void *_pd, va_list *list) -{ - Ecore_Poller_Type type = va_arg(*list, Ecore_Poller_Type); - (void)type; - int interval = va_arg(*list, int); - Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); - const void *data = va_arg(*list, const void *); - - - Ecore_Poller_Private_Data *poller = _pd; - poller->obj = obj; - - int ibit; - - if (EINA_UNLIKELY(!eina_main_loop_is())) - { - eo_error_set(obj); - EINA_MAIN_LOOP_CHECK_RETURN; - } - - eo_do_super(obj, eo_constructor()); - eo_manual_free_set(obj, EINA_TRUE); - - if (!func) - { - eo_error_set(obj); - ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); - return; - } - - /* 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_Private_Data *)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(); -} - -EAPI Eina_Bool -ecore_poller_poller_interval_set(Ecore_Poller *obj, - int interval) -{ - Eina_Bool ret; - ECORE_POLLER_CHECK(obj) EINA_FALSE; - eo_do(obj, ecore_poller_interval_set(interval, &ret)); - return ret; -} - -static void -_poller_interval_set(Eo *obj EINA_UNUSED, void *_pd, va_list *list) -{ - int interval = va_arg(*list, int); - Eina_Bool *ret = va_arg(*list, Eina_Bool *); - Eina_Bool int_ret; - - EINA_MAIN_LOOP_CHECK_RETURN; - - int ibit; - - Ecore_Poller_Private_Data *poller = _pd; - - /* 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; - /* if interval specified is the same as interval set, return true without wasting time */ - if (poller->ibit == ibit) - { - int_ret = EINA_TRUE; - goto end; - } - - pollers[poller->ibit] = (Ecore_Poller_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller)); - poller->ibit = ibit; - pollers[poller->ibit] = (Ecore_Poller_Private_Data *)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(); - - int_ret = EINA_TRUE; - -end: - if (ret) *ret = int_ret; -} - -EAPI int -ecore_poller_poller_interval_get(Ecore_Poller *obj) -{ - int ret; - ECORE_POLLER_CHECK(obj) EINA_FALSE; - eo_do(obj, ecore_poller_interval_get(&ret)); - return ret; -} - -static void -_poller_interval_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) -{ - int *ret = va_arg(*list, int *); - *ret =0; - - int ibit, interval = 1; - - EINA_MAIN_LOOP_CHECK_RETURN; - Ecore_Poller_Private_Data *poller = _pd; - - ibit = poller->ibit; - while (ibit != 0) - { - ibit--; - interval <<= 1; - } - *ret = interval; -} - -EAPI void * -ecore_poller_del(Ecore_Poller *obj) -{ - void *data; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - Ecore_Poller_Private_Data *poller = eo_data_get(obj, MY_CLASS); - /* 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_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller)); - - eo_parent_set(poller->obj, NULL); - if (eo_destructed_is(poller->obj)) - eo_manual_free(obj); - else - eo_manual_free_set(obj, EINA_FALSE); - - _ecore_poller_next_tick_eval(); - return data; -} - -static void -_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Poller_Private_Data *pd = _pd; - - if (!pd->delete_me) - { - pd->delete_me = 1; - poller_delete_count++; - } - - eo_do_super(obj, eo_destructor()); -} - -/** - * @} - */ - -void -_ecore_poller_shutdown(void) -{ - int i; - Ecore_Poller_Private_Data *poller; - - for (i = 0; i < 15; i++) - { - while ((poller = pollers[i])) - { - pollers[i] = (Ecore_Poller_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i])); - eo_parent_set(poller->obj, NULL); - if (eo_destructed_is(poller->obj)) - eo_manual_free(poller->obj); - else - eo_manual_free_set(poller->obj, EINA_FALSE); - } - } -} - -static void -_class_constructor(Eo_Class *klass) -{ - const Eo_Op_Func_Description func_desc[] = { - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), - EO_OP_FUNC(ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_CONSTRUCTOR), _poller_constructor), - EO_OP_FUNC(ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_SET), _poller_interval_set), - EO_OP_FUNC(ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_GET), _poller_interval_get), - EO_OP_FUNC_SENTINEL - }; - - eo_class_funcs_set(klass, func_desc); -} - -static const Eo_Op_Description op_desc[] = { - EO_OP_DESCRIPTION(ECORE_POLLER_SUB_ID_CONSTRUCTOR, "Add an idle enterer handler."), - EO_OP_DESCRIPTION(ECORE_POLLER_SUB_ID_INTERVAL_SET, "Changes the polling interval rate of poller."), - EO_OP_DESCRIPTION(ECORE_POLLER_SUB_ID_INTERVAL_GET, "Gets the polling interval rate of poller"), - EO_OP_DESCRIPTION_SENTINEL -}; -static const Eo_Class_Description class_desc = { - EO_VERSION, - MY_CLASS_NAME, - EO_CLASS_TYPE_REGULAR, - EO_CLASS_DESCRIPTION_OPS(&ECORE_POLLER_BASE_ID, op_desc, ECORE_POLLER_SUB_ID_LAST), - NULL, - sizeof(Ecore_Poller_Private_Data), - _class_constructor, - NULL -}; - -EO_DEFINE_CLASS(ecore_poller_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/legacy/ecore/src/lib/ecore/ecore_private.h b/legacy/ecore/src/lib/ecore/ecore_private.h deleted file mode 100644 index f0add822fe..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_private.h +++ /dev/null @@ -1,398 +0,0 @@ -#ifndef _ECORE_PRIVATE_H -#define _ECORE_PRIVATE_H - -#include - -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 EVAS_FRAME_QUEUING 1 /* for test */ - -#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 - -typedef unsigned int Ecore_Magic; -#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; \ - } - -EAPI void _ecore_magic_fail(const void *d, - Ecore_Magic m, - Ecore_Magic req_m, - const char *fname); - -void _ecore_time_init(void); - -Ecore_Timer *_ecore_timer_loop_add(double in, - Ecore_Task_Cb func, - const void *data); -void *_ecore_timer_del(Ecore_Timer *timer); -void _ecore_timer_delay(Ecore_Timer *timer, - double add); -void _ecore_timer_shutdown(void); -void _ecore_timer_cleanup(void); -void _ecore_timer_enable_new(void); -double _ecore_timer_next_get(void); -void _ecore_timer_expired_timers_call(double when); -int _ecore_timers_exists(void); - -int _ecore_timer_expired_call(double when); - -void _ecore_idler_shutdown(void); -int _ecore_idler_all_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, - Ecore_End_Cb func_free, - void *data); -void _ecore_event_call(void); -void *_ecore_event_handler_del(Ecore_Event_Handler *event_handler); - -Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe *exe); -void _ecore_exe_doomsday_clock_set(Ecore_Exe *exe, - Ecore_Timer *dc); - -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); - -Ecore_Pipe *_ecore_pipe_add(Ecore_Pipe_Cb handler, - const void *data); -int _ecore_pipe_wait(Ecore_Pipe *p, - int message_count, - double wait); -void *_ecore_pipe_del(Ecore_Pipe *p); - -Ecore_Fd_Handler * - _ecore_main_fd_handler_add(int fd, - Ecore_Fd_Handler_Flags flags, - Ecore_Fd_Cb func, - const void *data, - Ecore_Fd_Cb buf_func, - const void *buf_data); -void *_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); - -void _ecore_main_shutdown(void); - -#if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC) -static inline void _ecore_signal_shutdown(void) { } - -static inline void _ecore_signal_init(void) { } - -static inline void _ecore_signal_received_process(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); -void _ecore_signal_received_process(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); - -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); - -void _ecore_main_loop_init(void); -void _ecore_main_loop_shutdown(void); - -void _ecore_throttle(void); - -void _ecore_main_call_flush(void); - -extern int _ecore_main_lock_count; -extern Eina_Lock _ecore_main_loop_lock; - -static inline void -_ecore_lock(void) -{ -#ifdef HAVE_THREAD_SAFETY - eina_lock_take(&_ecore_main_loop_lock); -#else - /* at least check we're not being called from a thread */ - EINA_MAIN_LOOP_CHECK_RETURN; -#endif - _ecore_main_lock_count++; - /* assert(_ecore_main_lock_count == 1); */ -} - -static inline void -_ecore_unlock(void) -{ - _ecore_main_lock_count--; - /* assert(_ecore_main_lock_count == 0); */ -#ifdef HAVE_THREAD_SAFETY - eina_lock_release(&_ecore_main_loop_lock); -#endif -} - -/* - * Callback wrappers all assume that ecore _ecore_lock has been called - */ -static inline Eina_Bool -_ecore_call_task_cb(Ecore_Task_Cb func, - void *data) -{ - Eina_Bool r; - - _ecore_unlock(); - r = func(data); - _ecore_lock(); - - return r; -} - -static inline void * -_ecore_call_data_cb(Ecore_Data_Cb func, - void *data) -{ - void *r; - - _ecore_unlock(); - r = func(data); - _ecore_lock(); - - return r; -} - -static inline void -_ecore_call_end_cb(Ecore_End_Cb func, - void *user_data, - void *func_data) -{ - _ecore_unlock(); - func(user_data, func_data); - _ecore_lock(); -} - -static inline Eina_Bool -_ecore_call_filter_cb(Ecore_Filter_Cb func, - void *data, - void *loop_data, - int type, - void *event) -{ - Eina_Bool r; - - _ecore_unlock(); - r = func(data, loop_data, type, event); - _ecore_lock(); - - return r; -} - -static inline Eina_Bool -_ecore_call_handler_cb(Ecore_Event_Handler_Cb func, - void *data, - int type, - void *event) -{ - Eina_Bool r; - - _ecore_unlock(); - r = func(data, type, event); - _ecore_lock(); - - return r; -} - -static inline void -_ecore_call_prep_cb(Ecore_Fd_Prep_Cb func, - void *data, - Ecore_Fd_Handler *fd_handler) -{ - _ecore_unlock(); - func(data, fd_handler); - _ecore_lock(); -} - -static inline Eina_Bool -_ecore_call_fd_cb(Ecore_Fd_Cb func, - void *data, - Ecore_Fd_Handler *fd_handler) -{ - Eina_Bool r; - - _ecore_unlock(); - r = func(data, fd_handler); - _ecore_lock(); - - return r; -} - -extern int _ecore_fps_debug; -extern double _ecore_time_loop_time; -extern Eina_Bool _ecore_glib_always_integrate; -extern Ecore_Select_Function main_loop_select; - -Eina_Bool ecore_mempool_init(void); -void ecore_mempool_shutdown(void); -#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \ - TYPE *Type##_calloc(unsigned int); \ - void Type##_mp_free(TYPE *e); -#define GENERIC_ALLOC_SIZE_DECLARE(TYPE) \ - size_t _ecore_sizeof_##TYPE = sizeof (TYPE); - -//GENERIC_ALLOC_FREE_HEADER(Ecore_Animator, ecore_animator); -GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Handler, ecore_event_handler); -GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Filter, ecore_event_filter); -GENERIC_ALLOC_FREE_HEADER(Ecore_Event, ecore_event); -//GENERIC_ALLOC_FREE_HEADER(Ecore_Idle_Exiter, ecore_idle_exiter); -//GENERIC_ALLOC_FREE_HEADER(Ecore_Idle_Enterer, ecore_idle_enterer); -//GENERIC_ALLOC_FREE_HEADER(Ecore_Idler, ecore_idler); -//GENERIC_ALLOC_FREE_HEADER(Ecore_Job, ecore_job); -//GENERIC_ALLOC_FREE_HEADER(Ecore_Timer, ecore_timer); -//GENERIC_ALLOC_FREE_HEADER(Ecore_Poller, ecore_poller); -GENERIC_ALLOC_FREE_HEADER(Ecore_Pipe, ecore_pipe); -GENERIC_ALLOC_FREE_HEADER(Ecore_Fd_Handler, ecore_fd_handler); -#ifdef _WIN32 -GENERIC_ALLOC_FREE_HEADER(Ecore_Win32_Handler, ecore_win32_handler); -#endif - -#undef GENERIC_ALLOC_FREE_HEADER - -extern Eo *_ecore_parent; -#define ECORE_PARENT_CLASS ecore_parent_class_get() -const Eo_Class *ecore_parent_class_get(void) EINA_CONST; - -#endif diff --git a/legacy/ecore/src/lib/ecore/ecore_signal.c b/legacy/ecore/src/lib/ecore/ecore_signal.c deleted file mode 100644 index 8114f72b09..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_signal.c +++ /dev/null @@ -1,594 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#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 */ - -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 - -static Eina_Bool _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 - -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 - -void -_ecore_signal_shutdown(void) -{ - _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; -} - -void -_ecore_signal_init(void) -{ - _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 -} - -void -_ecore_signal_received_process(void) -{ - while (_ecore_signal_count_get()) _ecore_signal_call(); -} - -int -_ecore_signal_count_get(void) -{ - return sig_count; -} - -static void -_ecore_signal_generic_free(void *data EINA_UNUSED, - void *event) -{ - free(event); -} - -void -_ecore_signal_call(void) -{ - volatile sig_atomic_t n; - sigset_t oldset, newset; - int tot; - - 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 - 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); - tot = sigchld_count + sigusr1_count + sigusr2_count + - sighup_count + sigquit_count + sigint_count + sigterm_count -#ifdef SIGPWR - + sigpwr_count -#endif - ; - - if (sig_count != tot) - { - ERR("sig_count (%i) != actual totals (%i) ", sig_count, tot); - sig_count = tot; - } - - 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_unlock(); - doomsday_clock = ecore_timer_add - (0.1, _ecore_signal_exe_exit_delay, e); - _ecore_lock(); - _ecore_exe_doomsday_clock_set(e->exe, doomsday_clock); - } - 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, - _ecore_signal_generic_free, 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, - _ecore_signal_generic_free, 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, - _ecore_signal_generic_free, 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, - _ecore_signal_generic_free, 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, - _ecore_signal_generic_free, 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, - _ecore_signal_generic_free, 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, - _ecore_signal_generic_free, NULL); - } - sig_count--; - } - sigpwr_count = 0; -#endif - sig_count = 0; - - 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 EINA_UNUSED, - siginfo_t *si EINA_UNUSED, - void *foo EINA_UNUSED) -{ -} - -static void -_ecore_signal_callback_sigchld(int sig EINA_UNUSED, - siginfo_t *si, - void *foo EINA_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 EINA_UNUSED, - siginfo_t *si, - void *foo EINA_UNUSED) -{ - volatile sig_atomic_t n; - n = sigusr1_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 EINA_UNUSED, - siginfo_t *si, - void *foo EINA_UNUSED) -{ - volatile sig_atomic_t n; - n = sigusr2_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 EINA_UNUSED, - siginfo_t *si, - void *foo EINA_UNUSED) -{ - volatile sig_atomic_t n; - n = sighup_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 EINA_UNUSED, - siginfo_t *si, - void *foo EINA_UNUSED) -{ - volatile sig_atomic_t n; - n = sigquit_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 EINA_UNUSED, - siginfo_t *si, - void *foo EINA_UNUSED) -{ - volatile sig_atomic_t n; - n = sigint_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 EINA_UNUSED, - siginfo_t *si, - void *foo EINA_UNUSED) -{ - volatile sig_atomic_t n; - n = sigterm_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 EINA_UNUSED, - siginfo_t *si, - void *foo EINA_UNUSED) -{ - volatile sig_atomic_t n; - n = sigpwr_count; - if (n < MAXSIGQ) - { - if (si) - sigpwr_info[n] = *si; - else - sigpwr_info[n].si_signo = 0; - } - sigpwr_count++; - sig_count++; -} - -#endif - -static Eina_Bool -_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 ECORE_CALLBACK_CANCEL; -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_thread.c b/legacy/ecore/src/lib/ecore/ecore_thread.c deleted file mode 100644 index 4937ef5290..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_thread.c +++ /dev/null @@ -1,1509 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -#ifdef EFL_HAVE_THREADS - -# define LK(x) Eina_Lock x -# define LKI(x) eina_lock_new(&(x)) -# define LKD(x) eina_lock_free(&(x)) -# define LKL(x) eina_lock_take(&(x)) -# define LKU(x) eina_lock_release(&(x)) - -# define CD(x) Eina_Condition x -# define CDI(x, m) eina_condition_new(&(x), &(m)) -# define CDD(x) eina_condition_free(&(x)) -# define CDB(x) eina_condition_broadcast(&(x)) -# define CDW(x, t) eina_condition_timedwait(&(x), t) - -# define LRWK(x) Eina_RWLock x -# define LRWKI(x) eina_rwlock_new(&(x)); -# define LRWKD(x) eina_rwlock_free(&(x)); -# define LRWKWL(x) eina_rwlock_take_write(&(x)); -# define LRWKRL(x) eina_rwlock_take_read(&(x)); -# define LRWKU(x) eina_rwlock_release(&(x)); - -# define PH(x) Eina_Thread x -# define PHE(x, y) eina_thread_equal(x, y) -# define PHS() eina_thread_self() -# define PHC(x, f, d) eina_thread_create(&(x), EINA_THREAD_BACKGROUND, -1, (void *)f, d) -# define PHJ(x) eina_thread_join(x) - -# ifdef EFL_HAVE_POSIX_THREADS -# include -# ifdef __linux__ -# include -# include -# include -# include -# include -# endif - -# else /* EFL_HAVE_WIN32_THREADS */ - -# define WIN32_LEAN_AND_MEAN -# include -# undef WIN32_LEAN_AND_MEAN - -# endif - -#endif - -typedef struct _Ecore_Pthread_Worker Ecore_Pthread_Worker; -typedef struct _Ecore_Pthread Ecore_Pthread; -typedef struct _Ecore_Thread_Data Ecore_Thread_Data; - -struct _Ecore_Thread_Data -{ - void *data; - Eina_Free_Cb cb; -}; - -struct _Ecore_Pthread_Worker -{ - union { - struct - { - Ecore_Thread_Cb func_blocking; - } short_run; - struct - { - Ecore_Thread_Cb func_heavy; - Ecore_Thread_Notify_Cb func_notify; - - Ecore_Pthread_Worker *direct_worker; - - int send; - int received; - } feedback_run; - struct { - Ecore_Thread_Cb func_main; - Ecore_Thread_Notify_Cb func_notify; - - Ecore_Pipe *send; - Ecore_Pthread_Worker *direct_worker; - - struct { - int send; - int received; - } from, to; - } message_run; - } u; - - Ecore_Thread_Cb func_cancel; - Ecore_Thread_Cb func_end; -#ifdef EFL_HAVE_THREADS - PH(self); - Eina_Hash *hash; - CD(cond); - LK(mutex); -#endif - - const void *data; - - int cancel; - -#ifdef EFL_HAVE_THREADS - LK(cancel_mutex); -#endif - - Eina_Bool message_run : 1; - Eina_Bool feedback_run : 1; - Eina_Bool kill : 1; - Eina_Bool reschedule : 1; - Eina_Bool no_queue : 1; -}; - -#ifdef EFL_HAVE_THREADS -typedef struct _Ecore_Pthread_Notify Ecore_Pthread_Notify; -struct _Ecore_Pthread_Notify -{ - Ecore_Pthread_Worker *work; - const void *user_data; -}; - -typedef void *(*Ecore_Thread_Sync_Cb)(void* data, Ecore_Thread *thread); - -typedef struct _Ecore_Pthread_Message Ecore_Pthread_Message; -struct _Ecore_Pthread_Message -{ - union { - Ecore_Thread_Cb async; - Ecore_Thread_Sync_Cb sync; - } u; - - const void *data; - - int code; - - Eina_Bool callback : 1; - Eina_Bool sync : 1; -}; - -#endif - -static int _ecore_thread_count_max = 0; - -#ifdef EFL_HAVE_THREADS - -static void _ecore_thread_handler(void *data); - -static int _ecore_thread_count = 0; - -static Eina_List *_ecore_running_job = NULL; -static Eina_List *_ecore_pending_job_threads = NULL; -static Eina_List *_ecore_pending_job_threads_feedback = NULL; -static LK(_ecore_pending_job_threads_mutex); -static LK(_ecore_running_job_mutex); - -static Eina_Hash *_ecore_thread_global_hash = NULL; -static LRWK(_ecore_thread_global_hash_lock); -static LK(_ecore_thread_global_hash_mutex); -static CD(_ecore_thread_global_hash_cond); - -static Eina_Bool have_main_loop_thread = 0; - -static Eina_Trash *_ecore_thread_worker_trash = NULL; -static int _ecore_thread_worker_count = 0; - -static void *_ecore_thread_worker(void *); -static Ecore_Pthread_Worker *_ecore_thread_worker_new(void); - -static PH(get_main_loop_thread) (void) -{ - static PH(main_loop_thread); - static pid_t main_loop_pid; - pid_t pid = getpid(); - - if (pid != main_loop_pid) - { - main_loop_pid = pid; - main_loop_thread = PHS(); - have_main_loop_thread = 1; - } - - return main_loop_thread; -} - -static void -_ecore_thread_worker_free(Ecore_Pthread_Worker *worker) -{ - LKD(worker->cancel_mutex); - CDD(worker->cond); - LKD(worker->mutex); - - if (_ecore_thread_worker_count > ((_ecore_thread_count_max + 1) * 16)) - { - _ecore_thread_worker_count--; - free(worker); - return; - } - - eina_trash_push(&_ecore_thread_worker_trash, worker); -} - -static void -_ecore_thread_data_free(void *data) -{ - Ecore_Thread_Data *d = data; - - if (d->cb) d->cb(d->data); - free(d); -} - -static void -_ecore_thread_join(PH(thread)) -{ - PHJ(thread); -} - -static void -_ecore_thread_kill(Ecore_Pthread_Worker *work) -{ - if (work->cancel) - { - if (work->func_cancel) - work->func_cancel((void *)work->data, (Ecore_Thread *)work); - } - else - { - if (work->func_end) - work->func_end((void *)work->data, (Ecore_Thread *)work); - } - - if (work->feedback_run) - { - if (work->u.feedback_run.direct_worker) - _ecore_thread_worker_free(work->u.feedback_run.direct_worker); - } - if (work->hash) - eina_hash_free(work->hash); - _ecore_thread_worker_free(work); -} - -static void -_ecore_thread_handler(void *data) -{ - Ecore_Pthread_Worker *work = data; - - if (work->feedback_run) - { - if (work->u.feedback_run.send != work->u.feedback_run.received) - { - work->kill = EINA_TRUE; - return; - } - } - - _ecore_thread_kill(work); -} - -#if 0 -static void -_ecore_nothing_handler(void *data EINA_UNUSED, void *buffer EINA_UNUSED, unsigned int nbyte EINA_UNUSED) -{ -} -#endif - -static void -_ecore_notify_handler(void *data) -{ - Ecore_Pthread_Notify *notify = data; - Ecore_Pthread_Worker *work = notify->work; - void *user_data = (void*) notify->user_data; - - work->u.feedback_run.received++; - - if (work->u.feedback_run.func_notify) - work->u.feedback_run.func_notify((void *)work->data, (Ecore_Thread *)work, user_data); - - /* Force reading all notify event before killing the thread */ - if (work->kill && work->u.feedback_run.send == work->u.feedback_run.received) - { - _ecore_thread_kill(work); - } - - free(notify); -} - -static void -_ecore_message_notify_handler(void *data) -{ - Ecore_Pthread_Notify *notify = data; - Ecore_Pthread_Worker *work = notify->work; - Ecore_Pthread_Message *user_data = (void *) notify->user_data; - Eina_Bool delete = EINA_TRUE; - - work->u.message_run.from.received++; - - if (!user_data->callback) - { - if (work->u.message_run.func_notify) - work->u.message_run.func_notify((void *) work->data, (Ecore_Thread *) work, (void *) user_data->data); - } - else - { - if (user_data->sync) - { - user_data->data = user_data->u.sync((void*) user_data->data, (Ecore_Thread *) work); - user_data->callback = EINA_FALSE; - user_data->code = INT_MAX; - ecore_pipe_write(work->u.message_run.send, &user_data, sizeof (Ecore_Pthread_Message *)); - - delete = EINA_FALSE; - } - else - { - user_data->u.async((void*) user_data->data, (Ecore_Thread *) work); - } - } - - if (delete) - { - free(user_data); - } - - /* Force reading all notify event before killing the thread */ - if (work->kill && work->u.message_run.from.send == work->u.message_run.from.received) - { - _ecore_thread_kill(work); - } - free(notify); -} - -static void -_ecore_short_job(PH(thread)) -{ - Ecore_Pthread_Worker *work; - int cancel; - - LKL(_ecore_pending_job_threads_mutex); - - if (!_ecore_pending_job_threads) - { - LKU(_ecore_pending_job_threads_mutex); - return; - } - - work = eina_list_data_get(_ecore_pending_job_threads); - _ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, - _ecore_pending_job_threads); - LKU(_ecore_pending_job_threads_mutex); - - LKL(_ecore_running_job_mutex); - _ecore_running_job = eina_list_append(_ecore_running_job, work); - LKU(_ecore_running_job_mutex); - - LKL(work->cancel_mutex); - cancel = work->cancel; - LKU(work->cancel_mutex); - work->self = thread; - if (!cancel) - work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work); - - LKL(_ecore_running_job_mutex); - _ecore_running_job = eina_list_remove(_ecore_running_job, work); - LKU(_ecore_running_job_mutex); - - if (work->reschedule) - { - work->reschedule = EINA_FALSE; - - LKL(_ecore_pending_job_threads_mutex); - _ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work); - LKU(_ecore_pending_job_threads_mutex); - } - else - { - ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work); - } -} - -static void -_ecore_feedback_job(PH(thread)) -{ - Ecore_Pthread_Worker *work; - int cancel; - - LKL(_ecore_pending_job_threads_mutex); - - if (!_ecore_pending_job_threads_feedback) - { - LKU(_ecore_pending_job_threads_mutex); - return; - } - - work = eina_list_data_get(_ecore_pending_job_threads_feedback); - _ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback, - _ecore_pending_job_threads_feedback); - LKU(_ecore_pending_job_threads_mutex); - LKL(_ecore_running_job_mutex); - _ecore_running_job = eina_list_append(_ecore_running_job, work); - LKU(_ecore_running_job_mutex); - - LKL(work->cancel_mutex); - cancel = work->cancel; - LKU(work->cancel_mutex); - work->self = thread; - if (!cancel) - work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work); - - LKL(_ecore_running_job_mutex); - _ecore_running_job = eina_list_remove(_ecore_running_job, work); - LKU(_ecore_running_job_mutex); - - if (work->reschedule) - { - work->reschedule = EINA_FALSE; - - LKL(_ecore_pending_job_threads_mutex); - _ecore_pending_job_threads_feedback = eina_list_append(_ecore_pending_job_threads_feedback, work); - LKU(_ecore_pending_job_threads_mutex); - } - else - { - ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work); - } -} - -static void * -_ecore_direct_worker(Ecore_Pthread_Worker *work) -{ - work->self = PHS(); - if (work->message_run) - work->u.message_run.func_main((void *) work->data, (Ecore_Thread *) work); - else - work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work); - - ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work); - - ecore_main_loop_thread_safe_call_async((Ecore_Cb) _ecore_thread_join, - (void*) PHS()); - - return NULL; -} - -static void * -_ecore_thread_worker(void *data EINA_UNUSED) -{ -restart: - _ecore_short_job(PHS()); - _ecore_feedback_job(PHS()); - - /* FIXME: Check if there is feedback running task todo, and switch to feedback run handler. */ - - LKL(_ecore_pending_job_threads_mutex); - if (_ecore_pending_job_threads || _ecore_pending_job_threads_feedback) - { - LKU(_ecore_pending_job_threads_mutex); - goto restart; - } - LKU(_ecore_pending_job_threads_mutex); - - /* Sleep a little to prevent premature death */ -#ifdef _WIN32 - Sleep(1); /* around 50ms */ -#else - usleep(50); -#endif - - LKL(_ecore_pending_job_threads_mutex); - if (_ecore_pending_job_threads || _ecore_pending_job_threads_feedback) - { - LKU(_ecore_pending_job_threads_mutex); - goto restart; - } - _ecore_thread_count--; - - ecore_main_loop_thread_safe_call_async((Ecore_Cb) _ecore_thread_join, - (void*) PHS()); - LKU(_ecore_pending_job_threads_mutex); - - return NULL; -} - -#endif - -static Ecore_Pthread_Worker * -_ecore_thread_worker_new(void) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *result; - - result = eina_trash_pop(&_ecore_thread_worker_trash); - - if (!result) - { - result = calloc(1, sizeof(Ecore_Pthread_Worker)); - _ecore_thread_worker_count++; - } - - LKI(result->cancel_mutex); - LKI(result->mutex); - CDI(result->cond, result->mutex); - - return result; -#else - return malloc(sizeof (Ecore_Pthread_Worker)); -#endif -} - -void -_ecore_thread_init(void) -{ - _ecore_thread_count_max = eina_cpu_count(); - if (_ecore_thread_count_max <= 0) - _ecore_thread_count_max = 1; - -#ifdef EFL_HAVE_THREADS - LKI(_ecore_pending_job_threads_mutex); - LRWKI(_ecore_thread_global_hash_lock); - LKI(_ecore_thread_global_hash_mutex); - LKI(_ecore_running_job_mutex); - CDI(_ecore_thread_global_hash_cond, _ecore_thread_global_hash_mutex); -#endif -} - -void -_ecore_thread_shutdown(void) -{ - /* FIXME: If function are still running in the background, should we kill them ? */ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *work; - Eina_List *l; - Eina_Bool test; - int iteration = 0; - - LKL(_ecore_pending_job_threads_mutex); - - EINA_LIST_FREE(_ecore_pending_job_threads, work) - { - if (work->func_cancel) - work->func_cancel((void *)work->data, (Ecore_Thread *) work); - free(work); - } - - EINA_LIST_FREE(_ecore_pending_job_threads_feedback, work) - { - if (work->func_cancel) - work->func_cancel((void *)work->data, (Ecore_Thread *) work); - free(work); - } - - LKU(_ecore_pending_job_threads_mutex); - LKL(_ecore_running_job_mutex); - - EINA_LIST_FOREACH(_ecore_running_job, l, work) - ecore_thread_cancel((Ecore_Thread*) work); - - LKU(_ecore_running_job_mutex); - - do - { - LKL(_ecore_pending_job_threads_mutex); - if (_ecore_thread_count > 0) - { - test = EINA_TRUE; - } - else - { - test = EINA_FALSE; - } - LKU(_ecore_pending_job_threads_mutex); - iteration++; - if (test) usleep(50000); - } - while (test == EINA_TRUE && iteration < 20); - - if (iteration == 20 && _ecore_thread_count > 0) - { - ERR("%i of the child thread are still running after 1s. This can lead to a segv. Sorry.", _ecore_thread_count); - } - - if (_ecore_thread_global_hash) - eina_hash_free(_ecore_thread_global_hash); - have_main_loop_thread = 0; - - while ((work = eina_trash_pop(&_ecore_thread_worker_trash))) - { - free(work); - } - - LKD(_ecore_pending_job_threads_mutex); - LRWKD(_ecore_thread_global_hash_lock); - LKD(_ecore_thread_global_hash_mutex); - LKD(_ecore_running_job_mutex); - CDD(_ecore_thread_global_hash_cond); -#endif -} - -EAPI Ecore_Thread * -ecore_thread_run(Ecore_Thread_Cb func_blocking, - Ecore_Thread_Cb func_end, - Ecore_Thread_Cb func_cancel, - const void *data) -{ - Ecore_Pthread_Worker *work; - Eina_Bool tried = EINA_FALSE; -#ifdef EFL_HAVE_THREADS - PH(thread); -#endif - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - - if (!func_blocking) return NULL; - - work = _ecore_thread_worker_new(); - if (!work) - { - if (func_cancel) - func_cancel((void *)data, NULL); - return NULL; - } - - work->u.short_run.func_blocking = func_blocking; - work->func_end = func_end; - work->func_cancel = func_cancel; - work->cancel = EINA_FALSE; - work->feedback_run = EINA_FALSE; - work->message_run = EINA_FALSE; - work->kill = EINA_FALSE; - work->reschedule = EINA_FALSE; - work->no_queue = EINA_FALSE; - work->data = data; - -#ifdef EFL_HAVE_THREADS - work->self = 0; - work->hash = NULL; - - LKL(_ecore_pending_job_threads_mutex); - _ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work); - - if (_ecore_thread_count == _ecore_thread_count_max) - { - LKU(_ecore_pending_job_threads_mutex); - return (Ecore_Thread *)work; - } - - LKU(_ecore_pending_job_threads_mutex); - - /* One more thread could be created. */ - eina_threads_init(); - - LKL(_ecore_pending_job_threads_mutex); - - retry: - if (PHC(thread, _ecore_thread_worker, NULL)) - { - _ecore_thread_count++; - LKU(_ecore_pending_job_threads_mutex); - return (Ecore_Thread *)work; - } - if (!tried) - { - _ecore_main_call_flush(); - tried = EINA_TRUE; - goto retry; - } - - if (_ecore_thread_count == 0) - { - _ecore_pending_job_threads = eina_list_remove(_ecore_pending_job_threads, work); - - if (work->func_cancel) - work->func_cancel((void *) work->data, (Ecore_Thread *) work); - - _ecore_thread_worker_free(work); - work = NULL; - } - LKU(_ecore_pending_job_threads_mutex); - - eina_threads_shutdown(); - - return (Ecore_Thread *)work; -#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. - */ - do { - /* Handle reschedule by forcing it here. That would mean locking the app, - * would be better with an idler, but really to complex for a case where - * thread should really exist. - */ - work->reschedule = EINA_FALSE; - - func_blocking((void *)data, (Ecore_Thread *)work); - if (work->cancel == EINA_FALSE) func_end((void *)data, (Ecore_Thread *)work); - else func_cancel((void *)data, (Ecore_Thread *)work); - } while (work->reschedule == EINA_TRUE); - - free(work); - - return NULL; -#endif -} - -EAPI Eina_Bool -ecore_thread_cancel(Ecore_Thread *thread) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *volatile work = (Ecore_Pthread_Worker *)thread; - Eina_List *l; - int cancel; - - if (!work) - return EINA_TRUE; - LKL(work->cancel_mutex); - cancel = work->cancel; - LKU(work->cancel_mutex); - if (cancel) - return EINA_FALSE; - - if (work->feedback_run) - { - if (work->kill) - return EINA_TRUE; - if (work->u.feedback_run.send != work->u.feedback_run.received) - goto on_exit; - } - - LKL(_ecore_pending_job_threads_mutex); - - if ((have_main_loop_thread) && - (PHE(get_main_loop_thread(), PHS()))) - { - if (!work->feedback_run) - EINA_LIST_FOREACH(_ecore_pending_job_threads, l, work) - { - if ((void *)work == (void *)thread) - { - _ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, l); - - LKU(_ecore_pending_job_threads_mutex); - - if (work->func_cancel) - work->func_cancel((void *)work->data, (Ecore_Thread *)work); - free(work); - - return EINA_TRUE; - } - } - else - EINA_LIST_FOREACH(_ecore_pending_job_threads_feedback, l, work) - { - if ((void *)work == (void *)thread) - { - _ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback, l); - - LKU(_ecore_pending_job_threads_mutex); - - if (work->func_cancel) - work->func_cancel((void *)work->data, (Ecore_Thread *)work); - free(work); - - return EINA_TRUE; - } - } - } - - LKU(_ecore_pending_job_threads_mutex); - - work = (Ecore_Pthread_Worker *)thread; - - /* Delay the destruction */ - on_exit: - LKL(work->cancel_mutex); - work->cancel = EINA_TRUE; - LKU(work->cancel_mutex); - - return EINA_FALSE; -#else - (void) thread; - return EINA_TRUE; -#endif -} - -EAPI Eina_Bool -ecore_thread_check(Ecore_Thread *thread) -{ - Ecore_Pthread_Worker *volatile worker = (Ecore_Pthread_Worker *) thread; - int cancel; - - if (!worker) return EINA_TRUE; -#ifdef EFL_HAVE_THREADS - LKL(worker->cancel_mutex); -#endif - cancel = worker->cancel; - /* FIXME: there is an insane bug driving me nuts here. I don't know if - it's a race condition, some cache issue or some alien attack on our software. - But ecore_thread_check will only work correctly with a printf, all the volatile, - lock and even usleep don't help here... */ - /* fprintf(stderr, "wc: %i\n", cancel); */ -#ifdef EFL_HAVE_THREADS - LKU(worker->cancel_mutex); -#endif - return cancel; -} - -EAPI Ecore_Thread * -ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, - Ecore_Thread_Notify_Cb func_notify, - Ecore_Thread_Cb func_end, - Ecore_Thread_Cb func_cancel, - const void *data, - Eina_Bool try_no_queue) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *worker; - Eina_Bool tried = EINA_FALSE; - PH(thread); - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - - if (!func_heavy) return NULL; - - worker = _ecore_thread_worker_new(); - if (!worker) goto on_error; - - worker->u.feedback_run.func_heavy = func_heavy; - worker->u.feedback_run.func_notify = func_notify; - worker->hash = NULL; - worker->func_cancel = func_cancel; - worker->func_end = func_end; - worker->data = data; - worker->cancel = EINA_FALSE; - worker->message_run = EINA_FALSE; - worker->feedback_run = EINA_TRUE; - worker->kill = EINA_FALSE; - worker->reschedule = EINA_FALSE; - worker->self = 0; - - worker->u.feedback_run.send = 0; - worker->u.feedback_run.received = 0; - - worker->u.feedback_run.direct_worker = NULL; - - if (try_no_queue) - { - PH(t); - - worker->u.feedback_run.direct_worker = _ecore_thread_worker_new(); - worker->no_queue = EINA_TRUE; - - eina_threads_init(); - - retry_direct: - if (PHC(t, _ecore_direct_worker, worker)) - return (Ecore_Thread *)worker; - if (!tried) - { - _ecore_main_call_flush(); - tried = EINA_TRUE; - goto retry_direct; - } - - if (worker->u.feedback_run.direct_worker) - { - _ecore_thread_worker_free(worker->u.feedback_run.direct_worker); - worker->u.feedback_run.direct_worker = NULL; - } - - eina_threads_shutdown(); - } - - worker->no_queue = EINA_FALSE; - - LKL(_ecore_pending_job_threads_mutex); - _ecore_pending_job_threads_feedback = eina_list_append(_ecore_pending_job_threads_feedback, worker); - - if (_ecore_thread_count == _ecore_thread_count_max) - { - LKU(_ecore_pending_job_threads_mutex); - return (Ecore_Thread *)worker; - } - - LKU(_ecore_pending_job_threads_mutex); - - /* One more thread could be created. */ - eina_threads_init(); - - LKL(_ecore_pending_job_threads_mutex); - retry: - if (PHC(thread, _ecore_thread_worker, NULL)) - { - _ecore_thread_count++; - LKU(_ecore_pending_job_threads_mutex); - return (Ecore_Thread *)worker; - } - if (!tried) - { - _ecore_main_call_flush(); - tried = EINA_TRUE; - goto retry; - } - LKU(_ecore_pending_job_threads_mutex); - - eina_threads_shutdown(); - -on_error: - LKL(_ecore_pending_job_threads_mutex); - if (_ecore_thread_count == 0) - { - _ecore_pending_job_threads_feedback = eina_list_remove(_ecore_pending_job_threads_feedback, - worker); - - if (func_cancel) func_cancel((void *)data, NULL); - - if (worker) - { - CDD(worker->cond); - LKD(worker->mutex); - free(worker); - worker = NULL; - } - } - LKU(_ecore_pending_job_threads_mutex); - - return (Ecore_Thread *)worker; -#else - Ecore_Pthread_Worker worker; - - (void)try_no_queue; - - /* - 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. - */ - worker.u.feedback_run.func_heavy = func_heavy; - worker.u.feedback_run.func_notify = func_notify; - worker.u.feedback_run.send = 0; - worker.u.feedback_run.received = 0; - worker.func_cancel = func_cancel; - worker.func_end = func_end; - worker.data = data; - worker.cancel = EINA_FALSE; - worker.feedback_run = EINA_TRUE; - worker.message_run = EINA_FALSE; - worker.kill = EINA_FALSE; - - do { - worker.reschedule = EINA_FALSE; - - func_heavy((void *)data, (Ecore_Thread *)&worker); - - if (worker.cancel) func_cancel((void *)data, (Ecore_Thread *)&worker); - else func_end((void *)data, (Ecore_Thread *)&worker); - } while (worker.reschedule == EINA_TRUE); - - return NULL; -#endif -} - -EAPI Eina_Bool -ecore_thread_feedback(Ecore_Thread *thread, - const void *data) -{ - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; - - if (!worker) return EINA_FALSE; - -#ifdef EFL_HAVE_THREADS - if (!PHE(worker->self, PHS())) return EINA_FALSE; - - if (worker->feedback_run) - { - Ecore_Pthread_Notify *notify; - - notify = malloc(sizeof (Ecore_Pthread_Notify)); - if (!notify) return EINA_FALSE; - - notify->user_data = data; - notify->work = worker; - worker->u.feedback_run.send++; - - ecore_main_loop_thread_safe_call_async(_ecore_notify_handler, notify); - } - else if (worker->message_run) - { - Ecore_Pthread_Message *msg; - Ecore_Pthread_Notify *notify; - - msg = malloc(sizeof (Ecore_Pthread_Message)); - if (!msg) return EINA_FALSE; - msg->data = data; - msg->callback = EINA_FALSE; - msg->sync = EINA_FALSE; - - notify = malloc(sizeof (Ecore_Pthread_Notify)); - if (!notify) - { - free(msg); - return EINA_FALSE; - } - notify->work = worker; - notify->user_data = msg; - - worker->u.message_run.from.send++; - ecore_main_loop_thread_safe_call_async(_ecore_message_notify_handler, notify); - } - else - return EINA_FALSE; - - return EINA_TRUE; -#else - worker->u.feedback_run.func_notify((void *)worker->data, thread, (void *)data); - - return EINA_TRUE; -#endif -} - -#if 0 -EAPI Ecore_Thread * -ecore_thread_message_run(Ecore_Thread_Cb func_main, - Ecore_Thread_Notify_Cb func_notify, - Ecore_Thread_Cb func_end, - Ecore_Thread_Cb func_cancel, - const void *data) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *worker; - PH(t); - - if (!func_main) return NULL; - - worker = _ecore_thread_worker_new(); - if (!worker) return NULL; - - worker->u.message_run.func_main = func_main; - worker->u.message_run.func_notify = func_notify; - worker->u.message_run.direct_worker = _ecore_thread_worker_new(); - worker->u.message_run.send = ecore_pipe_add(_ecore_nothing_handler, worker); - worker->u.message_run.from.send = 0; - worker->u.message_run.from.received = 0; - worker->u.message_run.to.send = 0; - worker->u.message_run.to.received = 0; - - ecore_pipe_freeze(worker->u.message_run.send); - - worker->func_cancel = func_cancel; - worker->func_end = func_end; - worker->hash = NULL; - worker->data = data; - - worker->cancel = EINA_FALSE; - worker->message_run = EINA_TRUE; - worker->feedback_run = EINA_FALSE; - worker->kill = EINA_FALSE; - worker->reschedule = EINA_FALSE; - worker->no_queue = EINA_FALSE; - worker->self = 0; - - eina_threads_init(); - - if (PHC(t, _ecore_direct_worker, worker)) - return (Ecore_Thread*) worker; - - eina_threads_shutdown(); - - if (worker->u.message_run.direct_worker) _ecore_thread_worker_free(worker->u.message_run.direct_worker); - if (worker->u.message_run.send) ecore_pipe_del(worker->u.message_run.send); - - CDD(worker->cond); - LKD(worker->mutex); -#else - /* Note: This type of thread can't and never will work without thread support */ - WRN("ecore_thread_message_run called, but threads disable in Ecore, things will go wrong. Starting now !"); -# warning "You disabled threads support in ecore, I hope you know what you are doing !" -#endif - - func_cancel((void *) data, NULL); - - return NULL; -} -#endif - -EAPI Eina_Bool -ecore_thread_reschedule(Ecore_Thread *thread) -{ - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; - - if (!worker) return EINA_FALSE; - -#ifdef EFL_HAVE_THREADS - if (!PHE(worker->self, PHS())) return EINA_FALSE; -#endif - - worker->reschedule = EINA_TRUE; - return EINA_TRUE; -} - -EAPI int -ecore_thread_active_get(void) -{ -#ifdef EFL_HAVE_THREADS - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - return _ecore_thread_count; -#else - return 0; -#endif -} - -EAPI int -ecore_thread_pending_get(void) -{ -#ifdef EFL_HAVE_THREADS - int ret; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - LKL(_ecore_pending_job_threads_mutex); - ret = eina_list_count(_ecore_pending_job_threads); - LKU(_ecore_pending_job_threads_mutex); - return ret; -#else - return 0; -#endif -} - -EAPI int -ecore_thread_pending_feedback_get(void) -{ -#ifdef EFL_HAVE_THREADS - int ret; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - LKL(_ecore_pending_job_threads_mutex); - ret = eina_list_count(_ecore_pending_job_threads_feedback); - LKU(_ecore_pending_job_threads_mutex); - return ret; -#else - return 0; -#endif -} - -EAPI int -ecore_thread_pending_total_get(void) -{ -#ifdef EFL_HAVE_THREADS - int ret; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - LKL(_ecore_pending_job_threads_mutex); - ret = eina_list_count(_ecore_pending_job_threads) + eina_list_count(_ecore_pending_job_threads_feedback); - LKU(_ecore_pending_job_threads_mutex); - return ret; -#else - return 0; -#endif -} - -EAPI int -ecore_thread_max_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); - return _ecore_thread_count_max; -} - -EAPI void -ecore_thread_max_set(int num) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - if (num < 1) return; - /* avoid doing something hilarious by blocking dumb users */ - if (num > (16 * eina_cpu_count())) num = 16 * eina_cpu_count(); - - _ecore_thread_count_max = num; -} - -EAPI void -ecore_thread_max_reset(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_thread_count_max = eina_cpu_count(); -} - -EAPI int -ecore_thread_available_get(void) -{ -#ifdef EFL_HAVE_THREADS - int ret; - - LKL(_ecore_pending_job_threads_mutex); - ret = _ecore_thread_count_max - _ecore_thread_count; - LKU(_ecore_pending_job_threads_mutex); - return ret; -#else - return 0; -#endif -} - -EAPI Eina_Bool -ecore_thread_local_data_add(Ecore_Thread *thread, - const char *key, - void *value, - Eina_Free_Cb cb, - Eina_Bool direct) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; - Ecore_Thread_Data *d; - Eina_Bool ret; -#endif - - if ((!thread) || (!key) || (!value)) - return EINA_FALSE; -#ifdef EFL_HAVE_THREADS - if (!PHE(worker->self, PHS())) return EINA_FALSE; - - if (!worker->hash) - worker->hash = eina_hash_string_small_new(_ecore_thread_data_free); - - if (!worker->hash) - return EINA_FALSE; - - if (!(d = malloc(sizeof(Ecore_Thread_Data)))) - return EINA_FALSE; - - d->data = value; - d->cb = cb; - - if (direct) - ret = eina_hash_direct_add(worker->hash, key, d); - else - ret = eina_hash_add(worker->hash, key, d); - CDB(worker->cond); - return ret; -#else - (void) cb; - (void) direct; - return EINA_FALSE; -#endif -} - -EAPI void * -ecore_thread_local_data_set(Ecore_Thread *thread, - const char *key, - void *value, - Eina_Free_Cb cb) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; - Ecore_Thread_Data *d, *r; - void *ret; -#endif - - if ((!thread) || (!key) || (!value)) - return NULL; -#ifdef EFL_HAVE_THREADS - if (!PHE(worker->self, PHS())) return NULL; - - if (!worker->hash) - worker->hash = eina_hash_string_small_new(_ecore_thread_data_free); - - if (!worker->hash) - return NULL; - - if (!(d = malloc(sizeof(Ecore_Thread_Data)))) - return NULL; - - d->data = value; - d->cb = cb; - - r = eina_hash_set(worker->hash, key, d); - CDB(worker->cond); - ret = r->data; - free(r); - return ret; -#else - (void) cb; - return NULL; -#endif -} - -EAPI void * -ecore_thread_local_data_find(Ecore_Thread *thread, - const char *key) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; - Ecore_Thread_Data *d; -#endif - - if ((!thread) || (!key)) - return NULL; -#ifdef EFL_HAVE_THREADS - if (!PHE(worker->self, PHS())) return NULL; - - if (!worker->hash) - return NULL; - - d = eina_hash_find(worker->hash, key); - if (d) - return d->data; - return NULL; -#else - return NULL; -#endif -} - -EAPI Eina_Bool -ecore_thread_local_data_del(Ecore_Thread *thread, - const char *key) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; -#endif - - if ((!thread) || (!key)) - return EINA_FALSE; -#ifdef EFL_HAVE_THREADS - if (!PHE(worker->self, PHS())) return EINA_FALSE; - - if (!worker->hash) - return EINA_FALSE; - return eina_hash_del_by_key(worker->hash, key); -#else - return EINA_TRUE; -#endif -} - -EAPI Eina_Bool -ecore_thread_global_data_add(const char *key, - void *value, - Eina_Free_Cb cb, - Eina_Bool direct) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Thread_Data *d; - Eina_Bool ret; -#endif - - if ((!key) || (!value)) - return EINA_FALSE; -#ifdef EFL_HAVE_THREADS - LRWKWL(_ecore_thread_global_hash_lock); - if (!_ecore_thread_global_hash) - _ecore_thread_global_hash = eina_hash_string_small_new(_ecore_thread_data_free); - LRWKU(_ecore_thread_global_hash_lock); - - if (!(d = malloc(sizeof(Ecore_Thread_Data)))) - return EINA_FALSE; - - d->data = value; - d->cb = cb; - - if (!_ecore_thread_global_hash) - return EINA_FALSE; - LRWKWL(_ecore_thread_global_hash_lock); - if (direct) - ret = eina_hash_direct_add(_ecore_thread_global_hash, key, d); - else - ret = eina_hash_add(_ecore_thread_global_hash, key, d); - LRWKU(_ecore_thread_global_hash_lock); - CDB(_ecore_thread_global_hash_cond); - return ret; -#else - (void) cb; - (void) direct; - return EINA_TRUE; -#endif -} - -EAPI void * -ecore_thread_global_data_set(const char *key, - void *value, - Eina_Free_Cb cb) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Thread_Data *d, *r; - void *ret; -#endif - - if ((!key) || (!value)) - return NULL; -#ifdef EFL_HAVE_THREADS - LRWKWL(_ecore_thread_global_hash_lock); - if (!_ecore_thread_global_hash) - _ecore_thread_global_hash = eina_hash_string_small_new(_ecore_thread_data_free); - LRWKU(_ecore_thread_global_hash_lock); - - if (!_ecore_thread_global_hash) - return NULL; - - if (!(d = malloc(sizeof(Ecore_Thread_Data)))) - return NULL; - - d->data = value; - d->cb = cb; - - LRWKWL(_ecore_thread_global_hash_lock); - r = eina_hash_set(_ecore_thread_global_hash, key, d); - LRWKU(_ecore_thread_global_hash_lock); - CDB(_ecore_thread_global_hash_cond); - - ret = r->data; - free(r); - return ret; -#else - (void) cb; - return NULL; -#endif -} - -EAPI void * -ecore_thread_global_data_find(const char *key) -{ -#ifdef EFL_HAVE_THREADS - Ecore_Thread_Data *ret; -#endif - - if (!key) - return NULL; -#ifdef EFL_HAVE_THREADS - if (!_ecore_thread_global_hash) return NULL; - - LRWKRL(_ecore_thread_global_hash_lock); - ret = eina_hash_find(_ecore_thread_global_hash, key); - LRWKU(_ecore_thread_global_hash_lock); - if (ret) - return ret->data; - return NULL; -#else - return NULL; -#endif -} - -EAPI Eina_Bool -ecore_thread_global_data_del(const char *key) -{ -#ifdef EFL_HAVE_THREADS - Eina_Bool ret; -#endif - - if (!key) - return EINA_FALSE; -#ifdef EFL_HAVE_THREADS - if (!_ecore_thread_global_hash) - return EINA_FALSE; - - LRWKWL(_ecore_thread_global_hash_lock); - ret = eina_hash_del_by_key(_ecore_thread_global_hash, key); - LRWKU(_ecore_thread_global_hash_lock); - return ret; -#else - return EINA_TRUE; -#endif -} - -EAPI void * -ecore_thread_global_data_wait(const char *key, - double seconds) -{ -#ifdef EFL_HAVE_THREADS - double tm = 0; - Ecore_Thread_Data *ret = NULL; -#endif - - if (!key) - return NULL; -#ifdef EFL_HAVE_THREADS - if (!_ecore_thread_global_hash) - return NULL; - if (seconds > 0) - tm = ecore_time_get() + seconds; - - while (1) - { - LRWKRL(_ecore_thread_global_hash_lock); - ret = eina_hash_find(_ecore_thread_global_hash, key); - LRWKU(_ecore_thread_global_hash_lock); - if ((ret) || (!seconds) || ((seconds > 0) && (tm <= ecore_time_get()))) - break; - LKL(_ecore_thread_global_hash_mutex); - CDW(_ecore_thread_global_hash_cond, tm); - LKU(_ecore_thread_global_hash_mutex); - } - if (ret) return ret->data; - return NULL; -#else - (void) seconds; - return NULL; -#endif -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_throttle.c b/legacy/ecore/src/lib/ecore/ecore_throttle.c deleted file mode 100644 index febaeacb77..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_throttle.c +++ /dev/null @@ -1,104 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" - -static int throttle_val = 0; - -/** - * @addtogroup Ecore_Throttle_Group Ecore Throttle functions - * - * @{ - */ - -/** - * Increase throttle amount - * - * This will increase or decrease (if @p amount is positive or negative) the - * amount of "voluntary throttling" ecore will do to its main loop while - * running. This is intended to be used to limit animations and wakeups when - * in a strict power management state. The higher the current throttle value - * (which can be retrieved by ecore_throttle_get() ), the more throttling - * takes place. If the current throttle value is 0, then no throttling takes - * place at all. - * - * The value represents how long the ecore main loop will sleep (in seconds) - * before it goes into a fully idle state waiting for events, input or - * timing events to wake it up. For example, if the current throttle level - * is 0.5, then after every time the main loop cycles and goes into idle - * affter processing all events, the main loop will explicitly sleep for 0.5 - * seconds before sitting and waiting for incoming events or timeouts, thus - * preventing animation, async IO and network handling etc. for that period - * of time. Of course these events, data and timeouts will be buffered, - * thus not losing anything, simply delaying when they get handled by the - * throttle value. - * - * Example: - * @code - * void enter_powersave(void) { - * ecore_throttle_adjust(0.2); - * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); - * } - * - * void enter_deep_powersave(void) { - * ecore_throttle_adjust(0.5); - * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); - * } - * - * void exit_powersave(void) { - * ecore_throttle_adjust(-0.2); - * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); - * } - * - * void exit_deep_powersave(void) { - * ecore_throttle_adjust(-0.5); - * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); - * } - * @endcode - * - * @param amount Amount (in seconds) to adjust by - */ -EAPI void -ecore_throttle_adjust(double amount) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - int adj = amount * 1000000.0; - throttle_val += adj; - if (throttle_val < 0) throttle_val = 0; -} - -/** - * Get current throttle level - * - * This gets the current throttling level, which can be adjusted by - * ecore_throttle_adjust(). The value is in seconds. Please see - * ecore_throttle_adjust() for more information. - * - * @return The current throttle level - */ -EAPI double -ecore_throttle_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); - return (double)throttle_val / 1000000.0; -} - -/** - * @} - */ - -void -_ecore_throttle(void) -{ - if (throttle_val <= 0) return; - usleep(throttle_val); -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_time.c b/legacy/ecore/src/lib/ecore/ecore_time.c deleted file mode 100644 index 44b1dab81f..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_time.c +++ /dev/null @@ -1,184 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#ifdef HAVE_SYS_TIME_H -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#if defined(__APPLE__) && defined(__MACH__) -# include -#endif - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME) -static clockid_t _ecore_time_clock_id = -1; -#elif defined(__APPLE__) && defined(__MACH__) -static double _ecore_time_clock_conversion = 1e-9; -#endif -double _ecore_time_loop_time = -1.0; - -/** - * @addtogroup Ecore_Time_Group - * - * @{ - */ - -/** - * Retrieves the current system time as a floating point value in seconds. - * - * This uses a monotonic clock and thus never goes back in time while - * machine is live (even if user changes time or timezone changes, - * however it may be reset whenever the machine is restarted). - * - * @see ecore_loop_time_get(). - * @see ecore_time_unix_get(). - * - * @return The number of seconds. Start time is not defined (it may be - * when the machine was booted, unix time, etc), all it is - * defined is that it never goes backwards (unless you got big critical - * messages when the application started). - */ -EAPI double -ecore_time_get(void) -{ -#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME) - struct timespec t; - - if (EINA_UNLIKELY(_ecore_time_clock_id < 0)) - return ecore_time_unix_get(); - - if (EINA_UNLIKELY(clock_gettime(_ecore_time_clock_id, &t))) - { - CRIT("Cannot get current time."); - /* Try to at least return the latest value retrieved*/ - return _ecore_time_loop_time; - } - - return (double)t.tv_sec + (((double)t.tv_nsec) / 1000000000.0); -#elif defined(HAVE_EVIL) - return evil_time_get(); -#elif defined(__APPLE__) && defined(__MACH__) - return _ecore_time_clock_conversion * (double)mach_absolute_time(); -#else - return ecore_time_unix_get(); -#endif -} - -/** - * Retrieves the current UNIX time as a floating point value in seconds. - * - * @see ecore_time_get(). - * @see ecore_loop_time_get(). - * - * @return The number of seconds since 12.00AM 1st January 1970. - */ -EAPI double -ecore_time_unix_get(void) -{ -#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 -} - -/** - * Retrieves the time at which the last loop stopped waiting for timeouts or - * events. - * - * This gets the time 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(). Note that this time is meant to be used as relative to - * other times obtained on this run. If you need absolute time references, use - * ecore_time_unix_get() instead. - * - * This function can be called before any loop has ever been run, but either - * ecore_init() or ecore_time_get() must have been called once. - * - * @return The number of seconds. Start time is not defined (it may be - * when the machine was booted, unix time, etc), all it is - * defined is that it never goes backwards (unless you got big critical - * messages when the application started). - */ -EAPI double -ecore_loop_time_get(void) -{ - return _ecore_time_loop_time; -} - -/** - * @} - */ - -/********************** Internal methods ********************************/ - -/* TODO: Documentation says "All implementations support the system-wide - * real-time clock, which is identified by CLOCK_REALTIME. Check if the fallback - * to unix time (without specifying the resolution) might be removed - */ -void -_ecore_time_init(void) -{ -#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME) - struct timespec t; - - if (_ecore_time_clock_id != -1) return; - - if (!clock_gettime(CLOCK_MONOTONIC, &t)) - { - _ecore_time_clock_id = CLOCK_MONOTONIC; - DBG("using CLOCK_MONOTONIC."); - } - else if (!clock_gettime(CLOCK_REALTIME, &t)) - { - /* may go backwards */ - _ecore_time_clock_id = CLOCK_REALTIME; - WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME."); - } - else - { - _ecore_time_clock_id = -2; - CRIT("Cannot get a valid clock_gettime() clock id! " - "Fallback to unix time."); - } -#else -# ifndef HAVE_EVIL -# if defined(__APPLE__) && defined(__MACH__) - mach_timebase_info_data_t info; - kern_return_t err = mach_timebase_info(&info); - if (err == 0) - { - _ecore_time_clock_conversion = 1e-9 * (double)info.numer / (double)info.denom; - } - else - { - WRN("Unable to get timebase info. Fallback to nanoseconds."); - } -# else -# warning "Your platform isn't supported yet" - CRIT("Platform does not support clock_gettime. " - "Fallback to unix time."); -# endif -# endif -#endif - - _ecore_time_loop_time = ecore_time_get(); -} - diff --git a/legacy/ecore/src/lib/ecore/ecore_timer.c b/legacy/ecore/src/lib/ecore/ecore_timer.c deleted file mode 100644 index 768198876b..0000000000 --- a/legacy/ecore/src/lib/ecore/ecore_timer.c +++ /dev/null @@ -1,1015 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#define MY_CLASS ECORE_TIMER_CLASS -#define MY_CLASS_NAME "ecore_timer" - -EAPI Eo_Op ECORE_TIMER_BASE_ID = EO_NOOP; - -#define ECORE_TIMER_CHECK(obj) \ - if (!eo_isa((obj), ECORE_TIMER_CLASS)) \ - return - -#ifdef WANT_ECORE_TIMER_DUMP -# include -# include -# define ECORE_TIMER_DEBUG_BT_NUM 64 -typedef void (*Ecore_Timer_Bt_Func)(); -#endif - -struct _Ecore_Timer_Private_Data -{ - EINA_INLIST; - Ecore_Timer *obj; - double in; - double at; - double pending; - Ecore_Task_Cb func; - void *data; - -#ifdef WANT_ECORE_TIMER_DUMP - Ecore_Timer_Bt_Func timer_bt[ECORE_TIMER_DEBUG_BT_NUM]; - int timer_bt_num; -#endif - - int references; - unsigned char delete_me : 1; - unsigned char just_added : 1; - unsigned char frozen : 1; -}; - -typedef struct _Ecore_Timer_Private_Data Ecore_Timer_Private_Data; - -static void _ecore_timer_set(Ecore_Timer *timer, - double at, - double in, - Ecore_Task_Cb func, - void *data); -#ifdef WANT_ECORE_TIMER_DUMP -static int _ecore_timer_cmp(const void *d1, - const void *d2); -#endif - -static int timers_added = 0; -static int timers_delete_me = 0; -static Ecore_Timer_Private_Data *timers = NULL; -static Ecore_Timer_Private_Data *timer_current = NULL; -static Ecore_Timer_Private_Data *suspended = NULL; -static double last_check = 0.0; -static double precision = 10.0 / 1000000.0; - -/** - * @addtogroup Ecore_Timer_Group - * - * @{ - */ - -/** - * Retrieves the current precision used by timer infrastructure. - * @return Current precision. - * @see ecore_timer_precision_set() - */ -EAPI double -ecore_timer_precision_get(void) -{ - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); - return precision; -} - -/** - * @brief Sets the precision to be used by timer infrastructure. - * - * @param value allowed introduced timeout delay, in seconds. - * - * This sets the precision for @b all timers. The precision determines how much - * of an difference from the requested interval is acceptable. One common reason - * to use this function is to @b increase the allowed timeout and thus @b - * decrease precision of the timers, this is because less precise the timers - * result in the system waking up less often and thus consuming less resources. - * - * 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. - */ -EAPI void -ecore_timer_precision_set(double value) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - _ecore_lock(); - - if (value < 0.0) - { - ERR("Precision %f less than zero, ignored", value); - goto unlock; - } - precision = value; - -unlock: - _ecore_unlock(); -} - -/** - * 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. - * - * 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, - Ecore_Task_Cb func, - const void *data) -{ - Ecore_Timer *timer = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - timer = eo_add_custom(MY_CLASS, _ecore_parent, ecore_timer_constructor(in, func, data)); - eo_unref(timer); - return timer; -} - -static Eina_Bool -_ecore_timer_add(Ecore_Timer *obj, - Ecore_Timer_Private_Data *timer, - double now, - double in, - Ecore_Task_Cb func, - const void *data) -{ - - if (EINA_UNLIKELY(!eina_main_loop_is())) - { - eo_error_set(obj); - EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); - } - - timer->obj = obj; - eo_do_super(obj, eo_constructor()); - eo_manual_free_set(obj, EINA_TRUE); - - if (!func) - { - eo_error_set(obj); - ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); - return EINA_FALSE; - } - - if (in < 0.0) in = 0.0; - -#ifdef WANT_ECORE_TIMER_DUMP - timer->timer_bt_num = backtrace((void **)(timer->timer_bt), - ECORE_TIMER_DEBUG_BT_NUM); -#endif - _ecore_timer_set(obj, now + in, in, func, (void *)data); - return EINA_TRUE; -} - -static void -_timer_constructor(Eo *obj, void *_pd, va_list *list) -{ - double in = va_arg(*list, double); - Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); - const void *data = va_arg(*list, const void *); - double now; - - _ecore_lock(); - now = ecore_time_get(); - - Ecore_Timer_Private_Data *timer = _pd; - _ecore_timer_add(obj, timer, now, in, func, data); - _ecore_unlock(); -} - -static void -_timer_loop_constructor(Eo *obj, void *_pd, va_list *list) -{ - double in = va_arg(*list, double); - Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); - const void *data = va_arg(*list, const void *); - double now; - - now = ecore_loop_time_get(); - - Ecore_Timer_Private_Data *timer = _pd; - _ecore_timer_add(obj, timer, now, in, func, data); -} - -static void -_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) -{ - eo_error_set(obj); - ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); -} - - -/** - * 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. - * - * 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, - Ecore_Task_Cb func, - const void *data) -{ - Ecore_Timer *timer; - - _ecore_lock(); - timer = _ecore_timer_loop_add(in, func, data); - _ecore_unlock(); - - 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. - * - * 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) -{ - void *data = NULL; - - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - - data = _ecore_timer_del(timer); - - _ecore_unlock(); - return 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. - */ -EAPI void -ecore_timer_interval_set(Ecore_Timer *timer, - double in) -{ - ECORE_TIMER_CHECK(timer); - eo_do(timer, ecore_obj_timer_interval_set(in)); -} - -static void -_timer_interval_set(Eo *obj EINA_UNUSED, void *_pd, va_list *list) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - double in = va_arg(*list, double); - if (in < 0.0) in = 0.0; - Ecore_Timer_Private_Data *timer = _pd; - - _ecore_lock(); - timer->in = in; - _ecore_unlock(); -} - -/** - * Get the interval the timer ticks on. - * - * @param timer The timer to retrieve the interval from - * @return The interval on success. -1 on failure. - */ -EAPI double -ecore_timer_interval_get(Ecore_Timer *timer) -{ - double interval = -1.0; - - ECORE_TIMER_CHECK(timer) interval; - eo_do(timer, ecore_obj_timer_interval_get(&interval)); - return interval; -} - -static void -_timer_interval_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) -{ - double *ret = va_arg(*list, double *); - *ret = -1.0; - - EINA_MAIN_LOOP_CHECK_RETURN; - Ecore_Timer_Private_Data *timer = _pd; - _ecore_lock(); - *ret = timer->in; - _ecore_unlock(); -} - -/** - * Add some delay for the next occurrence of a timer. - * This doesn't affect the interval of a timer. - * - * @param timer The timer to change. - * @param add The delay to add to the next iteration. - */ -EAPI void -ecore_timer_delay(Ecore_Timer *timer, - double add) -{ - ECORE_TIMER_CHECK(timer); - eo_do(timer, ecore_obj_timer_delay(add)); -} - -static void -_timer_delay(Eo *obj, void *_pd EINA_UNUSED, va_list *list) -{ - double add = va_arg(*list, double); - EINA_MAIN_LOOP_CHECK_RETURN; - - _ecore_lock(); - _ecore_timer_delay(obj, add); - _ecore_unlock(); -} - -/** - * Reset a timer to its full interval - * This doesn't affect the interval of a timer - * @param timer The timer - * @since 1.2 - * @note This is equivalent to (but faster than) - * @code - * ecore_timer_delay(timer, ecore_timer_interval_get(timer) - ecore_timer_pending_get(timer)); - * @endcode - */ -EAPI void -ecore_timer_reset(Ecore_Timer *timer) -{ - ECORE_TIMER_CHECK(timer); - eo_do(timer, ecore_obj_timer_reset()); -} - -static void -_timer_reset(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - double now, add; - EINA_MAIN_LOOP_CHECK_RETURN; - - Ecore_Timer_Private_Data *timer = _pd; - - _ecore_lock(); - now = ecore_time_get(); - - if (timer->frozen) - add = timer->pending; - else - add = timer->at - now; - _ecore_timer_delay(obj, timer->in - add); - _ecore_unlock(); -} - -/** - * Get the pending time regarding a timer. - * - * @param timer The timer to learn from. - * @return The pending time. - * @ingroup Ecore_Timer_Group - */ -EAPI double -ecore_timer_pending_get(Ecore_Timer *timer) -{ - double ret = 0.0; - - ECORE_TIMER_CHECK(timer) ret; - eo_do(timer, ecore_obj_timer_pending_get(&ret)); - return ret; -} - -static void -_timer_pending_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) -{ - double now; - double *ret = va_arg(*list, double *); - *ret = 0.0; - - EINA_MAIN_LOOP_CHECK_RETURN; - - _ecore_lock(); - Ecore_Timer_Private_Data *timer = _pd; - - now = ecore_time_get(); - - if (timer->frozen) - *ret = timer->pending; - else - *ret = timer->at - now; - _ecore_unlock(); -} -/** - * Pauses a running timer. - * - * @param timer The timer to be paused. - * - * The timer callback won't be called while the timer is paused. The remaining - * time until the timer expires will be saved, so the timer can be resumed with - * that same remaining time to expire, instead of expiring instantly. Use - * ecore_timer_thaw() to resume it. - * - * @note Nothing happens if the timer was already paused. - * - * @see ecore_timer_thaw() - */ -EAPI void -ecore_timer_freeze(Ecore_Timer *timer) -{ - ECORE_TIMER_CHECK(timer); - eo_do(timer, eo_event_freeze()); -} - -static void -_timer_freeze(Eo *obj EINA_UNUSED, void *_pd, va_list *list EINA_UNUSED) -{ - double now; - - EINA_MAIN_LOOP_CHECK_RETURN; - - Ecore_Timer_Private_Data *timer = _pd; - _ecore_lock(); - - /* Timer already frozen */ - if (timer->frozen) - goto unlock; - - timers = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); - suspended = (Ecore_Timer_Private_Data *)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; -unlock: - _ecore_unlock(); -} - -/** - * Resumes a frozen (paused) timer. - * - * @param timer The timer to be resumed. - * - * The timer will be resumed from its previous relative position in time. That - * means, if it had X seconds remaining until expire when it was paused, it will - * be started now with those same X seconds remaining to expire again. But - * notice that the interval time won't be touched by this call or by - * ecore_timer_freeze(). - * - * @see ecore_timer_freeze() - */ -EAPI void -ecore_timer_thaw(Ecore_Timer *timer) -{ - ECORE_TIMER_CHECK(timer); - eo_do(timer, eo_event_thaw()); -} - -static void -_timer_thaw(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - double now; - - EINA_MAIN_LOOP_CHECK_RETURN; - Ecore_Timer_Private_Data *timer = _pd; - - _ecore_lock(); - - /* Timer not frozen */ - if (!timer->frozen) - goto unlock; - - suspended = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer)); - now = ecore_time_get(); - - _ecore_timer_set(obj, timer->pending + now, timer->in, timer->func, timer->data); -unlock: - _ecore_unlock(); -} - -EAPI char * -ecore_timer_dump(void) -{ -#ifdef WANT_ECORE_TIMER_DUMP - Eina_Strbuf *result; - char *out; - Ecore_Timer *tm; - Eina_List *tmp = NULL; - int living_timer = 0; - int unknow_timer = 0; - - EINA_MAIN_LOOP_CHECK_RETURN(NULL); - _ecore_lock(); - result = eina_strbuf_new(); - - EINA_INLIST_FOREACH(timers, tm) - tmp = eina_list_sorted_insert(tmp, _ecore_timer_cmp, tm); - - EINA_LIST_FREE(tmp, tm) - { - char **strings; - int j; - - if (!tm->frozen && !tm->delete_me) - living_timer++; - - strings = backtrace_symbols((void **)tm->timer_bt, tm->timer_bt_num); - if (tm->timer_bt_num <= 0 || strings == NULL) - { - unknow_timer++; - continue; - } - - eina_strbuf_append_printf(result, "*** timer: %f ***\n", tm->in); - if (tm->frozen) - eina_strbuf_append(result, "FROZEN\n"); - if (tm->delete_me) - eina_strbuf_append(result, "DELETED\n"); - for (j = 0; j < tm->timer_bt_num; j++) - eina_strbuf_append_printf(result, "%s\n", strings[j]); - - free(strings); - } - - eina_strbuf_append_printf(result, "\n***\nThere is %i living timer.\nWe did lost track of %i timers.\n", living_timer, unknow_timer); - - out = eina_strbuf_string_steal(result); - eina_strbuf_free(result); - _ecore_unlock(); - - return out; -#else - return NULL; -#endif -} - -/** - * @} - */ - -Ecore_Timer * -_ecore_timer_loop_add(double in, - Ecore_Task_Cb func, - const void *data) -{ - Ecore_Timer *timer = NULL; - timer = eo_add_custom(MY_CLASS, _ecore_parent, ecore_timer_loop_constructor(in, func, data)); - eo_unref(timer); - - return timer; -} - -EAPI void -_ecore_timer_delay(Ecore_Timer *obj, - double add) -{ - Ecore_Timer_Private_Data *timer = eo_data_get(obj, MY_CLASS); - - if (timer->frozen) - { - timer->pending += add; - } - else - { - timers = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); - _ecore_timer_set(obj, timer->at + add, timer->in, timer->func, timer->data); - } -} - -void * -_ecore_timer_del(Ecore_Timer *obj) -{ - Ecore_Timer_Private_Data *timer = eo_data_get(obj, MY_CLASS); - - if (timer->frozen && !timer->references) - { - void *data = timer->data; - - suspended = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer)); - - if (timer->delete_me) - timers_delete_me--; - - eo_parent_set(obj, NULL); - - if (eo_destructed_is(obj)) - eo_manual_free(obj); - else - eo_manual_free_set(obj, EINA_FALSE); - return data; - } - - EINA_SAFETY_ON_TRUE_RETURN_VAL(timer->delete_me, NULL); - timer->delete_me = 1; - timers_delete_me++; - return timer->data; -} - -static void -_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) -{ - Ecore_Timer_Private_Data *pd = _pd; - - if (!pd->delete_me) - { - pd->delete_me = 1; - timers_delete_me++; - } - - eo_do_super(obj, eo_destructor()); -} - -void -_ecore_timer_shutdown(void) -{ - Ecore_Timer_Private_Data *timer; - - while ((timer = timers)) - { - timers = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timers)); - - eo_parent_set(timer->obj, NULL); - if (eo_destructed_is(timer->obj)) - eo_manual_free(timer->obj); - else - eo_manual_free_set(timer->obj, EINA_FALSE); - } - - while ((timer = suspended)) - { - suspended = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(suspended)); - - eo_parent_set(timer->obj, NULL); - if (eo_destructed_is(timer->obj)) - eo_manual_free(timer->obj); - else - eo_manual_free_set(timer->obj, EINA_FALSE); - } - - timer_current = NULL; -} - -void -_ecore_timer_cleanup(void) -{ - Ecore_Timer_Private_Data *l; - int in_use = 0, todo = timers_delete_me, done = 0; - - if (!timers_delete_me) return; - for (l = timers; l; ) - { - Ecore_Timer_Private_Data *timer = l; - - l = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(l)->next; - if (timer->delete_me) - { - if (timer->references) - { - in_use++; - continue; - } - timers = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); - - eo_parent_set(timer->obj, NULL); - if (eo_destructed_is(timer->obj)) - eo_manual_free(timer->obj); - else - eo_manual_free_set(timer->obj, EINA_FALSE); - timers_delete_me--; - done++; - if (timers_delete_me == 0) return; - } - } - for (l = suspended; l; ) - { - Ecore_Timer_Private_Data *timer = l; - - l = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(l)->next; - if (timer->delete_me) - { - if (timer->references) - { - in_use++; - continue; - } - suspended = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer)); - - eo_parent_set(timer->obj, NULL); - if (eo_destructed_is(timer->obj)) - eo_manual_free(timer->obj); - else - eo_manual_free_set(timer->obj, EINA_FALSE); - timers_delete_me--; - done++; - if (timers_delete_me == 0) return; - } - } - - if ((!in_use) && (timers_delete_me)) - { - ERR("%d timers to delete, but they were not found!" - "Stats: todo=%d, done=%d, pending=%d, in_use=%d. " - "reset counter.", - timers_delete_me, todo, done, todo - done, in_use); - timers_delete_me = 0; - } -} - -void -_ecore_timer_enable_new(void) -{ - Ecore_Timer_Private_Data *timer; - - if (!timers_added) return; - timers_added = 0; - EINA_INLIST_FOREACH(timers, timer) timer->just_added = 0; -} - -int -_ecore_timers_exists(void) -{ - Ecore_Timer_Private_Data *timer = timers; - - while ((timer) && (timer->delete_me)) - timer = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer)->next; - - return !!timer; -} - -static inline Ecore_Timer * -_ecore_timer_first_get(void) -{ - Ecore_Timer *ret = NULL; - Ecore_Timer_Private_Data *timer = timers; - - while ((timer) && ((timer->delete_me) || (timer->just_added))) - timer = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer)->next; - - if (timer) - ret = timer->obj; - return ret; -} - -static inline Ecore_Timer * -_ecore_timer_after_get(Ecore_Timer *obj) -{ - Ecore_Timer *ret = NULL; - Ecore_Timer_Private_Data *base = eo_data_get(obj, MY_CLASS); - - Ecore_Timer_Private_Data *timer = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(base)->next; - Ecore_Timer_Private_Data *valid_timer = NULL; - double maxtime = base->at + precision; - - while ((timer) && (timer->at < maxtime)) - { - if (!((timer->delete_me) || (timer->just_added))) - valid_timer = timer; - timer = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer)->next; - } - - if (valid_timer) - ret = valid_timer->obj; - return ret; -} - -double -_ecore_timer_next_get(void) -{ - double now; - double in; - Ecore_Timer *first_obj, *second_obj; - Ecore_Timer_Private_Data *first; - - first_obj = _ecore_timer_first_get(); - if (!first_obj) return -1; - - second_obj = _ecore_timer_after_get(first_obj); - if (second_obj) first_obj = second_obj; - - first = eo_data_get(first_obj, MY_CLASS); - - now = ecore_loop_time_get(); - in = first->at - now; - if (in < 0) in = 0; - return in; -} - -static inline void -_ecore_timer_reschedule(Ecore_Timer *obj, - double when) -{ - Ecore_Timer_Private_Data *timer = eo_data_get(obj, MY_CLASS); - if ((timer->delete_me) || (timer->frozen)) return; - - timers = (Ecore_Timer_Private_Data *)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(obj, when + timer->in, timer->in, timer->func, timer->data); - else - _ecore_timer_set(obj, timer->at + timer->in, timer->in, timer->func, timer->data); -} - -/* assume that we hold the ecore lock when entering this function */ -void -_ecore_timer_expired_timers_call(double when) -{ - /* call the first expired timer until no expired timers exist */ - while (_ecore_timer_expired_call(when)) ; -} - -/* assume that we hold the ecore lock when entering this function */ -int -_ecore_timer_expired_call(double when) -{ - if (!timers) return 0; - if (last_check > when) - { - Ecore_Timer_Private_Data *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 */ - Ecore_Timer_Private_Data *timer_old = timer_current; - timer_current = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer_current)->next; - _ecore_timer_reschedule(timer_old->obj, when); - } - - while (timer_current) - { - Ecore_Timer_Private_Data *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_Private_Data *)EINA_INLIST_GET(timer_current)->next; - continue; - } - - timer->references++; - if (!_ecore_call_task_cb(timer->func, timer->data)) - { - if (!timer->delete_me) _ecore_timer_del(timer->obj); - } - timer->references--; - - if (timer_current) /* may have changed in recursive main loops */ - timer_current = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer_current)->next; - - _ecore_timer_reschedule(timer->obj, when); - } - return 0; -} - -static void -_ecore_timer_set(Ecore_Timer *obj, - double at, - double in, - Ecore_Task_Cb func, - void *data) -{ - Ecore_Timer_Private_Data *t2; - - Ecore_Timer_Private_Data *timer = eo_data_get(obj, MY_CLASS); - - 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_Private_Data *)eina_inlist_append_relative(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer), EINA_INLIST_GET(t2)); - return; - } - } - } - timers = (Ecore_Timer_Private_Data *)eina_inlist_prepend(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); -} - -#ifdef WANT_ECORE_TIMER_DUMP -static int -_ecore_timer_cmp(const void *d1, - const void *d2) -{ - const Ecore_Timer *t1 = d1; - const Ecore_Timer *t2 = d2; - - return (int)((t1->in - t2->in) * 100); -} -#endif - -static void -_class_constructor(Eo_Class *klass) -{ - const Eo_Op_Func_Description func_desc[] = { - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), - - EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_CONSTRUCTOR), _timer_constructor), - EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR), _timer_loop_constructor), - EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_SET), _timer_interval_set), - EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_GET), _timer_interval_get), - - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE), _timer_freeze), - EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW), _timer_thaw), - - EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_DELAY), _timer_delay), - EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_RESET), _timer_reset), - EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_PENDING_GET), _timer_pending_get), - EO_OP_FUNC_SENTINEL - }; - - eo_class_funcs_set(klass, func_desc); -} - -static const Eo_Op_Description op_desc[] = { - EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_CONSTRUCTOR, "Creates a timer to call the given function in the given period of time."), - EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR, "Creates a timer to call the given function in the given period of time."), - EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_INTERVAL_SET, "Change the interval the timer ticks of."), - EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_INTERVAL_GET, "Get the interval the timer ticks on."), - EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_DELAY, "Add some delay for the next occurrence of a timer."), - EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_RESET, "Reset a timer to its full interval"), - EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_PENDING_GET, "Get the pending time regarding a timer."), - EO_OP_DESCRIPTION_SENTINEL -}; -static const Eo_Class_Description class_desc = { - EO_VERSION, - MY_CLASS_NAME, - EO_CLASS_TYPE_REGULAR, - EO_CLASS_DESCRIPTION_OPS(&ECORE_TIMER_BASE_ID, op_desc, ECORE_TIMER_SUB_ID_LAST), - NULL, - sizeof(Ecore_Timer_Private_Data), - _class_constructor, - NULL -}; - -EO_DEFINE_CLASS(ecore_timer_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/legacy/ecore/src/lib/ecore_cocoa/Ecore_Cocoa.h b/legacy/ecore/src/lib/ecore_cocoa/Ecore_Cocoa.h deleted file mode 100644 index 51c8ead21b..0000000000 --- a/legacy/ecore/src/lib/ecore_cocoa/Ecore_Cocoa.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef __ECORE_COCOA_H__ -#define __ECORE_COCOA_H__ - -/* - * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND - * THE API MAY CHANGE. - */ - -#ifndef ECORE_COCOA_WIP_GNSIDNQI -# warning "You are using a work in progress API. This API is not stable" -# warning "and is subject to change. You use this at your own risk." -#endif - -#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(void); -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); - -EAPI void ecore_cocoa_window_view_set(Ecore_Cocoa_Window *window, - void *view); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/legacy/ecore/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h b/legacy/ecore/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h deleted file mode 100644 index 7068bc22a8..0000000000 --- a/legacy/ecore/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h +++ /dev/null @@ -1,285 +0,0 @@ -#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, "asterisk", "*" }, -{ 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__ */ diff --git a/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa.m b/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa.m deleted file mode 100644 index 3f6023af1f..0000000000 --- a/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa.m +++ /dev/null @@ -1,283 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include - -#include -#include -#include - -#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(void) -{ - if (++_ecore_cocoa_init_count != 1) - return _ecore_cocoa_init_count; - - if (!ecore_event_init()) - return --_ecore_cocoa_init_count; - - NSApplicationLoad(); - - 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]; -} diff --git a/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa_private.h b/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa_private.h deleted file mode 100644 index 0b4cf3178e..0000000000 --- a/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa_private.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ECORE_COCOA_PRIVATE_H -#define _ECORE_COCOA_PRIVATE_H - -struct _Ecore_Cocoa_Window -{ - NSWindow *window; - unsigned int borderless : 1; -}; - - -#endif diff --git a/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa_window.m b/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa_window.m deleted file mode 100644 index 2091a69b32..0000000000 --- a/legacy/ecore/src/lib/ecore_cocoa/ecore_cocoa_window.m +++ /dev/null @@ -1,163 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "Ecore_Cocoa.h" -#include "ecore_cocoa_private.h" - -Ecore_Cocoa_Window * -ecore_cocoa_window_new(int x, - int y, - int width, - int height) -{ - Ecore_Cocoa_Window *w; - - NSWindow *window = [[NSWindow alloc] - initWithContentRect:NSMakeRect(x, y, width, height) - styleMask:(NSTitledWindowMask | - NSClosableWindowMask | - NSResizableWindowMask | - NSMiniaturizableWindowMask) - backing:NSBackingStoreBuffered - defer:NO - screen:nil - ]; - - if (!window) - return NULL; - - [window setBackgroundColor:[NSColor whiteColor]]; - - w = calloc(1, sizeof(Ecore_Cocoa_Window)); - w->window = window; - w->borderless = 0; - - return w; -} - -void -ecore_cocoa_window_free(Ecore_Cocoa_Window *window) -{ - if (!window) - return; - - [window->window release]; - free(window); -} - -void -ecore_cocoa_window_move(Ecore_Cocoa_Window *window, - int x, - int y) -{ - NSRect win_frame; - - if (!window) - return; - - win_frame = [window->window frame]; - win_frame.origin.x = x; - win_frame.origin.y = y; - - [window->window setFrame:win_frame display:YES]; -} - -void -ecore_cocoa_window_resize(Ecore_Cocoa_Window *window, - int width, - int height) -{ - if (!window) - return; - - NSRect win_frame; - - if (!window) - return; - - win_frame = [window->window frame]; - win_frame.size.height = height; - win_frame.size.width = width; - - [window->window setFrame:win_frame display:YES]; -} - -void -ecore_cocoa_window_move_resize(Ecore_Cocoa_Window *window, - int x, - int y, - int width, - int height) -{ - if (!window) - return; - - NSRect win_frame; - - if (!window) - return; - - win_frame = [window->window frame]; - win_frame.size.height = height; - win_frame.size.width = width; - win_frame.origin.x = x; - win_frame.origin.y = y; - - [window->window setFrame:win_frame display:YES]; -} - -void -ecore_cocoa_window_title_set(Ecore_Cocoa_Window *window, const char *title) -{ - if (!window || !title) - return; - - [window->window setTitle:[NSString stringWithUTF8String:title]]; -} - -void -ecore_cocoa_window_show(Ecore_Cocoa_Window *window) -{ - if (!window || [window->window isVisible]) - { - printf("Window(%p) is not visible\n", window->window); - return; - } - - [window->window makeKeyAndOrderFront:NSApp]; -} - -void -ecore_cocoa_window_hide(Ecore_Cocoa_Window *window) -{ - if (!window || ![window->window isVisible]) - return; - - [window->window orderOut:NSApp]; -} - -void -ecore_cocoa_window_borderless_set(Ecore_Cocoa_Window *window, - int on) -{ - if (!window) - return; - - if (on) - [window->window setContentBorderThickness:0.0 - forEdje:NSMinXEdge | NSMinYEdge | NSMaxXEdge | NSMaxYEdge]; -} - -void -ecore_cocoa_window_view_set(Ecore_Cocoa_Window *window, - void *view) -{ - if (!window || !view) - return; - - [[window->window contentView] addSubview:view]; - -} diff --git a/legacy/ecore/src/lib/ecore_con/Ecore_Con.h b/legacy/ecore/src/lib/ecore_con/Ecore_Con.h deleted file mode 100644 index 0a832fc37a..0000000000 --- a/legacy/ecore/src/lib/ecore_con/Ecore_Con.h +++ /dev/null @@ -1,1948 +0,0 @@ -#ifndef _ECORE_CON_H -#define _ECORE_CON_H - -#include -#include -#ifdef _WIN32 -# include -#else -# include -#endif -#include - -#ifdef EAPI -# undef EAPI -#endif - -#ifdef _WIN32 -# ifdef EFL_ECORE_CON_BUILD -# ifdef DLL_EXPORT -# define EAPI __declspec(dllexport) -# else -# define EAPI -# endif -# 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 - -/** - * @defgroup Ecore_Con_Group Ecore_Con - Connection 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 descriptors 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(), optionally using - * an ECORE_CON_USE_* encryption type OR'ed with the type for encryption. - * - * 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(). - * - * 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 - * - * Events are described in @ref Ecore_Con_Events_Group. - */ - - -/** - * @defgroup Ecore_Con_Events_Group Ecore Connection Events Functions - * - * @li ECORE_CON_CLIENT_ADD: Whenever a client connection is made to an - * @c Ecore_Con_Server, an event of this type is emitted, allowing the - * retrieval of the client's ip with @ref ecore_con_client_ip_get and - * associating data with the client using ecore_con_client_data_set. - * @li ECORE_CON_EVENT_CLIENT_DEL: Whenever a client connection to an - * @c Ecore_Con_Server, an event of this type is emitted. The contents of - * the data with this event are variable, but if the client object in the data - * is non-null, it must be freed with @ref ecore_con_client_del. - * @li ECORE_CON_EVENT_SERVER_ADD: Whenever a server object is created - * with @ref ecore_con_server_connect, an event of this type is emitted, - * allowing for data to be serialized and sent to the server using - * @ref ecore_con_server_send. At this point, the http handshake has - * occurred. - * @li ECORE_CON_EVENT_SERVER_DEL: Whenever a server object is destroyed, - * usually by the server connection being refused or dropped, an event of this - * type is emitted. The contents of the data with this event are variable, - * but if the server object in the data is non-null, it must be freed - * with @ref ecore_con_server_del. - * @li ECORE_CON_EVENT_CLIENT_DATA: Whenever a client connects to your server - * object and sends data, an event of this type is emitted. The data will contain both - * the size and contents of the message sent by the client. It should be noted that - * data within this object is transient, so it must be duplicated in order to be - * retained. This event will continue to occur until the client has stopped sending its - * message, so a good option for storing this data is an Eina_Strbuf. Once the message has - * been received in full, the client object must be freed with ecore_con_client_free. - * @li ECORE_CON_EVENT_SERVER_DATA: Whenever your server object connects to its destination - * and receives data, an event of this type is emitted. The data will contain both - * the size and contents of the message sent by the server. It should be noted that - * data within this object is transient, so it must be duplicated in order to be - * retained. This event will continue to occur until the server has stopped sending its - * message, so a good option for storing this data is an Eina_Strbuf. Once the message has - * been received in full, the server object must be freed with ecore_con_server_free. - * - */ - -/** - * @defgroup Ecore_Con_Buffer Ecore Connection Buffering - * - * As Ecore_Con works on an event driven design, as data arrives, events will - * be produced containing the data that arrived. It is up to the user of - * Ecore_Con to either parse as they go, append to a file to later parse the - * whole file in one go, or append to memory to parse or handle leter. - * - * To help with this Eina has some handy API's. The Eina_Binbuf and - * Eina_Strbuf APIs, abstract dynamic buffer management and make it trivial - * to handle buffers at runtime, without having to manage them. Eina_Binbuf - * makes it possible to create, expand, reset and slice a blob of memory - - * all via API. No system calls, no pointer manipulations and no size - * calculation. - * - * Additional functions include adding content at specified byte positions in - * the buffer, escaping the inputs, find and replace strings. This provides - * extreme flexibility to play around, with a dynamic blob of memory. - * - * It is good to free it (using eina_binbuf_free()) after using it. - * - * Eina_Binbuf compliments Ecore_Con use cases, where dynamic sizes of data - * arrive from the network (think http download in chunks). Using - * Eina_Binbuf provides enough flexibility to handle data as it arrives and - * to defer its processing until desired, without having to think about - * where to store the temporary data and how to manage its size. - * - * An example of how to use these with Ecore_Con follows. - * - * @code - * #include - * #include - * #include - * - * static Eina_Bool - * data_callback(void *data, int type, void *event) - * { - * Ecore_Con_Event_Url_Data *url_data = event; - * if ( url_data->size > 0) - * { - * // append data as it arrives - don't worry where or how it gets stored. - * // Also don't worry about size, expanding, reallocing etc. - * // just keep appending - size is automatically handled. - * - * eina_binbuf_append_length(data, url_data->data, url_data->size); - * - * fprintf(stderr, "Appended %d \n", url_data->size); - * } - * return EINA_TRUE; - * } - * - * - * - * static Eina_Bool - * completion_callback(void *data, int type, void *event) - * { - * Ecore_Con_Event_Url_Complete *url_complete = event; - * printf("download completed with status code: %d\n", url_complete->status); - * - * // get the data back from Eina_Binbuf - * char *ptr = eina_binbuf_string_get(data); - * size_t size = eina_binbuf_length_get(data); - * - * // process data as required (write to file) - * fprintf(stderr, "Size of data = %d bytes\n", size); - * int fd = open("./elm.png", O_CREAT); - * write(fd, ptr, size); - * close(fd); - * - * // free it when done. - * eina_binbuf_free(data); - * - * ecore_main_loop_quit(); - * - * return EINA_TRUE; - * } - * - * - * int - * main(int argc, char **argv) - * { - * - * const char *url = "http://www.enlightenment.org/p/index/d/logo.png"; - * - * ecore_init(); - * ecore_con_init(); - * ecore_con_url_init(); - * - * - * // This is single additional line to manage dynamic network data. - * Eina_Binbuf *data = eina_binbuf_new(); - * Ecore_Con_Url *url_con = ecore_con_url_new(url); - * - * ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, - * completion_callback, - * data); - * ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, - * data_callback, - * data); - * ecore_con_url_get(url_con); - * - * ecore_main_loop_begin(); - * return 0; - * } - * @endcode - */ - -#ifdef __cplusplus -extern "C" { -#endif -#define ECORE_CON_USE_SSL ECORE_CON_USE_SSL2 -#define ECORE_CON_REMOTE_SYSTEM ECORE_CON_REMOTE_TCP - - -/** - * @typedef Ecore_Con_Server - * A connection handle to a server - * @ingroup Ecore_Con_Server_Group - */ -typedef struct _Ecore_Con_Server Ecore_Con_Server; - -/** - * @typedef Ecore_Con_Client - * A connection handle to a client - * @ingroup Ecore_Con_Client_Group - */ -typedef struct _Ecore_Con_Client Ecore_Con_Client; - -/** - * @typedef Ecore_Con_Socks - * An object representing a SOCKS proxy - * @ingroup Ecore_Con_Socks_Group - * @since 1.2 - */ -typedef struct Ecore_Con_Socks Ecore_Con_Socks; - -/** - * @typedef Ecore_Con_Url - * A handle to an http upload/download object - * @ingroup Ecore_Con_Url_Group - */ -typedef struct _Ecore_Con_Url Ecore_Con_Url; - - -/** - * @addtogroup Ecore_Con_Events_Group - * @{ - */ - -/** - * @typedef Ecore_Con_Event_Client_Add - * Used as the @p data param for the corresponding event - */ -typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add; - -/** - * @typedef Ecore_Con_Event_Client_Upgrade - * Used as the @p data param for the corresponding event - * @since 1.1 - */ -typedef struct _Ecore_Con_Event_Client_Upgrade Ecore_Con_Event_Client_Upgrade; - -/** - * @typedef Ecore_Con_Event_Client_Del - * Used as the @p data param for the corresponding event - */ -typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del; - -/** - * @typedef Ecore_Con_Event_Client_Error - * Used as the @p data param for the corresponding event - * @since 1.1 - */ -typedef struct _Ecore_Con_Event_Client_Error Ecore_Con_Event_Client_Error; - -/** - * @typedef Ecore_Con_Event_Server_Add - * Used as the @p data param for the corresponding event - */ -typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add; - -/** - * @typedef Ecore_Con_Event_Server_Upgrade - * Used as the @p data param for the corresponding event - * @since 1.1 - */ -typedef struct _Ecore_Con_Event_Server_Upgrade Ecore_Con_Event_Server_Upgrade; - -/** - * @typedef Ecore_Con_Event_Server_Del - * Used as the @p data param for the corresponding event - */ -typedef struct _Ecore_Con_Event_Server_Del Ecore_Con_Event_Server_Del; - -/** - * @typedef Ecore_Con_Event_Server_Error - * Used as the @p data param for the corresponding event - * @since 1.1 - */ -typedef struct _Ecore_Con_Event_Server_Error Ecore_Con_Event_Server_Error; - -/** - * @typedef Ecore_Con_Event_Client_Data - * Used as the @p data param for the corresponding event - */ -typedef struct _Ecore_Con_Event_Client_Data Ecore_Con_Event_Client_Data; - -/** - * @typedef Ecore_Con_Event_Server_Data - * Used as the @p data param for the corresponding event - */ -typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data; - -/** - * @typedef Ecore_Con_Event_Client_Write - * Used as the @p data param for the corresponding event - * @since 1.1 - */ -typedef struct _Ecore_Con_Event_Client_Write Ecore_Con_Event_Client_Write; - -/** - * @typedef Ecore_Con_Event_Server_Write - * Used as the @p data param for the corresponding event - * @since 1.1 - */ -typedef struct _Ecore_Con_Event_Server_Write Ecore_Con_Event_Server_Write; - -/** - * @typedef Ecore_Con_Event_Proxy_Bind - * Used as the @p data param for the corresponding event - * @since 1.2 - */ -typedef struct _Ecore_Con_Event_Proxy_Bind Ecore_Con_Event_Proxy_Bind; - -/** - * @typedef Ecore_Con_Event_Url_Data - * Used as the @p data param for the corresponding event - * @ingroup Ecore_Con_Url_Group - */ -typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data; - -/** - * @typedef Ecore_Con_Event_Url_Complete - * Used as the @p data param for the corresponding event - * @ingroup Ecore_Con_Url_Group - */ -typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete; - -/** - * @typedef Ecore_Con_Event_Url_Progress - * Used as the @p data param for the corresponding event - * @ingroup Ecore_Con_Url_Group - */ -typedef struct _Ecore_Con_Event_Url_Progress Ecore_Con_Event_Url_Progress; - -/** - * @struct _Ecore_Con_Event_Client_Add - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ADD event - */ -struct _Ecore_Con_Event_Client_Add -{ - Ecore_Con_Client *client; /** the client that connected */ -}; - -/** - * @struct _Ecore_Con_Event_Client_Upgrade - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_UPGRADE event - * @since 1.1 - */ -struct _Ecore_Con_Event_Client_Upgrade -{ - Ecore_Con_Client *client; /** the client that completed handshake */ -}; - -/** - * @struct _Ecore_Con_Event_Client_Del - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DEL event - */ -struct _Ecore_Con_Event_Client_Del -{ - Ecore_Con_Client *client; /** the client that was lost */ -}; - -/** - * @struct _Ecore_Con_Event_Client_Error - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ERROR event - */ -struct _Ecore_Con_Event_Client_Error -{ - Ecore_Con_Client *client; /** the client for which an error occurred */ - char *error; /**< the error string describing what happened */ -}; - -/** - * @struct _Ecore_Con_Event_Server_Add - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ADD event - */ -struct _Ecore_Con_Event_Server_Add -{ - Ecore_Con_Server *server; /** the server that was connected to */ -}; - -/** - * @struct _Ecore_Con_Event_Server_Upgrade - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_UPGRADE event - * @since 1.1 - */ -struct _Ecore_Con_Event_Server_Upgrade -{ - Ecore_Con_Server *server; /** the server that was connected to */ -}; - -/** - * @struct _Ecore_Con_Event_Server_Del - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DEL event - */ -struct _Ecore_Con_Event_Server_Del -{ - Ecore_Con_Server *server; /** the client that was lost */ -}; - -/** - * @struct _Ecore_Con_Event_Server_Error - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ERROR event - */ -struct _Ecore_Con_Event_Server_Error -{ - Ecore_Con_Server *server; /** the server for which an error occurred */ - char *error; /**< the error string describing what happened */ -}; - -/** - * @struct _Ecore_Con_Event_Client_Data - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DATA event - */ -struct _Ecore_Con_Event_Client_Data -{ - Ecore_Con_Client *client; /**< the client that connected */ - void *data; /**< the data that the client sent */ - int size; /**< the length of the data sent */ -}; - -/** - * @struct _Ecore_Con_Event_Server_Data - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DATA event - */ -struct _Ecore_Con_Event_Server_Data -{ - Ecore_Con_Server *server; /**< the server that was connected to */ - void *data; /**< the data that the server sent */ - int size; /**< the length of the data sent */ -}; - -/** - * @struct _Ecore_Con_Event_Client_Write - * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_WRITE event - */ -struct _Ecore_Con_Event_Client_Write -{ - Ecore_Con_Client *client; /**< the client that connected */ - int size; /**< the length of the data sent */ -}; - -/** - * @struct _Ecore_Con_Event_Server_Write - * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_WRITE event - */ -struct _Ecore_Con_Event_Server_Write -{ - Ecore_Con_Server *server; /**< the server that was connected to */ - int size; /**< the length of the data sent */ -}; - -/** - * @struct _Ecore_Con_Event_Proxy_Bind - * Used as the @p data param for the @ref ECORE_CON_EVENT_PROXY_BIND event - * @ingroup Ecore_Con_Socks_Group - * @since 1.2 - */ -struct _Ecore_Con_Event_Proxy_Bind -{ - Ecore_Con_Server *server; /**< the server object connected to the proxy */ - const char *ip; /**< the proxy-bound ip address */ - int port; /**< the proxy-bound port */ -}; - -/** - * @struct _Ecore_Con_Event_Url_Data - * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_DATA event - * @ingroup Ecore_Con_Url_Group - */ -struct _Ecore_Con_Event_Url_Data -{ - Ecore_Con_Url *url_con; /**< a pointer to the connection object */ - int size; /**< the size of the current received data (in bytes) */ - unsigned char data[1]; /**< the data received on this event */ -}; - -/** - * @struct _Ecore_Con_Event_Url_Complete - * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_COMPLETE event - * @ingroup Ecore_Con_Url_Group - */ -struct _Ecore_Con_Event_Url_Complete -{ - Ecore_Con_Url *url_con; /**< a pointer to the connection object */ - int status; /**< HTTP status code of the operation (200, 404, 401, etc.) */ -}; - -/** - * @struct _Ecore_Con_Event_Url_Progress - * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_PROGRESS event - * @ingroup Ecore_Con_Url_Group - */ -struct _Ecore_Con_Event_Url_Progress -{ - Ecore_Con_Url *url_con; /**< a pointer to the connection object */ - struct - { - double total; /**< total size of the downloading data (in bytes) */ - double now; /**< current size of the downloading data (in bytes) */ - } down; /**< download info */ - struct - { - double total; /**< total size of the uploading data (in bytes) */ - double now; /**< current size of the uploading data (in bytes) */ - } up; /**< upload info */ -}; - -/** A client has connected to the server */ -EAPI extern int ECORE_CON_EVENT_CLIENT_ADD; -/** A client has disconnected from the server */ -EAPI extern int ECORE_CON_EVENT_CLIENT_DEL; -/** A client experienced an error - * @since 1.1 - */ -EAPI extern int ECORE_CON_EVENT_CLIENT_ERROR; -/** A client connection has been upgraded to SSL - * @since 1.1 - */ -EAPI extern int ECORE_CON_EVENT_CLIENT_UPGRADE; -/** A server was created */ -EAPI extern int ECORE_CON_EVENT_SERVER_ADD; -/** A server connection was lost */ -EAPI extern int ECORE_CON_EVENT_SERVER_DEL; -/** A server experienced an error - * @since 1.1 - */ -EAPI extern int ECORE_CON_EVENT_SERVER_ERROR; -/** A server connection has been upgraded to SSL - * @since 1.1 - */ -EAPI extern int ECORE_CON_EVENT_SERVER_UPGRADE; -/** A server connection has sent data to its client - * @since 1.1 - */ -EAPI extern int ECORE_CON_EVENT_CLIENT_WRITE; -/** A server connection object has sent data - * @since 1.1 - */ -EAPI extern int ECORE_CON_EVENT_SERVER_WRITE; -/** A client connected to the server has sent data */ -EAPI extern int ECORE_CON_EVENT_CLIENT_DATA; -/** A server connection object has data */ -EAPI extern int ECORE_CON_EVENT_SERVER_DATA; -/** A server connection has successfully negotiated an ip:port binding - * @since 1.2 - */ -EAPI extern int ECORE_CON_EVENT_PROXY_BIND; -/** A URL object has data */ -EAPI extern int ECORE_CON_EVENT_URL_DATA; -/** A URL object has completed its transfer to and from the server and can be reused */ -EAPI extern int ECORE_CON_EVENT_URL_COMPLETE; -/** A URL object has made progress in its transfer */ -EAPI extern int ECORE_CON_EVENT_URL_PROGRESS; - -/** - * @} - */ - -/** - * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions - * - * Utility functions that set up and shut down the Ecore Connection - * library. - * - * There's also ecore_con_lookup() that can be used to make simple asynchronous - * DNS lookups. - * - * A simple example of how to use these functions: - * @li @ref ecore_con_lookup_example_c - * - * @{ - */ - -/** - * @typedef Ecore_Con_Dns_Cb - * A callback type for use with @ref ecore_con_lookup. - */ -typedef void (*Ecore_Con_Dns_Cb)(const char *canonname, - const char *ip, - struct sockaddr *addr, - int addrlen, - void *data); - -/** - * @typedef Ecore_Con_Type - * @enum _Ecore_Con_Type - * Types for an ecore_con client/server object. A correct way to set this type is - * with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if encryption is desired, - * and LOAD_CERT if the previously loaded certificate should be used. - * @code - * ECORE_CON_REMOTE_TCP | ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT - * @endcode - * @ingroup Ecore_Con_Server_Group - */ -typedef enum _Ecore_Con_Type -{ - /** Socket in ~/.ecore */ - ECORE_CON_LOCAL_USER = 0, - /** Socket in /tmp */ - ECORE_CON_LOCAL_SYSTEM = 1, - /** Abstract socket */ - ECORE_CON_LOCAL_ABSTRACT = 2, - /** Remote server using TCP */ - ECORE_CON_REMOTE_TCP = 3, - /** Remote multicast server */ - ECORE_CON_REMOTE_MCAST = 4, - /** Remote server using UDP */ - ECORE_CON_REMOTE_UDP = 5, - /** Remote broadcast using UDP */ - ECORE_CON_REMOTE_BROADCAST = 6, - /** Remote connection sending packets immediately */ - ECORE_CON_REMOTE_NODELAY = 7, - /** Remote connection sending data in large chunks - * @note Only available on Linux - * @since 1.2 - */ - ECORE_CON_REMOTE_CORK = 8, - /** Use SSL2: UNSUPPORTED. **/ - ECORE_CON_USE_SSL2 = (1 << 4), - /** Use SSL3 */ - ECORE_CON_USE_SSL3 = (1 << 5), - /** Use TLS */ - ECORE_CON_USE_TLS = (1 << 6), - /** Use both TLS and SSL3 */ - ECORE_CON_USE_MIXED = ECORE_CON_USE_SSL3 | ECORE_CON_USE_TLS, - /** Attempt to use the loaded certificate */ - ECORE_CON_LOAD_CERT = (1 << 7), - /** Disable all types of proxy on the server - * @note Only functional for clients - * @since 1.2 - */ - ECORE_CON_NO_PROXY = (1 << 8) -} Ecore_Con_Type; - -/** - * Initialises the Ecore_Con library. - * @return Number of times the library has been initialised without being - * shut down. - * - * @note This function already calls ecore_init() internally, so you don't need - * to call it explicitly. - */ -EAPI int ecore_con_init(void); - -/** - * Shuts down the Ecore_Con library. - * @return Number of times the library has been initialised without being - * shut down. - * @note This function already calls ecore_shutdown() internally, so you don't - * need to call it explicitly unless you called ecore_init() explicitly too. - */ -EAPI int ecore_con_shutdown(void); - -/** - * Do an asynchronous DNS lookup. - * - * @param name IP address or server name to translate. - * @param done_cb Callback to notify when done. - * @param data User data to be given to done_cb. - * @return @c EINA_TRUE if the request did not fail to be set up, @c EINA_FALSE - * if it failed. - * - * This function performs a DNS lookup on the hostname specified by @p name, - * then calls @p done_cb with the result and the @p data given as parameter. - * The result will be given to the @p done_cb as follows: - * @li @c canonname - the canonical name of the address - * @li @c ip - the resolved ip address - * @li @c addr - a pointer to the socket address - * @li @c addrlen - the length of the socket address, in bytes - * @li @c data - the data pointer given as parameter to ecore_con_lookup() - */ -EAPI Eina_Bool ecore_con_lookup(const char *name, - Ecore_Con_Dns_Cb done_cb, - const void *data); - -/** - * @} - */ - -/** - * @defgroup Ecore_Con_SSL_Group Ecore Connection SSL Functions - * - * @{ - */ -EAPI int ecore_con_ssl_available_get(void); -EAPI Eina_Bool ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr, const char *cert); -EAPI Eina_Bool ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr, const char *key_file); -EAPI Eina_Bool ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, const char *crl_file); -EAPI Eina_Bool ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, const char *ca_file); -EAPI void ecore_con_ssl_server_verify(Ecore_Con_Server *svr); -EAPI void ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr); -EAPI void ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name); -EAPI const char *ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr); -EAPI Eina_Bool ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type compl_type); -EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type compl_type); - -/** - * @} - */ - -EAPI Ecore_Con_Socks *ecore_con_socks4_remote_add(const char *ip, int port, const char *username); -EAPI Eina_Bool ecore_con_socks4_remote_exists(const char *ip, int port, const char *username); -EAPI void ecore_con_socks4_remote_del(const char *ip, int port, const char *username); -EAPI Ecore_Con_Socks *ecore_con_socks5_remote_add(const char *ip, int port, const char *username, const char *password); -EAPI Eina_Bool ecore_con_socks5_remote_exists(const char *ip, int port, const char *username, const char *password); -EAPI void ecore_con_socks5_remote_del(const char *ip, int port, const char *username, const char *password); -EAPI void ecore_con_socks_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable); -EAPI Eina_Bool ecore_con_socks_lookup_get(Ecore_Con_Socks *ecs); -EAPI void ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind); -EAPI Eina_Bool ecore_con_socks_bind_get(Ecore_Con_Socks *ecs); -EAPI unsigned int ecore_con_socks_version_get(Ecore_Con_Socks *ecs); -EAPI void ecore_con_socks_remote_del(Ecore_Con_Socks *ecs); -EAPI void ecore_con_socks_apply_once(Ecore_Con_Socks *ecs); -EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs); - -/** - * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions - * - * This group of functions is applied to an @ref Ecore_Con_Server object. It - * doesn't mean that they should be used in the server application, but on the - * server object. In fact, most of them should be used in the client - * application, when retrieving information or sending data. - * - * Setting up a server is very simple: you just need to start it with - * ecore_con_server_add() and setup some callbacks to the events - * @ref ECORE_CON_EVENT_CLIENT_ADD, @ref ECORE_CON_EVENT_CLIENT_DEL and - * @ref ECORE_CON_EVENT_CLIENT_DATA, that will be called when a client is - * communicating with the server: - * - * @code - * if (!(svr = ecore_con_server_add(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL))) - * exit(1); - * - * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, _add_cb, NULL); - * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, _del_cb, NULL); - * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, _data_cb, NULL); - * - * ecore_main_loop_begin(); - * @endcode - * - * The function ecore_con_server_connect() can be used to write a client that - * connects to a server. The resulting code will be very similar to the server - * code: - * - * @code - * if (!(svr = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL))) - * exit(1); - * - * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _add_cb, NULL); - * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _del_cb, NULL); - * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _data_cb, NULL); - * - * ecore_main_loop_begin(); - * @endcode - * - * After these two pieces of code are executed, respectively, in the server and - * client code, the server will be up and running and the client will try to - * connect to it. The connection, with its subsequent messages being sent from - * server to client and client to server, can be represented in the following - * sequence diagram: - * - * @htmlonly - * - * Full size - * @endhtmlonly - * - * @image rtf ecore_con-client-server.png - * @image latex ecore_con-client-server.eps width=\textwidth - * - * Please notice the important difference between these two codes: the first is - * used for writing a @b server, while the second should be used for writing a - * @b client. - * - * A reference for the @c client functions can be found at @ref - * Ecore_Con_Client_Group. - * - * Examples of usage for this API can be found here: - * @li @ref ecore_con_server_simple_example_c - * @li @ref ecore_con_client_simple_example_c - * - * @{ - */ - -/** - * Creates a server to listen for connections. - * - * @param type The connection type. - * @param name Name to associate with the socket. It is used when - * generating the socket name of a Unix socket, or for - * determining what host to listen on for TCP sockets. - * @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. - * - * The socket on which the server listens depends on the connection - * type: - * @li If @a type is @c ECORE_CON_LOCAL_USER, the server will listen on - * the Unix socket "~/.ecore/[name]/[port]". - * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen - * on Unix socket "/tmp/.ecore_service|[name]|[port]". - * @li If @a type is @c ECORE_CON_REMOTE_TCP, the server will listen - * on TCP port @c port. - * - * More information about the @p type can be found at @ref _Ecore_Con_Type. - * - * The @p data parameter can be fetched later using ecore_con_server_data_get() - * or changed with ecore_con_server_data_set(). - */ -EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, - const char *name, int port, - const void *data); - -/** - * Creates a connection to the specified server and returns an associated object. - * - * @param 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. - * - * The socket to which the connection is made depends on the connection type: - * @li If @a type is @c ECORE_CON_LOCAL_USER, the function will - * connect to the server at the Unix socket - * "~/.ecore/[name]/[port]". - * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the function will - * connect to the server at the Unix socket - * "/tmp/.ecore_service|[name]|[port]". - * @li If @a type is @c ECORE_CON_REMOTE_TCP, the function will - * connect to the server at the TCP port "[name]:[port]". - * - * More information about the @p type can be found at @ref _Ecore_Con_Type. - * - * This function won't block. It will either succeed, or fail due to invalid - * parameters, failed memory allocation, etc., returning @c NULL on that case. - * - * However, even if this call returns a valid @ref Ecore_Con_Server, the - * connection will only be successfully completed if an event of type - * @ref ECORE_CON_EVENT_SERVER_ADD is received. If it fails to complete, an - * @ref ECORE_CON_EVENT_SERVER_DEL will be received. - * - * The @p data parameter can be fetched later using ecore_con_server_data_get() - * or changed with ecore_con_server_data_set(). - */ -EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, - const char *name, int port, - const void *data); -/** - * Closes the connection and frees the given server. - * - * @param svr The given server. - * @return Data associated with the server when it was created. - * - * All the clients connected to this server will be disconnected. - * - * @see ecore_con_server_add, ecore_con_server_connect - */ -EAPI void * ecore_con_server_del(Ecore_Con_Server *svr); - -/** - * Retrieves the data associated with the given server. - * - * @param svr The given server. - * @return The associated data. - * - * @see ecore_con_server_data_set() - */ -EAPI void * ecore_con_server_data_get(Ecore_Con_Server *svr); -/** - * Sets the data associated with the given server. - * - * @param svr The given server. - * @param data The data to associate with @p svr - * @return The previously associated data, if any. - * - * @see ecore_con_server_data_get() - */ -EAPI void * ecore_con_server_data_set(Ecore_Con_Server *svr, - void *data); -/** - * Retrieves whether the given server is currently connected. - * - * @param svr The given server. - * @return @c EINA_TRUE if the server is connected, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool ecore_con_server_connected_get(Ecore_Con_Server *svr); -/** - * Retrieves the current list of clients. - * - * @param svr The given server. - * @return The list of clients on this server. - * - * Each node in the returned list points to an @ref Ecore_Con_Client. This list - * cannot be modified or freed. It can also change if new clients are connected - * or disconnected, and will become invalid when the server is deleted/freed. - */ -EAPI const Eina_List * ecore_con_server_clients_get(Ecore_Con_Server *svr); - -/** - * Retrieves the name of server. - * - * @param svr The given server. - * @return The name of the server. - * - * The name returned is the name used to connect on this server. - */ -EAPI const char * ecore_con_server_name_get(Ecore_Con_Server *svr); - -/** - * Retrieves the server port in use. - * - * @param svr The given server. - * @return The server port in use. - * - * The port where the server is listening for connections. - */ -EAPI int ecore_con_server_port_get(Ecore_Con_Server *svr); -/** - * @brief Check how long a server has been connected - * - * @param svr The server to check - * @return The total time, in seconds, that the server has been - * connected/running - * - * This function is used to find out the time that has been elapsed since - * ecore_con_server_add() succeeded. - */ -EAPI double ecore_con_server_uptime_get(Ecore_Con_Server *svr); -/** - * 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. - * - * This function will send the given data to the server as soon as the program - * is back to the main loop. Thus, this function returns immediately - * (non-blocking). If the data needs to be sent @b now, call - * ecore_con_server_flush() after this one. - * - * @see ecore_con_client_send() - * @see ecore_con_server_flush() - */ -EAPI int ecore_con_server_send(Ecore_Con_Server *svr, - const void *data, - int 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. - * - * @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). - * - * 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. - */ -EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, - int client_limit, - char 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 @c NULL is - * returned. - */ -EAPI const char * ecore_con_server_ip_get(Ecore_Con_Server *svr); -/** - * Flushes all pending data to the given server. - * - * @param svr The given server. - * - * This function will block until all data is sent to the server. - * - * @see ecore_con_server_send() - * @see ecore_con_client_flush() - */ -EAPI void ecore_con_server_flush(Ecore_Con_Server *svr); -/** - * Set the default time after which an inactive client will be disconnected - * - * @param svr The server object - * @param timeout The timeout, in seconds, to disconnect after - * - * This function is used by the server to set the default idle timeout on - * clients. If the any of the clients becomes idle for a time higher than this - * value, it will be disconnected. A value of < 1 disables the idle timeout. - * - * This timeout is not affected by the one set by - * ecore_con_client_timeout_set(). A client will be disconnected whenever the - * client or the server timeout is reached. That means, the lower timeout value - * will be used for that client if ecore_con_client_timeout_set() is used on it. - * - * @see ecore_con_server_timeout_get() - * @see ecore_con_client_timeout_set() - */ -EAPI void ecore_con_server_timeout_set(Ecore_Con_Server *svr, double timeout); -/** - * Get the default time after which an inactive client will be disconnected - * - * @param svr The server object - * @return The timeout, in seconds, to disconnect after - * - * This function is used to get the idle timeout for clients. A value of < 1 - * means the idle timeout is disabled. - * - * @see ecore_con_server_timeout_set() - * @see ecore_con_client_timeout_get() - */ -EAPI double ecore_con_server_timeout_get(Ecore_Con_Server *svr); - -/** - * Get the fd that the server is connected to - * - * @param svr The server object - * @return The fd, or -1 on failure - * - * This function returns the fd which is used by the underlying server connection. - * It should not be tampered with unless you REALLY know what you are doing. - * @note This function is only valid for servers created with ecore_con_server_connect() - * @warning Seriously. Don't use this unless you know what you are doing. - * @since 1.1 - */ -EAPI int ecore_con_server_fd_get(Ecore_Con_Server *svr); - -/** - * Get the fd that the client is connected to - * - * @param cl The client object - * @return The fd, or -1 on failure - * - * This function returns the fd which is used by the underlying client connection. - * It should not be tampered with unless you REALLY know what you are doing. - * @since 1.1 - */ -EAPI int ecore_con_client_fd_get(Ecore_Con_Client *cl); -/** - * @} - */ - -/** - * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions - * - * Functions to communicate with and/or set options on a client. - * - * This set of functions, as explained in @ref Ecore_Con_Server_Group, is used - * to send data to a client, or to set options and get information about this - * client. Most of them should be used on the server, applied on the client - * object. - * - * If you need to implement a client, the way to connect to a server is - * described in @ref Ecore_Con_Server_Group. - * - * An example of usage of these functions can be found at: - * @li @ref ecore_con_client_simple_example_c - * - * @{ - */ - -/** - * 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. - * - * This function will send the given data to the client as soon as the program - * is back to the main loop. Thus, this function returns immediately - * (non-blocking). If the data needs to be sent @b now, call - * ecore_con_client_flush() after this one. - * - * @see ecore_con_server_send() - * @see ecore_con_client_flush() - */ -EAPI int ecore_con_client_send(Ecore_Con_Client *cl, - const void *data, - int 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. - */ -EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl); -/** - * Closes the connection and frees memory allocated to the given client. - * - * @param cl The given client. - * @return Data associated with the client. - */ -EAPI void * ecore_con_client_del(Ecore_Con_Client *cl); -/** - * Sets the data associated with the given client to @p data. - * - * @param cl The given client. - * @param data What to set the data to. - */ -EAPI void ecore_con_client_data_set(Ecore_Con_Client *cl, - const void *data); -/** - * Retrieves the data associated with the given client. - * - * @param cl The given client. - * @return The data associated with @p cl. - */ -EAPI void * ecore_con_client_data_get(Ecore_Con_Client *cl); - -/** - * Gets the IP address of a client 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. - * - * The returned string should not be modified, freed or trusted to stay valid - * after deletion for the @p cl object. If no IP is known @c NULL is returned. - */ -EAPI const char * ecore_con_client_ip_get(Ecore_Con_Client *cl); -/** - * Flushes all pending data to the given client. - * - * @param cl The given client. - * - * This function will block until all data is sent to the server. - * - * @see ecore_con_client_send() - * @see ecore_con_server_flush() - */ -EAPI void ecore_con_client_flush(Ecore_Con_Client *cl); -/** - * @brief Check how long a client has been connected - * - * @param cl The client to check - * @return The total time, in seconds, that the client has been connected to - * the server - * - * This function is used to find out how long a client has been connected for. - */ -EAPI double ecore_con_client_uptime_get(Ecore_Con_Client *cl); -/** - * Get the default time after which the client will be disconnected when - * inactive - * - * @param cl The client object - * @return The timeout, in seconds, to disconnect after - * - * This function is used to get the idle timeout for a client. A value of < 1 - * means the idle timeout is disabled. - * - * @see ecore_con_client_timeout_set() - */ -EAPI double ecore_con_client_timeout_get(Ecore_Con_Client *cl); -/** - * Set the time after which the client will be disconnected when inactive - * - * @param cl The client object - * @param timeout The timeout, in seconds, to disconnect after - * - * This function is used by the server to set the idle timeout on a specific - * client. If the client becomes idle for a time higher than this value, it will - * be disconnected. A value of < 1 disables the idle timeout. - * - * This timeout is not affected by the one set by - * ecore_con_server_timeout_set(). A client will be disconnected whenever the - * client or the server timeout is reached. That means, the lower timeout value - * will be used for that client if ecore_con_server_timeout_set() is used on the - * server. - * - * @see ecore_con_client_timeout_get() - * @see ecore_con_server_timeout_set() - */ -EAPI void ecore_con_client_timeout_set(Ecore_Con_Client *cl, double timeout); -/** - * Returns whether the client is still connected - * - * @param cl The given client. - * @return @c EINA_TRUE if connected, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool ecore_con_client_connected_get(Ecore_Con_Client *cl); -/** - * @brief Return the port that the client has connected to - * - * @param cl The client - * @return The port that @p cl has connected to, or -1 on error - * Use this function to return the port on which a given client has connected. - */ -EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl); - - - -/** - * @} - */ - -/** - * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions - * - * Utility functions that set up, use and shut down the Ecore URL - * Connection library. - * - * These functions are a shortcut to make it easy to perform http requests - * (POST, GET, etc). - * - * Brief usage: - * 1. Create an Ecore_Con_Url object with ecore_con_url_new(url); - * 2. Register to receive the #ECORE_CON_EVENT_URL_COMPLETE event - * (and optionally the #ECORE_CON_EVENT_URL_DATA and - * #ECORE_CON_EVENT_URL_PROGRESS event to receive - * the response, e.g. for HTTP/FTP downloads) - * 3. Perform the operation with ecore_con_url_get(...); - * - * Note that it is good to reuse @ref 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. - * - * If it's necessary to change the @ref Ecore_Con_Url object url, use - * ecore_con_url_url_set(). - * - * Simple Usage 1 (HTTP GET): - * @code - * ecore_con_url_url_set(url_con, "http://www.google.com"); - * ecore_con_url_get(url_con); - * @endcode - * - * Simple usage 2 (HTTP POST): - * @code - * ecore_con_url_url_set(url_con, "http://www.example.com/post_handler.cgi"); - * ecore_con_url_post(url_con, data, data_length, "multipart/form-data"); - * @endcode - * - * Simple Usage 3 (FTP download): - * @code - * fd = creat(filename, 0644) - * ecore_con_url_url_set(url_con, "ftp://ftp.example.com/pub/myfile"); - * ecore_con_url_fd_set(url_con, fd); - * ecore_con_url_get(url_con); - * @endcode - * - * Simple Usage 4 (FTP upload as ftp://ftp.example.com/file): - * @code - * ecore_con_url_url_set(url_con, "ftp://ftp.example.com"); - * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass", NULL); - * @endcode - * - * Simple Usage 5 (FTP upload as ftp://ftp.example.com/dir/file): - * @code - * ecore_con_url_url_set(url_con, "ftp://ftp.example.com"); - * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass","dir"); - * @endcode - * - * These are complete examples for the API: - * @li @ref ecore_con_url_download_example.c "Downloading a file" - * @li @ref ecore_con_url_headers_example.c "Setting many options for the connection" - * - * @{ - */ - -/** - * @typedef Ecore_Con_Url_Time - * @enum _Ecore_Con_Url_Time - * The type of condition to use when making an HTTP request dependent on time, - * so that headers such as "If-Modified-Since" are used. - */ -typedef enum _Ecore_Con_Url_Time -{ - /** - * Do not place time restrictions on the HTTP requests. - */ - ECORE_CON_URL_TIME_NONE = 0, - /** - * Add the "If-Modified-Since" HTTP header, so that the request is performed - * by the server only if the target has been modified since the time value - * passed to it in the request. - */ - ECORE_CON_URL_TIME_IFMODSINCE, - /** - * Add the "If-Unmodified-Since" HTTP header, so that the request is - * performed by the server only if the target has NOT been modified since - * the time value passed to it in the request. - */ - ECORE_CON_URL_TIME_IFUNMODSINCE -} Ecore_Con_Url_Time; - -/** - * @typedef Ecore_Con_Url_Http_Version - * @enum _Ecore_Con_Url_Http_Version - * The http version to use - * @since 1.2 - */ -typedef enum _Ecore_Con_Url_Http_Version -{ - /** - * HTTP version 1.0 - * @since 1.2 - */ - ECORE_CON_URL_HTTP_VERSION_1_0, - /** - * HTTP version 1.1 (default) - * @since 1.2 - */ - ECORE_CON_URL_HTTP_VERSION_1_1 -} Ecore_Con_Url_Http_Version; - -/** - * Change the HTTP version used for the request - * @param url_con Connection object through which the request will be sent. - * @param version The version to be used - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure to change version. - * @since 1.2 - * @see ecore_con_url_pipeline_get() - */ -EAPI Eina_Bool ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Version version); - -/** - * Initialises the Ecore_Con_Url library. - * @return Number of times the library has been initialised without being - * shut down. - * - * @note This function doesn't call ecore_con_init(). You still need to call it - * explicitly before calling this one. - */ -EAPI int ecore_con_url_init(void); - -/** - * Shuts down the Ecore_Con_Url library. - * @return Number of calls that still uses Ecore_Con_Url - * - * @note This function doesn't call ecore_con_shutdown(). You still need to call - * it explicitly after calling this one. - */ -EAPI int ecore_con_url_shutdown(void); - -/** - * Enable or disable HTTP 1.1 pipelining. - * @param enable @c EINA_TRUE will turn it on, @c EINA_FALSE will disable it. - * - * Pipelining allows to send one request after another one, without having to - * wait for the reply of the first request. The respective replies are received - * in the order that the requests were sent. - * - * Enabling this feature will be valid for all requests done using @c - * ecore_con_url. - * - * See http://en.wikipedia.org/wiki/HTTP_pipelining for more info. - * - * @see ecore_con_url_pipeline_get() - */ -EAPI void ecore_con_url_pipeline_set(Eina_Bool enable); -/** - * Is HTTP 1.1 pipelining enable ? - * @return @c EINA_TRUE if it is enable. - * - * @see ecore_con_url_pipeline_set() - */ -EAPI Eina_Bool ecore_con_url_pipeline_get(void); - -/** - * Creates and initializes a new Ecore_Con_Url connection object. - * - * @param url URL that will receive requests. Can be changed using - * ecore_con_url_url_set. - * - * @return @c NULL on error, a new Ecore_Con_Url on success. - * - * Creates and initializes a new Ecore_Con_Url connection object that can be - * used for sending requests. - * - * @see ecore_con_url_custom_new() - * @see ecore_con_url_url_set() - */ -EAPI Ecore_Con_Url * ecore_con_url_new(const char *url); -/** - * Creates a custom connection object. - * - * @param url URL that will receive requests - * @param custom_request Custom request (e.g. GET, POST, HEAD, PUT, etc) - * - * @return @c NULL on error, a new Ecore_Con_Url on success. - * - * 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(). - * - * @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); -/** - * Destroys a Ecore_Con_Url connection object. - * - * @param url_con Connection object to free. - * - * @see ecore_con_url_new() - */ -EAPI void ecore_con_url_free(Ecore_Con_Url *url_con); -/** - * 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 @c EINA_TRUE on success, @c EINA_FALSE on error. - */ -EAPI Eina_Bool ecore_con_url_url_set(Ecore_Con_Url *url_con, - const char *url); -/** - * Gets the URL to send the request to. - * - * @param url_con Connection object through which the request will be sent. - * @return URL that will receive the request, @c NULL on failure. URL is - * stringshared. - * @since 1.1 - */ -EAPI const char *ecore_con_url_url_get(Ecore_Con_Url *url_con); -/** - * Associates data with a connection object. - * - * @param url_con Connection object to associate data. - * @param data Data to be set. - * - * Associates data with a connection object, which can be retrieved later with - * ecore_con_url_data_get()). - * - * @see ecore_con_url_data_get() - */ -EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con, - void *data); -/** - * Retrieves data associated with a Ecore_Con_Url connection object. - * - * @param url_con Connection object to retrieve data from. - * - * @return Data associated with the given object. - * - * Retrieves data associated with a Ecore_Con_Url connection object (previously - * set with ecore_con_url_data_set()). - * - * @see ecore_con_url_data_set() - */ -EAPI void * ecore_con_url_data_get(Ecore_Con_Url *url_con); -/** - * Adds an additional header to the request connection object. - * - * @param url_con Connection object - * @param key Header key - * @param value Header value - * - * Adds an additional header (User-Agent, Content-Type, etc.) to the request - * connection object. This addition will be valid for only one - * ecore_con_url_get() or ecore_con_url_post() call. - * - * Some functions like ecore_con_url_time() also add headers to the request. - * - * @see ecore_con_url_get() - * @see ecore_con_url_post() - * @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); -/** - * Cleans additional headers. - * - * @param url_con Connection object to clean additional headers. - * - * Cleans additional headers associated with a connection object (previously - * added with ecore_con_url_additional_header_add()). - * - * @see ecore_con_url_additional_header_add() - * @see ecore_con_url_get() - * @see ecore_con_url_post() - */ -EAPI void ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con); -/** - * Retrieves headers from last request sent. - * - * @param url_con Connection object to retrieve response headers from. - * - * 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). - * - * @return List of response headers. This list must not be modified by the user. - */ -EAPI const Eina_List * ecore_con_url_response_headers_get(Ecore_Con_Url *url_con); -/** - * Setup a file for receiving response data. - * - * @param url_con Connection object to set file - * @param fd File descriptor associated with the file. A negative value will - * unset any previously set fd. - * - * Sets up 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. - * - * This call can be used to easily setup a file where the downloaded data will - * be saved. - */ -EAPI void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd); -/** - * 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. - * - * @see ecore_con_url_get() - * @see ecore_con_url_post() - */ -EAPI int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con); -/** - * 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 @c EINA_TRUE on success, @c EINA_FALSE on error. - * - * @attention Requires libcurl >= 7.19.1 to work, otherwise will always return - * @c 0. - */ -EAPI Eina_Bool ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, - const char *username, - const char *password, - Eina_Bool safe); -/** - * Sends a get request. - * - * @param url_con Connection object to perform a request on, previously created - * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. - * - * The request is performed immediately, but you need to setup event handlers - * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or - * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. - * - * @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() - * @see ecore_con_url_time() - * @see ecore_con_url_post() - */ -EAPI Eina_Bool ecore_con_url_get(Ecore_Con_Url *url_con); -/** - * Sends a post 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). Can be @c NULL. - * @param length Payload length. If @c -1, rely on automatic length - * calculation via @c strlen() on @p data. - * @param content_type Content type of the payload (e.g. text/xml). Can be @c - * NULL. - * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. - * - * The request starts immediately, but you need to setup event handlers - * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or - * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. - * - * This call won't block your main loop. - * - * @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() - * @see ecore_con_url_time() - * @see ecore_con_url_get() - */ -EAPI Eina_Bool ecore_con_url_post(Ecore_Con_Url *url_con, - const void *data, long length, - const char *content_type); -/** - * Sets whether HTTP requests should be conditional, dependent on - * modification time. - * - * @param url_con Ecore_Con_Url to act upon. - * @param time_condition Condition to use for HTTP requests. - * @param timestamp Time since 1 Jan 1970 to use in the condition. - * - * This function may set the header "If-Modified-Since" or - * "If-Unmodified-Since", depending on the value of @p time_condition, with the - * value @p timestamp. - * - * @sa ecore_con_url_get() - * @sa ecore_con_url_post() - */ -EAPI void ecore_con_url_time(Ecore_Con_Url *url_con, - Ecore_Con_Url_Time time_condition, - double timestamp); - -/** - * @brief Uploads a file to an ftp site. - * - * @param url_con The Ecore_Con_Url object to send with - * @param filename The path to the file to send - * @param user The username to log in with - * @param pass The password to log in with - * @param upload_dir The directory to which the file should be uploaded - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * Upload @p filename to an ftp server set in @p url_con using @p user - * and @p pass to directory @p upload_dir - */ -EAPI Eina_Bool ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, - const char *filename, - const char *user, - const char *pass, - const char *upload_dir); -/** - * Toggle libcurl's verbose output. - * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param verbose Whether or not to enable libcurl's verbose output. - * - * If @p verbose is @c EINA_TRUE, libcurl will output a lot of verbose - * information about its operations, which is useful for - * debugging. The verbose information will be sent to stderr. - */ -EAPI void ecore_con_url_verbose_set(Ecore_Con_Url *url_con, - Eina_Bool verbose); -/** - * Enable or disable EPSV extension - * @param url_con The Ecore_Con_Url instance which will be acted upon. - * @param use_epsv Boolean to enable/disable the EPSV extension. - */ -EAPI void ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, - Eina_Bool use_epsv); - -/** - * Enables the cookie engine for subsequent HTTP requests. - * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * - * After this function is called, cookies set by the server in HTTP responses - * will be parsed and stored, as well as sent back to the server in new HTTP - * requests. - * - * @note Even though this function is called @c ecore_con_url_cookies_init(), - * there is no symmetrical shutdown operation. - */ -EAPI void ecore_con_url_cookies_init(Ecore_Con_Url *url_con); -/** - * Controls whether session cookies from previous sessions shall be loaded. - * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param ignore If @c EINA_TRUE, ignore session cookies when loading cookies - * from files. If @c EINA_FALSE, all cookies will be loaded. - * - * Session cookies are cookies with no expire date set, which usually means - * they are removed after the current session is closed. - * - * By default, when Ecore_Con_Url loads cookies from a file, all cookies are - * loaded, including session cookies, which, most of the time, were supposed - * to be loaded and valid only for that session. - * - * If @p ignore is set to @c EINA_TRUE, when Ecore_Con_Url loads cookies from - * the files passed to @c ecore_con_url_cookies_file_add(), session cookies - * will not be loaded. - * - * @see ecore_con_url_cookies_file_add() - */ -EAPI void ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, - Eina_Bool ignore); -/** - * Clears currently loaded cookies. - * @param url_con Ecore_Con_Url instance which will be acted upon. - * - * The cleared cookies are removed and will not be sent in subsequent HTTP - * requests, nor will they be written to the cookiejar file set via - * @c ecore_con_url_cookies_jar_file_set(). - * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. - * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded - * immediately, just when the request is started. Thus, if you ask to - * clear the cookies, but has a file already set by that function, the - * cookies will then be loaded and you will have old cookies set. In order - * to don't have any old cookie set, you need to don't call - * ecore_con_url_cookies_file_add() ever on the @p url_con handler, and - * call this function to clear any cookie set by a previous request on - * this handler. - * - * @see ecore_con_url_cookies_session_clear() - * @see ecore_con_url_cookies_ignore_old_session_set() - */ -EAPI void ecore_con_url_cookies_clear(Ecore_Con_Url *url_con); -/** - * Clears currently loaded session cookies. - * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * - * Session cookies are cookies with no expire date set, which usually means - * they are removed after the current session is closed. - * - * The cleared cookies are removed and will not be sent in subsequent HTTP - * requests, nor will they be written to the cookiejar file set via - * @c ecore_con_url_cookies_jar_file_set(). - * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. - * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded - * immediately, just when the request is started. Thus, if you ask to - * clear the session cookies, but has a file already set by that function, - * the session cookies will then be loaded and you will have old cookies - * set. In order to don't have any old session cookie set, you need to - * don't call ecore_con_url_cookies_file_add() ever on the @p url_con - * handler, and call this function to clear any session cookie set by a - * previous request on this handler. An easier way to don't use old - * session cookies is by using the function - * ecore_con_url_cookies_ignore_old_session_set(). - * - * @see ecore_con_url_cookies_clear() - * @see ecore_con_url_cookies_ignore_old_session_set() - */ -EAPI void ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con); -/** - * Adds a file to the list of files from which to load cookies. - * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param file_name Name of the file that will be added to the list. - * - * Files must contain cookies defined according to two possible formats: - * - * @li HTTP-style header ("Set-Cookie: ..."). - * @li Netscape/Mozilla cookie data format. - * - * Cookies will only be @b read from this file. If you want to save cookies to a - * file, use ecore_con_url_cookies_jar_file_set(). Also notice that this - * function supports the both types of cookie file cited above, while - * ecore_con_url_cookies_jar_file_set() will save only in the Netscape/Mozilla's - * format. - * - * Please notice that the file will not be read immediately, but rather added - * to a list of files that will be loaded and parsed at a later time. - * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. - * - * @see ecore_con_url_cookies_ignore_old_session_set() - * @see ecore_con_url_cookies_jar_file_set() - */ -EAPI void ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, - const char * const file_name); -/** - * Sets the name of the file to which all current cookies will be written when - * either cookies are flushed or Ecore_Con is shut down. - * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param cookiejar_file File to which the cookies will be written. - * - * @return @c EINA_TRUE is the file name has been set successfully, - * @c EINA_FALSE otherwise. - * - * Cookies are written following Netscape/Mozilla's data format, also known as - * cookie-jar. - * - * Cookies will only be @b saved to this file. If you need to read cookies from - * a file, use ecore_con_url_cookies_file_add() instead. - * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. - * - * @see ecore_con_url_cookies_jar_write() - */ -EAPI Eina_Bool ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, - const char * const cookiejar_file); -/** - * Writes all current cookies to the cookie jar immediately. - * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * - * A cookie-jar file must have been previously set by - * @c ecore_con_url_jar_file_set, otherwise nothing will be done. - * - * @note This function will initialize the cookie engine if it has not been - * initialized yet. - * - * @see ecore_con_url_cookies_jar_file_set() - */ -EAPI void ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con); - -EAPI void ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con, - Eina_Bool verify); -EAPI int ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, - const char *ca_path); - -/** - * Set HTTP proxy to use. - * - * The parameter should be a char * to a zero terminated string holding - * the host name or dotted IP address. To specify port number in this string, - * append :[port] to the end of the host name. - * The proxy string may be prefixed with [protocol]:// since any such prefix - * will be ignored. - * The proxy's port number may optionally be specified with the separate option. - * If not specified, libcurl will default to using port 1080 for proxies. - * - * @param url_con Connection object that will use the proxy. - * @param proxy Porxy string or @c NULL to disable - * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. - * @since 1.2 - */ -EAPI Eina_Bool ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy); - -/** - * Set zero terminated username to use for proxy. - * - * if socks protocol is used for proxy, protocol should be socks5 and above. - * - * @param url_con Connection object that will use the proxy. - * @param username Username string. - * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. - * - * @see ecore_con_url_proxy_set() - * - * @since 1.2 - */ -EAPI Eina_Bool ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username); - -/** - * Set zero terminated password to use for proxy. - * - * if socks protocol is used for proxy, protocol should be socks5 and above. - * - * @param url_con Connection object that will use the proxy. - * @param password Password string. - * - * @return @c EINA_TRUE on success, @c EINA_FALSE on error. - * - * @see ecore_con_url_proxy_set() - * - * @since 1.2 - */ -EAPI Eina_Bool ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password); - -/** - * Set timeout in seconds. - * - * the maximum time in seconds that you allow the ecore con url transfer - * operation to take. Normally, name lookups can take a considerable time - * and limiting operations to less than a few minutes risk aborting perfectly - * normal operations. - * - * @param url_con Connection object that will use the timeout. - * @param timeout time in seconds. - * - * @see ecore_con_url_cookies_jar_file_set() - * - * @since 1.2 - */ -EAPI void ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout); - -/** - * Get the returned HTTP STATUS code - * - * This is used to, at any time, try to return the status code for a transmission. - * @param url_con Connection object - * @return A valid HTTP STATUS code, or 0 on failure - * - * @since 1.2 - */ -EAPI int ecore_con_url_status_code_get(Ecore_Con_Url *url_con); -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/legacy/ecore/src/lib/ecore_con/Ecore_Con_Eet.h b/legacy/ecore/src/lib/ecore_con/Ecore_Con_Eet.h deleted file mode 100644 index bdf0d2d605..0000000000 --- a/legacy/ecore/src/lib/ecore_con/Ecore_Con_Eet.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _ECORE_CON_EET -# define _ECORE_CON_EET - -#include -#include -#include - -#ifdef EAPI -# undef EAPI -#endif - -#ifdef _WIN32 -# ifdef EFL_ECORE_CON_BUILD -# ifdef DLL_EXPORT -# define EAPI __declspec(dllexport) -# else -# define EAPI -# endif -# 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 - -typedef struct _Ecore_Con_Eet Ecore_Con_Eet; -typedef struct _Ecore_Con_Reply Ecore_Con_Reply; - -typedef void (*Ecore_Con_Eet_Data_Cb)(void *data, Ecore_Con_Reply *reply, const char *protocol_name, void *value); -typedef void (*Ecore_Con_Eet_Raw_Data_Cb)(void *data, Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, size_t length); -typedef Eina_Bool (*Ecore_Con_Eet_Client_Cb)(void *data, Ecore_Con_Reply *reply, Ecore_Con_Client *conn); -typedef Eina_Bool (*Ecore_Con_Eet_Server_Cb)(void *data, Ecore_Con_Reply *reply, Ecore_Con_Server *conn); - -EAPI Ecore_Con_Eet *ecore_con_eet_server_new(Ecore_Con_Server *server); -EAPI Ecore_Con_Eet *ecore_con_eet_client_new(Ecore_Con_Server *server); -EAPI void ecore_con_eet_server_free(Ecore_Con_Eet *ece); - -EAPI void ecore_con_eet_register(Ecore_Con_Eet *ece, const char *name, Eet_Data_Descriptor *edd); - -EAPI void ecore_con_eet_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Data_Cb func, const void *data); -EAPI void ecore_con_eet_data_callback_del(Ecore_Con_Eet *ece, const char *name); - -EAPI void ecore_con_eet_raw_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Raw_Data_Cb func, const void *data); -EAPI void ecore_con_eet_raw_data_callback_del(Ecore_Con_Eet *ece, const char *name); - -EAPI void ecore_con_eet_client_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); -EAPI void ecore_con_eet_client_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); - -EAPI void ecore_con_eet_client_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); -EAPI void ecore_con_eet_client_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); - -EAPI void ecore_con_eet_server_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); -EAPI void ecore_con_eet_server_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); - -EAPI void ecore_con_eet_server_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); -EAPI void ecore_con_eet_server_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); - -EAPI void ecore_con_eet_data_set(Ecore_Con_Eet *ece, const void *data); -EAPI void *ecore_con_eet_data_get(Ecore_Con_Eet *ece); - -EAPI Ecore_Con_Eet *ecore_con_eet_reply(Ecore_Con_Reply *reply); -EAPI void ecore_con_eet_send(Ecore_Con_Reply *reply, const char *protocol_name, void *value); -EAPI void ecore_con_eet_raw_send(Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, unsigned int length); - -#endif diff --git a/legacy/ecore/src/lib/ecore_con/dns.c b/legacy/ecore/src/lib/ecore_con/dns.c deleted file mode 100644 index b50d306dc6..0000000000 --- a/legacy/ecore/src/lib/ecore_con/dns.c +++ /dev/null @@ -1,7878 +0,0 @@ -/* ========================================================================== - * dns.c - Recursive, Reentrant DNS Resolver. - * -------------------------------------------------------------------------- - * Copyright (c) 2008, 2009, 2010 William Ahern - * - * 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 or substantial portions of the Software. - * - * 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 OR COPYRIGHT HOLDERS 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. - * ========================================================================== - */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if !defined(__FreeBSD__) -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 -#endif - -#undef _BSD_SOURCE -#define _BSD_SOURCE - -#undef _DARWIN_C_SOURCE -#define _DARWIN_C_SOURCE - -#undef _NETBSD_SOURCE -#define _NETBSD_SOURCE -#endif - -#include /* offsetof() */ -#include /* uint32_t */ -#include /* malloc(3) realloc(3) free(3) rand(3) random(3) arc4random(3) */ -#include /* FILE fopen(3) fclose(3) getc(3) rewind(3) */ - -#include /* memcpy(3) strlen(3) memmove(3) memchr(3) memcmp(3) strchr(3) strsep(3) strcspn(3) */ -#include /* strcasecmp(3) strncasecmp(3) */ - -#include /* isspace(3) isdigit(3) */ - -#include /* time_t time(2) */ - -#include /* sig_atomic_t */ - -#include /* errno EINVAL ENOENT */ - -#undef NDEBUG -#include /* assert(3) */ - -#if _WIN32 -#include -#include -#else -#include /* FD_SETSIZE socklen_t */ -#include /* FD_ZERO FD_SET fd_set select(2) */ -#include /* AF_INET AF_INET6 AF_UNIX struct sockaddr struct sockaddr_in struct sockaddr_in6 socket(2) */ - -#if defined(AF_UNIX) -#include /* struct sockaddr_un */ -#endif - -#include /* F_SETFD F_GETFL F_SETFL O_NONBLOCK fcntl(2) */ - -#include /* gethostname(3) close(2) */ - -#include /* POLLIN POLLOUT */ - -#include /* struct sockaddr_in struct sockaddr_in6 */ - -#include /* inet_pton(3) inet_ntop(3) htons(3) ntohs(3) */ - -#include /* struct addrinfo */ -#endif - -#include "dns.h" - - -/* - * S T A N D A R D M A C R O S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef MIN -#define MIN(a, b) (((a) < (b))? (a) : (b)) -#endif - - -#ifndef MAX -#define MAX(a, b) (((a) > (b))? (a) : (b)) -#endif - - -#ifndef lengthof -#define lengthof(a) (sizeof (a) / sizeof (a)[0]) -#endif - -#ifndef endof -#define endof(a) (&(a)[lengthof((a))]) -#endif - - -/* - * D E B U G M A C R O S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -int dns_debug = 0; - -#if DNS_DEBUG - -#undef DNS_DEBUG -#define DNS_DEBUG dns_debug - -#define DNS_SAY_(fmt, ...) \ - do { if (DNS_DEBUG > 0) fprintf(stderr, fmt "%.1s", __func__, __LINE__, __VA_ARGS__); } while (0) -#define DNS_SAY(...) DNS_SAY_("@@ (%s:%d) " __VA_ARGS__, "\n") -#define DNS_HAI DNS_SAY("HAI") - -#define DNS_SHOW_(P, fmt, ...) do { \ - if (DNS_DEBUG > 1) { \ - fprintf(stderr, "@@ BEGIN * * * * * * * * * * * *\n"); \ - fprintf(stderr, "@@ " fmt "%.0s\n", __VA_ARGS__); \ - dns_p_dump((P), stderr); \ - fprintf(stderr, "@@ END * * * * * * * * * * * * *\n\n"); \ - } \ -} while (0) - -#define DNS_SHOW(...) DNS_SHOW_(__VA_ARGS__, "") - -#else /* !DNS_DEBUG */ - -#undef DNS_DEBUG -#define DNS_DEBUG 0 - -#define DNS_SAY(...) -#define DNS_HAI -#define DNS_SHOW(...) - -#endif /* DNS_DEBUG */ - - -/* - * V E R S I O N R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -const char *dns_vendor(void) { - return DNS_VENDOR; -} /* dns_vendor() */ - - -int dns_v_rel(void) { - return DNS_V_REL; -} /* dns_v_rel() */ - - -int dns_v_abi(void) { - return DNS_V_ABI; -} /* dns_v_abi() */ - - -int dns_v_api(void) { - return DNS_V_API; -} /* dns_v_api() */ - - -/* - * E R R O R R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#if _WIN32 - -#define DNS_EINTR WSAEINTR -#define DNS_EINPROGRESS WSAEINPROGRESS -#define DNS_EISCONN WSAEISCONN -#define DNS_EWOULDBLOCK WSAEWOULDBLOCK -#define DNS_EALREADY WSAEALREADY -#define DNS_EAGAIN EAGAIN -#define DNS_ETIMEDOUT WSAETIMEDOUT - -#define dns_syerr() ((int)GetLastError()) -#define dns_soerr() ((int)WSAGetLastError()) - -#else - -#define DNS_EINTR EINTR -#define DNS_EINPROGRESS EINPROGRESS -#define DNS_EISCONN EISCONN -#define DNS_EWOULDBLOCK EWOULDBLOCK -#define DNS_EALREADY EALREADY -#define DNS_EAGAIN EAGAIN -#define DNS_ETIMEDOUT ETIMEDOUT - -#define dns_syerr() errno -#define dns_soerr() errno - -#endif - - -const char *dns_strerror(int error) { - switch (error) { - case DNS_ENOBUFS: - return "DNS packet buffer too small"; - case DNS_EILLEGAL: - return "Illegal DNS RR name or data"; - case DNS_EORDER: - return "Attempt to push RR out of section order"; - case DNS_ESECTION: - return "Invalid section specified"; - case DNS_EUNKNOWN: - return "Unknown DNS error"; - default: - return strerror(error); - } /* switch() */ -} /* dns_strerror() */ - - -/* - * A T O M I C R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -static unsigned dns_atomic_inc(dns_atomic_t *i) { - return (*i)++; -} /* dns_atomic_inc() */ - - -static unsigned dns_atomic_dec(dns_atomic_t *i) { - return (*i)--; -} /* dns_atomic_dec() */ - - -/* - * C R Y P T O R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * P R N G - */ - -#ifndef DNS_RANDOM -#if defined(HAVE_ARC4RANDOM) \ - || defined(__OpenBSD__) \ - || defined(__FreeBSD__) \ - || defined(__NetBSD__) \ - || defined(__APPLE__) -#define DNS_RANDOM arc4random -#elif __linux -#define DNS_RANDOM random -#else -#define DNS_RANDOM rand -#endif -#endif - -#define DNS_RANDOM_arc4random 1 -#define DNS_RANDOM_random 2 -#define DNS_RANDOM_rand 3 -#define DNS_RANDOM_RAND_bytes 4 - -#define DNS_RANDOM_OPENSSL (DNS_RANDOM_RAND_bytes == DNS_PP_XPASTE(DNS_RANDOM_, DNS_RANDOM)) - -#if DNS_RANDOM_OPENSSL -#include -#endif - -static unsigned dns_random_(void) { -#if DNS_RANDOM_OPENSSL - unsigned r; - - assert(1 == RAND_bytes((unsigned char *)&r, sizeof r)); - - return r; -#else - return DNS_RANDOM(); -#endif -} /* dns_random_() */ - -unsigned (*dns_random)(void) __attribute__((weak)) = &dns_random_; - - -/* - * P E R M U T A T I O N G E N E R A T O R - */ - -#define DNS_K_TEA_KEY_SIZE 16 -#define DNS_K_TEA_BLOCK_SIZE 8 -#define DNS_K_TEA_CYCLES 32 -#define DNS_K_TEA_MAGIC 0x9E3779B9U - -struct dns_k_tea { - uint32_t key[DNS_K_TEA_KEY_SIZE / sizeof (uint32_t)]; - unsigned cycles; -}; /* struct dns_k_tea */ - - -static void dns_k_tea_init(struct dns_k_tea *tea, uint32_t key[], unsigned cycles) { - memcpy(tea->key, key, sizeof tea->key); - - tea->cycles = (cycles)? cycles : DNS_K_TEA_CYCLES; -} /* dns_k_tea_init() */ - - -static void dns_k_tea_encrypt(struct dns_k_tea *tea, uint32_t v[], uint32_t *w) { - uint32_t y, z, sum, n; - - y = v[0]; - z = v[1]; - sum = 0; - - for (n = 0; n < tea->cycles; n++) { - sum += DNS_K_TEA_MAGIC; - y += ((z << 4) + tea->key[0]) ^ (z + sum) ^ ((z >> 5) + tea->key[1]); - z += ((y << 4) + tea->key[2]) ^ (y + sum) ^ ((y >> 5) + tea->key[3]); - } - - w[0] = y; - w[1] = z; - - return /* void */; -} /* dns_k_tea_encrypt() */ - - -/* - * Permutation generator, based on a Luby-Rackoff Feistel construction. - * - * Specifically, this is a generic balanced Feistel block cipher using TEA - * (another block cipher) as the pseudo-random function, F. At best it's as - * strong as F (TEA), notwithstanding the seeding. F could be AES, SHA-1, or - * perhaps Bernstein's Salsa20 core; I am naively trying to keep things - * simple. - * - * The generator can create a permutation of any set of numbers, as long as - * the size of the set is an even power of 2. This limitation arises either - * out of an inherent property of balanced Feistel constructions, or by my - * own ignorance. I'll tackle an unbalanced construction after I wrap my - * head around Schneier and Kelsey's paper. - * - * CAVEAT EMPTOR. IANAC. - */ -#define DNS_K_PERMUTOR_ROUNDS 8 - -struct dns_k_permutor { - unsigned stepi, length, limit; - unsigned shift, mask, rounds; - - struct dns_k_tea tea; -}; /* struct dns_k_permutor */ - - -static inline unsigned dns_k_permutor_powof(unsigned n) { - unsigned m, i = 0; - - for (m = 1; m < n; m <<= 1, i++) - ;; - - return i; -} /* dns_k_permutor_powof() */ - -static void dns_k_permutor_init(struct dns_k_permutor *p, unsigned low, unsigned high) { - uint32_t key[DNS_K_TEA_KEY_SIZE / sizeof (uint32_t)]; - unsigned width, i; - - p->stepi = 0; - - p->length = (high - low) + 1; - p->limit = high; - - width = dns_k_permutor_powof(p->length); - width += width % 2; - - p->shift = width / 2; - p->mask = (1U << p->shift) - 1; - p->rounds = DNS_K_PERMUTOR_ROUNDS; - - for (i = 0; i < lengthof(key); i++) - key[i] = dns_random(); - - dns_k_tea_init(&p->tea, key, 0); - - return /* void */; -} /* dns_k_permutor_init() */ - - -static unsigned dns_k_permutor_F(struct dns_k_permutor *p, unsigned k, unsigned x) { - uint32_t in[DNS_K_TEA_BLOCK_SIZE / sizeof (uint32_t)], out[DNS_K_TEA_BLOCK_SIZE / sizeof (uint32_t)]; - - memset(in, '\0', sizeof in); - - in[0] = k; - in[1] = x; - - dns_k_tea_encrypt(&p->tea, in, out); - - return p->mask & out[0]; -} /* dns_k_permutor_F() */ - - -static unsigned dns_k_permutor_E(struct dns_k_permutor *p, unsigned n) { - unsigned l[2], r[2]; - unsigned i; - - i = 0; - l[i] = p->mask & (n >> p->shift); - r[i] = p->mask & (n >> 0); - - do { - l[(i + 1) % 2] = r[i % 2]; - r[(i + 1) % 2] = l[i % 2] ^ dns_k_permutor_F(p, i, r[i % 2]); - - i++; - } while (i < p->rounds - 1); - - return ((l[i % 2] & p->mask) << p->shift) | ((r[i % 2] & p->mask) << 0); -} /* dns_k_permutor_E() */ - -static unsigned dns_k_permutor_step(struct dns_k_permutor *p) { - unsigned n; - - do { - n = dns_k_permutor_E(p, p->stepi++); - } while (n >= p->length); - - return n + (p->limit + 1 - p->length); -} /* dns_k_permutor_step() */ - - -/* - * Simple permutation box. Useful for shuffling rrsets from an iterator. - * Uses AES s-box to provide good diffusion. - * - * Seems to pass muster under runs test. - * - * $ for i in 0 1 2 3 4 5 6 7 8 9; do ./dns shuffle-16 > /tmp/out; done - * $ R -q -f /dev/stdin 2>/dev/null <<-EOF | awk '/p-value/{ print $8 }' - * library(lawstat) - * runs.test(scan(file="/tmp/out")) - * EOF - */ -static unsigned short dns_k_shuffle16(unsigned short n, unsigned s) { - static const unsigned char sbox[256] = - { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; - unsigned char a, b; - unsigned i; - - a = 0xff & (n >> 0); - b = 0xff & (n >> 8); - - for (i = 0; i < 4; i++) { - a ^= 0xff & s; - a = sbox[a] ^ b; - b = sbox[b] ^ a; - s >>= 8; - } - - return ((0xff00 & (a << 8)) | (0x00ff & (b << 0))); -} /* dns_k_shuffle16() */ - - -/* - * U T I L I T Y R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Monotonic Time - * - */ -static time_t dns_now(void) { - /* XXX: Assumes sizeof (time_t) <= sizeof (sig_atomic_t) */ - static volatile sig_atomic_t last, tick; - volatile sig_atomic_t tmp_last, tmp_tick; - time_t now; - - time(&now); - - tmp_last = last; - - if (now > tmp_last) { - tmp_tick = tick; - tmp_tick += now - tmp_last; - tick = tmp_tick; - } - - last = now; - - return tick; -} /* dns_now() */ - -static time_t dns_elapsed(time_t from) { - time_t now = dns_now(); - - return (now > from)? now - from : 0; -} /* dns_elpased() */ - - -static size_t dns_af_len(int af) { - static const size_t table[AF_MAX] = { - [AF_INET6] = sizeof (struct sockaddr_in6), - [AF_INET] = sizeof (struct sockaddr_in), -#if defined(AF_UNIX) && !defined(_WIN32) - [AF_UNIX] = sizeof (struct sockaddr_un), -#endif - }; - - return table[af]; -} /* dns_af_len() */ - -#define dns_sa_len(sa) dns_af_len(dns_sa_family(sa)) - - -#define DNS_SA_NOPORT &dns_sa_noport -static unsigned short dns_sa_noport; - -unsigned short *dns_sa_port(int af, void *sa) { - switch (af) { - case AF_INET6: - return &((struct sockaddr_in6 *)sa)->sin6_port; - case AF_INET: - return &((struct sockaddr_in *)sa)->sin_port; - default: - return DNS_SA_NOPORT; - } -} /* dns_sa_port() */ - - -void *dns_sa_addr(int af, void *sa) { - switch (af) { - case AF_INET6: - return &((struct sockaddr_in6 *)sa)->sin6_addr; - case AF_INET: - return &((struct sockaddr_in *)sa)->sin_addr; - default: - return 0; - } -} /* dns_sa_addr() */ - - -#if _WIN32 -static int dns_inet_pton(int af, const void *src, void *dst) { - union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } u; - - u.sin.sin_family = af; - - if (0 != WSAStringToAddressA((void *)src, af, (void *)0, (struct sockaddr *)&u, &(int){ sizeof u })) - return -1; - - switch (af) { - case AF_INET6: - *(struct in6_addr *)dst = u.sin6.sin6_addr; - - return 1; - case AF_INET: - *(struct in_addr *)dst = u.sin.sin_addr; - - return 1; - default: - return 0; - } -} /* dns_inet_pton() */ - -const char *dns_inet_ntop(int af, const void *src, void *dst, unsigned long lim) { - union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } u; - - /* NOTE: WSAAddressToString will print .sin_port unless zeroed. */ - memset(&u, 0, sizeof u); - - u.sin.sin_family = af; - - switch (af) { - case AF_INET6: - u.sin6.sin6_addr = *(struct in6_addr *)src; - break; - case AF_INET: - u.sin.sin_addr = *(struct in_addr *)src; - - break; - default: - return 0; - } - - if (0 != WSAAddressToStringA((struct sockaddr *)&u, dns_sa_len(&u), (void *)0, dst, &lim)) - return 0; - - return dst; -} /* dns_inet_ntop() */ -#endif - - -size_t dns_strlcpy(char *dst, const char *src, size_t lim) { - char *d = dst; - char *e = &dst[lim]; - const char *s = src; - - if (d < e) { - do { - if ('\0' == (*d++ = *s++)) - return s - src - 1; - } while (d < e); - - d[-1] = '\0'; - } - - while (*s++ != '\0') - ;; - - return s - src - 1; -} /* dns_strlcpy() */ - - -size_t dns_strlcat(char *dst, const char *src, size_t lim) { - char *d = memchr(dst, '\0', lim); - char *e = &dst[lim]; - const char *s = src; - const char *p; - - if (d && d < e) { - do { - if ('\0' == (*d++ = *s++)) - return d - dst - 1; - } while (d < e); - - d[-1] = '\0'; - } - - p = s; - - while (*s++ != '\0') - ;; - - return lim + (s - p - 1); -} /* dns_strlcat() */ - - -#if defined(_WIN32) || defined(__SUNPRO_C) - -static char *dns_strsep(char **sp, const char *delim) { - char *p; - - if (!(p = *sp)) - return 0; - - *sp += strcspn(p, delim); - - if (**sp != '\0') { - **sp = '\0'; - ++*sp; - } else - *sp = NULL; - - return p; -} /* dns_strsep() */ - -#else -#define dns_strsep(...) strsep(__VA_ARGS__) -#endif - - -#if _WIN32 -#define strcasecmp(...) _stricmp(__VA_ARGS__) -#define strncasecmp(...) _strnicmp(__VA_ARGS__) -#endif - - -static int dns_poll(int fd, short events, int timeout) { - fd_set rset, wset; - - if (!events) - return 0; - - assert(fd >= 0 && fd < FD_SETSIZE); - - FD_ZERO(&rset); - FD_ZERO(&wset); - - if (events & DNS_POLLIN) - FD_SET(fd, &rset); - - if (events & DNS_POLLOUT) - FD_SET(fd, &wset); - - select(fd + 1, &rset, &wset, 0, (timeout >= 0)? &(struct timeval){ timeout, 0 } : NULL); - - return 0; -} /* dns_poll() */ - - -/* - * P A C K E T R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -unsigned dns_p_count(struct dns_packet *P, enum dns_section section) { - unsigned count; - - switch (section) { - case DNS_S_QD: - return ntohs(dns_header(P)->qdcount); - case DNS_S_AN: - return ntohs(dns_header(P)->ancount); - case DNS_S_NS: - return ntohs(dns_header(P)->nscount); - case DNS_S_AR: - return ntohs(dns_header(P)->arcount); - default: - count = 0; - - if (section & DNS_S_QD) - count += ntohs(dns_header(P)->qdcount); - if (section & DNS_S_AN) - count += ntohs(dns_header(P)->ancount); - if (section & DNS_S_NS) - count += ntohs(dns_header(P)->nscount); - if (section & DNS_S_AR) - count += ntohs(dns_header(P)->arcount); - - return count; - } -} /* dns_p_count() */ - - -struct dns_packet *dns_p_init(struct dns_packet *P, size_t size) { - if (!P) - return 0; - - assert(size >= offsetof(struct dns_packet, data) + 12); - - memset(P, 0, sizeof *P); - P->size = size - offsetof(struct dns_packet, data); - P->end = 12; - - memset(P->data, '\0', 12); - - return P; -} /* dns_p_init() */ - - -static unsigned short dns_p_qend(struct dns_packet *P) { - unsigned short qend = 12; - unsigned i, count = dns_p_count(P, DNS_S_QD); - - for (i = 0; i < count && qend < P->end; i++) { - if (P->end == (qend = dns_d_skip(qend, P))) - goto invalid; - - if (P->end - qend < 4) - goto invalid; - - qend += 4; - } - - return MIN(qend, P->end); -invalid: - return P->end; -} /* dns_p_qend() */ - - -struct dns_packet *dns_p_make(size_t len, int *error) { - struct dns_packet *P; - size_t size = dns_p_calcsize(len); - - if (!(P = dns_p_init(malloc(size), size))) - *error = dns_syerr(); - - return P; -} /* dns_p_make() */ - - -int dns_p_grow(struct dns_packet **P) { - struct dns_packet *tmp; - size_t size; - int error; - - if (!*P) { - if (!(*P = dns_p_make(DNS_P_QBUFSIZ, &error))) - return error; - - return 0; - } - - size = dns_p_sizeof(*P); - size |= size >> 1; - size |= size >> 2; - size |= size >> 4; - size |= size >> 8; - size++; - - if (size > 65536) - return DNS_ENOBUFS; - - if (!(tmp = realloc(*P, dns_p_calcsize(size)))) - return dns_syerr(); - - tmp->size = size; - *P = tmp; - - return 0; -} /* dns_p_grow() */ - - -struct dns_packet *dns_p_copy(struct dns_packet *P, const struct dns_packet *P0) { - if (!P) - return 0; - - P->end = MIN(P->size, P0->end); - - memcpy(P->data, P0->data, P->end); - - return P; -} /* dns_p_copy() */ - - -struct dns_packet *dns_p_merge(struct dns_packet *A, enum dns_section Amask, struct dns_packet *B, enum dns_section Bmask, int *error_) { - size_t bufsiz = MIN(65535, ((A)? A->end : 0) + ((B)? B->end : 0)); - struct dns_packet *M; - enum dns_section section; - struct dns_rr rr, mr; - int error, copy; - - if (!A && B) { - A = B; - Amask = Bmask; - B = 0; - } - -merge: - if (!(M = dns_p_make(bufsiz, &error))) - goto error; - - for (section = DNS_S_QD; (DNS_S_ALL & section); section <<= 1) { - if (A && (section & Amask)) { - dns_rr_foreach(&rr, A, .section = section) { - if ((error = dns_rr_copy(M, &rr, A))) - goto error; - } - } - - if (B && (section & Bmask)) { - dns_rr_foreach(&rr, B, .section = section) { - copy = 1; - - dns_rr_foreach(&mr, M, .type = rr.type, .section = DNS_S_ALL) { - if (!(copy = dns_rr_cmp(&rr, B, &mr, M))) - break; - } - - if (copy && (error = dns_rr_copy(M, &rr, B))) - goto error; - } - } - } - - return M; -error: - free(M); M = 0; - - if (error == DNS_ENOBUFS && bufsiz < 65535) { - bufsiz = MIN(65535, bufsiz * 2); - - goto merge; - } - - *error_ = error; - - return 0; -} /* dns_p_merge() */ - - -static unsigned short dns_l_skip(unsigned short, const unsigned char *, size_t); - -void dns_p_dictadd(struct dns_packet *P, unsigned short dn) { - unsigned short lp, lptr, i; - - lp = dn; - - while (lp < P->end) { - if (0xc0 == (0xc0 & P->data[lp]) && P->end - lp >= 2 && lp != dn) { - lptr = ((0x3f & P->data[lp + 0]) << 8) - | ((0xff & P->data[lp + 1]) << 0); - - for (i = 0; i < lengthof(P->dict) && P->dict[i]; i++) { - if (P->dict[i] == lptr) { - P->dict[i] = dn; - - return; - } - } - } - - lp = dns_l_skip(lp, P->data, P->end); - } - - for (i = 0; i < lengthof(P->dict); i++) { - if (!P->dict[i]) { - P->dict[i] = dn; - - break; - } - } -} /* dns_p_dictadd() */ - - -int dns_p_push(struct dns_packet *P, enum dns_section section, const void *dn, size_t dnlen, enum dns_type type, enum dns_class class, unsigned ttl, const void *any) { - size_t end = P->end; - int error; - - if ((error = dns_d_push(P, dn, dnlen))) - goto error; - - if (P->size - P->end < 4) - goto nobufs; - - P->data[P->end++] = 0xff & (type >> 8); - P->data[P->end++] = 0xff & (type >> 0); - - P->data[P->end++] = 0xff & (class >> 8); - P->data[P->end++] = 0xff & (class >> 0); - - if (section == DNS_S_QD) - goto update; - - if (P->size - P->end < 6) - goto nobufs; - - P->data[P->end++] = 0x7f & (ttl >> 24); - P->data[P->end++] = 0xff & (ttl >> 16); - P->data[P->end++] = 0xff & (ttl >> 8); - P->data[P->end++] = 0xff & (ttl >> 0); - - if ((error = dns_any_push(P, (union dns_any *)any, type))) - goto error; - -update: - switch (section) { - case DNS_S_QD: - if (dns_p_count(P, DNS_S_AN|DNS_S_NS|DNS_S_AR)) - goto order; - - if (!P->qd.base && (error = dns_p_study(P))) - goto error; - - dns_header(P)->qdcount = htons(ntohs(dns_header(P)->qdcount) + 1); - - P->qd.end = P->end; - P->an.base = P->end; - P->an.end = P->end; - P->ns.base = P->end; - P->ns.end = P->end; - P->ar.base = P->end; - P->ar.end = P->end; - - break; - case DNS_S_AN: - if (dns_p_count(P, DNS_S_NS|DNS_S_AR)) - goto order; - - if (!P->an.base && (error = dns_p_study(P))) - goto error; - - dns_header(P)->ancount = htons(ntohs(dns_header(P)->ancount) + 1); - - P->an.end = P->end; - P->ns.base = P->end; - P->ns.end = P->end; - P->ar.base = P->end; - P->ar.end = P->end; - - break; - case DNS_S_NS: - if (dns_p_count(P, DNS_S_AR)) - goto order; - - if (!P->ns.base && (error = dns_p_study(P))) - goto error; - - dns_header(P)->nscount = htons(ntohs(dns_header(P)->nscount) + 1); - - P->ns.end = P->end; - P->ar.base = P->end; - P->ar.end = P->end; - - break; - case DNS_S_AR: - if (!P->ar.base && (error = dns_p_study(P))) - goto error; - - dns_header(P)->arcount = htons(ntohs(dns_header(P)->arcount) + 1); - - P->ar.end = P->end; - - break; - default: - error = DNS_ESECTION; - - goto error; - } /* switch() */ - - return 0; -nobufs: - error = DNS_ENOBUFS; - - goto error; -order: - error = DNS_EORDER; - - goto error; -error: - P->end = end; - - return error; -} /* dns_p_push() */ - - -static void dns_p_dump3(struct dns_packet *P, struct dns_rr_i *I, FILE *fp) { - enum dns_section section; - struct dns_rr rr; - int error; - union dns_any any; - char pretty[sizeof any * 2]; - size_t len; - - fputs(";; [HEADER]\n", fp); - fprintf(fp, ";; qr : %s(%d)\n", (dns_header(P)->qr)? "RESPONSE" : "QUERY", dns_header(P)->qr); - fprintf(fp, ";; opcode : %s(%d)\n", dns_stropcode(dns_header(P)->opcode), dns_header(P)->opcode); - fprintf(fp, ";; aa : %s(%d)\n", (dns_header(P)->aa)? "AUTHORITATIVE" : "NON-AUTHORITATIVE", dns_header(P)->aa); - fprintf(fp, ";; tc : %s(%d)\n", (dns_header(P)->tc)? "TRUNCATED" : "NOT-TRUNCATED", dns_header(P)->tc); - fprintf(fp, ";; rd : %s(%d)\n", (dns_header(P)->rd)? "RECURSION-DESIRED" : "RECURSION-NOT-DESIRED", dns_header(P)->rd); - fprintf(fp, ";; ra : %s(%d)\n", (dns_header(P)->ra)? "RECURSION-ALLOWED" : "RECURSION-NOT-ALLOWED", dns_header(P)->ra); - fprintf(fp, ";; rcode : %s(%d)\n", dns_strrcode(dns_header(P)->rcode), dns_header(P)->rcode); - - section = 0; - - while (dns_rr_grep(&rr, 1, I, P, &error)) { - if (section != rr.section) - fprintf(fp, "\n;; [%s:%d]\n", dns_strsection(rr.section), dns_p_count(P, rr.section)); - - if ((len = dns_rr_print(pretty, sizeof pretty, &rr, P, &error))) - fprintf(fp, "%s\n", pretty); - - section = rr.section; - } -} /* dns_p_dump3() */ - - -void dns_p_dump(struct dns_packet *P, FILE *fp) { - dns_p_dump3(P, dns_rr_i_new(P, .section = 0), fp); -} /* dns_p_dump() */ - - -static void dns_s_unstudy(struct dns_s_memo *m) - { m->base = 0; m->end = 0; } - -static void dns_p_unstudy(struct dns_packet *P) { - dns_s_unstudy(&P->qd); - dns_s_unstudy(&P->an); - dns_s_unstudy(&P->ns); - dns_s_unstudy(&P->ar); -} /* dns_p_unstudy() */ - -static int dns_s_study(struct dns_s_memo *m, enum dns_section section, unsigned base, struct dns_packet *P) { - unsigned short count, rp; - - count = dns_p_count(P, section); - - for (rp = base; count && rp < P->end; count--) - rp = dns_rr_skip(rp, P); - - m->base = base; - m->end = rp; - - return 0; -} /* dns_s_study() */ - -int dns_p_study(struct dns_packet *P) { - int error; - - if ((error = dns_s_study(&P->qd, DNS_S_QD, 12, P))) - goto error; - - if ((error = dns_s_study(&P->an, DNS_S_AN, P->qd.end, P))) - goto error; - - if ((error = dns_s_study(&P->ns, DNS_S_NS, P->an.end, P))) - goto error; - - if ((error = dns_s_study(&P->ar, DNS_S_AR, P->ns.end, P))) - goto error; - - return 0; -error: - dns_p_unstudy(P); - - return error; -} /* dns_p_study() */ - - -/* - * D O M A I N N A M E R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef DNS_D_MAXPTRS -#define DNS_D_MAXPTRS 127 /* Arbitrary; possible, valid depth is something like packet size / 2 + fudge. */ -#endif - -static size_t dns_l_expand(unsigned char *dst, size_t lim, unsigned short src, unsigned short *nxt, const unsigned char *data, size_t end) { - unsigned short len; - unsigned nptrs = 0; - -retry: - if (src >= end) - goto invalid; - - switch (0x03 & (data[src] >> 6)) { - case 0x00: - len = (0x3f & (data[src++])); - - if (end - src < len) - goto invalid; - - if (lim > 0) { - memcpy(dst, &data[src], MIN(lim, len)); - - dst[MIN(lim - 1, len)] = '\0'; - } - - *nxt = src + len; - - return len; - case 0x01: - goto invalid; - case 0x02: - goto invalid; - case 0x03: - if (++nptrs > DNS_D_MAXPTRS) - goto invalid; - - if (end - src < 2) - goto invalid; - - src = ((0x3f & data[src + 0]) << 8) - | ((0xff & data[src + 1]) << 0); - - goto retry; - } /* switch() */ - - /* NOT REACHED */ -invalid: - *nxt = end; - - return 0; -} /* dns_l_expand() */ - - -static unsigned short dns_l_skip(unsigned short src, const unsigned char *data, size_t end) { - unsigned short len; - - if (src >= end) - goto invalid; - - switch (0x03 & (data[src] >> 6)) { - case 0x00: - len = (0x3f & (data[src++])); - - if (end - src < len) - goto invalid; - - return (len)? src + len : end; - case 0x01: - goto invalid; - case 0x02: - goto invalid; - case 0x03: - return end; - } /* switch() */ - - /* NOT REACHED */ -invalid: - return end; -} /* dns_l_skip() */ - - -size_t dns_d_trim(void *dst_, size_t lim, const void *src_, size_t len, int flags) { - unsigned char *dst = dst_; - const unsigned char *src = src_; - size_t dp = 0, sp = 0; - int lc; - - /* trim any leading dot(s) */ - while (sp < len && src[sp] == '.') - sp++; - - for (lc = 0; sp < len; lc = src[sp]) { - if (dp < lim) - dst[dp] = src[sp]; - - sp++; - dp++; - - /* trim extra dot(s) */ - while (sp < len && src[sp] == '.') - sp++; - } - - if ((flags & DNS_D_ANCHOR) && lc != '.') { - if (dp < lim) - dst[dp] = '.'; - - dp++; - } - - if (lim > 0) - dst[MIN(dp, lim - 1)] = '\0'; - - return dp; -} /* dns_d_trim() */ - - -char *dns_d_init(void *dst, size_t lim, const void *src, size_t len, int flags) { - if (flags & DNS_D_TRIM) { - dns_d_trim(dst, lim, src, len, flags); - } if (flags & DNS_D_ANCHOR) { - dns_d_anchor(dst, lim, src, len); - } else { - memmove(dst, src, MIN(lim, len)); - - if (lim > 0) - ((char *)dst)[MIN(len, lim - 1)] = '\0'; - } - - return dst; -} /* dns_d_init() */ - - -size_t dns_d_anchor(void *dst, size_t lim, const void *src, size_t len) { - if (len == 0) - return 0; - - memmove(dst, src, MIN(lim, len)); - - if (((const char *)src)[len - 1] != '.') { - if (len < lim) - ((char *)dst)[len] = '.'; - len++; - } - - if (lim > 0) - ((char *)dst)[MIN(lim - 1, len)] = '\0'; - - return len; -} /* dns_d_anchor() */ - - -size_t dns_d_cleave(void *dst, size_t lim, const void *src, size_t len) { - const char *dot; - - /* XXX: Skip any leading dot. Handles cleaving root ".". */ - if (len == 0 || !(dot = memchr((const char *)src + 1, '.', len - 1))) - return 0; - - len -= dot - (const char *)src; - - /* XXX: Unless root, skip the label's trailing dot. */ - if (len > 1) { - src = ++dot; - len--; - } else - src = dot; - - memmove(dst, src, MIN(lim, len)); - - if (lim > 0) - ((char *)dst)[MIN(lim - 1, len)] = '\0'; - - return len; -} /* dns_d_cleave() */ - - -size_t dns_d_comp(void *dst_, size_t lim, const void *src_, size_t len, struct dns_packet *P, int *error EINA_UNUSED) { - struct { unsigned char *b; size_t p, x; } dst, src; - unsigned char ch = '.'; - - dst.b = dst_; - dst.p = 0; - dst.x = 1; - - src.b = (unsigned char *)src_; - src.p = 0; - src.x = 0; - - while (src.x < len) { - ch = src.b[src.x]; - - if (ch == '.') { - if (dst.p < lim) - dst.b[dst.p] = (0x3f & (src.x - src.p)); - - dst.p = dst.x++; - src.p = ++src.x; - } else { - if (dst.x < lim) - dst.b[dst.x] = ch; - - dst.x++; - src.x++; - } - } /* while() */ - - if (src.x > src.p) { - if (dst.p < lim) - dst.b[dst.p] = (0x3f & (src.x - src.p)); - - dst.p = dst.x; - } - - if (dst.p > 1) { - if (dst.p < lim) - dst.b[dst.p] = 0x00; - - dst.p++; - } - -#if 1 - if (dst.p < lim) { - struct { unsigned char label[DNS_D_MAXLABEL + 1]; size_t len; unsigned short p, x, y; } a, b; - unsigned i; - - a.p = 0; - - while ((a.len = dns_l_expand(a.label, sizeof a.label, a.p, &a.x, dst.b, lim))) { - for (i = 0; i < lengthof(P->dict) && P->dict[i]; i++) { - b.p = P->dict[i]; - - while ((b.len = dns_l_expand(b.label, sizeof b.label, b.p, &b.x, P->data, P->end))) { - a.y = a.x; - b.y = b.x; - - while (a.len && b.len && 0 == strcasecmp((char *)a.label, (char *)b.label)) { - a.len = dns_l_expand(a.label, sizeof a.label, a.y, &a.y, dst.b, lim); - b.len = dns_l_expand(b.label, sizeof b.label, b.y, &b.y, P->data, P->end); - } - - if (a.len == 0 && b.len == 0 && b.p <= 0x3fff) { - dst.b[a.p++] = 0xc0 - | (0x3f & (b.p >> 8)); - dst.b[a.p++] = (0xff & (b.p >> 0)); - - return a.p; - } - - b.p = b.x; - } /* while() */ - } /* for() */ - - a.p = a.x; - } /* while() */ - } /* if () */ -#endif - - return dst.p; -} /* dns_d_comp() */ - - -unsigned short dns_d_skip(unsigned short src, struct dns_packet *P) { - unsigned short len; - - while (src < P->end) { - switch (0x03 & (P->data[src] >> 6)) { - case 0x00: /* FOLLOWS */ - len = (0x3f & P->data[src++]); - - if (0 == len) { -/* success ==> */ return src; - } else if (P->end - src > len) { - src += len; - - break; - } else - goto invalid; - - /* NOT REACHED */ - case 0x01: /* RESERVED */ - goto invalid; - case 0x02: /* RESERVED */ - goto invalid; - case 0x03: /* POINTER */ - if (P->end - src < 2) - goto invalid; - - src += 2; - -/* success ==> */ return src; - } /* switch() */ - } /* while() */ - -invalid: -//assert(0); - return P->end; -} /* dns_d_skip() */ - - -#include - -size_t dns_d_expand(void *dst, size_t lim, unsigned short src, struct dns_packet *P, int *error) { - size_t dstp = 0; - unsigned nptrs = 0; - unsigned char len; - - while (src < P->end) { - switch ((0x03 & (P->data[src] >> 6))) { - case 0x00: /* FOLLOWS */ - len = (0x3f & P->data[src]); - - if (0 == len) { - if (dstp == 0) { - if (dstp < lim) - ((unsigned char *)dst)[dstp] = '.'; - - dstp++; - } - - /* NUL terminate */ - if (lim > 0) - ((unsigned char *)dst)[MIN(dstp, lim - 1)] = '\0'; - -/* success ==> */ return dstp; - } - - src++; - - if (P->end - src < len) - goto toolong; - - if (dstp < lim) - memcpy(&((unsigned char *)dst)[dstp], &P->data[src], MIN(len, lim - dstp)); - - src += len; - dstp += len; - - if (dstp < lim) - ((unsigned char *)dst)[dstp] = '.'; - - dstp++; - - nptrs = 0; - - continue; - case 0x01: /* RESERVED */ - goto reserved; - case 0x02: /* RESERVED */ - goto reserved; - case 0x03: /* POINTER */ - if (++nptrs > DNS_D_MAXPTRS) - goto toolong; - - if (P->end - src < 2) - goto toolong; - - src = ((0x3f & P->data[src + 0]) << 8) - | ((0xff & P->data[src + 1]) << 0); - - continue; - } /* switch() */ - } /* while() */ - -toolong: - *error = DNS_EILLEGAL; - - if (lim > 0) - ((unsigned char *)dst)[MIN(dstp, lim - 1)] = '\0'; - - return 0; -reserved: - *error = DNS_EILLEGAL; - - if (lim > 0) - ((unsigned char *)dst)[MIN(dstp, lim - 1)] = '\0'; - - return 0; -} /* dns_d_expand() */ - - -int dns_d_push(struct dns_packet *P, const void *dn, size_t len) { - size_t lim = P->size - P->end; - unsigned dp = P->end; - int error; - - len = dns_d_comp(&P->data[dp], lim, dn, len, P, &error); - - if (len == 0) - return error; - if (len > lim) - return DNS_ENOBUFS; - - P->end += len; - - dns_p_dictadd(P, dp); - - return 0; -} /* dns_d_push() */ - - -size_t dns_d_cname(void *dst, size_t lim, const void *dn, size_t len, struct dns_packet *P, int *error_) { - char host[DNS_D_MAXNAME + 1]; - struct dns_rr_i i; - struct dns_rr rr; - unsigned depth; - int error; - - if (sizeof host <= dns_d_anchor(host, sizeof host, dn, len)) - { error = ENAMETOOLONG; goto error; } - - for (depth = 0; depth < 7; depth++) { - dns_rr_i_init(memset(&i, 0, sizeof i), P); - - i.section = DNS_S_ALL & ~DNS_S_QD; - i.name = host; - i.type = DNS_T_CNAME; - - if (!dns_rr_grep(&rr, 1, &i, P, &error)) - break; - - if ((error = dns_cname_parse((struct dns_cname *)host, &rr, P))) - goto error; - } - - return dns_strlcpy(dst, host, lim); -error: - *error_ = error; - - return 0; -} /* dns_d_cname() */ - - -/* - * R E S O U R C E R E C O R D R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -int dns_rr_copy(struct dns_packet *P, struct dns_rr *rr, struct dns_packet *Q) { - unsigned char dn[DNS_D_MAXNAME + 1]; - union dns_any any; - size_t len; - int error; - - if (!(len = dns_d_expand(dn, sizeof dn, rr->dn.p, Q, &error))) - return error; - else if (len >= sizeof dn) - return DNS_EILLEGAL; - - if (rr->section != DNS_S_QD && (error = dns_any_parse(dns_any_init(&any, sizeof any), rr, Q))) - return error; - - return dns_p_push(P, rr->section, dn, len, rr->type, rr->class, rr->ttl, &any); -} /* dns_rr_copy() */ - - -int dns_rr_parse(struct dns_rr *rr, unsigned short src, struct dns_packet *P) { - unsigned short p = src; - - if (src >= P->end) - goto invalid; - - rr->dn.p = p; - rr->dn.len = (p = dns_d_skip(p, P)) - rr->dn.p; - - if (P->end - p < 4) - goto invalid; - - rr->type = ((0xff & P->data[p + 0]) << 8) - | ((0xff & P->data[p + 1]) << 0); - - rr->class = ((0xff & P->data[p + 2]) << 8) - | ((0xff & P->data[p + 3]) << 0); - - p += 4; - - if (src < dns_p_qend(P)) { - rr->section = DNS_S_QUESTION; - - rr->ttl = 0; - rr->rd.p = 0; - rr->rd.len = 0; - - return 0; - } - - if (P->end - p < 4) - goto invalid; - - rr->ttl = ((0x7f & P->data[p + 0]) << 24) - | ((0xff & P->data[p + 1]) << 16) - | ((0xff & P->data[p + 2]) << 8) - | ((0xff & P->data[p + 3]) << 0); - - p += 4; - - if (P->end - p < 2) - goto invalid; - - rr->rd.len = ((0xff & P->data[p + 0]) << 8) - | ((0xff & P->data[p + 1]) << 0); - rr->rd.p = p + 2; - - p += 2; - - if (P->end - p < rr->rd.len) - goto invalid; - - return 0; -invalid: -//assert(0); - return DNS_EILLEGAL; -} /* dns_rr_parse() */ - - -static unsigned short dns_rr_len(const unsigned short src, struct dns_packet *P) { - unsigned short rp, rdlen; - - rp = dns_d_skip(src, P); - - if (P->end - rp < 4) - return P->end - src; - - rp += 4; /* TYPE, CLASS */ - - if (rp <= dns_p_qend(P)) - return rp - src; - - if (P->end - rp < 6) - return P->end - src; - - rp += 6; /* TTL, RDLEN */ - - rdlen = ((0xff & P->data[rp - 2]) << 8) - | ((0xff & P->data[rp - 1]) << 0); - - if (P->end - rp < rdlen) - return P->end - src; - - rp += rdlen; - - return rp - src; -} /* dns_rr_len() */ - - -unsigned short dns_rr_skip(unsigned short src, struct dns_packet *P) { - return src + dns_rr_len(src, P); -} /* dns_rr_skip() */ - - -static enum dns_section dns_rr_section(unsigned short src, struct dns_packet *P) { - enum dns_section section; - unsigned count, ind; - unsigned short rp; - - if (src >= P->qd.base && src < P->qd.end) - return DNS_S_QD; - if (src >= P->an.base && src < P->an.end) - return DNS_S_AN; - if (src >= P->ns.base && src < P->ns.end) - return DNS_S_NS; - if (src >= P->ar.base && src < P->ar.end) - return DNS_S_AR; - - /* NOTE: Possibly bad memoization. Try it the hard-way. */ - - for (rp = 12, ind = 0; rp < src && rp < P->end; ind++) - rp = dns_rr_skip(rp, P); - - section = DNS_S_QD; - count = dns_p_count(P, section); - - while (ind >= count && section <= DNS_S_AR) { - section <<= 1; - count += dns_p_count(P, section); - } - - return DNS_S_ALL & section; -} /* dns_rr_section() */ - - -static enum dns_type dns_rr_type(unsigned short src, struct dns_packet *P) { - struct dns_rr rr; - int error; - - if ((error = dns_rr_parse(&rr, src, P))) - return 0; - - return rr.type; -} /* dns_rr_type() */ - - -int dns_rr_cmp(struct dns_rr *r0, struct dns_packet *P0, struct dns_rr *r1, struct dns_packet *P1) { - char host0[DNS_D_MAXNAME + 1], host1[DNS_D_MAXNAME + 1]; - union dns_any any0, any1; - int cmp, error; - size_t len; - - if ((cmp = r0->type - r1->type)) - return cmp; - - if ((cmp = r0->class - r1->class)) - return cmp; - - /* - * FIXME: Do label-by-label comparison to handle illegally long names? - */ - - if (!(len = dns_d_expand(host0, sizeof host0, r0->dn.p, P0, &error)) - || len >= sizeof host0) - return -1; - - if (!(len = dns_d_expand(host1, sizeof host1, r1->dn.p, P1, &error)) - || len >= sizeof host1) - return 1; - - if ((cmp = strcasecmp(host0, host1))) - return cmp; - - if (DNS_S_QD & (r0->section | r1->section)) { - if (r0->section == r1->section) - return 0; - - return (r0->section == DNS_S_QD)? -1 : 1; - } - - if ((error = dns_any_parse(&any0, r0, P0))) - return -1; - - if ((error = dns_any_parse(&any1, r1, P1))) - return 1; - - return dns_any_cmp(&any0, r0->type, &any1, r1->type); -} /* dns_rr_cmp() */ - - -static _Bool dns_rr_exists(struct dns_rr *rr0, struct dns_packet *P0, struct dns_packet *P1) { - struct dns_rr rr1; - - dns_rr_foreach(&rr1, P1, .section = rr0->section, .type = rr0->type) { - if (0 == dns_rr_cmp(rr0, P0, &rr1, P1)) - return 1; - } - - return 0; -} /* dns_rr_exists() */ - - -static unsigned short dns_rr_offset(struct dns_rr *rr) { - return rr->dn.p; -} /* dns_rr_offset() */ - - -static _Bool dns_rr_i_match(struct dns_rr *rr, struct dns_rr_i *i, struct dns_packet *P) { - if (i->section && !(rr->section & i->section)) - return 0; - - if (i->type && rr->type != i->type && i->type != DNS_T_ALL) - return 0; - - if (i->class && rr->class != i->class && i->class != DNS_C_ANY) - return 0; - - if (i->name) { - char dn[DNS_D_MAXNAME + 1]; - size_t len; - int error; - - if (!(len = dns_d_expand(dn, sizeof dn, rr->dn.p, P, &error)) - || len >= sizeof dn) - return 0; - - if (0 != strcasecmp(dn, i->name)) - return 0; - } - - if (i->data && i->type && rr->section > DNS_S_QD) { - union dns_any rd; - int error; - - if ((error = dns_any_parse(&rd, rr, P))) - return 0; - - if (0 != dns_any_cmp(&rd, rr->type, i->data, i->type)) - return 0; - } - - return 1; -} /* dns_rr_i_match() */ - - -static unsigned short dns_rr_i_start(struct dns_rr_i *i, struct dns_packet *P) { - unsigned short rp; - struct dns_rr r0, rr; - int error; - - if ((i->section & DNS_S_QD) && P->qd.base) - rp = P->qd.base; - else if ((i->section & DNS_S_AN) && P->an.base) - rp = P->an.base; - else if ((i->section & DNS_S_NS) && P->ns.base) - rp = P->ns.base; - else if ((i->section & DNS_S_AR) && P->ar.base) - rp = P->ar.base; - else - rp = 12; - - for (rp = 12; rp < P->end; rp = dns_rr_skip(rp, P)) { - if ((error = dns_rr_parse(&rr, rp, P))) - continue; - - rr.section = dns_rr_section(rp, P); - - if (!dns_rr_i_match(&rr, i, P)) - continue; - - r0 = rr; - - goto lower; - } - - return P->end; -lower: - if (i->sort == &dns_rr_i_packet) - return dns_rr_offset(&r0); - - while ((rp = dns_rr_skip(rp, P)) < P->end) { - if ((error = dns_rr_parse(&rr, rp, P))) - continue; - - rr.section = dns_rr_section(rp, P); - - if (!dns_rr_i_match(&rr, i, P)) - continue; - - if (i->sort(&rr, &r0, i, P) < 0) - r0 = rr; - } - - return dns_rr_offset(&r0); -} /* dns_rr_i_start() */ - - -static unsigned short dns_rr_i_skip(unsigned short rp, struct dns_rr_i *i, struct dns_packet *P) { - struct dns_rr r0, r1, rr; - int error; - - if ((error = dns_rr_parse(&r0, rp, P))) - return P->end; - - r0.section = dns_rr_section(rp, P); - - rp = (i->sort == &dns_rr_i_packet)? dns_rr_skip(rp, P) : 12; - - for (; rp < P->end; rp = dns_rr_skip(rp, P)) { - if ((error = dns_rr_parse(&rr, rp, P))) - continue; - - rr.section = dns_rr_section(rp, P); - - if (!dns_rr_i_match(&rr, i, P)) - continue; - - if (i->sort(&rr, &r0, i, P) <= 0) - continue; - - r1 = rr; - - goto lower; - } - - return P->end; -lower: - if (i->sort == &dns_rr_i_packet) - return dns_rr_offset(&r1); - - while ((rp = dns_rr_skip(rp, P)) < P->end) { - if ((error = dns_rr_parse(&rr, rp, P))) - continue; - - rr.section = dns_rr_section(rp, P); - - if (!dns_rr_i_match(&rr, i, P)) - continue; - - if (i->sort(&rr, &r0, i, P) <= 0) - continue; - - if (i->sort(&rr, &r1, i, P) >= 0) - continue; - - r1 = rr; - } - - return dns_rr_offset(&r1); -} /* dns_rr_i_skip() */ - - -int dns_rr_i_packet(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i EINA_UNUSED, struct dns_packet *P EINA_UNUSED) { - return (int)a->dn.p - (int)b->dn.p; -} /* dns_rr_i_packet() */ - - -int dns_rr_i_order(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i EINA_UNUSED, struct dns_packet *P) { - int cmp; - - if ((cmp = a->section - b->section)) - return cmp; - - if (a->type != b->type) - return (int)a->dn.p - (int)b->dn.p; - - return dns_rr_cmp(a, P, b, P); -} /* dns_rr_i_order() */ - - -int dns_rr_i_shuffle(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i, struct dns_packet *P EINA_UNUSED) { - int cmp; - - while (!i->state.regs[0]) - i->state.regs[0] = dns_random(); - - if ((cmp = a->section - b->section)) - return cmp; - - return dns_k_shuffle16(a->dn.p, i->state.regs[0]) - dns_k_shuffle16(b->dn.p, i->state.regs[0]); -} /* dns_rr_i_shuffle() */ - - -struct dns_rr_i *dns_rr_i_init(struct dns_rr_i *i, struct dns_packet *P EINA_UNUSED) { - static const struct dns_rr_i i_initializer; - - i->state = i_initializer.state; - i->saved = i->state; - - return i; -} /* dns_rr_i_init() */ - - -unsigned dns_rr_grep(struct dns_rr *rr, unsigned lim, struct dns_rr_i *i, struct dns_packet *P, int *error_) { - unsigned count = 0; - int error; - - switch (i->state.exec) { - case 0: - if (!i->sort) - i->sort = &dns_rr_i_packet; - - i->state.next = dns_rr_i_start(i, P); - i->state.exec++; - - /* FALL THROUGH */ - case 1: - while (count < lim && i->state.next < P->end) { - if ((error = dns_rr_parse(rr, i->state.next, P))) - goto error; - - rr->section = dns_rr_section(i->state.next, P); - - rr++; - count++; - i->state.count++; - - i->state.next = dns_rr_i_skip(i->state.next, i, P); - } /* while() */ - - break; - } /* switch() */ - - return count; -error: - *error_ = error; - - return count; -} /* dns_rr_grep() */ - - -static size_t dns__printchar(void *dst, size_t lim, size_t cp, unsigned char ch) { - if (cp < lim) - ((unsigned char *)dst)[cp] = ch; - - return 1; -} /* dns__printchar() */ - - -static size_t dns__printstring(void *dst, size_t lim, size_t cp, const void *src, size_t len) { - if (cp < lim) - memcpy(&((unsigned char *)dst)[cp], src, MIN(len, lim - cp)); - - return len; -} /* dns__printstring() */ - -#define dns__printstring5(a, b, c, d, e) dns__printstring((a), (b), (c), (d), (e)) -#define dns__printstring4(a, b, c, d) dns__printstring((a), (b), (c), (d), strlen((d))) -#define dns__printstring(...) DNS_PP_CALL(DNS_PP_XPASTE(dns__printstring, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) - - -static void dns__printnul(void *dst, size_t lim, size_t off) { - if (lim > 0) - ((unsigned char *)dst)[MIN(off, lim - 1)] = '\0'; -} /* dns__printnul() */ - - -static size_t dns__print10(void *dst, size_t lim, size_t off, unsigned n, unsigned pad) { - unsigned char tmp[32]; - unsigned dp = off; - unsigned cp = 0; - unsigned d = 1000000000; - unsigned ch; - - pad = MAX(1, pad); - - while (d) { - if ((ch = n / d) || cp > 0) { - n -= ch * d; - - tmp[cp] = '0' + ch; - - cp++; - } - - d /= 10; - } - - while (cp < pad) { - dp += dns__printchar(dst, lim, dp, '0'); - pad--; - } - - dp += dns__printstring(dst, lim, dp, tmp, cp); - - return dp - off; -} /* dns__print10() */ - - -size_t dns_rr_print(void *dst, size_t lim, struct dns_rr *rr, struct dns_packet *P, int *error_) { - union dns_any any; - size_t cp, n, rdlen; - void *rd; - int error; - - cp = 0; - - if (rr->section == DNS_S_QD) - cp += dns__printchar(dst, lim, cp, ';'); - - if (!(n = dns_d_expand(&((unsigned char *)dst)[cp], (cp < lim)? lim - cp : 0, rr->dn.p, P, &error))) - goto error; - - cp += n; - - if (rr->section != DNS_S_QD) { - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__print10(dst, lim, cp, rr->ttl, 0); - } - - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__printstring(dst, lim, cp, dns_strclass(rr->class), strlen(dns_strclass(rr->class))); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__printstring(dst, lim, cp, dns_strtype(rr->type), strlen(dns_strtype(rr->type))); - - if (rr->section == DNS_S_QD) - goto epilog; - - cp += dns__printchar(dst, lim, cp, ' '); - - if ((error = dns_any_parse(dns_any_init(&any, sizeof any), rr, P))) - goto error; - - if (cp < lim) { - rd = &((unsigned char *)dst)[cp]; - rdlen = lim - cp; - } else { - rd = 0; - rdlen = 0; - } - - cp += dns_any_print(rd, rdlen, &any, rr->type); - -epilog: - dns__printnul(dst, lim, cp); - - return cp; -error: - *error_ = error; - - return 0; -} /* dns_rr_print() */ - - -int dns_a_parse(struct dns_a *a, struct dns_rr *rr, struct dns_packet *P) { - unsigned long addr; - - if (rr->rd.len != 4) - return DNS_EILLEGAL; - - addr = ((0xff & P->data[rr->rd.p + 0]) << 24) - | ((0xff & P->data[rr->rd.p + 1]) << 16) - | ((0xff & P->data[rr->rd.p + 2]) << 8) - | ((0xff & P->data[rr->rd.p + 3]) << 0); - - a->addr.s_addr = htonl(addr); - - return 0; -} /* dns_a_parse() */ - - -int dns_a_push(struct dns_packet *P, struct dns_a *a) { - unsigned long addr; - - if (P->size - P->end < 6) - return DNS_ENOBUFS; - - P->data[P->end++] = 0x00; - P->data[P->end++] = 0x04; - - addr = ntohl(a->addr.s_addr); - - P->data[P->end++] = 0xff & (addr >> 24); - P->data[P->end++] = 0xff & (addr >> 16); - P->data[P->end++] = 0xff & (addr >> 8); - P->data[P->end++] = 0xff & (addr >> 0); - - return 0; -} /* dns_a_push() */ - - -size_t dns_a_arpa(void *dst, size_t lim, const struct dns_a *a) { - unsigned long a4 = ntohl(a->addr.s_addr); - size_t cp = 0; - unsigned i; - - for (i = 4; i > 0; i--) { - cp += dns__print10(dst, lim, cp, (0xff & a4), 0); - cp += dns__printchar(dst, lim, cp, '.'); - a4 >>= 8; - } - - cp += dns__printstring(dst, lim, cp, "in-addr.arpa."); - - dns__printnul(dst, lim, cp); - - return cp; -} /* dns_a_arpa() */ - - -int dns_a_cmp(const struct dns_a *a, const struct dns_a *b) { - if (ntohl(a->addr.s_addr) < ntohl(b->addr.s_addr)) - return -1; - if (ntohl(a->addr.s_addr) > ntohl(b->addr.s_addr)) - return 1; - - return 0; -} /* dns_a_cmp() */ - - -size_t dns_a_print(void *dst, size_t lim, struct dns_a *a) { - char addr[INET_ADDRSTRLEN + 1] = "0.0.0.0"; - size_t len; - - dns_inet_ntop(AF_INET, &a->addr, addr, sizeof addr); - - dns__printnul(dst, lim, (len = dns__printstring(dst, lim, 0, addr))); - - return len; -} /* dns_a_print() */ - - -int dns_aaaa_parse(struct dns_aaaa *aaaa, struct dns_rr *rr, struct dns_packet *P) { - if (rr->rd.len != sizeof aaaa->addr.s6_addr) - return DNS_EILLEGAL; - - memcpy(aaaa->addr.s6_addr, &P->data[rr->rd.p], sizeof aaaa->addr.s6_addr); - - return 0; -} /* dns_aaaa_parse() */ - - -int dns_aaaa_push(struct dns_packet *P, struct dns_aaaa *aaaa) { - if (P->size - P->end < 2 + sizeof aaaa->addr.s6_addr) - return DNS_ENOBUFS; - - P->data[P->end++] = 0x00; - P->data[P->end++] = 0x10; - - memcpy(&P->data[P->end], aaaa->addr.s6_addr, sizeof aaaa->addr.s6_addr); - - P->end += sizeof aaaa->addr.s6_addr; - - return 0; -} /* dns_aaaa_push() */ - - -int dns_aaaa_cmp(const struct dns_aaaa *a, const struct dns_aaaa *b) { - unsigned i; - int cmp; - - for (i = 0; i < lengthof(a->addr.s6_addr); i++) { - if ((cmp = (a->addr.s6_addr[i] - b->addr.s6_addr[i]))) - return cmp; - } - - return 0; -} /* dns_aaaa_cmp() */ - - -size_t dns_aaaa_arpa(void *dst, size_t lim, const struct dns_aaaa *aaaa) { - static const unsigned char hex[16] = "0123456789abcdef"; - size_t cp = 0; - unsigned nyble; - int i, j; - - for (i = sizeof aaaa->addr.s6_addr - 1; i >= 0; i--) { - nyble = aaaa->addr.s6_addr[i]; - - for (j = 0; j < 2; j++) { - cp += dns__printchar(dst, lim, cp, hex[0x0f & nyble]); - cp += dns__printchar(dst, lim, cp, '.'); - nyble >>= 4; - } - } - - cp += dns__printstring(dst, lim, cp, "ip6.arpa."); - - dns__printnul(dst, lim, cp); - - return cp; -} /* dns_aaaa_arpa() */ - - -size_t dns_aaaa_print(void *dst, size_t lim, struct dns_aaaa *aaaa) { - char addr[INET6_ADDRSTRLEN + 1] = "::"; - size_t len; - - dns_inet_ntop(AF_INET6, &aaaa->addr, addr, sizeof addr); - - dns__printnul(dst, lim, (len = dns__printstring(dst, lim, 0, addr))); - - return len; -} /* dns_aaaa_print() */ - - -int dns_mx_parse(struct dns_mx *mx, struct dns_rr *rr, struct dns_packet *P) { - size_t len; - int error; - - if (rr->rd.len < 3) - return DNS_EILLEGAL; - - mx->preference = (0xff00 & (P->data[rr->rd.p + 0] << 8)) - | (0x00ff & (P->data[rr->rd.p + 1] << 0)); - - if (!(len = dns_d_expand(mx->host, sizeof mx->host, rr->rd.p + 2, P, &error))) - return error; - else if (len >= sizeof mx->host) - return DNS_EILLEGAL; - - return 0; -} /* dns_mx_parse() */ - - -int dns_mx_push(struct dns_packet *P, struct dns_mx *mx) { - size_t end, len; - int error; - - if (P->size - P->end < 5) - return DNS_ENOBUFS; - - end = P->end; - P->end += 2; - - P->data[P->end++] = 0xff & (mx->preference >> 8); - P->data[P->end++] = 0xff & (mx->preference >> 0); - - if ((error = dns_d_push(P, mx->host, strlen(mx->host)))) - goto error; - - len = P->end - end - 2; - - P->data[end + 0] = 0xff & (len >> 8); - P->data[end + 1] = 0xff & (len >> 0); - - return 0; -error: - P->end = end; - - return error; -} /* dns_mx_push() */ - - -int dns_mx_cmp(const struct dns_mx *a, const struct dns_mx *b) { - int cmp; - - if ((cmp = a->preference - b->preference)) - return cmp; - - return strcasecmp(a->host, b->host); -} /* dns_mx_cmp() */ - - -size_t dns_mx_print(void *dst, size_t lim, struct dns_mx *mx) { - size_t cp = 0; - - cp += dns__print10(dst, lim, cp, mx->preference, 0); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__printstring(dst, lim, cp, mx->host, strlen(mx->host)); - - dns__printnul(dst, lim, cp); - - return cp; -} /* dns_mx_print() */ - - -size_t dns_mx_cname(void *dst, size_t lim, struct dns_mx *mx) { - return dns_strlcpy(dst, mx->host, lim); -} /* dns_mx_cname() */ - - -int dns_ns_parse(struct dns_ns *ns, struct dns_rr *rr, struct dns_packet *P) { - size_t len; - int error; - - if (!(len = dns_d_expand(ns->host, sizeof ns->host, rr->rd.p, P, &error))) - return error; - else if (len >= sizeof ns->host) - return DNS_EILLEGAL; - - return 0; -} /* dns_ns_parse() */ - - -int dns_ns_push(struct dns_packet *P, struct dns_ns *ns) { - size_t end, len; - int error; - - if (P->size - P->end < 3) - return DNS_ENOBUFS; - - end = P->end; - P->end += 2; - - if ((error = dns_d_push(P, ns->host, strlen(ns->host)))) - goto error; - - len = P->end - end - 2; - - P->data[end + 0] = 0xff & (len >> 8); - P->data[end + 1] = 0xff & (len >> 0); - - return 0; -error: - P->end = end; - - return error; -} /* dns_ns_push() */ - - -int dns_ns_cmp(const struct dns_ns *a, const struct dns_ns *b) { - return strcasecmp(a->host, b->host); -} /* dns_ns_cmp() */ - - -size_t dns_ns_print(void *dst, size_t lim, struct dns_ns *ns) { - size_t cp; - - cp = dns__printstring(dst, lim, 0, ns->host, strlen(ns->host)); - - dns__printnul(dst, lim, cp); - - return cp; -} /* dns_ns_print() */ - - -size_t dns_ns_cname(void *dst, size_t lim, struct dns_ns *ns) { - return dns_strlcpy(dst, ns->host, lim); -} /* dns_ns_cname() */ - - -int dns_cname_parse(struct dns_cname *cname, struct dns_rr *rr, struct dns_packet *P) { - return dns_ns_parse((struct dns_ns *)cname, rr, P); -} /* dns_cname_parse() */ - - -int dns_cname_push(struct dns_packet *P, struct dns_cname *cname) { - return dns_ns_push(P, (struct dns_ns *)cname); -} /* dns_cname_push() */ - - -int dns_cname_cmp(const struct dns_cname *a, const struct dns_cname *b) { - return strcasecmp(a->host, b->host); -} /* dns_cname_cmp() */ - - -size_t dns_cname_print(void *dst, size_t lim, struct dns_cname *cname) { - return dns_ns_print(dst, lim, (struct dns_ns *)cname); -} /* dns_cname_print() */ - - -size_t dns_cname_cname(void *dst, size_t lim, struct dns_cname *cname) { - return dns_strlcpy(dst, cname->host, lim); -} /* dns_cname_cname() */ - - -int dns_soa_parse(struct dns_soa *soa, struct dns_rr *rr, struct dns_packet *P) { - struct { void *dst; size_t lim; } dn[] = - { { soa->mname, sizeof soa->mname }, - { soa->rname, sizeof soa->rname } }; - unsigned *ts[] = - { &soa->serial, &soa->refresh, &soa->retry, &soa->expire, &soa->minimum }; - unsigned short rp; - unsigned i, j, n; - int error; - - /* MNAME / RNAME */ - if ((rp = rr->rd.p) >= P->end) - return DNS_EILLEGAL; - - for (i = 0; i < lengthof(dn); i++) { - if (!(n = dns_d_expand(dn[i].dst, dn[i].lim, rp, P, &error))) - return error; - else if (n >= dn[i].lim) - return DNS_EILLEGAL; - - if ((rp = dns_d_skip(rp, P)) >= P->end) - return DNS_EILLEGAL; - } - - /* SERIAL / REFRESH / RETRY / EXPIRE / MINIMUM */ - for (i = 0; i < lengthof(ts); i++) { - for (j = 0; j < 4; j++, rp++) { - if (rp >= P->end) - return DNS_EILLEGAL; - - *ts[i] <<= 8; - *ts[i] |= (0xff & P->data[rp]); - } - } - - return 0; -} /* dns_soa_parse() */ - - -int dns_soa_push(struct dns_packet *P, struct dns_soa *soa) { - void *dn[] = { soa->mname, soa->rname }; - unsigned ts[] = { (0xffffffff & soa->serial), - (0x7fffffff & soa->refresh), - (0x7fffffff & soa->retry), - (0x7fffffff & soa->expire), - (0xffffffff & soa->minimum) }; - unsigned i, j; - size_t end, len; - int error; - - end = P->end; - - if ((P->end += 2) >= P->size) - goto toolong; - - /* MNAME / RNAME */ - for (i = 0; i < lengthof(dn); i++) { - if ((error = dns_d_push(P, dn[i], strlen(dn[i])))) - goto error; - } - - /* SERIAL / REFRESH / RETRY / EXPIRE / MINIMUM */ - for (i = 0; i < lengthof(ts); i++) { - if ((P->end += 4) >= P->size) - goto toolong; - - for (j = 1; j <= 4; j++) { - P->data[P->end - j] = (0xff & ts[i]); - ts[i] >>= 8; - } - } - - len = P->end - end - 2; - P->data[end + 0] = (0xff & (len >> 8)); - P->data[end + 1] = (0xff & (len >> 0)); - - return 0; -toolong: - error = DNS_ENOBUFS; - - /* FALL THROUGH */ -error: - P->end = end; - - return error; -} /* dns_soa_push() */ - - -int dns_soa_cmp(const struct dns_soa *a, const struct dns_soa *b) { - int cmp; - - if ((cmp = strcasecmp(a->mname, b->mname))) - return cmp; - - if ((cmp = strcasecmp(a->rname, b->rname))) - return cmp; - - if (a->serial > b->serial) - return -1; - else if (a->serial < b->serial) - return 1; - - if (a->refresh > b->refresh) - return -1; - else if (a->refresh < b->refresh) - return 1; - - if (a->retry > b->retry) - return -1; - else if (a->retry < b->retry) - return 1; - - if (a->expire > b->expire) - return -1; - else if (a->expire < b->expire) - return 1; - - if (a->minimum > b->minimum) - return -1; - else if (a->minimum < b->minimum) - return 1; - - return 0; -} /* dns_soa_cmp() */ - - -size_t dns_soa_print(void *dst, size_t lim, struct dns_soa *soa) { - size_t cp = 0; - - cp += dns__printstring(dst, lim, cp, soa->mname, strlen(soa->mname)); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__printstring(dst, lim, cp, soa->rname, strlen(soa->rname)); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__print10(dst, lim, cp, soa->serial, 0); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__print10(dst, lim, cp, soa->refresh, 0); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__print10(dst, lim, cp, soa->retry, 0); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__print10(dst, lim, cp, soa->expire, 0); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__print10(dst, lim, cp, soa->minimum, 0); - - dns__printnul(dst, lim, cp); - - return cp; -} /* dns_soa_print() */ - - -int dns_srv_parse(struct dns_srv *srv, struct dns_rr *rr, struct dns_packet *P) { - unsigned short rp; - unsigned i; - size_t n; - int error; - - memset(srv, '\0', sizeof *srv); - - rp = rr->rd.p; - - if (P->size - P->end < 6) - return DNS_EILLEGAL; - - for (i = 0; i < 2; i++, rp++) { - srv->priority <<= 8; - srv->priority |= (0xff & P->data[rp]); - } - - for (i = 0; i < 2; i++, rp++) { - srv->weight <<= 8; - srv->weight |= (0xff & P->data[rp]); - } - - for (i = 0; i < 2; i++, rp++) { - srv->port <<= 8; - srv->port |= (0xff & P->data[rp]); - } - - if (!(n = dns_d_expand(srv->target, sizeof srv->target, rp, P, &error))) - return error; - else if (n >= sizeof srv->target) - return DNS_EILLEGAL; - - return 0; -} /* dns_srv_parse() */ - - -int dns_srv_push(struct dns_packet *P, struct dns_srv *srv) { - size_t end, len; - int error; - - end = P->end; - - if (P->size - P->end < 2) - goto toolong; - - P->end += 2; - - if (P->size - P->end < 6) - goto toolong; - - P->data[P->end++] = 0xff & (srv->priority >> 8); - P->data[P->end++] = 0xff & (srv->priority >> 0); - - P->data[P->end++] = 0xff & (srv->weight >> 8); - P->data[P->end++] = 0xff & (srv->weight >> 0); - - P->data[P->end++] = 0xff & (srv->port >> 8); - P->data[P->end++] = 0xff & (srv->port >> 0); - - if (0 == (len = dns_d_comp(&P->data[P->end], P->size - P->end, srv->target, strlen(srv->target), P, &error))) - goto error; - else if (P->size - P->end < len) - goto toolong; - - P->end += len; - - if (P->end > 65535) - goto toolong; - - len = P->end - end - 2; - - P->data[end + 0] = 0xff & (len >> 8); - P->data[end + 1] = 0xff & (len >> 0); - - return 0; -toolong: - error = DNS_ENOBUFS; - - /* FALL THROUGH */ -error: - P->end = end; - - return error; -} /* dns_srv_push() */ - - -int dns_srv_cmp(const struct dns_srv *a, const struct dns_srv *b) { - int cmp; - - if ((cmp = a->priority - b->priority)) - return cmp; - - /* - * FIXME: We need some sort of random seed to implement the dynamic - * weighting required by RFC 2782. - */ - if ((cmp = a->weight - b->weight)) - return cmp; - - if ((cmp = a->port - b->port)) - return cmp; - - return strcasecmp(a->target, b->target); -} /* dns_srv_cmp() */ - - -size_t dns_srv_print(void *dst, size_t lim, struct dns_srv *srv) { - size_t cp = 0; - - cp += dns__print10(dst, lim, cp, srv->priority, 0); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__print10(dst, lim, cp, srv->weight, 0); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__print10(dst, lim, cp, srv->port, 0); - cp += dns__printchar(dst, lim, cp, ' '); - cp += dns__printstring(dst, lim, cp, srv->target, strlen(srv->target)); - - dns__printnul(dst, lim, cp); - - return cp; -} /* dns_srv_print() */ - - -size_t dns_srv_cname(void *dst, size_t lim, struct dns_srv *srv) { - return dns_strlcpy(dst, srv->target, lim); -} /* dns_srv_cname() */ - - -int dns_ptr_parse(struct dns_ptr *ptr, struct dns_rr *rr, struct dns_packet *P) { - return dns_ns_parse((struct dns_ns *)ptr, rr, P); -} /* dns_ptr_parse() */ - - -int dns_ptr_push(struct dns_packet *P, struct dns_ptr *ptr) { - return dns_ns_push(P, (struct dns_ns *)ptr); -} /* dns_ptr_push() */ - - -size_t dns_ptr_qname(void *dst, size_t lim, int af, void *addr) { - unsigned len = (af == AF_INET6) - ? dns_aaaa_arpa(dst, lim, addr) - : dns_a_arpa(dst, lim, addr); - - dns__printnul(dst, lim, len); - - return len; -} /* dns_ptr_qname() */ - - -int dns_ptr_cmp(const struct dns_ptr *a, const struct dns_ptr *b) { - return strcasecmp(a->host, b->host); -} /* dns_ptr_cmp() */ - - -size_t dns_ptr_print(void *dst, size_t lim, struct dns_ptr *ptr) { - return dns_ns_print(dst, lim, (struct dns_ns *)ptr); -} /* dns_ptr_print() */ - - -size_t dns_ptr_cname(void *dst, size_t lim, struct dns_ptr *ptr) { - return dns_strlcpy(dst, ptr->host, lim); -} /* dns_ptr_cname() */ - - -int dns_sshfp_parse(struct dns_sshfp *fp, struct dns_rr *rr, struct dns_packet *P) { - unsigned p = rr->rd.p, pe = rr->rd.p + rr->rd.len; - - if (pe - p < 2) - return DNS_EILLEGAL; - - fp->algo = P->data[p++]; - fp->type = P->data[p++]; - - switch (fp->type) { - case DNS_SSHFP_SHA1: - if (pe - p < sizeof fp->digest.sha1) - return DNS_EILLEGAL; - - memcpy(fp->digest.sha1, &P->data[p], sizeof fp->digest.sha1); - - break; - default: - break; - } /* switch() */ - - return 0; -} /* dns_sshfp_parse() */ - - -int dns_sshfp_push(struct dns_packet *P, struct dns_sshfp *fp) { - unsigned p = P->end, pe = P->size, n; - - if (pe - p < 4) - return DNS_ENOBUFS; - - p += 2; - P->data[p++] = 0xff & fp->algo; - P->data[p++] = 0xff & fp->type; - - switch (fp->type) { - case DNS_SSHFP_SHA1: - if (pe - p < sizeof fp->digest.sha1) - return DNS_ENOBUFS; - - memcpy(&P->data[p], fp->digest.sha1, sizeof fp->digest.sha1); - p += sizeof fp->digest.sha1; - - break; - default: - return DNS_EILLEGAL; - } /* switch() */ - - n = p - P->end - 2; - P->data[P->end++] = 0xff & (n >> 8); - P->data[P->end++] = 0xff & (n >> 0); - P->end = p; - - return 0; -} /* dns_sshfp_push() */ - - -int dns_sshfp_cmp(const struct dns_sshfp *a, const struct dns_sshfp *b) { - int cmp; - - if ((cmp = a->algo - b->algo) || (cmp - a->type - b->type)) - return cmp; - - switch (a->type) { - case DNS_SSHFP_SHA1: - return memcmp(a->digest.sha1, b->digest.sha1, sizeof a->digest.sha1); - default: - return 0; - } /* switch() */ - - /* NOT REACHED */ -} /* dns_sshfp_cmp() */ - - -size_t dns_sshfp_print(void *dst, size_t lim, struct dns_sshfp *fp) { - static const unsigned char hex[16] = "0123456789abcdef"; - size_t i, p = 0; - - p += dns__print10(dst, lim, p, fp->algo, 0); - p += dns__printchar(dst, lim, p, ' '); - p += dns__print10(dst, lim, p, fp->type, 0); - p += dns__printchar(dst, lim, p, ' '); - - switch (fp->type) { - case DNS_SSHFP_SHA1: - for (i = 0; i < sizeof fp->digest.sha1; i++) { - p += dns__printchar(dst, lim, p, hex[0x0f & (fp->digest.sha1[i] >> 4)]); - p += dns__printchar(dst, lim, p, hex[0x0f & (fp->digest.sha1[i] >> 0)]); - } - - break; - default: - p += dns__printchar(dst, lim, p, '0'); - - break; - } /* switch() */ - - dns__printnul(dst, lim, p); - - return p; -} /* dns_sshfp_print() */ - - -struct dns_txt *dns_txt_init(struct dns_txt *txt, size_t size) { - assert(size > offsetof(struct dns_txt, data)); - - txt->size = size - offsetof(struct dns_txt, data); - txt->len = 0; - - return txt; -} /* dns_txt_init() */ - - -int dns_txt_parse(struct dns_txt *txt, struct dns_rr *rr, struct dns_packet *P) { - struct { unsigned char *b; size_t p, end; } dst, src; - unsigned n; - - dst.b = txt->data; - dst.p = 0; - dst.end = txt->size; - - src.b = P->data; - src.p = rr->rd.p; - src.end = src.p + rr->rd.len; - - while (src.p < src.end) { - n = 0xff & P->data[src.p++]; - - if (src.end - src.p < n || dst.end - dst.p < n) - return DNS_EILLEGAL; - - memcpy(&dst.b[dst.p], &src.b[src.p], n); - - dst.p += n; - src.p += n; - } - - txt->len = dst.p; - - return 0; -} /* dns_txt_parse() */ - - -int dns_txt_push(struct dns_packet *P, struct dns_txt *txt) { - struct { unsigned char *b; size_t p, end; } dst, src; - unsigned n; - - dst.b = P->data; - dst.p = P->end; - dst.end = P->size; - - src.b = txt->data; - src.p = 0; - src.end = txt->len; - - if (dst.end - dst.p < 2) - return DNS_ENOBUFS; - - n = txt->len + ((txt->len + 254) / 255); - - dst.b[dst.p++] = 0xff & (n >> 8); - dst.b[dst.p++] = 0xff & (n >> 0); - - while (src.p < src.end) { - n = MIN(255, src.end - src.p); - - if (dst.p >= dst.end) - return DNS_ENOBUFS; - - dst.b[dst.p++] = n; - - if (dst.end - dst.p < n) - return DNS_ENOBUFS; - - memcpy(&dst.b[dst.p], &src.b[src.p], n); - - dst.p += n; - src.p += n; - } - - P->end = dst.p; - - return 0; -} /* dns_txt_push() */ - - -int dns_txt_cmp(const struct dns_txt *a EINA_UNUSED, const struct dns_txt *b EINA_UNUSED) { - return -1; -} /* dns_txt_cmp() */ - - -size_t dns_txt_print(void *dst_, size_t lim, struct dns_txt *txt) { - struct { unsigned char *b; size_t p, end; } dst, src; - unsigned ch; - - dst.b = dst_; - dst.end = lim; - dst.p = 0; - - src.b = txt->data; - src.end = txt->len; - src.p = 0; - - dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); - - while (src.p < src.end) { - ch = src.b[src.p]; - - if (0 == (src.p++ % 255) && src.p != 1) { - dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); - dst.p += dns__printchar(dst.b, dst.end, dst.p, ' '); - dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); - } - - if (ch < 32 || ch > 126 || ch == '"' || ch == '\\') { - dst.p += dns__printchar(dst.b, dst.end, dst.p, '\\'); - dst.p += dns__print10(dst.b, dst.end, dst.p, ch, 3); - } else { - dst.p += dns__printchar(dst.b, dst.end, dst.p, ch); - } - } - - dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); - - dns__printnul(dst.b, dst.end, dst.p); - - return dst.p; -} /* dns_txt_print() */ - - -static const struct { - enum dns_type type; - const char *name; - int (*parse)(); - int (*push)(); - int (*cmp)(); - size_t (*print)(); - size_t (*cname)(); -} dns_rrtypes[] = { - { DNS_T_A, "A", &dns_a_parse, &dns_a_push, &dns_a_cmp, &dns_a_print, 0 }, - { DNS_T_AAAA, "AAAA", &dns_aaaa_parse, &dns_aaaa_push, &dns_aaaa_cmp, &dns_aaaa_print, 0 }, - { DNS_T_MX, "MX", &dns_mx_parse, &dns_mx_push, &dns_mx_cmp, &dns_mx_print, &dns_mx_cname }, - { DNS_T_NS, "NS", &dns_ns_parse, &dns_ns_push, &dns_ns_cmp, &dns_ns_print, &dns_ns_cname }, - { DNS_T_CNAME, "CNAME", &dns_cname_parse, &dns_cname_push, &dns_cname_cmp, &dns_cname_print, &dns_cname_cname }, - { DNS_T_SOA, "SOA", &dns_soa_parse, &dns_soa_push, &dns_soa_cmp, &dns_soa_print, 0 }, - { DNS_T_SRV, "SRV", &dns_srv_parse, &dns_srv_push, &dns_srv_cmp, &dns_srv_print, &dns_srv_cname }, - { DNS_T_PTR, "PTR", &dns_ptr_parse, &dns_ptr_push, &dns_ptr_cmp, &dns_ptr_print, &dns_ptr_cname }, - { DNS_T_TXT, "TXT", &dns_txt_parse, &dns_txt_push, &dns_txt_cmp, &dns_txt_print, 0 }, - { DNS_T_SPF, "SPF", &dns_txt_parse, &dns_txt_push, &dns_txt_cmp, &dns_txt_print, 0 }, - { DNS_T_SSHFP, "SSHFP", &dns_sshfp_parse, &dns_sshfp_push, &dns_sshfp_cmp, &dns_sshfp_print, 0 }, -}; /* dns_rrtypes[] */ - - -union dns_any *dns_any_init(union dns_any *any, size_t size) { - return (union dns_any *)dns_txt_init(&any->rdata, size); -} /* dns_any_init() */ - - -int dns_any_parse(union dns_any *any, struct dns_rr *rr, struct dns_packet *P) { - unsigned i; - - for (i = 0; i < lengthof(dns_rrtypes); i++) { - if (dns_rrtypes[i].type == rr->type) - return dns_rrtypes[i].parse(any, rr, P); - } - - if (rr->rd.len > any->rdata.size) - return DNS_EILLEGAL; - - memcpy(any->rdata.data, &P->data[rr->rd.p], rr->rd.len); - any->rdata.len = rr->rd.len; - - return 0; -} /* dns_any_parse() */ - - -int dns_any_push(struct dns_packet *P, union dns_any *any, enum dns_type type) { - unsigned i; - - for (i = 0; i < lengthof(dns_rrtypes); i++) { - if (dns_rrtypes[i].type == type) - return dns_rrtypes[i].push(P, any); - } - - if (P->size - P->end < any->rdata.len + 2) - return DNS_ENOBUFS; - - P->data[P->end++] = 0xff & (any->rdata.len >> 8); - P->data[P->end++] = 0xff & (any->rdata.len >> 0); - - memcpy(&P->data[P->end], any->rdata.data, any->rdata.len); - P->end += any->rdata.len; - - return 0; -} /* dns_any_push() */ - - -int dns_any_cmp(const union dns_any *a, enum dns_type x, const union dns_any *b, enum dns_type y) { - unsigned i; - int cmp; - - if ((cmp = x - y)) - return cmp; - - for (i = 0; i < lengthof(dns_rrtypes); i++) { - if (dns_rrtypes[i].type == x) - return dns_rrtypes[i].cmp(a, b); - } - - return -1; -} /* dns_any_cmp() */ - - -size_t dns_any_print(void *dst_, size_t lim, union dns_any *any, enum dns_type type) { - struct { unsigned char *b; size_t p, end; } dst, src; - unsigned i, ch; - - for (i = 0; i < lengthof(dns_rrtypes); i++) { - if (dns_rrtypes[i].type == type) - return dns_rrtypes[i].print(dst_, lim, any); - } - - dst.b = dst_; - dst.end = lim; - dst.p = 0; - - src.b = any->rdata.data; - src.end = any->rdata.len; - src.p = 0; - - dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); - - while (src.p < src.end) { - ch = src.b[src.p++]; - - dst.p += dns__printchar(dst.b, dst.end, dst.p, '\\'); - dst.p += dns__print10(dst.b, dst.end, dst.p, ch, 3); - } - - dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); - - dns__printnul(dst.b, dst.end, dst.p); - - return dst.p; -} /* dns_any_print() */ - - -size_t dns_any_cname(void *dst, size_t lim, union dns_any *any, enum dns_type type) { - unsigned i; - - for (i = 0; i < lengthof(dns_rrtypes); i++) { - if (dns_rrtypes[i].type == type) - return (dns_rrtypes[i].cname)? dns_rrtypes[i].cname(dst, lim, any) : 0; - } - - return 0; -} /* dns_any_cname() */ - - -/* - * H O S T S R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_hosts { - struct dns_hosts_entry { - char host[DNS_D_MAXNAME + 1]; - char arpa[73 + 1]; - - int af; - - union { - struct in_addr a4; - struct in6_addr a6; - } addr; - - _Bool alias; - - struct dns_hosts_entry *next; - } *head, **tail; - - dns_atomic_t refcount; -}; /* struct dns_hosts */ - - -struct dns_hosts *dns_hosts_open(int *error) { - static const struct dns_hosts hosts_initializer = { .refcount = 1 }; - struct dns_hosts *hosts; - - if (!(hosts = malloc(sizeof *hosts))) - goto syerr; - - *hosts = hosts_initializer; - - hosts->tail = &hosts->head; - - return hosts; -syerr: - *error = dns_syerr(); - - free(hosts); - - return 0; -} /* dns_hosts_open() */ - - -void dns_hosts_close(struct dns_hosts *hosts) { - struct dns_hosts_entry *ent, *xnt; - - if (!hosts || 1 != dns_hosts_release(hosts)) - return; - - for (ent = hosts->head; ent; ent = xnt) { - xnt = ent->next; - - free(ent); - } - - free(hosts); - - return; -} /* dns_hosts_close() */ - - -unsigned dns_hosts_acquire(struct dns_hosts *hosts) { - return dns_atomic_inc(&hosts->refcount); -} /* dns_hosts_acquire() */ - - -unsigned dns_hosts_release(struct dns_hosts *hosts) { - return dns_atomic_dec(&hosts->refcount); -} /* dns_hosts_release() */ - - -struct dns_hosts *dns_hosts_mortal(struct dns_hosts *hosts) { - if (hosts) - dns_hosts_release(hosts); - - return hosts; -} /* dns_hosts_mortal() */ - - -struct dns_hosts *dns_hosts_local(int *error_) { - struct dns_hosts *hosts; - int error; - - if (!(hosts = dns_hosts_open(&error))) - goto error; - - if ((error = dns_hosts_loadpath(hosts, "/etc/hosts"))) - goto error; - - return hosts; -error: - *error_ = error; - - dns_hosts_close(hosts); - - return 0; -} /* dns_hosts_local() */ - - -#define dns_hosts_issep(ch) (isspace(ch)) -#define dns_hosts_iscom(ch) ((ch) == '#' || (ch) == ';') - -int dns_hosts_loadfile(struct dns_hosts *hosts, FILE *fp) { - struct dns_hosts_entry ent; - char word[MAX(INET6_ADDRSTRLEN, DNS_D_MAXNAME) + 1]; - unsigned wp, wc, skip; - int ch, error; - - rewind(fp); - - do { - memset(&ent, '\0', sizeof ent); - wc = 0; - skip = 0; - - do { - memset(word, '\0', sizeof word); - wp = 0; - - while (EOF != (ch = fgetc(fp)) && ch != '\n') { - skip |= !!dns_hosts_iscom(ch); - - if (skip) - continue; - - if (dns_hosts_issep(ch)) - break; - - if (wp < sizeof word - 1) - word[wp] = ch; - wp++; - } - - if (!wp) - continue; - - wc++; - - switch (wc) { - case 0: - break; - case 1: - ent.af = (strchr(word, ':'))? AF_INET6 : AF_INET; - skip = (1 != dns_inet_pton(ent.af, word, &ent.addr)); - - break; - default: - if (!wp) - break; - - dns_d_anchor(ent.host, sizeof ent.host, word, wp); - - if ((error = dns_hosts_insert(hosts, ent.af, &ent.addr, ent.host, (wc > 2)))) - return error; - - break; - } /* switch() */ - } while (ch != EOF && ch != '\n'); - } while (ch != EOF); - - return 0; -} /* dns_hosts_loadfile() */ - - -int dns_hosts_loadpath(struct dns_hosts *hosts, const char *path) { - FILE *fp; - int error; - - if (!(fp = fopen(path, "r"))) - return dns_syerr(); - - error = dns_hosts_loadfile(hosts, fp); - - fclose(fp); - - return error; -} /* dns_hosts_loadpath() */ - - -int dns_hosts_dump(struct dns_hosts *hosts, FILE *fp) { - struct dns_hosts_entry *ent, *xnt; - char addr[INET6_ADDRSTRLEN + 1]; - unsigned i; - - for (ent = hosts->head; ent; ent = xnt) { - xnt = ent->next; - - dns_inet_ntop(ent->af, &ent->addr, addr, sizeof addr); - - fputs(addr, fp); - - for (i = strlen(addr); i < INET_ADDRSTRLEN; i++) - fputc(' ', fp); - - fputc(' ', fp); - - fputs(ent->host, fp); - fputc('\n', fp); - } - - return 0; -} /* dns_hosts_dump() */ - - -int dns_hosts_insert(struct dns_hosts *hosts, int af, const void *addr, const void *host, _Bool alias) { - struct dns_hosts_entry *ent; - int error; - - if (!(ent = malloc(sizeof *ent))) - goto syerr; - - dns_d_anchor(ent->host, sizeof ent->host, host, strlen(host)); - - switch ((ent->af = af)) { - case AF_INET6: - memcpy(&ent->addr.a6, addr, sizeof ent->addr.a6); - - dns_aaaa_arpa(ent->arpa, sizeof ent->arpa, addr); - - break; - case AF_INET: - memcpy(&ent->addr.a4, addr, sizeof ent->addr.a4); - - dns_a_arpa(ent->arpa, sizeof ent->arpa, addr); - - break; - default: - error = EINVAL; - - goto error; - } /* switch() */ - - ent->alias = alias; - - ent->next = 0; - *hosts->tail = ent; - hosts->tail = &ent->next; - - return 0; -syerr: - error = dns_syerr(); -error: - free(ent); - - return error; -} /* dns_hosts_insert() */ - - -struct dns_packet *dns_hosts_query(struct dns_hosts *hosts, struct dns_packet *Q, int *error_) { - struct dns_packet *P = dns_p_new(512); - struct dns_packet *A = 0; - struct dns_rr rr; - struct dns_hosts_entry *ent; - int error, af; - char qname[DNS_D_MAXNAME + 1]; - size_t qlen; - - if ((error = dns_rr_parse(&rr, 12, Q))) - goto error; - - if (!(qlen = dns_d_expand(qname, sizeof qname, rr.dn.p, Q, &error))) - goto error; - else if (qlen >= sizeof qname) - goto toolong; - - if ((error = dns_p_push(P, DNS_S_QD, qname, qlen, rr.type, rr.class, 0, 0))) - goto error; - - switch (rr.type) { - case DNS_T_PTR: - for (ent = hosts->head; ent; ent = ent->next) { - if (ent->alias || 0 != strcasecmp(qname, ent->arpa)) - continue; - - if ((error = dns_p_push(P, DNS_S_AN, qname, qlen, rr.type, rr.class, 0, ent->host))) - goto error; - } - - break; - case DNS_T_AAAA: - af = AF_INET6; - - goto loop; - case DNS_T_A: - af = AF_INET; - -loop: for (ent = hosts->head; ent; ent = ent->next) { - if (ent->af != af || 0 != strcasecmp(qname, ent->host)) - continue; - - if ((error = dns_p_push(P, DNS_S_AN, qname, qlen, rr.type, rr.class, 0, &ent->addr))) - goto error; - } - - break; - default: - break; - } /* switch() */ - - - if (!(A = dns_p_copy(dns_p_make(P->end, &error), P))) - goto error; - - return A; -toolong: - error = DNS_EILLEGAL; -error: - *error_ = error; - - free(A); - - return 0; -} /* dns_hosts_query() */ - - -/* - * R E S O L V . C O N F R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_resolv_conf *dns_resconf_open(int *error) { - static const struct dns_resolv_conf resconf_initializer - = { .lookup = "bf", .options = { .ndots = 1, .timeout = 5, .attempts = 2, .tcp = DNS_RESCONF_TCP_ENABLE, }, - .iface = { .ss_family = AF_INET }, }; - struct dns_resolv_conf *resconf; - struct sockaddr_in *sin; - - if (!(resconf = malloc(sizeof *resconf))) - goto syerr; - - *resconf = resconf_initializer; - - sin = (struct sockaddr_in *)&resconf->nameserver[0]; - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = INADDR_ANY; - sin->sin_port = htons(53); -#if defined(SA_LEN) - sin->sin_len = sizeof *sin; -#endif - - if (0 != gethostname(resconf->search[0], sizeof resconf->search[0])) - goto syerr; - - dns_d_anchor(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); - dns_d_cleave(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); - - /* - * XXX: If gethostname() returned a string without any label - * separator, then search[0][0] should be NUL. - */ - - dns_resconf_acquire(resconf); - - return resconf; -syerr: - *error = dns_syerr(); - - free(resconf); - - return 0; -} /* dns_resconf_open() */ - - -void dns_resconf_close(struct dns_resolv_conf *resconf) { - if (!resconf || 1 != dns_resconf_release(resconf)) - return /* void */; - - free(resconf); -} /* dns_resconf_close() */ - - -unsigned dns_resconf_acquire(struct dns_resolv_conf *resconf) { - return dns_atomic_inc(&resconf->_.refcount); -} /* dns_resconf_acquire() */ - - -unsigned dns_resconf_release(struct dns_resolv_conf *resconf) { - return dns_atomic_dec(&resconf->_.refcount); -} /* dns_resconf_release() */ - - -struct dns_resolv_conf *dns_resconf_mortal(struct dns_resolv_conf *resconf) { - if (resconf) - dns_resconf_release(resconf); - - return resconf; -} /* dns_resconf_mortal() */ - - -struct dns_resolv_conf *dns_resconf_local(int *error_) { - struct dns_resolv_conf *resconf; - int error; - - if (!(resconf = dns_resconf_open(&error))) - goto error; - - if ((error = dns_resconf_loadpath(resconf, "/etc/resolv.conf"))) - goto error; - - return resconf; -error: - *error_ = error; - - dns_resconf_close(resconf); - - return 0; -} /* dns_resconf_local() */ - - -struct dns_resolv_conf *dns_resconf_root(int *error_) { - struct dns_resolv_conf *resconf; - int error; - - if (!(resconf = dns_resconf_open(&error))) - goto error; - - if ((error = dns_resconf_loadpath(resconf, "/etc/resolv.conf"))) - goto error; - - resconf->options.recurse = 1; - - return resconf; -error: - *error_ = error; - - dns_resconf_close(resconf); - - return 0; -} /* dns_resconf_root() */ - - -enum dns_resconf_keyword { - DNS_RESCONF_NAMESERVER, - DNS_RESCONF_DOMAIN, - DNS_RESCONF_SEARCH, - DNS_RESCONF_LOOKUP, - DNS_RESCONF_FILE, - DNS_RESCONF_BIND, - DNS_RESCONF_CACHE, - DNS_RESCONF_OPTIONS, - DNS_RESCONF_EDNS0, - DNS_RESCONF_NDOTS, - DNS_RESCONF_TIMEOUT, - DNS_RESCONF_ATTEMPTS, - DNS_RESCONF_ROTATE, - DNS_RESCONF_RECURSE, - DNS_RESCONF_SMART, - DNS_RESCONF_TCP, - DNS_RESCONF_TCPx, - DNS_RESCONF_INTERFACE, - DNS_RESCONF_ZERO, - DNS_RESCONF_ONE, - DNS_RESCONF_ENABLE, - DNS_RESCONF_ONLY, - DNS_RESCONF_DISABLE, -}; /* enum dns_resconf_keyword */ - -static enum dns_resconf_keyword dns_resconf_keyword(const char *word) { - static const char *words[] = { - [DNS_RESCONF_NAMESERVER] = "nameserver", - [DNS_RESCONF_DOMAIN] = "domain", - [DNS_RESCONF_SEARCH] = "search", - [DNS_RESCONF_LOOKUP] = "lookup", - [DNS_RESCONF_FILE] = "file", - [DNS_RESCONF_BIND] = "bind", - [DNS_RESCONF_CACHE] = "cache", - [DNS_RESCONF_OPTIONS] = "options", - [DNS_RESCONF_EDNS0] = "edns0", - [DNS_RESCONF_ROTATE] = "rotate", - [DNS_RESCONF_RECURSE] = "recurse", - [DNS_RESCONF_SMART] = "smart", - [DNS_RESCONF_TCP] = "tcp", - [DNS_RESCONF_INTERFACE] = "interface", - [DNS_RESCONF_ZERO] = "0", - [DNS_RESCONF_ONE] = "1", - [DNS_RESCONF_ENABLE] = "enable", - [DNS_RESCONF_ONLY] = "only", - [DNS_RESCONF_DISABLE] = "disable", - }; - unsigned i; - - for (i = 0; i < lengthof(words); i++) { - if (words[i] && 0 == strcasecmp(words[i], word)) - return i; - } - - if (0 == strncasecmp(word, "ndots:", sizeof "ndots:" - 1)) - return DNS_RESCONF_NDOTS; - - if (0 == strncasecmp(word, "timeout:", sizeof "timeout:" - 1)) - return DNS_RESCONF_TIMEOUT; - - if (0 == strncasecmp(word, "attempts:", sizeof "attempts:" - 1)) - return DNS_RESCONF_ATTEMPTS; - - if (0 == strncasecmp(word, "tcp:", sizeof "tcp:" - 1)) - return DNS_RESCONF_TCPx; - - return -1; -} /* dns_resconf_keyword() */ - - -/** OpenBSD-style "[1.2.3.4]:53" nameserver syntax */ -static int dns_resconf_pton(struct sockaddr_storage *ss, const char *src) { - struct { char buf[128], *p; } addr = { "", addr.buf }; - unsigned short port = 0; - int ch, af = AF_INET; - - while ((ch = *src++)) { - switch (ch) { - case ' ': - /* FALL THROUGH */ - case '\t': - break; - case '[': - break; - case ']': - while ((ch = *src++)) { - if (isdigit((unsigned char)ch)) { - port *= 10; - port += ch - '0'; - } - } - - goto inet; - case ':': - af = AF_INET6; - - /* FALL THROUGH */ - default: - if (addr.p < endof(addr.buf) - 1) - *addr.p++ = ch; - - break; - } /* switch() */ - } /* while() */ -inet: - - switch (dns_inet_pton(af, addr.buf, dns_sa_addr(af, ss))) { - case -1: - return errno; - case 0: - return EINVAL; - } /* switch() */ - - port = (!port)? 53 : port; - *dns_sa_port(af, ss) = htons(port); - dns_sa_family(ss) = af; - - return 0; -} /* dns_resconf_pton() */ - -#define dns_resconf_issep(ch) (isspace(ch) || (ch) == ',') -#define dns_resconf_iscom(ch) ((ch) == '#' || (ch) == ';') - -int dns_resconf_loadfile(struct dns_resolv_conf *resconf, FILE *fp) { - unsigned sa_count = 0; - char words[6][DNS_D_MAXNAME + 1]; - unsigned wp, wc, i, j, n; - int ch, error; - - rewind(fp); - - do { - memset(words, '\0', sizeof words); - wp = 0; - wc = 0; - - while (EOF != (ch = getc(fp)) && ch != '\n') { - if (dns_resconf_issep(ch)) { - if (wp > 0) { - wp = 0; - - if (++wc >= lengthof(words)) - goto skip; - } - } else if (dns_resconf_iscom(ch)) { -skip: - do { - ch = getc(fp); - } while (ch != EOF && ch != '\n'); - - break; - } else { - dns__printchar(words[wc], sizeof words[wc], wp, ch); - wp++; - } - } - - if (wp > 0) - wc++; - - if (wc < 2) - continue; - - switch (dns_resconf_keyword(words[0])) { - case DNS_RESCONF_NAMESERVER: - if (sa_count >= lengthof(resconf->nameserver)) - continue; - - if ((error = dns_resconf_pton(&resconf->nameserver[sa_count], words[1]))) - continue; - - sa_count++; - - break; - case DNS_RESCONF_DOMAIN: - case DNS_RESCONF_SEARCH: - memset(resconf->search, '\0', sizeof resconf->search); - - for (i = 1, j = 0; i < wc && j < lengthof(resconf->search); i++, j++) - dns_d_anchor(resconf->search[j], sizeof resconf->search[j], words[i], strlen(words[i])); - - break; - case DNS_RESCONF_LOOKUP: - for (i = 1, j = 0; i < wc && j < lengthof(resconf->lookup); i++) { - switch (dns_resconf_keyword(words[i])) { - case DNS_RESCONF_FILE: - resconf->lookup[j++] = 'f'; - - break; - case DNS_RESCONF_BIND: - resconf->lookup[j++] = 'b'; - - break; - case DNS_RESCONF_CACHE: - resconf->lookup[j++] = 'c'; - - break; - default: - break; - } /* switch() */ - } /* for() */ - - break; - case DNS_RESCONF_OPTIONS: - for (i = 1; i < wc; i++) { - switch (dns_resconf_keyword(words[i])) { - case DNS_RESCONF_EDNS0: - resconf->options.edns0 = 1; - - break; - case DNS_RESCONF_NDOTS: - for (j = sizeof "ndots:" - 1, n = 0; isdigit((int)words[i][j]); j++) { - n *= 10; - n += words[i][j] - '0'; - } /* for() */ - - resconf->options.ndots = n; - - break; - case DNS_RESCONF_TIMEOUT: - for (j = sizeof "timeout:" - 1, n = 0; isdigit((int)words[i][j]); j++) { - n *= 10; - n += words[i][j] - '0'; - } /* for() */ - - resconf->options.timeout = n; - - break; - case DNS_RESCONF_ATTEMPTS: - for (j = sizeof "attempts:" - 1, n = 0; isdigit((int)words[i][j]); j++) { - n *= 10; - n += words[i][j] - '0'; - } /* for() */ - - resconf->options.attempts = n; - - break; - case DNS_RESCONF_ROTATE: - resconf->options.rotate = 1; - - break; - case DNS_RESCONF_RECURSE: - resconf->options.recurse = 1; - - break; - case DNS_RESCONF_SMART: - resconf->options.smart = 1; - - break; - case DNS_RESCONF_TCP: - resconf->options.tcp = DNS_RESCONF_TCP_ONLY; - - break; - case DNS_RESCONF_TCPx: - switch (dns_resconf_keyword(&words[i][sizeof "tcp:" - 1])) { - case DNS_RESCONF_ENABLE: - resconf->options.tcp = DNS_RESCONF_TCP_ENABLE; - - break; - case DNS_RESCONF_ONE: - case DNS_RESCONF_ONLY: - resconf->options.tcp = DNS_RESCONF_TCP_ONLY; - - break; - case DNS_RESCONF_ZERO: - case DNS_RESCONF_DISABLE: - resconf->options.tcp = DNS_RESCONF_TCP_DISABLE; - - break; - default: - break; - } /* switch() */ - - break; - default: - break; - } /* switch() */ - } /* for() */ - - break; - case DNS_RESCONF_INTERFACE: - for (i = 0, n = 0; isdigit((int)words[2][i]); i++) { - n *= 10; - n += words[2][i] - '0'; - } - - dns_resconf_setiface(resconf, words[1], n); - - break; - default: - break; - } /* switch() */ - } while (ch != EOF); - - return 0; -} /* dns_resconf_loadfile() */ - - -int dns_resconf_loadpath(struct dns_resolv_conf *resconf, const char *path) { - FILE *fp; - int error; - - if (!(fp = fopen(path, "r"))) - return dns_syerr(); - - error = dns_resconf_loadfile(resconf, fp); - - fclose(fp); - - return error; -} /* dns_resconf_loadpath() */ - - -int dns_resconf_setiface(struct dns_resolv_conf *resconf, const char *addr, unsigned short port) { - int af = (strchr(addr, ':'))? AF_INET6 : AF_INET; - - if (1 != dns_inet_pton(af, addr, dns_sa_addr(af, &resconf->iface))) - return dns_soerr(); - - *dns_sa_port(af, &resconf->iface) = htons(port); - resconf->iface.ss_family = af; - - return 0; -} /* dns_resconf_setiface() */ - - -size_t dns_resconf_search(void *dst, size_t lim, const void *qname, size_t qlen, struct dns_resolv_conf *resconf, dns_resconf_i_t *state) { - unsigned srchi = 0xff & (*state >> 8); - unsigned ndots = 0xff & (*state >> 16); - unsigned slen, len = 0; - const char *qp, *qe; - -// assert(0xff > lengthof(resconf->search)); - - switch (0xff & *state) { - case 0: - qp = qname; - qe = qp + qlen; - - while ((qp = memchr(qp, '.', qe - qp))) - { ndots++; qp++; } - - ++*state; - - if (ndots >= resconf->options.ndots) { - len = dns_d_anchor(dst, lim, qname, qlen); - - break; - } - - /* FALL THROUGH */ - case 1: - if (srchi < lengthof(resconf->search) && (slen = strlen(resconf->search[srchi]))) { - len = dns__printstring(dst, lim, 0, qname, qlen); - len = dns_d_anchor(dst, lim, dst, len); - len += dns__printstring(dst, lim, len, resconf->search[srchi], slen); - - srchi++; - - break; - } - - ++*state; - - /* FALL THROUGH */ - case 2: - ++*state; - - if (ndots < resconf->options.ndots) { - len = dns_d_anchor(dst, lim, qname, qlen); - - break; - } - - /* FALL THROUGH */ - default: - break; - } /* switch() */ - - dns__printnul(dst, lim, len); - - *state = ((0xff & *state) << 0) - | ((0xff & srchi) << 8) - | ((0xff & ndots) << 16); - - return len; -} /* dns_resconf_search() */ - - -int dns_resconf_dump(struct dns_resolv_conf *resconf, FILE *fp) { - unsigned i; - int af; - - for (i = 0; i < lengthof(resconf->nameserver) && (af = resconf->nameserver[i].ss_family) != AF_UNSPEC; i++) { - char addr[INET6_ADDRSTRLEN + 1] = "[INVALID]"; - unsigned short port; - - dns_inet_ntop(af, dns_sa_addr(af, &resconf->nameserver[i]), addr, sizeof addr); - port = ntohs(*dns_sa_port(af, &resconf->nameserver[i])); - - if (port == 53) - fprintf(fp, "nameserver %s\n", addr); - else - fprintf(fp, "nameserver [%s]:%hu\n", addr, port); - } - - - fprintf(fp, "search"); - - for (i = 0; i < lengthof(resconf->search) && resconf->search[i][0]; i++) - fprintf(fp, " %s", resconf->search[i]); - - fputc('\n', fp); - - - fprintf(fp, "lookup"); - - for (i = 0; i < lengthof(resconf->lookup) && resconf->lookup[i]; i++) { - switch (resconf->lookup[i]) { - case 'b': - fprintf(fp, " bind"); break; - case 'f': - fprintf(fp, " file"); break; - case 'c': - fprintf(fp, " cache"); break; - } - } - - fputc('\n', fp); - - - fprintf(fp, "options ndots:%u timeout:%u attempts:%u", resconf->options.ndots, resconf->options.timeout, resconf->options.attempts); - - if (resconf->options.edns0) - fprintf(fp, " edns0"); - if (resconf->options.rotate) - fprintf(fp, " rotate"); - if (resconf->options.recurse) - fprintf(fp, " recurse"); - if (resconf->options.smart) - fprintf(fp, " smart"); - - fputc('\n', fp); - - - if ((af = resconf->iface.ss_family) != AF_UNSPEC) { - char addr[INET6_ADDRSTRLEN + 1] = "[INVALID]"; - - dns_inet_ntop(af, dns_sa_addr(af, &resconf->iface), addr, sizeof addr); - - fprintf(fp, "interface %s %hu\n", addr, ntohs(*dns_sa_port(af, &resconf->iface))); - } - - return 0; -} /* dns_resconf_dump() */ - - -/* - * H I N T S E R V E R R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_hints_soa { - unsigned char zone[DNS_D_MAXNAME + 1]; - - struct { - struct sockaddr_storage ss; - unsigned priority; - } addrs[16]; - - unsigned count; - - struct dns_hints_soa *next; -}; /* struct dns_hints_soa */ - - -struct dns_hints { - dns_atomic_t refcount; - - struct dns_hints_soa *head; -}; /* struct dns_hints */ - - -struct dns_hints *dns_hints_open(struct dns_resolv_conf *resconf EINA_UNUSED, int *error) { - static const struct dns_hints H_initializer; - struct dns_hints *H; - - if (!(H = malloc(sizeof *H))) - goto syerr; - - *H = H_initializer; - - dns_hints_acquire(H); - - return H; -syerr: - *error = dns_syerr(); - - free(H); - - return 0; -} /* dns_hints_open() */ - - -void dns_hints_close(struct dns_hints *H) { - struct dns_hints_soa *soa, *nxt; - - if (!H || 1 != dns_hints_release(H)) - return /* void */; - - for (soa = H->head; soa; soa = nxt) { - nxt = soa->next; - - free(soa); - } - - free(H); - - return /* void */; -} /* dns_hints_close() */ - - -unsigned dns_hints_acquire(struct dns_hints *H) { - return dns_atomic_inc(&H->refcount); -} /* dns_hints_acquire() */ - - -unsigned dns_hints_release(struct dns_hints *H) { - return dns_atomic_dec(&H->refcount); -} /* dns_hints_release() */ - - -struct dns_hints *dns_hints_mortal(struct dns_hints *hints) { - if (hints) - dns_hints_release(hints); - - return hints; -} /* dns_hints_mortal() */ - - -struct dns_hints *dns_hints_local(struct dns_resolv_conf *resconf, int *error_) { - struct dns_hints *hints = 0; - int error; - - if (resconf) - dns_resconf_acquire(resconf); - else if (!(resconf = dns_resconf_local(&error))) - goto error; - - if (!(hints = dns_hints_open(resconf, &error))) - goto error; - - error = 0; - - if (0 == dns_hints_insert_resconf(hints, ".", resconf, &error) && error) - goto error; - - dns_resconf_close(resconf); - - return hints; -error: - *error_ = error; - - dns_resconf_close(resconf); - dns_hints_close(hints); - - return 0; -} /* dns_hints_local() */ - - -struct dns_hints *dns_hints_root(struct dns_resolv_conf *resconf, int *error_) { - static const struct { - int af; - char addr[INET6_ADDRSTRLEN]; - } root_hints[] = { - { AF_INET, "198.41.0.4" }, /* A.ROOT-SERVERS.NET. */ - { AF_INET6, "2001:503:ba3e::2:30" }, /* A.ROOT-SERVERS.NET. */ - { AF_INET, "192.228.79.201" }, /* B.ROOT-SERVERS.NET. */ - { AF_INET, "192.33.4.12" }, /* C.ROOT-SERVERS.NET. */ - { AF_INET, "128.8.10.90" }, /* D.ROOT-SERVERS.NET. */ - { AF_INET, "192.203.230.10" }, /* E.ROOT-SERVERS.NET. */ - { AF_INET, "192.5.5.241" }, /* F.ROOT-SERVERS.NET. */ - { AF_INET6, "2001:500:2f::f" }, /* F.ROOT-SERVERS.NET. */ - { AF_INET, "192.112.36.4" }, /* G.ROOT-SERVERS.NET. */ - { AF_INET, "128.63.2.53" }, /* H.ROOT-SERVERS.NET. */ - { AF_INET6, "2001:500:1::803f:235" }, /* H.ROOT-SERVERS.NET. */ - { AF_INET, "192.36.148.17" }, /* I.ROOT-SERVERS.NET. */ - { AF_INET, "192.58.128.30" }, /* J.ROOT-SERVERS.NET. */ - { AF_INET6, "2001:503:c27::2:30" }, /* J.ROOT-SERVERS.NET. */ - }; - struct dns_hints *hints = 0; - struct sockaddr_storage ss; - unsigned i; - int error, af; - - if (!(hints = dns_hints_open(resconf, &error))) - goto error; - - for (i = 0; i < lengthof(root_hints); i++) { - af = root_hints[i].af; - - if (1 != dns_inet_pton(af, root_hints[i].addr, dns_sa_addr(af, &ss))) - goto soerr; - - *dns_sa_port(af, &ss) = htons(53); - ss.ss_family = af; - - if ((error = dns_hints_insert(hints, ".", (struct sockaddr *)&ss, 1))) - goto error; - } - - return hints; -soerr: - error = dns_soerr(); - - goto error; -error: - *error_ = error; - - dns_hints_close(hints); - - return 0; -} /* dns_hints_root() */ - - -static struct dns_hints_soa *dns_hints_fetch(struct dns_hints *H, const char *zone) { - struct dns_hints_soa *soa; - - for (soa = H->head; soa; soa = soa->next) { - if (0 == strcasecmp(zone, (char *)soa->zone)) - return soa; - } - - return 0; -} /* dns_hints_fetch() */ - - -int dns_hints_insert(struct dns_hints *H, const char *zone, const struct sockaddr *sa, unsigned priority) { - static const struct dns_hints_soa soa_initializer; - struct dns_hints_soa *soa; - unsigned i; - - if (!(soa = dns_hints_fetch(H, zone))) { - if (!(soa = malloc(sizeof *soa))) - return dns_syerr(); - - *soa = soa_initializer; - - dns__printstring(soa->zone, sizeof soa->zone, 0, zone); - - soa->next = H->head; - H->head = soa; - } - - i = soa->count % lengthof(soa->addrs); - - memcpy(&soa->addrs[i].ss, sa, dns_sa_len(sa)); - - soa->addrs[i].priority = MAX(1, priority); - - if (soa->count < lengthof(soa->addrs)) - soa->count++; - - return 0; -} /* dns_hints_insert() */ - - -unsigned dns_hints_insert_resconf(struct dns_hints *H, const char *zone, const struct dns_resolv_conf *resconf, int *error_) { - unsigned i, n, p; - int error; - - for (i = 0, n = 0, p = 1; i < lengthof(resconf->nameserver) && resconf->nameserver[i].ss_family != AF_UNSPEC; i++, n++) { - if ((error = dns_hints_insert(H, zone, (struct sockaddr *)&resconf->nameserver[i], p))) - goto error; - - p += !resconf->options.rotate; - } - - return n; -error: - *error_ = error; - - return n; -} /* dns_hints_insert_resconf() */ - - -static int dns_hints_i_cmp(unsigned a, unsigned b, struct dns_hints_i *i, struct dns_hints_soa *soa) { - int cmp; - - if ((cmp = soa->addrs[a].priority - soa->addrs[b].priority)) - return cmp; - - return dns_k_shuffle16(a, i->state.seed) - dns_k_shuffle16(b, i->state.seed); -} /* dns_hints_i_cmp() */ - - -static unsigned dns_hints_i_start(struct dns_hints_i *i, struct dns_hints_soa *soa) { - unsigned p0, p; - - p0 = 0; - - for (p = 1; p < soa->count; p++) { - if (dns_hints_i_cmp(p, p0, i, soa) < 0) - p0 = p; - } - - return p0; -} /* dns_hints_i_start() */ - - -static unsigned dns_hints_i_skip(unsigned p0, struct dns_hints_i *i, struct dns_hints_soa *soa) { - unsigned pZ, p; - - for (pZ = 0; pZ < soa->count; pZ++) { - if (dns_hints_i_cmp(pZ, p0, i, soa) > 0) - goto cont; - } - - return soa->count; -cont: - for (p = pZ + 1; p < soa->count; p++) { - if (dns_hints_i_cmp(p, p0, i, soa) <= 0) - continue; - - if (dns_hints_i_cmp(p, pZ, i, soa) >= 0) - continue; - - pZ = p; - } - - - return pZ; -} /* dns_hints_i_skip() */ - - -struct dns_hints_i *dns_hints_i_init(struct dns_hints_i *i, struct dns_hints *hints) { - static const struct dns_hints_i i_initializer; - struct dns_hints_soa *soa; - - i->state = i_initializer.state; - - do { - i->state.seed = dns_random(); - } while (0 == i->state.seed); - - if ((soa = dns_hints_fetch(hints, i->zone))) { - i->state.next = dns_hints_i_start(i, soa); - } - - return i; -} /* dns_hints_i_init() */ - - -unsigned dns_hints_grep(struct sockaddr **sa, socklen_t *sa_len, unsigned lim, struct dns_hints_i *i, struct dns_hints *H) { - struct dns_hints_soa *soa; - unsigned n; - - if (!(soa = dns_hints_fetch(H, i->zone))) - return 0; - - n = 0; - - while (i->state.next < soa->count && n < lim) { - *sa = (struct sockaddr *)&soa->addrs[i->state.next].ss; - *sa_len = dns_sa_len(*sa); - - sa++; - sa_len++; - n++; - - i->state.next = dns_hints_i_skip(i->state.next, i, soa); - } - - return n; -} /* dns_hints_grep() */ - - -struct dns_packet *dns_hints_query(struct dns_hints *hints, struct dns_packet *Q, int *error_) { - struct dns_packet *A, *P; - struct dns_rr rr; - char zone[DNS_D_MAXNAME + 1]; - size_t zlen; - struct dns_hints_i i; - struct sockaddr *sa; - socklen_t slen; - int error; - - if (!dns_rr_grep(&rr, 1, dns_rr_i_new(Q, .section = DNS_S_QUESTION), Q, &error)) - goto error; - - if (!(zlen = dns_d_expand(zone, sizeof zone, rr.dn.p, Q, &error))) - goto error; - else if (zlen >= sizeof zone) - goto toolong; - - P = dns_p_new(512); - dns_header(P)->qr = 1; - - if ((error = dns_rr_copy(P, &rr, Q))) - goto error; - - if ((error = dns_p_push(P, DNS_S_AUTHORITY, ".", strlen("."), DNS_T_NS, DNS_C_IN, 0, "hints.local."))) - goto error; - - do { - i.zone = zone; - - dns_hints_i_init(&i, hints); - - while (dns_hints_grep(&sa, &slen, 1, &i, hints)) { - int af = sa->sa_family; - int rtype = (af == AF_INET6)? DNS_T_AAAA : DNS_T_A; - - if ((error = dns_p_push(P, DNS_S_ADDITIONAL, "hints.local.", strlen("hints.local."), rtype, DNS_C_IN, 0, dns_sa_addr(af, sa)))) - goto error; - } - } while ((zlen = dns_d_cleave(zone, sizeof zone, zone, zlen))); - - if (!(A = dns_p_copy(dns_p_make(P->end, &error), P))) - goto error; - - return A; -toolong: - error = DNS_EILLEGAL; -error: - *error_ = error; - - return 0; -} /* dns_hints_query() */ - - -/** ugly hack to support specifying ports other than 53 in resolv.conf. */ -static unsigned short dns_hints_port(struct dns_hints *hints, int af, void *addr) { - struct dns_hints_soa *soa; - unsigned short port; - unsigned i; - - for (soa = hints->head; soa; soa = soa->next) { - for (i = 0; i < soa->count; i++) { - if (af != soa->addrs[i].ss.ss_family) - continue; - - if (memcmp(addr, dns_sa_addr(af, &soa->addrs[i].ss), (af == AF_INET6)? sizeof (struct in6_addr) : sizeof (struct in_addr))) - continue; - - port = *dns_sa_port(af, &soa->addrs[i].ss); - - return (port)? port : htons(53); - } - } - - return htons(53); -} /* dns_hints_port() */ - - -int dns_hints_dump(struct dns_hints *hints, FILE *fp) { - struct dns_hints_soa *soa; - char addr[INET6_ADDRSTRLEN]; - unsigned i; - int af; - - for (soa = hints->head; soa; soa = soa->next) { - fprintf(fp, "ZONE \"%s\"\n", soa->zone); - - for (i = 0; i < soa->count; i++) { - af = soa->addrs[i].ss.ss_family; - if (!dns_inet_ntop(af, dns_sa_addr(af, &soa->addrs[i].ss), addr, sizeof addr)) - return dns_soerr(); - - fprintf(fp, "\t(%d) [%s]:%hu\n", (int)soa->addrs[i].priority, addr, ntohs(*dns_sa_port(af, &soa->addrs[i].ss))); - } - } - - return 0; -} /* dns_hints_dump() */ - - -/* - * C A C H E R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -static dns_atomic_t dns_cache_acquire(struct dns_cache *cache EINA_UNUSED) { - return 0; -} /* dns_cache_acquire() */ - - -static dns_atomic_t dns_cache_release(struct dns_cache *cache EINA_UNUSED) { - return 0; -} /* dns_cache_release() */ - - -static struct dns_packet *dns_cache_query(struct dns_packet *query EINA_UNUSED, struct dns_cache *cache EINA_UNUSED, int *error EINA_UNUSED) { - return 0; -} /* dns_cache_submit() */ - - -static int dns_cache_submit(struct dns_packet *query EINA_UNUSED, struct dns_cache *cache EINA_UNUSED) { - return 0; -} /* dns_cache_submit() */ - - -static int dns_cache_check(struct dns_cache *cache EINA_UNUSED) { - return 0; -} /* dns_cache_check() */ - - -static struct dns_packet *dns_cache_fetch(struct dns_cache *cache EINA_UNUSED, int *error EINA_UNUSED) { - return 0; -} /* dns_cache_fetch() */ - - -static int dns_cache_pollfd(struct dns_cache *cache EINA_UNUSED) { - return -1; -} /* dns_cache_pollfd() */ - - -static short dns_cache_events(struct dns_cache *cache EINA_UNUSED) { - return 0; -} /* dns_cache_events() */ - - -static void dns_cache_clear(struct dns_cache *cache EINA_UNUSED) { - return; -} /* dns_cache_clear() */ - - -struct dns_cache *dns_cache_init(struct dns_cache *cache) { - static const struct dns_cache c_init = { - .acquire = &dns_cache_acquire, - .release = &dns_cache_release, - .query = &dns_cache_query, - .submit = &dns_cache_submit, - .check = &dns_cache_check, - .fetch = &dns_cache_fetch, - .pollfd = &dns_cache_pollfd, - .events = &dns_cache_events, - .clear = &dns_cache_clear, - }; - - *cache = c_init; - - return cache; -} /* dns_cache_init() */ - - -void dns_cache_close(struct dns_cache *cache) { - if (cache) - cache->release(cache); -} /* dns_cache_close() */ - - -/* - * S O C K E T R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -static void dns_socketclose(int *fd) { - if (*fd != -1) { -#if _WIN32 - closesocket(*fd); -#else - close(*fd); -#endif - *fd = -1; - } -} /* dns_socketclose() */ - - -#define DNS_SO_MAXTRY 7 - -static int dns_socket(struct sockaddr *local, int type, int *error_) { - int error, fd = -1; -#if defined(O_NONBLOCK) - int flags; -#elif defined(FIONBIO) - unsigned long opt; -#endif - - if (-1 == (fd = socket(local->sa_family, type, 0))) - goto soerr; - -#if defined(F_SETFD) - if (-1 == fcntl(fd, F_SETFD, 1)) - goto syerr; -#endif - -#if defined(O_NONBLOCK) - if (-1 == (flags = fcntl(fd, F_GETFL))) - goto syerr; - - if (-1 == fcntl(fd, F_SETFL, flags | O_NONBLOCK)) - goto syerr; -#elif defined(FIONBIO) - opt = 1; - - if (0 != ioctlsocket(fd, FIONBIO, &opt)) - goto soerr; -#endif - - if (local->sa_family != AF_INET && local->sa_family != AF_INET6) - return fd; - - if (type != SOCK_DGRAM) - return fd; - - if (*dns_sa_port(local->sa_family, local) == 0) { - struct sockaddr_storage tmp; - unsigned i, port; - - memcpy(&tmp, local, dns_sa_len(local)); - - for (i = 0; i < DNS_SO_MAXTRY; i++) { - port = 1025 + (dns_random() % 64510); - - *dns_sa_port(tmp.ss_family, &tmp) = htons(port); - - if (0 == bind(fd, (struct sockaddr *)&tmp, dns_sa_len(&tmp))) - return fd; - } - } - - if (0 == bind(fd, local, dns_sa_len(local))) - return fd; - - /* FALL THROUGH */ -soerr: - error = dns_soerr(); - - goto error; -syerr: - error = dns_syerr(); - - goto error; -error: - *error_ = error; - - dns_socketclose(&fd); - - return -1; -} /* dns_socket() */ - - -enum { - DNS_SO_UDP_INIT = 1, - DNS_SO_UDP_CONN, - DNS_SO_UDP_SEND, - DNS_SO_UDP_RECV, - DNS_SO_UDP_DONE, - - DNS_SO_TCP_INIT, - DNS_SO_TCP_CONN, - DNS_SO_TCP_SEND, - DNS_SO_TCP_RECV, - DNS_SO_TCP_DONE, -}; - -struct dns_socket { - struct dns_options opts; - - int udp; - int tcp; - - int *old; - unsigned onum, olim; - - int type; - - struct sockaddr_storage local, remote; - - struct dns_k_permutor qids; - - struct dns_stat stat; - - /* - * NOTE: dns_so_reset() zeroes everything from here down. - */ - int state; - - unsigned short qid; - char qname[DNS_D_MAXNAME + 1]; - size_t qlen; - enum dns_type qtype; - enum dns_class qclass; - - struct dns_packet *query; - size_t qout; - - time_t began; - - struct dns_packet *answer; - size_t alen, apos; -}; /* struct dns_socket() */ - - -/* - * NOTE: Actual closure delayed so that kqueue(2) and epoll(2) callers have - * a chance to recognize a state change after installing a persistent event - * and where sequential descriptors with the same integer value returned - * from _pollfd() would be ambiguous. See dns_so_closefds(). - */ -static int dns_so_closefd(struct dns_socket *so, int *fd) { - int error; - - if (*fd == -1) - return 0; - - if (so->opts.closefd.cb) { - if ((error = so->opts.closefd.cb(fd, so->opts.closefd.arg))) { - return error; - } else if (*fd == -1) - return 0; - } - - if (!(so->onum < so->olim)) { - unsigned olim = MAX(4, so->olim * 2); - void *old; - - if (!(old = realloc(so->old, sizeof so->old[0] * olim))) - return dns_syerr(); - - so->old = old; - so->olim = olim; - } - - so->old[so->onum++] = *fd; - *fd = -1; - - return 0; -} /* dns_so_closefd() */ - - -#define DNS_SO_CLOSE_UDP 0x01 -#define DNS_SO_CLOSE_TCP 0x02 -#define DNS_SO_CLOSE_OLD 0x04 -#define DNS_SO_CLOSE_ALL (DNS_SO_CLOSE_UDP|DNS_SO_CLOSE_TCP|DNS_SO_CLOSE_OLD) - -static void dns_so_closefds(struct dns_socket *so, int which) { - if (DNS_SO_CLOSE_UDP & which) - dns_socketclose(&so->udp); - if (DNS_SO_CLOSE_TCP & which) - dns_socketclose(&so->tcp); - if (DNS_SO_CLOSE_OLD & which) { - unsigned i; - for (i = 0; i < so->onum; i++) - dns_socketclose(&so->old[i]); - so->onum = 0; - free(so->old); - so->old = 0; - so->olim = 0; - } -} /* dns_so_closefds() */ - - -static void dns_so_destroy(struct dns_socket *); - -static struct dns_socket *dns_so_init(struct dns_socket *so, const struct sockaddr *local, int type, const struct dns_options *opts, int *error) { - static const struct dns_socket so_initializer = { .opts = DNS_OPTS_INITIALIZER, .udp = -1, .tcp = -1, }; - - *so = so_initializer; - so->type = type; - - if (opts) - so->opts = *opts; - - if (local) - memcpy(&so->local, local, dns_sa_len(local)); - - if (-1 == (so->udp = dns_socket((struct sockaddr *)&so->local, SOCK_DGRAM, error))) - goto error; - - dns_k_permutor_init(&so->qids, 1, 65535); - - return so; -error: - dns_so_destroy(so); - - return 0; -} /* dns_so_init() */ - - -struct dns_socket *dns_so_open(const struct sockaddr *local, int type, const struct dns_options *opts, int *error) { - struct dns_socket *so; - - if (!(so = malloc(sizeof *so))) - goto syerr; - - if (!dns_so_init(so, local, type, opts, error)) - goto error; - - return so; -syerr: - *error = dns_syerr(); -error: - dns_so_close(so); - - return 0; -} /* dns_so_open() */ - - -static void dns_so_destroy(struct dns_socket *so) { - dns_so_reset(so); - dns_so_closefds(so, DNS_SO_CLOSE_ALL); -} /* dns_so_destroy() */ - - -void dns_so_close(struct dns_socket *so) { - if (!so) - return; - - dns_so_destroy(so); - - free(so); -} /* dns_so_close() */ - - -void dns_so_reset(struct dns_socket *so) { - free(so->answer); - - memset(&so->state, '\0', sizeof *so - offsetof(struct dns_socket, state)); -} /* dns_so_reset() */ - - -unsigned short dns_so_mkqid(struct dns_socket *so) { - return dns_k_permutor_step(&so->qids); -} /* dns_so_mkqid() */ - - -#define DNS_SO_MINBUF 768 - -static int dns_so_newanswer(struct dns_socket *so, size_t len) { - size_t size = offsetof(struct dns_packet, data) + MAX(len, DNS_SO_MINBUF); - void *p; - - if (!(p = realloc(so->answer, size))) - return dns_syerr(); - - so->answer = dns_p_init(p, size); - - return 0; -} /* dns_so_newanswer() */ - - -int dns_so_submit(struct dns_socket *so, struct dns_packet *Q, struct sockaddr *host) { - struct dns_rr rr; - int error = -1; - - dns_so_reset(so); - - if ((error = dns_rr_parse(&rr, 12, Q))) - goto error; - - if (!(so->qlen = dns_d_expand(so->qname, sizeof so->qname, rr.dn.p, Q, &error))) - goto error; - /* - * NOTE: don't bail if expansion is too long; caller may be - * intentionally sending long names. However, we won't be able to - * verify it on return. - */ - - so->qtype = rr.type; - so->qclass = rr.class; - - if ((error = dns_so_newanswer(so, DNS_SO_MINBUF))) - goto syerr; - - memcpy(&so->remote, host, dns_sa_len(host)); - - so->query = Q; - so->qout = 0; - so->began = dns_now(); - - if (dns_header(so->query)->qid == 0) - dns_header(so->query)->qid = dns_so_mkqid(so); - - so->qid = dns_header(so->query)->qid; - so->state = (so->type == SOCK_STREAM)? DNS_SO_TCP_INIT : DNS_SO_UDP_INIT; - - so->stat.queries++; - - return 0; -syerr: - error = dns_syerr(); -error: - dns_so_reset(so); - - return error; -} /* dns_so_submit() */ - - -static int dns_so_verify(struct dns_socket *so, struct dns_packet *P) { - char qname[DNS_D_MAXNAME + 1]; - size_t qlen; - struct dns_rr rr; - int error = -1; - - if (so->qid != dns_header(so->answer)->qid) - return DNS_EUNKNOWN; - - if (!dns_p_count(so->answer, DNS_S_QD)) - return DNS_EUNKNOWN; - - if (0 != dns_rr_parse(&rr, 12, so->answer)) - return DNS_EUNKNOWN; - - if (rr.type != so->qtype || rr.class != so->qclass) - return DNS_EUNKNOWN; - - if (!(qlen = dns_d_expand(qname, sizeof qname, rr.dn.p, P, &error))) - return error; - else if (qlen >= sizeof qname || qlen != so->qlen) - return DNS_EUNKNOWN; - - if (0 != strcasecmp(so->qname, qname)) - return DNS_EUNKNOWN; - - return 0; -} /* dns_so_verify() */ - - -static int dns_so_tcp_send(struct dns_socket *so) { - unsigned char *qsrc; - size_t qend; - long n; - - so->query->data[-2] = 0xff & (so->query->end >> 8); - so->query->data[-1] = 0xff & (so->query->end >> 0); - - qsrc = &so->query->data[-2] + so->qout; - qend = so->query->end + 2; - - while (so->qout < qend) { - if (0 > (n = send(so->tcp, (void *)&qsrc[so->qout], qend - so->qout, 0))) - return dns_soerr(); - - so->qout += n; - so->stat.tcp.sent.bytes += n; - } - - so->stat.tcp.sent.count++; - - return 0; -} /* dns_so_tcp_send() */ - - -static int dns_so_tcp_recv(struct dns_socket *so) { - unsigned char *asrc; - size_t aend, alen; - int error; - long n; - - aend = so->alen + 2; - - while (so->apos < aend) { - asrc = &so->answer->data[-2]; - - if (0 > (n = recv(so->tcp, (void *)&asrc[so->apos], aend - so->apos, 0))) - return dns_soerr(); - else if (n == 0) - return DNS_EUNKNOWN; /* FIXME */ - - so->apos += n; - so->stat.tcp.rcvd.bytes += n; - - if (so->alen == 0 && so->apos >= 2) { - alen = ((0xff & so->answer->data[-2]) << 8) - | ((0xff & so->answer->data[-1]) << 0); - - if ((error = dns_so_newanswer(so, alen))) - return error; - - so->alen = alen; - aend = alen + 2; - } - } - - so->answer->end = so->alen; - so->stat.tcp.rcvd.count++; - - return 0; -} /* dns_so_tcp_recv() */ - - -int dns_so_check(struct dns_socket *so) { - int error; - long n; - -retry: - switch (so->state) { - case DNS_SO_UDP_INIT: - so->state++; - case DNS_SO_UDP_CONN: - if (0 != connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote))) - goto soerr; - - so->state++; - case DNS_SO_UDP_SEND: - if (0 > (n = send(so->udp, (void *)so->query->data, so->query->end, 0))) - goto soerr; - - so->stat.udp.sent.bytes += n; - so->stat.udp.sent.count++; - - so->state++; - case DNS_SO_UDP_RECV: - if (0 > (n = recv(so->udp, (void *)so->answer->data, so->answer->size, 0))) - goto soerr; - - so->stat.udp.rcvd.bytes += n; - so->stat.udp.rcvd.count++; - - if ((so->answer->end = n) < 12) - goto trash; - - if ((error = dns_so_verify(so, so->answer))) - goto trash; - - so->state++; - case DNS_SO_UDP_DONE: - if (!dns_header(so->answer)->tc || so->type == SOCK_DGRAM) - return 0; - - so->state++; - case DNS_SO_TCP_INIT: - if ((error = dns_so_closefd(so, &so->tcp))) - goto error; - - if (-1 == (so->tcp = dns_socket((struct sockaddr *)&so->local, SOCK_STREAM, &error))) - goto error; - - so->state++; - case DNS_SO_TCP_CONN: - if (0 != connect(so->tcp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote))) { - if (dns_soerr() != DNS_EISCONN) - goto soerr; - } - - so->state++; - case DNS_SO_TCP_SEND: - if ((error = dns_so_tcp_send(so))) - goto error; - - so->state++; - case DNS_SO_TCP_RECV: - if ((error = dns_so_tcp_recv(so))) - goto error; - - so->state++; - case DNS_SO_TCP_DONE: - if ((error = dns_so_closefd(so, &so->tcp))) - goto error; - - if (so->answer->end < 12) - return DNS_EILLEGAL; - - if ((error = dns_so_verify(so, so->answer))) - goto error; - - return 0; - default: - error = DNS_EUNKNOWN; - - goto error; - } /* switch() */ - -trash: - goto retry; -soerr: - error = dns_soerr(); - - goto error; -error: - switch (error) { - case DNS_EINTR: - goto retry; - case DNS_EINPROGRESS: - /* FALL THROUGH */ - case DNS_EALREADY: - /* FALL THROUGH */ -#if DNS_EWOULDBLOCK != DNS_EAGAIN - case DNS_EWOULDBLOCK: - /* FALL THROUGH */ -#endif - error = DNS_EAGAIN; - - break; - } /* switch() */ - - return error; -} /* dns_so_check() */ - - -struct dns_packet *dns_so_fetch(struct dns_socket *so, int *error) { - struct dns_packet *answer; - - switch (so->state) { - case DNS_SO_UDP_DONE: - case DNS_SO_TCP_DONE: - answer = so->answer; - so->answer = 0; - - return answer; - default: - *error = DNS_EUNKNOWN; - - return 0; - } -} /* dns_so_fetch() */ - - -struct dns_packet *dns_so_query(struct dns_socket *so, struct dns_packet *Q, struct sockaddr *host, int *error_) { - struct dns_packet *A; - int error; - - if (!so->state) { - if ((error = dns_so_submit(so, Q, host))) - goto error; - } - - if ((error = dns_so_check(so))) - goto error; - - if (!(A = dns_so_fetch(so, &error))) - goto error; - - dns_so_reset(so); - - return A; -error: - *error_ = error; - - return 0; -} /* dns_so_query() */ - - -time_t dns_so_elapsed(struct dns_socket *so) { - return dns_elapsed(so->began); -} /* dns_so_elapsed() */ - - -void dns_so_clear(struct dns_socket *so) { - dns_so_closefds(so, DNS_SO_CLOSE_OLD); -} /* dns_so_clear() */ - - -static int dns_so_events2(struct dns_socket *so, enum dns_events type) { - int events = 0; - - switch (so->state) { - case DNS_SO_UDP_CONN: - case DNS_SO_UDP_SEND: - events |= DNS_POLLOUT; - - break; - case DNS_SO_UDP_RECV: - events |= DNS_POLLIN; - - break; - case DNS_SO_TCP_CONN: - case DNS_SO_TCP_SEND: - events |= DNS_POLLOUT; - - break; - case DNS_SO_TCP_RECV: - events |= DNS_POLLIN; - - break; - } /* switch() */ - - switch (type) { - case DNS_LIBEVENT: - return DNS_POLL2EV(events); - default: - return events; - } /* switch() */ -} /* dns_so_events2() */ - - -int dns_so_events(struct dns_socket *so) { - return dns_so_events2(so, so->opts.events); -} /* dns_so_events() */ - - -int dns_so_pollfd(struct dns_socket *so) { - switch (so->state) { - case DNS_SO_UDP_CONN: - case DNS_SO_UDP_SEND: - case DNS_SO_UDP_RECV: - return so->udp; - case DNS_SO_TCP_CONN: - case DNS_SO_TCP_SEND: - case DNS_SO_TCP_RECV: - return so->tcp; - } /* switch() */ - - return -1; -} /* dns_so_pollfd() */ - - -int dns_so_poll(struct dns_socket *so, int timeout) { - return dns_poll(dns_so_pollfd(so), dns_so_events2(so, DNS_SYSPOLL), timeout); -} /* dns_so_poll() */ - - -const struct dns_stat *dns_so_stat(struct dns_socket *so) { - return &so->stat; -} /* dns_so_stat() */ - - -/* - * R E S O L V E R R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -enum dns_res_state { - DNS_R_INIT, - DNS_R_GLUE, - DNS_R_SWITCH, /* (B)IND, (F)ILE, (C)ACHE */ - - DNS_R_FILE, /* Lookup in local hosts database */ - - DNS_R_CACHE, /* Lookup in application cache */ - DNS_R_SUBMIT, - DNS_R_CHECK, - DNS_R_FETCH, - - DNS_R_BIND, /* Lookup in the network */ - DNS_R_SEARCH, - DNS_R_HINTS, - DNS_R_ITERATE, - DNS_R_FOREACH_NS, - DNS_R_RESOLV0_NS, /* Prologue: Setup next frame and recurse */ - DNS_R_RESOLV1_NS, /* Epilog: Inspect answer */ - DNS_R_FOREACH_A, - DNS_R_QUERY_A, - DNS_R_CNAME0_A, - DNS_R_CNAME1_A, - - DNS_R_FINISH, - DNS_R_SMART0_A, - DNS_R_SMART1_A, - DNS_R_DONE, - DNS_R_SERVFAIL, -}; /* enum dns_res_state */ - - -#define DNS_R_MAXDEPTH 8 -#define DNS_R_ENDFRAME (DNS_R_MAXDEPTH - 1) - -struct dns_resolver { - struct dns_socket so; - - struct dns_resolv_conf *resconf; - struct dns_hosts *hosts; - struct dns_hints *hints; - struct dns_cache *cache; - - dns_atomic_t refcount; - - /* Reset zeroes everything below here. */ - - char qname[DNS_D_MAXNAME + 1]; - size_t qlen; - - enum dns_type qtype; - enum dns_class qclass; - - time_t began; - - dns_resconf_i_t search; - - struct dns_rr_i smart; - - struct dns_res_frame { - enum dns_res_state state; - - int error; - int which; /* (B)IND, (F)ILE; index into resconf->lookup */ - - unsigned attempts; - - struct dns_packet *query, *answer, *hints; - - struct dns_rr_i hints_i, hints_j; - struct dns_rr hints_ns, ans_cname; - } stack[DNS_R_MAXDEPTH]; - - unsigned sp; -}; /* struct dns_resolver */ - - -static int dns_res_tcp2type(int tcp) { - switch (tcp) { - case DNS_RESCONF_TCP_ONLY: - return SOCK_STREAM; - case DNS_RESCONF_TCP_DISABLE: - return SOCK_DGRAM; - default: - return 0; - } -} /* dns_res_tcp2type() */ - -struct dns_resolver *dns_res_open(struct dns_resolv_conf *resconf, struct dns_hosts *hosts, struct dns_hints *hints, struct dns_cache *cache, const struct dns_options *opts, int *error_) { - static const struct dns_resolver R_initializer - = { .refcount = 1, }; - struct dns_resolver *R = 0; - int type, error; - - /* - * Grab ref count early because the caller may have passed us a mortal - * reference, and we want to do the right thing if we return early - * from an error. - */ - if (resconf) - dns_resconf_acquire(resconf); - if (hosts) - dns_hosts_acquire(hosts); - if (hints) - dns_hints_acquire(hints); - if (cache) - dns_cache_acquire(cache); - - /* - * Don't try to load it ourselves because a NULL object might be an - * error from, say, dns_resconf_root(), and loading - * dns_resconf_local() by default would create undesirable surpises. - */ - if (!resconf || !hosts || !hints) - goto error; - - if (!(R = malloc(sizeof *R))) - goto syerr; - - *R = R_initializer; - type = dns_res_tcp2type(resconf->options.tcp); - - if (!dns_so_init(&R->so, (struct sockaddr *)&resconf->iface, type, opts, &error)) - goto error; - - R->resconf = resconf; - R->hosts = hosts; - R->hints = hints; - R->cache = cache; - - return R; -syerr: - error = dns_syerr(); -error: - *error_ = error; - - dns_res_close(R); - - dns_resconf_close(resconf); - dns_hosts_close(hosts); - dns_hints_close(hints); - dns_cache_close(cache); - - return 0; -} /* dns_res_open() */ - - -struct dns_resolver *dns_res_stub(const struct dns_options *opts, int *error) { - struct dns_resolv_conf *resconf = 0; - struct dns_hosts *hosts = 0; - struct dns_hints *hints = 0; - struct dns_resolver *res = 0; - - if (!(resconf = dns_resconf_local(error))) - goto epilog; - - if (!(hosts = dns_hosts_local(error))) - goto epilog; - - if (!(hints = dns_hints_local(resconf, error))) - goto epilog; - - if (!(res = dns_res_open(resconf, hosts, hints, NULL, opts, error))) - goto epilog; - -epilog: - dns_resconf_close(resconf); - dns_hosts_close(hosts); - dns_hints_close(hints); - - return res; -} /* dns_res_stub() */ - - -static void dns_res_reset_frame(struct dns_resolver *R EINA_UNUSED, struct dns_res_frame *frame) { - free(frame->query); - free(frame->answer); - free(frame->hints); - - memset(frame, '\0', sizeof *frame); -} /* dns_res_reset_frame() */ - - -void dns_res_reset(struct dns_resolver *R) { - unsigned i; - - dns_so_reset(&R->so); - - for (i = 0; i < lengthof(R->stack); i++) - dns_res_reset_frame(R, &R->stack[i]); - - memset(&R->qname, '\0', sizeof *R - offsetof(struct dns_resolver, qname)); -} /* dns_res_reset() */ - - -void dns_res_close(struct dns_resolver *R) { - if (!R || 1 < dns_res_release(R)) - return; - - dns_res_reset(R); - - dns_so_destroy(&R->so); - - dns_hints_close(R->hints); - dns_hosts_close(R->hosts); - dns_resconf_close(R->resconf); - dns_cache_close(R->cache); - - free(R); -} /* dns_res_close() */ - - -unsigned dns_res_acquire(struct dns_resolver *R) { - return dns_atomic_inc(&R->refcount); -} /* dns_res_acquire() */ - - -unsigned dns_res_release(struct dns_resolver *R) { - return dns_atomic_dec(&R->refcount); -} /* dns_res_release() */ - - -struct dns_resolver *dns_res_mortal(struct dns_resolver *res) { - if (res) - dns_res_release(res); - return res; -} /* dns_res_mortal() */ - - -static struct dns_packet *dns_res_merge(struct dns_packet *P0, struct dns_packet *P1, int *error_) { - size_t bufsiz = P0->end + P1->end; - struct dns_packet *P[3] = { P0, P1, 0 }; - struct dns_rr rr[3]; - int error, copy, i; - enum dns_section section; - -retry: - if (!(P[2] = dns_p_make(bufsiz, &error))) - goto error; - - dns_rr_foreach(&rr[0], P[0], .section = DNS_S_QD) { - if ((error = dns_rr_copy(P[2], &rr[0], P[0]))) - goto error; - } - - for (section = DNS_S_AN; (DNS_S_ALL & section); section <<= 1) { - for (i = 0; i < 2; i++) { - dns_rr_foreach(&rr[i], P[i], .section = section) { - copy = 1; - - dns_rr_foreach(&rr[2], P[2], .type = rr[i].type, .section = (DNS_S_ALL & ~DNS_S_QD)) { - if (0 == dns_rr_cmp(&rr[i], P[i], &rr[2], P[2])) { - copy = 0; - - break; - } - } - - if (copy && (error = dns_rr_copy(P[2], &rr[i], P[i]))) { - if (error == DNS_ENOBUFS && bufsiz < 65535) { - free(P[2]); P[2] = 0; - - bufsiz = MAX(65535, bufsiz * 2); - - goto retry; - } - - goto error; - } - } /* foreach(rr) */ - } /* foreach(packet) */ - } /* foreach(section) */ - - return P[2]; -error: - *error_ = error; - - free(P[2]); - - return 0; -} /* dns_res_merge() */ - - -static struct dns_packet *dns_res_glue(struct dns_resolver *R, struct dns_packet *Q) { - struct dns_packet *P = dns_p_new(512); - char qname[DNS_D_MAXNAME + 1]; - size_t qlen; - enum dns_type qtype; - struct dns_rr rr; - unsigned sp; - int error; - - if (!(qlen = dns_d_expand(qname, sizeof qname, 12, Q, &error)) - || qlen >= sizeof qname) - return 0; - - if (!(qtype = dns_rr_type(12, Q))) - return 0; - - if ((error = dns_p_push(P, DNS_S_QD, qname, strlen(qname), qtype, DNS_C_IN, 0, 0))) - return 0; - - for (sp = 0; sp <= R->sp; sp++) { - if (!R->stack[sp].answer) - continue; - - dns_rr_foreach(&rr, R->stack[sp].answer, .name = qname, .type = qtype, .section = (DNS_S_ALL & ~DNS_S_QD)) { - rr.section = DNS_S_AN; - - if ((error = dns_rr_copy(P, &rr, R->stack[sp].answer))) - return 0; - } - } - - if (dns_p_count(P, DNS_S_AN) > 0) - goto copy; - - /* Otherwise, look for a CNAME */ - for (sp = 0; sp <= R->sp; sp++) { - if (!R->stack[sp].answer) - continue; - - dns_rr_foreach(&rr, R->stack[sp].answer, .name = qname, .type = DNS_T_CNAME, .section = (DNS_S_ALL & ~DNS_S_QD)) { - rr.section = DNS_S_AN; - - if ((error = dns_rr_copy(P, &rr, R->stack[sp].answer))) - return 0; - } - } - - if (!dns_p_count(P, DNS_S_AN)) - return 0; - -copy: - return dns_p_copy(dns_p_make(P->end, &error), P); -} /* dns_res_glue() */ - - -static struct dns_packet *dns_res_mkquery(struct dns_resolver *R, const char *qname, enum dns_type qtype, enum dns_class qclass, int *error_) { - struct dns_packet *Q = 0; - int error; - - if (!(Q = dns_p_init(malloc(DNS_P_QBUFSIZ), DNS_P_QBUFSIZ))) - goto syerr; - - if ((error = dns_p_push(Q, DNS_S_QD, qname, strlen(qname), qtype, qclass, 0, 0))) - goto error; - - dns_header(Q)->rd = !R->resconf->options.recurse; - - return Q; -syerr: - error = dns_syerr(); -error: - free(Q); - - *error_ = error; - - return 0; -} /* dns_res_mkquery() */ - - -/* - * Sort NS records by three criteria: - * - * 1) Whether glue is present. - * 2) Whether glue record is original or of recursive lookup. - * 3) Randomly shuffle records which share the above criteria. - * - * NOTE: Assumes only NS records passed, AND ASSUMES no new NS records will - * be added during an iteration. - * - * FIXME: Only groks A glue, not AAAA glue. - */ -static int dns_res_nameserv_cmp(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i, struct dns_packet *P) { - _Bool glued[2] = { 0 }; - struct dns_ns ns; - struct dns_rr x, y; - int cmp, error; - - if (!(error = dns_ns_parse(&ns, a, P))) - if (!(glued[0] = !!dns_rr_grep(&x, 1, dns_rr_i_new(P, .section = (DNS_S_ALL & ~DNS_S_QD), .name = ns.host, .type = DNS_T_A), P, &error))) - x.dn.p = 0; - - if (!(error = dns_ns_parse(&ns, b, P))) - if (!(glued[1] = !!dns_rr_grep(&y, 1, dns_rr_i_new(P, .section = (DNS_S_ALL & ~DNS_S_QD), .name = ns.host, .type = DNS_T_A), P, &error))) - y.dn.p = 0; - - if ((cmp = glued[1] - glued[0])) - return cmp; - else if ((cmp = (dns_rr_offset(&y) < i->args[0]) - (dns_rr_offset(&x) < i->args[0]))) - return cmp; - else - return dns_rr_i_shuffle(a, b, i, P); -} /* dns_res_nameserv_cmp() */ - - -#define goto(sp, i) \ - do { R->stack[(sp)].state = (i); goto exec; } while (0) - -static int dns_res_exec(struct dns_resolver *R) { - struct dns_res_frame *F; - struct dns_packet *P; - char host[DNS_D_MAXNAME + 1]; - size_t len; - struct dns_rr rr; - struct sockaddr_in sin; - int error; - -exec: - - F = &R->stack[R->sp]; - - switch (F->state) { - case DNS_R_INIT: - F->state++; - case DNS_R_GLUE: - if (R->sp == 0) - goto(R->sp, DNS_R_SWITCH); - - assert(F->query); - - if (!(F->answer = dns_res_glue(R, F->query))) - goto(R->sp, DNS_R_SWITCH); - - if (!(len = dns_d_expand(host, sizeof host, 12, F->query, &error))) - goto error; - else if (len >= sizeof host) - goto toolong; - - dns_rr_foreach(&rr, F->answer, .name = host, .type = dns_rr_type(12, F->query), .section = DNS_S_AN) { - goto(R->sp, DNS_R_FINISH); - } - - dns_rr_foreach(&rr, F->answer, .name = host, .type = DNS_T_CNAME, .section = DNS_S_AN) { - F->ans_cname = rr; - - goto(R->sp, DNS_R_CNAME0_A); - } - - F->state++; - case DNS_R_SWITCH: - while (F->which < (int)sizeof R->resconf->lookup) { - switch (R->resconf->lookup[F->which++]) { - case 'b': case 'B': - goto(R->sp, DNS_R_BIND); - case 'f': case 'F': - goto(R->sp, DNS_R_FILE); - case 'c': case 'C': - if (R->cache) - goto(R->sp, DNS_R_CACHE); - - break; - default: - break; - } - } - - goto(R->sp, DNS_R_SERVFAIL); /* FIXME: Right behavior? */ - case DNS_R_FILE: - if (R->sp > 0) { - free(F->answer); - - if (!(F->answer = dns_hosts_query(R->hosts, F->query, &error))) - goto error; - - if (dns_p_count(F->answer, DNS_S_AN) > 0) - goto(R->sp, DNS_R_FINISH); - - free(F->answer); F->answer = 0; - } else { - R->search = 0; - - while ((len = dns_resconf_search(host, sizeof host, R->qname, R->qlen, R->resconf, &R->search))) { -/* - * FIXME: Some sort of bug, either with this code or with GCC 3.3.5 on - * OpenBSD 4.4, overwites the stack guard. If the bug is in this file, it - * appears to be localized somewhere around here. It can also be mitigated - * in dns_hosts_query(). In any event, the bug manifests only when using - * compound literals. alloca(), malloc(), calloc(), etc, all work fine. - * Valgrind (tested on Linux) cannot detect any issues, but stack issues are - * not Valgrind's forte. Neither can I spot anything in the assembly, but - * that's not my forte. - */ -#if __OpenBSD__ && __GNUC__ - struct dns_packet *query = __builtin_alloca(DNS_P_QBUFSIZ); - - dns_p_init(query, DNS_P_QBUFSIZ); -#else - struct dns_packet *query = dns_p_new(DNS_P_QBUFSIZ); -#endif - - if ((error = dns_p_push(query, DNS_S_QD, host, len, R->qtype, R->qclass, 0, 0))) - goto error; - - free(F->answer); - - if (!(F->answer = dns_hosts_query(R->hosts, query, &error))) - goto error; - - if (dns_p_count(F->answer, DNS_S_AN) > 0) - goto(R->sp, DNS_R_FINISH); - - free(F->answer); F->answer = 0; - } - } - - goto(R->sp, DNS_R_SWITCH); - case DNS_R_CACHE: - error = 0; - - if (!F->query && !(F->query = dns_res_mkquery(R, R->qname, R->qtype, R->qclass, &error))) - goto error; - - free(F->answer); - - if ((F->answer = R->cache->query(F->query, R->cache, &error))) { - if (dns_p_count(F->answer, DNS_S_AN) > 0) - goto(R->sp, DNS_R_FINISH); - - free(F->answer); F->answer = 0; - - goto(R->sp, DNS_R_SWITCH); - } else if (error) - goto error; - - F->state++; - case DNS_R_SUBMIT: - if ((error = R->cache->submit(F->query, R->cache))) - goto error; - - F->state++; - case DNS_R_CHECK: - if ((error = R->cache->check(R->cache))) - goto error; - - F->state++; - case DNS_R_FETCH: - error = 0; - - free(F->answer); - - if ((F->answer = R->cache->fetch(R->cache, &error))) { - if (dns_p_count(F->answer, DNS_S_AN) > 0) - goto(R->sp, DNS_R_FINISH); - - free(F->answer); F->answer = 0; - - goto(R->sp, DNS_R_SWITCH); - } else if (error) - goto error; - - goto(R->sp, DNS_R_SWITCH); - case DNS_R_BIND: - if (R->sp > 0) { - assert(F->query); - - goto(R->sp, DNS_R_HINTS); - } - - R->search = 0; - - F->state++; - case DNS_R_SEARCH: - if (!(len = dns_resconf_search(host, sizeof host, R->qname, R->qlen, R->resconf, &R->search))) - goto(R->sp, DNS_R_SWITCH); - - if (!(P = dns_p_make(DNS_P_QBUFSIZ, &error))) - goto error; - - dns_header(P)->rd = !R->resconf->options.recurse; - - free(F->query); F->query = P; - - if ((error = dns_p_push(F->query, DNS_S_QD, host, len, R->qtype, R->qclass, 0, 0))) - goto error; - - F->state++; - case DNS_R_HINTS: - if (!(F->hints = dns_hints_query(R->hints, F->query, &error))) - goto error; - - F->state++; - case DNS_R_ITERATE: - dns_rr_i_init(&F->hints_i, F->hints); - - F->hints_i.section = DNS_S_AUTHORITY; - F->hints_i.type = DNS_T_NS; - F->hints_i.sort = &dns_res_nameserv_cmp; - F->hints_i.args[0] = F->hints->end; - - F->state++; - case DNS_R_FOREACH_NS: - dns_rr_i_save(&F->hints_i); - - /* Load our next nameserver host. */ - if (!dns_rr_grep(&F->hints_ns, 1, &F->hints_i, F->hints, &error)) { - if (++F->attempts < R->resconf->options.attempts) - goto(R->sp, DNS_R_ITERATE); - - goto(R->sp, DNS_R_SWITCH); - } - - dns_rr_i_init(&F->hints_j, F->hints); - - /* Assume there are glue records */ - goto(R->sp, DNS_R_FOREACH_A); - case DNS_R_RESOLV0_NS: - /* Have we reached our max depth? */ - if (&F[1] >= endof(R->stack)) - goto(R->sp, DNS_R_FOREACH_NS); - - dns_res_reset_frame(R, &F[1]); - - if (!(F[1].query = dns_p_make(DNS_P_QBUFSIZ, &error))) - goto error; - - if ((error = dns_ns_parse((struct dns_ns *)host, &F->hints_ns, F->hints))) - goto error; - - if ((error = dns_p_push(F[1].query, DNS_S_QD, host, strlen(host), DNS_T_A, DNS_C_IN, 0, 0))) - goto error; - - F->state++; - - goto(++R->sp, DNS_R_INIT); - case DNS_R_RESOLV1_NS: - if (!(len = dns_d_expand(host, sizeof host, 12, F[1].query, &error))) - goto error; - else if (len >= sizeof host) - goto toolong; - - dns_rr_foreach(&rr, F[1].answer, .name = host, .type = DNS_T_A, .section = (DNS_S_ALL & ~DNS_S_QD)) { - rr.section = DNS_S_AR; - - if ((error = dns_rr_copy(F->hints, &rr, F[1].answer))) - goto error; - - dns_rr_i_rewind(&F->hints_i); /* Now there's glue. */ - } - - goto(R->sp, DNS_R_FOREACH_NS); - case DNS_R_FOREACH_A: - /* - * NOTE: Iterator initialized in DNS_R_FOREACH_NS because - * this state is re-entrant, but we need to reset - * .name to a valid pointer each time. - */ - if ((error = dns_ns_parse((struct dns_ns *)host, &F->hints_ns, F->hints))) - goto error; - - F->hints_j.name = host; - F->hints_j.type = DNS_T_A; - F->hints_j.section = DNS_S_ALL & ~DNS_S_QD; - - if (!dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) { - if (!dns_rr_i_count(&F->hints_j)) - goto(R->sp, DNS_R_RESOLV0_NS); - - goto(R->sp, DNS_R_FOREACH_NS); - } - - sin.sin_family = AF_INET; - - if ((error = dns_a_parse((struct dns_a *)&sin.sin_addr, &rr, F->hints))) - goto error; - - if (R->sp == 0) - sin.sin_port = dns_hints_port(R->hints, AF_INET, (struct sockaddr *)&sin.sin_addr); - else - sin.sin_port = htons(53); - - if (DNS_DEBUG) { - char addr[INET_ADDRSTRLEN + 1]; - dns_a_print(addr, sizeof addr, (struct dns_a *)&sin.sin_addr); - DNS_SHOW(F->query, "ASKING: %s/%s @ DEPTH: %u)", host, addr, R->sp); - } - - if ((error = dns_so_submit(&R->so, F->query, (struct sockaddr *)&sin))) - goto error; - - F->state++; - case DNS_R_QUERY_A: - if (dns_so_elapsed(&R->so) >= (time_t)R->resconf->options.timeout) - goto(R->sp, DNS_R_FOREACH_A); - - if ((error = dns_so_check(&R->so))) - goto error; - - free(F->answer); - - if (!(F->answer = dns_so_fetch(&R->so, &error))) - goto error; - - if (DNS_DEBUG) { - DNS_SHOW(F->answer, "ANSWER @ DEPTH: %u)", R->sp); - } - - if ((error = dns_rr_parse(&rr, 12, F->query))) - goto error; - - if (!(len = dns_d_expand(host, sizeof host, rr.dn.p, F->query, &error))) - goto error; - else if (len >= sizeof host) - goto toolong; - - dns_rr_foreach(&rr, F->answer, .section = DNS_S_AN, .name = host, .type = rr.type) { - goto(R->sp, DNS_R_FINISH); /* Found */ - } - - dns_rr_foreach(&rr, F->answer, .section = DNS_S_AN, .name = host, .type = DNS_T_CNAME) { - F->ans_cname = rr; - - goto(R->sp, DNS_R_CNAME0_A); - } - - if (!R->resconf->options.recurse) - goto(R->sp, DNS_R_SWITCH); - - dns_rr_foreach(&rr, F->answer, .section = DNS_S_NS, .type = DNS_T_NS) { - free(F->hints); - - F->hints = F->answer; - F->answer = 0; - - goto(R->sp, DNS_R_ITERATE); - } - - /* XXX: Should this go further up? */ - if (dns_header(F->answer)->aa) - goto(R->sp, DNS_R_FINISH); - - goto(R->sp, DNS_R_FOREACH_A); - case DNS_R_CNAME0_A: - if (&F[1] >= endof(R->stack)) - goto(R->sp, DNS_R_FINISH); - - if ((error = dns_cname_parse((struct dns_cname *)host, &F->ans_cname, F->answer))) - goto error; - - dns_res_reset_frame(R, &F[1]); - - if (!(F[1].query = dns_p_make(DNS_P_QBUFSIZ, &error))) - goto error; - - if ((error = dns_p_push(F[1].query, DNS_S_QD, host, strlen(host), dns_rr_type(12, F->query), DNS_C_IN, 0, 0))) - goto error; - - F->state++; - - goto(++R->sp, DNS_R_INIT); - case DNS_R_CNAME1_A: - if (!(P = dns_res_merge(F->answer, F[1].answer, &error))) - goto error; - - free(F->answer); F->answer = P; - - goto(R->sp, DNS_R_FINISH); - case DNS_R_FINISH: - assert(F->answer); - - if (!R->resconf->options.smart || R->sp > 0) - goto(R->sp, DNS_R_DONE); - - R->smart.section = DNS_S_AN; - R->smart.type = R->qtype; - - dns_rr_i_init(&R->smart, F->answer); - - F->state++; - case DNS_R_SMART0_A: - if (&F[1] >= endof(R->stack)) - goto(R->sp, DNS_R_DONE); - - while (dns_rr_grep(&rr, 1, &R->smart, F->answer, &error)) { - union { - struct dns_ns ns; - struct dns_mx mx; - struct dns_srv srv; - } rd; - const char *qname; - enum dns_type qtype; - enum dns_class qclass; - - switch (rr.type) { - case DNS_T_NS: - if ((error = dns_ns_parse(&rd.ns, &rr, F->answer))) - goto error; - - qname = rd.ns.host; - qtype = DNS_T_A; - qclass = DNS_C_IN; - - break; - case DNS_T_MX: - if ((error = dns_mx_parse(&rd.mx, &rr, F->answer))) - goto error; - - qname = rd.mx.host; - qtype = DNS_T_A; - qclass = DNS_C_IN; - - break; - case DNS_T_SRV: - if ((error = dns_srv_parse(&rd.srv, &rr, F->answer))) - goto error; - - qname = rd.srv.target; - qtype = DNS_T_A; - qclass = DNS_C_IN; - - break; - default: - continue; - } /* switch() */ - - dns_res_reset_frame(R, &F[1]); - - if (!(F[1].query = dns_res_mkquery(R, qname, qtype, qclass, &error))) - goto error; - - F->state++; - - goto(++R->sp, DNS_R_INIT); - } /* while() */ - - /* - * NOTE: SMTP specification says to fallback to A record. - * - * XXX: Should we add a mock MX answer? - */ - if (R->qtype == DNS_T_MX && R->smart.state.count == 0) { - dns_res_reset_frame(R, &F[1]); - - if (!(F[1].query = dns_res_mkquery(R, R->qname, DNS_T_A, DNS_C_IN, &error))) - goto error; - - R->smart.state.count++; - F->state++; - - goto(++R->sp, DNS_R_INIT); - } - - goto(R->sp, DNS_R_DONE); - case DNS_R_SMART1_A: - assert(F[1].answer); - - /* - * FIXME: For CNAME chains (which are typically illegal in - * this context), we should rewrite the record host name - * to the original smart qname. All the user cares about - * is locating that A/AAAA record. - */ - dns_rr_foreach(&rr, F[1].answer, .section = DNS_S_AN, .type = DNS_T_A) { - rr.section = DNS_S_AR; - - if (dns_rr_exists(&rr, F[1].answer, F->answer)) - continue; - - while ((error = dns_rr_copy(F->answer, &rr, F[1].answer))) { - if (error != DNS_ENOBUFS) - goto error; - if ((error = dns_p_grow(&F->answer))) - goto error; - } - } - - goto(R->sp, DNS_R_SMART0_A); - case DNS_R_DONE: - assert(F->answer); - - if (R->sp > 0) - goto(--R->sp, F[-1].state); - - break; - case DNS_R_SERVFAIL: - free(F->answer); - - if (!(F->answer = dns_p_make(DNS_P_QBUFSIZ, &error))) - goto error; - - dns_header(F->answer)->qr = 1; - dns_header(F->answer)->rcode = DNS_RC_SERVFAIL; - - if ((error = dns_p_push(F->answer, DNS_S_QD, R->qname, strlen(R->qname), R->qtype, R->qclass, 0, 0))) - goto error; - - goto(R->sp, DNS_R_DONE); - default: - error = EINVAL; - - goto error; - } /* switch () */ - - return 0; -toolong: - error = DNS_EILLEGAL; -error: - return error; -} /* dns_res_exec() */ - -#undef goto - - -void dns_res_clear(struct dns_resolver *R) { - switch (R->stack[R->sp].state) { - case DNS_R_CHECK: - return R->cache->clear(R->cache); - default: - return dns_so_clear(&R->so); - } -} /* dns_res_clear() */ - - -static int dns_res_events2(struct dns_resolver *R, enum dns_events type) { - int events; - - switch (R->stack[R->sp].state) { - case DNS_R_CHECK: - events = R->cache->events(R->cache); - - return (type == DNS_LIBEVENT)? DNS_POLL2EV(events) : events; - default: - return dns_so_events2(&R->so, type); - } -} /* dns_res_events2() */ - - -int dns_res_events(struct dns_resolver *R) { - return dns_res_events2(R, R->so.opts.events); -} /* dns_res_events() */ - - -int dns_res_pollfd(struct dns_resolver *R) { - switch (R->stack[R->sp].state) { - case DNS_R_CHECK: - return R->cache->pollfd(R->cache); - default: - return dns_so_pollfd(&R->so); - } -} /* dns_res_pollfd() */ - - -time_t dns_res_elapsed(struct dns_resolver *R) { - return dns_elapsed(R->began); -} /* dns_res_elapsed() */ - - -int dns_res_poll(struct dns_resolver *R, int timeout) { - return dns_poll(dns_res_pollfd(R), dns_res_events2(R, DNS_SYSPOLL), timeout); -} /* dns_res_poll() */ - - -int dns_res_submit(struct dns_resolver *R, const char *qname, enum dns_type qtype, enum dns_class qclass) { - dns_res_reset(R); - - /* Don't anchor; that can conflict with searchlist generation. */ - dns_d_init(R->qname, sizeof R->qname, qname, (R->qlen = strlen(qname)), 0); - - R->qtype = qtype; - R->qclass = qclass; - - R->began = dns_now(); - - return 0; -} /* dns_res_submit() */ - - -int dns_res_check(struct dns_resolver *R) { - int error; - - if ((error = dns_res_exec(R))) - return error; - - return 0; -} /* dns_res_check() */ - - -struct dns_packet *dns_res_fetch(struct dns_resolver *R, int *error) { - struct dns_packet *answer; - - if (R->stack[0].state != DNS_R_DONE) { - *error = DNS_EUNKNOWN; - - return 0; - } - - answer = R->stack[0].answer; - R->stack[0].answer = 0; - - return answer; -} /* dns_res_fetch() */ - - -struct dns_packet *dns_res_query(struct dns_resolver *res, const char *qname, enum dns_type qtype, enum dns_class qclass, int timeout, int *error_) { - int error; - - if ((error = dns_res_submit(res, qname, qtype, qclass))) - goto error; - - while ((error = dns_res_check(res))) { - if (dns_res_elapsed(res) > timeout) - error = DNS_ETIMEDOUT; - - if (error != DNS_EAGAIN) - goto error; - - if ((error = dns_res_poll(res, 1))) - goto error; - } - - return dns_res_fetch(res, error_); -error: - *error_ = error; - - return 0; -} /* dns_res_query() */ - - -const struct dns_stat *dns_res_stat(struct dns_resolver *res) { - return dns_so_stat(&res->so); -} /* dns_res_stat() */ - - -/* - * A D D R I N F O R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_addrinfo { - struct addrinfo hints; - struct dns_resolver *res; - - char qname[DNS_D_MAXNAME + 1]; - enum dns_type qtype; - unsigned short qport, port; - - struct dns_packet *answer; - struct dns_packet *glue; - - struct dns_rr_i i, g; - struct dns_rr rr; - - char cname[DNS_D_MAXNAME + 1]; - - int state; -}; /* struct dns_addrinfo */ - - -struct dns_addrinfo *dns_ai_open(const char *host, const char *serv, enum dns_type qtype, const struct addrinfo *hints, struct dns_resolver *res, int *error_) { - static const struct dns_addrinfo ai_initializer; - struct dns_addrinfo *ai; - int error; - - if (!res) - return 0; - - dns_res_acquire(res); - - if (!(ai = malloc(sizeof *ai))) - goto syerr; - - *ai = ai_initializer; - ai->hints = *hints; - - ai->res = res; - res = 0; - - if (sizeof ai->qname <= dns_strlcpy(ai->qname, host, sizeof ai->qname)) - { error = ENAMETOOLONG; goto error; } - - ai->qtype = qtype; - ai->qport = 0; - - if (serv) { - while (isdigit((unsigned char)*serv)) { - ai->qport *= 10; - ai->qport += *serv++ - '0'; - } - } - - ai->port = ai->qport; - - return ai; -syerr: - error = dns_syerr(); -error: - *error_ = error; - - dns_ai_close(ai); - dns_res_close(res); - - return 0; -} /* dns_ai_open() */ - - -void dns_ai_close(struct dns_addrinfo *ai) { - if (!ai) - return; - - dns_res_close(ai->res); - - if (ai->answer != ai->glue) - free(ai->glue); - - free(ai->answer); - free(ai); -} /* dns_ai_close() */ - - -static int dns_ai_setent(struct addrinfo **ent, union dns_any *any, enum dns_type type, struct dns_addrinfo *ai) { - struct sockaddr *saddr; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - const char *cname; - size_t clen; - - switch (type) { - case DNS_T_A: - saddr = memset(&sin, '\0', sizeof sin); - - sin.sin_family = AF_INET; - sin.sin_port = htons(ai->port); - - memcpy(&sin.sin_addr, any, sizeof sin.sin_addr); - - break; - case DNS_T_AAAA: - saddr = memset(&sin6, '\0', sizeof sin6); - - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(ai->port); - - memcpy(&sin6.sin6_addr, any, sizeof sin6.sin6_addr); - - break; - default: - return EINVAL; - } /* switch() */ - - if (ai->hints.ai_flags & AI_CANONNAME) { - cname = (*ai->cname)? ai->cname : ai->qname; - clen = strlen(cname); - } else { - cname = NULL; - clen = 0; - } - - if (!(*ent = malloc(sizeof **ent + dns_sa_len(saddr) + ((ai->hints.ai_flags & AI_CANONNAME)? clen + 1 : 0)))) - return dns_syerr(); - - memset(*ent, '\0', sizeof **ent); - - (*ent)->ai_family = saddr->sa_family; - (*ent)->ai_socktype = ai->hints.ai_socktype; - (*ent)->ai_protocol = ai->hints.ai_protocol; - - (*ent)->ai_addr = memcpy((unsigned char *)*ent + sizeof **ent, saddr, dns_sa_len(saddr)); - (*ent)->ai_addrlen = dns_sa_len(saddr); - - if (ai->hints.ai_flags & AI_CANONNAME) - (*ent)->ai_canonname = memcpy((unsigned char *)*ent + sizeof **ent + dns_sa_len(saddr), cname, clen + 1); - - return 0; -} /* dns_ai_setent() */ - - -enum dns_ai_state { - DNS_AI_S_INIT, - DNS_AI_S_NUMERIC, - DNS_AI_S_SUBMIT, - DNS_AI_S_CHECK, - DNS_AI_S_FETCH, - DNS_AI_S_FOREACH_I, - DNS_AI_S_FOREACH_G, - DNS_AI_S_SUBMIT_G, - DNS_AI_S_CHECK_G, - DNS_AI_S_FETCH_G, - DNS_AI_S_DONE, -}; /* enum dns_ai_state */ - -#define dns_ai_goto(which) do { ai->state = (which); goto exec; } while (0) - -int dns_ai_nextent(struct addrinfo **ent, struct dns_addrinfo *ai) { - struct dns_packet *ans, *glue; - struct dns_rr rr; - char qname[DNS_D_MAXNAME + 1]; - union dns_any any; - size_t len; - int error; - - *ent = 0; - -exec: - - switch (ai->state) { - case DNS_AI_S_INIT: - ai->state++; - case DNS_AI_S_NUMERIC: - if (1 == dns_inet_pton(AF_INET, ai->qname, &any.a)) { - ai->state = DNS_AI_S_DONE; - - return dns_ai_setent(ent, &any, DNS_T_A, ai); - } - - if (1 == dns_inet_pton(AF_INET6, ai->qname, &any.aaaa)) { - ai->state = DNS_AI_S_DONE; - - return dns_ai_setent(ent, &any, DNS_T_AAAA, ai); - } - - if (ai->hints.ai_flags & AI_NUMERICHOST) - dns_ai_goto(DNS_AI_S_DONE); - - ai->state++; - case DNS_AI_S_SUBMIT: - if ((error = dns_res_submit(ai->res, ai->qname, ai->qtype, DNS_C_IN))) - return error; - - ai->state++; - case DNS_AI_S_CHECK: - if ((error = dns_res_check(ai->res))) - return error; - - ai->state++; - case DNS_AI_S_FETCH: - if (!(ai->answer = dns_res_fetch(ai->res, &error))) - return error; - - if ((error = dns_p_study(ai->answer))) - return error; - - ai->glue = ai->answer; - - dns_rr_i_init(&ai->i, ai->answer); - - ai->i.section = DNS_S_AN; - ai->i.type = ai->qtype; - ai->i.sort = &dns_rr_i_order; - - ai->state++; - case DNS_AI_S_FOREACH_I: - /* Search generator may have changed our qname. */ - if (!(len = dns_d_expand(qname, sizeof qname, 12, ai->answer, &error))) - return error; - else if (len >= sizeof qname) - return DNS_EILLEGAL; - - if (!dns_d_cname(ai->cname, sizeof ai->cname, qname, strlen(qname), ai->answer, &error)) - return error; - - ai->i.name = ai->cname; - - if (!dns_rr_grep(&rr, 1, &ai->i, ai->answer, &error)) - dns_ai_goto(DNS_AI_S_DONE); - - if ((error = dns_any_parse(&any, &rr, ai->answer))) - return error; - - ai->port = ai->qport; - - switch (rr.type) { - case DNS_T_A: - case DNS_T_AAAA: - return dns_ai_setent(ent, &any, rr.type, ai); - default: - if (!dns_any_cname(ai->cname, sizeof ai->cname, &any, rr.type)) - dns_ai_goto(DNS_AI_S_FOREACH_I); - - /* - * Find the "real" canonical name. Some authorities - * publish aliases where an RFC defines a canonical - * name. We trust that the resolver followed any - * CNAME chains on it's own, regardless of whether - * the "smart" option is enabled. - */ - if (!dns_d_cname(ai->cname, sizeof ai->cname, ai->cname, strlen(ai->cname), ai->answer, &error)) - return error; - - if (rr.type == DNS_T_SRV) - ai->port = any.srv.port; - - break; - } /* switch() */ - - dns_rr_i_init(&ai->g, ai->glue); - - ai->g.section = DNS_S_ALL & ~DNS_S_QD; - ai->g.name = ai->cname; - ai->g.type = (ai->hints.ai_family == AF_INET6)? DNS_T_AAAA : DNS_T_A; - - ai->state++; - case DNS_AI_S_FOREACH_G: - if (!dns_rr_grep(&rr, 1, &ai->g, ai->glue, &error)) { - if (dns_rr_i_count(&ai->g) > 0) - dns_ai_goto(DNS_AI_S_FOREACH_I); - else - dns_ai_goto(DNS_AI_S_SUBMIT_G); - } - - if ((error = dns_any_parse(&any, &rr, ai->glue))) - return error; - - return dns_ai_setent(ent, &any, rr.type, ai); - case DNS_AI_S_SUBMIT_G: - if (dns_rr_grep(&rr, 1, dns_rr_i_new(ai->glue, .section = DNS_S_QD, .name = ai->g.name, .type = ai->g.type), ai->glue, &error)) - dns_ai_goto(DNS_AI_S_FOREACH_I); - - if ((error = dns_res_submit(ai->res, ai->g.name, ai->g.type, DNS_C_IN))) - return error; - - ai->state++; - case DNS_AI_S_CHECK_G: - if ((error = dns_res_check(ai->res))) - return error; - - ai->state++; - case DNS_AI_S_FETCH_G: - if (!(ans = dns_res_fetch(ai->res, &error))) - return error; - - dns_p_study(ans); - - glue = dns_p_merge(ai->glue, DNS_S_ALL, ans, DNS_S_ALL, &error); - - free(ans); - - if (!glue) - return error; - - if (ai->glue != ai->answer) - free(ai->glue); - - ai->glue = glue; - - dns_rr_i_init(&ai->g, ai->glue); - - /* ai->g.name should already point to ai->cname */ - if (!dns_d_cname(ai->cname, sizeof ai->cname, ai->cname, strlen(ai->cname), ai->glue, &error)) - dns_ai_goto(DNS_AI_S_FOREACH_I); - - /* NOTE: Keep all the other iterator filters */ - - dns_ai_goto(DNS_AI_S_FOREACH_G); - case DNS_AI_S_DONE: - return ENOENT; - default: - return EINVAL; - } /* switch() */ -} /* dns_ai_nextent() */ - - -time_t dns_ai_elapsed(struct dns_addrinfo *ai) { - return dns_res_elapsed(ai->res); -} /* dns_ai_elapsed() */ - - -void dns_ai_clear(struct dns_addrinfo *ai) { - return dns_res_clear(ai->res); -} /* dns_ai_clear() */ - - -int dns_ai_events(struct dns_addrinfo *ai) { - return dns_res_events(ai->res); -} /* dns_ai_events() */ - - -int dns_ai_pollfd(struct dns_addrinfo *ai) { - return dns_res_pollfd(ai->res); -} /* dns_ai_pollfd() */ - - -int dns_ai_poll(struct dns_addrinfo *ai, int timeout) { - return dns_res_poll(ai->res, timeout); -} /* dns_ai_poll() */ - - -size_t dns_ai_print(void *dst, size_t lim, struct addrinfo *ent, struct dns_addrinfo *ai) { - char addr[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1]; - size_t cp = 0; - - cp += dns__printstring(dst, lim, cp, "[ "); - cp += dns__printstring(dst, lim, cp, ai->qname); - cp += dns__printstring(dst, lim, cp, " IN "); - cp += dns__printstring(dst, lim, cp, dns_strtype(ai->qtype)); - cp += dns__printstring(dst, lim, cp, " ]\n"); - - cp += dns__printstring(dst, lim, cp, ".ai_family = "); - - switch (ent->ai_family) { - case AF_INET: - cp += dns__printstring(dst, lim, cp, "AF_INET"); - break; - case AF_INET6: - cp += dns__printstring(dst, lim, cp, "AF_INET6"); - break; - default: - cp += dns__print10(dst, lim, cp, ent->ai_family, 0); - break; - } - - cp += dns__printchar(dst, lim, cp, '\n'); - - cp += dns__printstring(dst, lim, cp, ".ai_socktype = "); - - switch (ent->ai_socktype) { - case SOCK_STREAM: - cp += dns__printstring(dst, lim, cp, "SOCK_STREAM"); - break; - case SOCK_DGRAM: - cp += dns__printstring(dst, lim, cp, "SOCK_DGRAM"); - break; - default: - cp += dns__print10(dst, lim, cp, ent->ai_socktype, 0); - break; - } - - cp += dns__printchar(dst, lim, cp, '\n'); - - cp += dns__printstring(dst, lim, cp, ".ai_addr = ["); - - dns_inet_ntop(dns_sa_family(ent->ai_addr), dns_sa_addr(dns_sa_family(ent->ai_addr), ent->ai_addr), addr, sizeof addr); - - cp += dns__printstring(dst, lim, cp, addr); - cp += dns__printstring(dst, lim, cp, "]:"); - - cp += dns__print10(dst, lim, cp, ntohs(*dns_sa_port(dns_sa_family(ent->ai_addr), ent->ai_addr)), 0); - cp += dns__printchar(dst, lim, cp, '\n'); - - cp += dns__printstring(dst, lim, cp, ".ai_canonname = "); - cp += dns__printstring(dst, lim, cp, (ent->ai_canonname)? ent->ai_canonname : "[NULL]"); - cp += dns__printchar(dst, lim, cp, '\n'); - - dns__printnul(dst, lim, cp); - - return cp; -} /* dns_ai_print() */ - - -const struct dns_stat *dns_ai_stat(struct dns_addrinfo *ai) { - return dns_res_stat(ai->res); -} /* dns_ai_stat() */ - - -/* - * M I S C E L L A N E O U S R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -static const struct { - char name[16]; - enum dns_section type; -} dns_sections[] = { - { "QUESTION", DNS_S_QUESTION }, - { "QD", DNS_S_QUESTION }, - { "ANSWER", DNS_S_ANSWER }, - { "AN", DNS_S_ANSWER }, - { "AUTHORITY", DNS_S_AUTHORITY }, - { "NS", DNS_S_AUTHORITY }, - { "ADDITIONAL", DNS_S_ADDITIONAL }, - { "AR", DNS_S_ADDITIONAL }, -}; - -const char *(dns_strsection)(enum dns_section section, void *dst, size_t lim) { - unsigned i, p = 0; - - for (i = 0; i < lengthof(dns_sections); i++) { - if (dns_sections[i].type & section) { - if (p > 0) - p += dns__printchar(dst, lim, p, '|'); - - p += dns__printstring(dst, lim, p, dns_sections[i].name); - - section &= ~dns_sections[i].type; - } - } - - if (!p) - p += dns__print10(dst, lim, 0, (0xffff & section), 0); - - dns__printnul(dst, lim, p); - - return dst; -} /* dns_strsection() */ - - -enum dns_section dns_isection(const char *src) { - enum dns_section section = 0; - char sbuf[128]; - char *name, *next; - unsigned i; - - dns_strlcpy(sbuf, src, sizeof sbuf); - next = sbuf; - - while ((name = dns_strsep(&next, "|+, \t"))) { - for (i = 0; i < lengthof(dns_sections); i++) { - if (!strcasecmp(dns_sections[i].name, name)) { - section |= dns_sections[i].type; - break; - } - } - } - - return section; -} /* dns_isection() */ - - -static const struct { - char name[8]; - enum dns_class type; -} dns_classes[] = { - { "IN", DNS_C_IN }, -}; - -const char *(dns_strclass)(enum dns_class type, void *dst, size_t lim) { - unsigned i; - - for (i = 0; i < lengthof(dns_classes); i++) { - if (dns_classes[i].type == type) { - dns__printnul(dst, lim, dns__printstring(dst, lim, 0, dns_classes[i].name)); - - return dst; - } - } - - dns__printnul(dst, lim, dns__print10(dst, lim, 0, (0xffff & type), 0)); - - return dst; -} /* dns_strclass() */ - - -enum dns_class dns_iclass(const char *name) { - unsigned i; - - for (i = 0; i < lengthof(dns_classes); i++) { - if (!strcasecmp(dns_classes[i].name, name)) - return dns_classes[i].type; - } - - return 0; -} /* dns_iclass() */ - - -const char *(dns_strtype)(enum dns_type type, void *dst, size_t lim) { - unsigned i; - - for (i = 0; i < lengthof(dns_rrtypes); i++) { - if (dns_rrtypes[i].type == type) { - dns__printnul(dst, lim, dns__printstring(dst, lim, 0, dns_rrtypes[i].name)); - - return dst; - } - } - - dns__printnul(dst, lim, dns__print10(dst, lim, 0, (0xffff & type), 0)); - - return dst; -} /* dns_strtype() */ - - -enum dns_type dns_itype(const char *type) { - unsigned i; - - for (i = 0; i < lengthof(dns_rrtypes); i++) { - if (!strcasecmp(dns_rrtypes[i].name, type)) - return dns_rrtypes[i].type; - } - - return 0; -} /* dns_itype() */ - - -static char dns_opcodes[16][16] = { - [DNS_OP_QUERY] = "QUERY", - [DNS_OP_IQUERY] = "IQUERY", - [DNS_OP_STATUS] = "STATUS", - [DNS_OP_NOTIFY] = "NOTIFY", - [DNS_OP_UPDATE] = "UPDATE", -}; - -const char *dns_stropcode(enum dns_opcode opcode) { - opcode &= 0xf; - - if ('\0' == dns_opcodes[opcode][0]) - dns__printnul(dns_opcodes[opcode], sizeof dns_opcodes[opcode], dns__print10(dns_opcodes[opcode], sizeof dns_opcodes[opcode], 0, opcode, 0)); - - return dns_opcodes[opcode]; -} /* dns_stropcode() */ - - -enum dns_opcode dns_iopcode(const char *name) { - unsigned opcode; - - for (opcode = 0; opcode < lengthof(dns_opcodes); opcode++) { - if (!strcasecmp(name, dns_opcodes[opcode])) - return opcode; - } - - return lengthof(dns_opcodes) - 1; -} /* dns_iopcode() */ - - -static char dns_rcodes[16][16] = { - [DNS_RC_NOERROR] = "NOERROR", - [DNS_RC_FORMERR] = "FORMERR", - [DNS_RC_SERVFAIL] = "SERVFAIL", - [DNS_RC_NXDOMAIN] = "NXDOMAIN", - [DNS_RC_NOTIMP] = "NOTIMP", - [DNS_RC_REFUSED] = "REFUSED", - [DNS_RC_YXDOMAIN] = "YXDOMAIN", - [DNS_RC_YXRRSET] = "YXRRSET", - [DNS_RC_NXRRSET] = "NXRRSET", - [DNS_RC_NOTAUTH] = "NOTAUTH", - [DNS_RC_NOTZONE] = "NOTZONE", -}; - -const char *dns_strrcode(enum dns_rcode rcode) { - rcode &= 0xf; - - if ('\0' == dns_rcodes[rcode][0]) - dns__printnul(dns_rcodes[rcode], sizeof dns_rcodes[rcode], dns__print10(dns_rcodes[rcode], sizeof dns_rcodes[rcode], 0, rcode, 0)); - - return dns_rcodes[rcode]; -} /* dns_strrcode() */ - - -enum dns_rcode dns_ircode(const char *name) { - unsigned rcode; - - for (rcode = 0; rcode < lengthof(dns_rcodes); rcode++) { - if (!strcasecmp(name, dns_rcodes[rcode])) - return rcode; - } - - return lengthof(dns_rcodes) - 1; -} /* dns_ircode() */ - - -/* - * C O M M A N D - L I N E / R E G R E S S I O N R O U T I N E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#if DNS_MAIN - -#include -#include -#include - -#include - -#if _WIN32 -#include -#endif - -#if !_WIN32 -#include -#endif - - -struct { - struct { - const char *path[8]; - unsigned count; - } resconf; - - struct { - const char *path[8]; - unsigned count; - } hosts; - - struct { - const char *path[8]; - unsigned count; - } cache; - - const char *qname; - enum dns_type qtype; - - int (*sort)(); - - int verbose; -} MAIN = { - .sort = &dns_rr_i_packet, -}; - - -void hexdump(const unsigned char *src, size_t len, FILE *fp) { - static const unsigned char hex[] = "0123456789abcdef"; - static const unsigned char tmpl[] = " | |\n"; - unsigned char ln[sizeof tmpl]; - const unsigned char *sp, *se; - unsigned char *h, *g; - unsigned i, n; - - sp = src; - se = sp + len; - - while (sp < se) { - memcpy(ln, tmpl, sizeof ln); - - h = &ln[2]; - g = &ln[53]; - - for (n = 0; n < 2; n++) { - for (i = 0; i < 8 && se - sp > 0; i++, sp++) { - h[0] = hex[0x0f & (*sp >> 4)]; - h[1] = hex[0x0f & (*sp >> 0)]; - h += 3; - - *g++ = (isgraph(*sp))? *sp : '.'; - } - - h++; - } - - fputs((char *)ln, fp); - } - - return /* void */; -} /* hexdump() */ - - -static void panic(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - -#if _WIN32 - vfprintf(stderr, fmt, ap); - - exit(EXIT_FAILURE); -#else - verrx(EXIT_FAILURE, fmt, ap); -#endif -} /* panic() */ - -#define panic_(fn, ln, fmt, ...) \ - panic(fmt "%0s", (fn), (ln), __VA_ARGS__) -#define panic(...) \ - panic_(__func__, __LINE__, "(%s:%d) " __VA_ARGS__, "") - - -static void *grow(unsigned char *p, size_t size) { - void *tmp; - - if (!(tmp = realloc(p, size))) - panic("realloc(%zu): %s", size, dns_strerror(errno)); - - return tmp; -} /* grow() */ - - -static size_t add(size_t a, size_t b) { - if (~a < b) - panic("%zu + %zu: integer overflow", a, b); - - return a + b; -} /* add() */ - - -static size_t append(unsigned char **dst, size_t osize, const void *src, size_t len) { - size_t size = add(osize, len); - - *dst = grow(*dst, size); - memcpy(*dst + osize, src, len); - - return size; -} /* append() */ - - -static size_t slurp(unsigned char **dst, size_t osize, FILE *fp, const char *path) { - size_t size = osize; - unsigned char buf[1024]; - size_t count; - - while ((count = fread(buf, 1, sizeof buf, fp))) - size = append(dst, size, buf, count); - - if (ferror(fp)) - panic("%s: %s", path, dns_strerror(errno)); - - return size; -} /* slurp() */ - - -static struct dns_resolv_conf *resconf(void) { - static struct dns_resolv_conf *resconf; - const char *path; - unsigned i; - int error; - - if (resconf) - return resconf; - - if (!(resconf = dns_resconf_open(&error))) - panic("dns_resconf_open: %s", dns_strerror(error)); - - if (!MAIN.resconf.count) - MAIN.resconf.path[MAIN.resconf.count++] = "/etc/resolv.conf"; - - for (i = 0; i < MAIN.resconf.count; i++) { - path = MAIN.resconf.path[i]; - - if (0 == strcmp(path, "-")) - error = dns_resconf_loadfile(resconf, stdin); - else - error = dns_resconf_loadpath(resconf, path); - - if (error) - panic("%s: %s", path, dns_strerror(error)); - } - - return resconf; -} /* resconf() */ - - -static struct dns_hosts *hosts(void) { - static struct dns_hosts *hosts; - const char *path; - unsigned i; - int error; - - if (hosts) - return hosts; - - if (!MAIN.hosts.count) { - MAIN.hosts.path[MAIN.hosts.count++] = "/etc/hosts"; - - /* Explicitly test dns_hosts_local() */ - if (!(hosts = dns_hosts_local(&error))) - panic("%s: %s", "/etc/hosts", dns_strerror(error)); - - return hosts; - } - - if (!(hosts = dns_hosts_open(&error))) - panic("dns_hosts_open: %s", dns_strerror(error)); - - for (i = 0; i < MAIN.hosts.count; i++) { - path = MAIN.hosts.path[i]; - - if (0 == strcmp(path, "-")) - error = dns_hosts_loadfile(hosts, stdin); - else - error = dns_hosts_loadpath(hosts, path); - - if (error) - panic("%s: %s", path, dns_strerror(error)); - } - - return hosts; -} /* hosts() */ - - -#if DNS_CACHE -#include "cache.h" - -struct dns_cache *cache(void) { - static struct cache *cache; - const char *path; - unsigned i; - int error; - - if (cache) - return cache_resi(cache); - if (!MAIN.cache.count) - return NULL; - - if (!(cache = cache_open(&error))) - panic("%s: %s", MAIN.cache.path[0], dns_strerror(error)); - - for (i = 0; i < MAIN.cache.count; i++) { - path = MAIN.cache.path[i]; - - if (!strcmp(path, "-")) { - if ((error = cache_loadfile(cache, stdin, NULL, 0))) - panic("%s: %s", path, dns_strerror(error)); - } else if ((error = cache_loadpath(cache, path, NULL, 0))) - panic("%s: %s", path, dns_strerror(error)); - } - - return cache_resi(cache); -} /* cache() */ -#else -struct dns_cache *cache(void) { return NULL; } -#endif - - -static void print_packet(struct dns_packet *P, FILE *fp) { - dns_p_dump3(P, dns_rr_i_new(P, .sort = MAIN.sort), fp); - - if (MAIN.verbose > 2) - hexdump(P->data, P->end, fp); -} /* print_packet() */ - - -static int parse_packet(int argc, char *argv[]) { - struct dns_packet *P = dns_p_new(512); - struct dns_packet *Q = dns_p_new(512); - enum dns_section section; - struct dns_rr rr; - int error; - union dns_any any; - char pretty[sizeof any * 2]; - size_t len; - - P->end = fread(P->data, 1, P->size, stdin); - - fputs(";; [HEADER]\n", stdout); - fprintf(stdout, ";; qr : %s(%d)\n", (dns_header(P)->qr)? "QUERY" : "RESPONSE", dns_header(P)->qr); - fprintf(stdout, ";; opcode : %s(%d)\n", dns_stropcode(dns_header(P)->opcode), dns_header(P)->opcode); - fprintf(stdout, ";; aa : %s(%d)\n", (dns_header(P)->aa)? "AUTHORITATIVE" : "NON-AUTHORITATIVE", dns_header(P)->aa); - fprintf(stdout, ";; tc : %s(%d)\n", (dns_header(P)->tc)? "TRUNCATED" : "NOT-TRUNCATED", dns_header(P)->tc); - fprintf(stdout, ";; rd : %s(%d)\n", (dns_header(P)->rd)? "RECURSION-DESIRED" : "RECURSION-NOT-DESIRED", dns_header(P)->rd); - fprintf(stdout, ";; ra : %s(%d)\n", (dns_header(P)->ra)? "RECURSION-ALLOWED" : "RECURSION-NOT-ALLOWED", dns_header(P)->ra); - fprintf(stdout, ";; rcode : %s(%d)\n", dns_strrcode(dns_header(P)->rcode), dns_header(P)->rcode); - - section = 0; - - dns_rr_foreach(&rr, P, .sort = MAIN.sort) { - if (section != rr.section) - fprintf(stdout, "\n;; [%s:%d]\n", dns_strsection(rr.section), dns_p_count(P, rr.section)); - - if ((len = dns_rr_print(pretty, sizeof pretty, &rr, P, &error))) - fprintf(stdout, "%s\n", pretty); - - dns_rr_copy(Q, &rr, P); - - section = rr.section; - } - - fputs("; ; ; ; ; ; ; ;\n\n", stdout); - - section = 0; - -#if 0 - dns_rr_foreach(&rr, Q, .name = "ns8.yahoo.com.") { -#else - struct dns_rr rrset[32]; - struct dns_rr_i *rri = dns_rr_i_new(Q, .name = dns_d_new("ns8.yahoo.com", DNS_D_ANCHOR), .sort = MAIN.sort); - unsigned rrcount = dns_rr_grep(rrset, lengthof(rrset), rri, Q, &error); - unsigned i; - - for (i = 0; i < rrcount; i++) { - rr = rrset[i]; -#endif - if (section != rr.section) - fprintf(stdout, "\n;; [%s:%d]\n", dns_strsection(rr.section), dns_p_count(Q, rr.section)); - - if ((len = dns_rr_print(pretty, sizeof pretty, &rr, Q, &error))) - fprintf(stdout, "%s\n", pretty); - - section = rr.section; - } - - if (MAIN.verbose > 1) { - fprintf(stderr, "orig:%zu\n", P->end); - hexdump(P->data, P->end, stdout); - - fprintf(stderr, "copy:%zu\n", Q->end); - hexdump(Q->data, Q->end, stdout); - } - - return 0; -} /* parse_packet() */ - - -static int parse_domain(int argc, char *argv[]) { - char *dn; - - dn = (argc > 1)? argv[1] : "f.l.google.com"; - - printf("[%s]\n", dn); - - dn = dns_d_new(dn); - - do { - puts(dn); - } while (dns_d_cleave(dn, strlen(dn) + 1, dn, strlen(dn))); - - return 0; -} /* parse_domain() */ - - -static int expand_domain(int argc, char *argv[]) { - unsigned short rp = 0; - unsigned char *src = NULL; - unsigned char *dst; - struct dns_packet *pkt; - size_t lim = 0, len; - int error; - - if (argv[1]) - rp = atoi(argv[1]); - - len = slurp(&src, 0, stdin, "-"); - - if (!(pkt = dns_p_make(len, &error))) - panic("malloc(%zu): %s", len, dns_strerror(error)); - - memcpy(pkt->data, src, len); - pkt->end = len; - - lim = 1; - dst = grow(NULL, lim); - - while (lim <= (len = dns_d_expand(dst, lim, rp, pkt, &error))) { - lim = add(len, 1); - dst = grow(dst, lim); - } - - if (!len) - panic("expand: %s", dns_strerror(error)); - - fwrite(dst, 1, len, stdout); - fflush(stdout); - - free(src); - free(dst); - free(pkt); - - return 0; -} /* expand_domain() */ - - -static int show_resconf(int argc, char *argv[]) { - unsigned i; - - resconf(); /* load it */ - - fputs("; SOURCES\n", stdout); - - for (i = 0; i < MAIN.resconf.count; i++) - fprintf(stdout, "; %s\n", MAIN.resconf.path[i]); - - fputs(";\n", stdout); - - dns_resconf_dump(resconf(), stdout); - - return 0; -} /* show_resconf() */ - - -static int show_hosts(int argc, char *argv[]) { - unsigned i; - - hosts(); - - fputs("# SOURCES\n", stdout); - - for (i = 0; i < MAIN.hosts.count; i++) - fprintf(stdout, "# %s\n", MAIN.hosts.path[i]); - - fputs("#\n", stdout); - - dns_hosts_dump(hosts(), stdout); - - return 0; -} /* show_hosts() */ - - -static int query_hosts(int argc, char *argv[]) { - struct dns_packet *Q = dns_p_new(512); - struct dns_packet *A; - char qname[DNS_D_MAXNAME + 1]; - size_t qlen; - int error; - - if (!MAIN.qname) - MAIN.qname = (argc > 1)? argv[1] : "localhost"; - if (!MAIN.qtype) - MAIN.qtype = DNS_T_A; - - hosts(); - - if (MAIN.qtype == DNS_T_PTR && !strstr(MAIN.qname, "arpa")) { - union { struct in_addr a; struct in6_addr a6; } addr; - int af = (strchr(MAIN.qname, ':'))? AF_INET6 : AF_INET; - - if (1 != dns_inet_pton(af, MAIN.qname, &addr)) - panic("%s: %s", MAIN.qname, dns_strerror(error)); - - qlen = dns_ptr_qname(qname, sizeof qname, af, &addr); - } else - qlen = dns__printstring(qname, sizeof qname, 0, MAIN.qname); - - if ((error = dns_p_push(Q, DNS_S_QD, qname, qlen, MAIN.qtype, DNS_C_IN, 0, 0))) - panic("%s: %s", qname, dns_strerror(error)); - - if (!(A = dns_hosts_query(hosts(), Q, &error))) - panic("%s: %s", qname, dns_strerror(error)); - - print_packet(A, stdout); - - free(A); - - return 0; -} /* query_hosts() */ - - -static int search_list(int argc, char *argv[]) { - const char *qname = (argc > 1)? argv[1] : "f.l.google.com"; - unsigned long i = 0; - char name[DNS_D_MAXNAME + 1]; - - printf("[%s]\n", qname); - - while (dns_resconf_search(name, sizeof name, qname, strlen(qname), resconf(), &i)) - puts(name); - - return 0; -} /* search_list() */ - - -int permute_set(int argc, char *argv[]) { - unsigned lo, hi, i; - struct dns_k_permutor p; - - hi = (--argc > 0)? atoi(argv[argc]) : 8; - lo = (--argc > 0)? atoi(argv[argc]) : 0; - - fprintf(stderr, "[%u .. %u]\n", lo, hi); - - dns_k_permutor_init(&p, lo, hi); - - for (i = lo; i <= hi; i++) - fprintf(stdout, "%u\n", dns_k_permutor_step(&p)); -// printf("%u -> %u -> %u\n", i, dns_k_permutor_E(&p, i), dns_k_permutor_D(&p, dns_k_permutor_E(&p, i))); - - return 0; -} /* permute_set() */ - - -int shuffle_16(int argc, char *argv[]) { - unsigned n, r; - - if (--argc > 0) { - n = 0xffff & atoi(argv[argc]); - r = (--argc > 0)? (unsigned)atoi(argv[argc]) : dns_random(); - - fprintf(stdout, "%hu\n", dns_k_shuffle16(n, r)); - } else { - r = dns_random(); - - for (n = 0; n < 65536; n++) - fprintf(stdout, "%hu\n", dns_k_shuffle16(n, r)); - } - - return 0; -} /* shuffle_16() */ - - -int dump_random(int argc, char *argv[]) { - unsigned char b[32]; - unsigned i, j, n, r; - - n = (argc > 1)? atoi(argv[1]) : 32; - - while (n) { - i = 0; - - do { - r = dns_random(); - - for (j = 0; j < sizeof r && i < n && i < sizeof b; i++, j++) { - b[i] = 0xff & r; - r >>= 8; - } - } while (i < n && i < sizeof b); - - hexdump(b, i, stdout); - - n -= i; - } - - return 0; -} /* dump_random() */ - - -static int send_query(int argc, char *argv[]) { - struct dns_packet *A, *Q = dns_p_new(512); - char host[INET6_ADDRSTRLEN + 1]; - struct sockaddr_storage ss; - struct dns_socket *so; - int error, type; - - if (argc > 1) { - ss.ss_family = (strchr(argv[1], ':'))? AF_INET6 : AF_INET; - - if (1 != dns_inet_pton(ss.ss_family, argv[1], dns_sa_addr(ss.ss_family, &ss))) - panic("%s: invalid host address", argv[1]); - - *dns_sa_port(ss.ss_family, &ss) = htons(53); - } else - memcpy(&ss, &resconf()->nameserver[0], dns_sa_len(&resconf()->nameserver[0])); - - if (!dns_inet_ntop(ss.ss_family, dns_sa_addr(ss.ss_family, &ss), host, sizeof host)) - panic("bad host address, or none provided"); - - if (!MAIN.qname) - MAIN.qname = "ipv6.google.com"; - if (!MAIN.qtype) - MAIN.qtype = DNS_T_AAAA; - - if ((error = dns_p_push(Q, DNS_S_QD, MAIN.qname, strlen(MAIN.qname), MAIN.qtype, DNS_C_IN, 0, 0))) - panic("dns_p_push: %s", dns_strerror(error)); - - dns_header(Q)->rd = 1; - - if (strstr(argv[0], "udp")) - type = SOCK_DGRAM; - else if (strstr(argv[0], "tcp")) - type = SOCK_STREAM; - else - type = dns_res_tcp2type(resconf()->options.tcp); - - fprintf(stderr, "querying %s for %s IN %s\n", host, MAIN.qname, dns_strtype(MAIN.qtype)); - - if (!(so = dns_so_open((struct sockaddr *)&resconf()->iface, type, dns_opts(), &error))) - panic("dns_so_open: %s", dns_strerror(error)); - - while (!(A = dns_so_query(so, Q, (struct sockaddr *)&ss, &error))) { - if (error != EAGAIN) - panic("dns_so_query: %s (%d)", dns_strerror(error), error); - if (dns_so_elapsed(so) > 10) - panic("query timed-out"); - - dns_so_poll(so, 1); - } - - print_packet(A, stdout); - - dns_so_close(so); - - return 0; -} /* send_query() */ - - -static int print_arpa(int argc, char *argv[]) { - const char *ip = (argc > 1)? argv[1] : "::1"; - int af = (strchr(ip, ':'))? AF_INET6 : AF_INET; - union { struct in_addr a4; struct in6_addr a6; } addr; - char host[DNS_D_MAXNAME + 1]; - - if (1 != dns_inet_pton(af, ip, &addr) || 0 == dns_ptr_qname(host, sizeof host, af, &addr)) - panic("%s: invalid address", ip); - - fprintf(stdout, "%s\n", host); - - return 0; -} /* print_arpa() */ - - -static int show_hints(int argc, char *argv[]) { - struct dns_hints *(*load)(struct dns_resolv_conf *, int *); - const char *which, *how, *who; - struct dns_hints *hints; - int error; - - which = (argc > 1)? argv[1] : "local"; - how = (argc > 2)? argv[2] : "plain"; - who = (argc > 3)? argv[3] : "google.com"; - - load = (0 == strcmp(which, "local")) - ? &dns_hints_local - : &dns_hints_root; - - if (!(hints = load(resconf(), &error))) - panic("%s: %s", argv[0], dns_strerror(error)); - - if (0 == strcmp(how, "plain")) { - dns_hints_dump(hints, stdout); - } else { - struct dns_packet *query, *answer; - - query = dns_p_new(512); - - if ((error = dns_p_push(query, DNS_S_QUESTION, who, strlen(who), DNS_T_A, DNS_C_IN, 0, 0))) - panic("%s: %s", who, dns_strerror(error)); - - if (!(answer = dns_hints_query(hints, query, &error))) - panic("%s: %s", who, dns_strerror(error)); - - print_packet(answer, stdout); - - free(answer); - } - - dns_hints_close(hints); - - return 0; -} /* show_hints() */ - - -static int resolve_query(int argc, char *argv[]) { - struct dns_hints *(*hints)() = (strstr(argv[0], "recurse"))? &dns_hints_root : &dns_hints_local; - struct dns_resolver *R; - struct dns_packet *ans; - const struct dns_stat *st; - int error; - - if (!MAIN.qname) - MAIN.qname = "www.google.com"; - if (!MAIN.qtype) - MAIN.qtype = DNS_T_A; - - resconf()->options.recurse = (0 != strstr(argv[0], "recurse")); - - if (!(R = dns_res_open(resconf(), hosts(), dns_hints_mortal(hints(resconf(), &error)), cache(), dns_opts(), &error))) - panic("%s: %s", MAIN.qname, dns_strerror(error)); - - if ((error = dns_res_submit(R, MAIN.qname, MAIN.qtype, DNS_C_IN))) - panic("%s: %s", MAIN.qname, dns_strerror(error)); - - while ((error = dns_res_check(R))) { - if (error != EAGAIN) - panic("dns_res_check: %s (%d)", dns_strerror(error), error); - if (dns_res_elapsed(R) > 30) - panic("query timed-out"); - - dns_res_poll(R, 1); - } - - ans = dns_res_fetch(R, &error); - print_packet(ans, stdout); - free(ans); - - st = dns_res_stat(R); - putchar('\n'); - printf(";; queries: %zu\n", st->queries); - printf(";; udp sent: %zu in %zu bytes\n", st->udp.sent.count, st->udp.sent.bytes); - printf(";; udp rcvd: %zu in %zu bytes\n", st->udp.rcvd.count, st->udp.rcvd.bytes); - printf(";; tcp sent: %zu in %zu bytes\n", st->tcp.sent.count, st->tcp.sent.bytes); - printf(";; tcp rcvd: %zu in %zu bytes\n", st->tcp.rcvd.count, st->tcp.rcvd.bytes); - - dns_res_close(R); - - return 0; -} /* resolve_query() */ - - -static int resolve_addrinfo(int argc, char *argv[]) { - struct dns_hints *(*hints)() = (strstr(argv[0], "recurse"))? &dns_hints_root : &dns_hints_local; - struct dns_resolver *res = 0; - struct dns_addrinfo *ai = 0; - struct addrinfo ai_hints = { .ai_family = PF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_flags = AI_CANONNAME }; - struct addrinfo *ent; - char pretty[512]; - int error; - - if (!MAIN.qname) - MAIN.qname = "www.google.com"; - if (!MAIN.qtype) - MAIN.qtype = DNS_T_A; - - resconf()->options.recurse = (0 != strstr(argv[0], "recurse")); - - if (!(res = dns_res_open(resconf(), hosts(), dns_hints_mortal(hints(resconf(), &error)), cache(), dns_opts(), &error))) - panic("%s: %s", MAIN.qname, dns_strerror(error)); - - if (!(ai = dns_ai_open(MAIN.qname, "80", MAIN.qtype, &ai_hints, res, &error))) - panic("%s: %s", MAIN.qname, dns_strerror(error)); - - do { - switch (error = dns_ai_nextent(&ent, ai)) { - case 0: - dns_ai_print(pretty, sizeof pretty, ent, ai); - - fputs(pretty, stdout); - - free(ent); - - break; - case ENOENT: - break; - case EAGAIN: - if (dns_ai_elapsed(ai) > 30) - panic("query timed-out"); - - dns_ai_poll(ai, 1); - - break; - default: - panic("dns_ai_nextent: %s (%d)", dns_strerror(error), error); - } - } while (error != ENOENT); - - dns_res_close(res); - dns_ai_close(ai); - - return 0; -} /* resolve_addrinfo() */ - - -static int echo_port(int argc, char *argv[]) { - union { - struct sockaddr sa; - struct sockaddr_in sin; - } port; - int fd; - - memset(&port, 0, sizeof port); - port.sin.sin_family = AF_INET; - port.sin.sin_port = htons(5354); - port.sin.sin_addr.s_addr = inet_addr("127.0.0.1"); - - if (-1 == (fd = socket(PF_INET, SOCK_DGRAM, 0))) - panic("socket: %s", strerror(errno)); - - if (0 != bind(fd, &port.sa, sizeof port.sa)) - panic("127.0.0.1:5353: %s", dns_strerror(errno)); - - for (;;) { - struct dns_packet *pkt = dns_p_new(512); - struct sockaddr_storage ss; - socklen_t slen = sizeof ss; - ssize_t count; -#if defined(MSG_WAITALL) /* MinGW issue */ - int rflags = MSG_WAITALL; -#else - int rflags = 0; -#endif - - count = recvfrom(fd, (char *)pkt->data, pkt->size, rflags, (struct sockaddr *)&ss, &slen); - - - if (!count || count < 0) - panic("recvfrom: %s", strerror(errno)); - - pkt->end = count; - - dns_p_dump(pkt, stdout); - - (void)sendto(fd, (char *)pkt->data, pkt->end, 0, (struct sockaddr *)&ss, slen); - } - - return 0; -} /* echo_port() */ - - -static int isection(int argc, char *argv[]) { - const char *name = (argv[1])? argv[1] : ""; - int type; - - type = dns_isection(name); - name = dns_strsection(type); - - printf("%s (%d)\n", name, type); - - return 0; -} /* isection() */ - - -static int iclass(int argc, char *argv[]) { - const char *name = (argv[1])? argv[1] : ""; - int type; - - type = dns_iclass(name); - name = dns_strclass(type); - - printf("%s (%d)\n", name, type); - - return 0; -} /* iclass() */ - - -static int itype(int argc, char *argv[]) { - const char *name = (argv[1])? argv[1] : ""; - int type; - - type = dns_itype(name); - name = dns_strtype(type); - - printf("%s (%d)\n", name, type); - - return 0; -} /* itype() */ - - -static int iopcode(int argc, char *argv[]) { - const char *name = (argv[1])? argv[1] : ""; - int type; - - type = dns_iopcode(name); - name = dns_stropcode(type); - - printf("%s (%d)\n", name, type); - - return 0; -} /* iopcode() */ - - -static int ircode(int argc, char *argv[]) { - const char *name = (argv[1])? argv[1] : ""; - int type; - - type = dns_ircode(name); - name = dns_strrcode(type); - - printf("%s (%d)\n", name, type); - - return 0; -} /* ircode() */ - - -#define SIZE1(x) { DNS_PP_STRINGIFY(x), sizeof (x) } -#define SIZE2(x, ...) SIZE1(x), SIZE1(__VA_ARGS__) -#define SIZE3(x, ...) SIZE1(x), SIZE2(__VA_ARGS__) -#define SIZE4(x, ...) SIZE1(x), SIZE3(__VA_ARGS__) -#define SIZE(...) DNS_PP_CALL(DNS_PP_XPASTE(SIZE, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) - -static int sizes(int argc, char *argv[]) { - static const struct { const char *name; size_t size; } type[] = { - SIZE(struct dns_header, struct dns_packet, struct dns_rr, struct dns_rr_i), - SIZE(struct dns_a, struct dns_aaaa, struct dns_mx, struct dns_ns), - SIZE(struct dns_cname, struct dns_soa, struct dns_ptr, struct dns_srv), - SIZE(struct dns_sshfp, struct dns_txt, union dns_any), - SIZE(struct dns_resolv_conf, struct dns_hosts, struct dns_hints, struct dns_hints_i), - SIZE(struct dns_options, struct dns_socket, struct dns_resolver, struct dns_addrinfo), - SIZE(struct dns_cache), - }; - unsigned i, max; - - for (i = 0, max = 0; i < lengthof(type); i++) - max = MAX(max, strlen(type[i].name)); - - for (i = 0; i < lengthof(type); i++) - printf("%*s : %zu\n", max, type[i].name, type[i].size); - - return 0; -} /* sizes() */ - - -static const struct { const char *cmd; int (*run)(); const char *help; } cmds[] = { - { "parse-packet", &parse_packet, "parse binary packet from stdin" }, - { "parse-domain", &parse_domain, "anchor and iteratively cleave domain" }, - { "expand-domain", &expand_domain, "expand domain at offset NN in packet from stdin" }, - { "show-resconf", &show_resconf, "show resolv.conf data" }, - { "show-hosts", &show_hosts, "show hosts data" }, - { "query-hosts", &query_hosts, "query A, AAAA or PTR in hosts data" }, - { "search-list", &search_list, "generate query search list from domain" }, - { "permute-set", &permute_set, "generate random permutation -> (0 .. N or N .. M)" }, - { "shuffle-16", &shuffle_16, "simple 16-bit permutation" }, - { "dump-random", &dump_random, "generate random bytes" }, - { "send-query", &send_query, "send query to host" }, - { "send-query-udp", &send_query, "send udp query to host" }, - { "send-query-tcp", &send_query, "send tcp query to host" }, - { "print-arpa", &print_arpa, "print arpa. zone name of address" }, - { "show-hints", &show_hints, "print hints: show-hints [local|root] [plain|packet]" }, - { "resolve-stub", &resolve_query, "resolve as stub resolver" }, - { "resolve-recurse", &resolve_query, "resolve as recursive resolver" }, - { "addrinfo-stub", &resolve_addrinfo, "resolve through getaddrinfo clone" }, - { "addrinfo-recurse", &resolve_addrinfo, "resolve through getaddrinfo clone" }, -/* { "resolve-nameinfo", &resolve_query, "resolve as recursive resolver" }, */ - { "echo", &echo_port, "server echo mode, for nmap fuzzing" }, - { "isection", &isection, "parse section string" }, - { "iclass", &iclass, "parse class string" }, - { "itype", &itype, "parse type string" }, - { "iopcode", &iopcode, "parse opcode string" }, - { "ircode", &ircode, "parse rcode string" }, - { "sizes", &sizes, "print data structure sizes" }, -}; - - -static void print_usage(const char *progname, FILE *fp) { - static const char *usage = - " [OPTIONS] COMMAND [ARGS]\n" - " -c PATH Path to resolv.conf\n" - " -l PATH Path to local hosts\n" - " -z PATH Path to zone cache\n" - " -q QNAME Query name\n" - " -t QTYPE Query type\n" - " -s HOW Sort records\n" - " -v Be more verbose (-vv show packets; -vvv hexdump packets)\n" - " -V Print version info\n" - " -h Print this usage message\n" - "\n"; - unsigned i, n, m; - - fputs(progname, fp); - fputs(usage, fp); - - for (i = 0, m = 0; i < lengthof(cmds); i++) { - if (strlen(cmds[i].cmd) > m) - m = strlen(cmds[i].cmd); - } - - for (i = 0; i < lengthof(cmds); i++) { - fprintf(fp, " %s ", cmds[i].cmd); - - for (n = strlen(cmds[i].cmd); n < m; n++) - putc(' ', fp); - - fputs(cmds[i].help, fp); - putc('\n', fp); - } - - fputs("\nReport bugs to William Ahern \n", fp); -} /* print_usage() */ - - -static void print_version(const char *progname, FILE *fp) { - fprintf(fp, "%s (dns.c) %.8X\n", progname, dns_v_rel()); - fprintf(fp, "vendor %s\n", dns_vendor()); - fprintf(fp, "release %.8X\n", dns_v_rel()); - fprintf(fp, "abi %.8X\n", dns_v_abi()); - fprintf(fp, "api %.8X\n", dns_v_api()); -} /* print_version() */ - - -int main(int argc, char **argv) { - extern int optind; - extern char *optarg; - const char *progname = argv[0]; - unsigned i; - int ch; - - while (-1 != (ch = getopt(argc, argv, "q:t:c:l:z:s:vVh"))) { - switch (ch) { - case 'c': - assert(MAIN.resconf.count < lengthof(MAIN.resconf.path)); - - MAIN.resconf.path[MAIN.resconf.count++] = optarg; - - break; - case 'l': - assert(MAIN.hosts.count < lengthof(MAIN.hosts.path)); - - MAIN.hosts.path[MAIN.hosts.count++] = optarg; - - break; - case 'z': - assert(MAIN.cache.count < lengthof(MAIN.cache.path)); - - MAIN.cache.path[MAIN.cache.count++] = optarg; - - break; - case 'q': - MAIN.qname = optarg; - - break; - case 't': - for (i = 0; i < lengthof(dns_rrtypes); i++) { - if (0 == strcasecmp(dns_rrtypes[i].name, optarg)) - { MAIN.qtype = dns_rrtypes[i].type; break; } - } - - if (MAIN.qtype) - break; - - for (i = 0; isdigit((int)optarg[i]); i++) { - MAIN.qtype *= 10; - MAIN.qtype += optarg[i] - '0'; - } - - if (!MAIN.qtype) - panic("%s: invalid query type", optarg); - - break; - case 's': - if (0 == strcasecmp(optarg, "packet")) - MAIN.sort = &dns_rr_i_packet; - else if (0 == strcasecmp(optarg, "shuffle")) - MAIN.sort = &dns_rr_i_shuffle; - else if (0 == strcasecmp(optarg, "order")) - MAIN.sort = &dns_rr_i_order; - else - panic("%s: invalid sort method", optarg); - - break; - case 'v': - dns_debug = ++MAIN.verbose; - - break; - case 'V': - print_version(progname, stdout); - - return 0; - case 'h': - print_usage(progname, stdout); - - return 0; - default: - print_usage(progname, stderr); - - return EXIT_FAILURE; - } /* switch() */ - } /* while() */ - - argc -= optind; - argv += optind; - - for (i = 0; i < lengthof(cmds) && argv[0]; i++) { - if (0 == strcmp(cmds[i].cmd, argv[0])) - return cmds[i].run(argc, argv); - } - - print_usage(progname, stderr); - - return EXIT_FAILURE; -} /* main() */ - - -#endif /* DNS_MAIN */ diff --git a/legacy/ecore/src/lib/ecore_con/dns.h b/legacy/ecore/src/lib/ecore_con/dns.h deleted file mode 100644 index f9213167e5..0000000000 --- a/legacy/ecore/src/lib/ecore_con/dns.h +++ /dev/null @@ -1,1076 +0,0 @@ -/* ========================================================================== - * dns.h - Recursive, Reentrant DNS Resolver. - * -------------------------------------------------------------------------- - * Copyright (c) 2009, 2010 William Ahern - * - * 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 or substantial portions of the Software. - * - * 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 OR COPYRIGHT HOLDERS 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. - * ========================================================================== - */ -#ifndef DNS_H -#define DNS_H - -#include /* size_t offsetof() */ -#include /* FILE */ - -#include /* strlen(3) */ - -#include /* time_t */ - -#if _WIN32 -#include -#include -#else -#include /* socklen_t */ -#include /* struct socket */ - -#include /* POLLIN POLLOUT */ - -#include /* struct in_addr struct in6_addr */ - -#include /* struct addrinfo */ -#endif - -#include /* EINA_UNUSED */ - - -/* - * V E R S I O N - * - * Vendor: Entity for which versions numbers are relevant. (If forking - * change DNS_VENDOR to avoid confusion.) - * - * Three versions: - * - * REL Official "release"--bug fixes, new features, etc. - * ABI Changes to existing object sizes or parameter types. - * API Changes that might effect application source. - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#define DNS_VENDOR "william@25thandClement.com" - -#define DNS_V_REL 0x20110117 -#define DNS_V_ABI 0x20100709 -#define DNS_V_API 0x20100709 - - -const char *dns_vendor(void); - -int dns_v_rel(void); -int dns_v_abi(void); -int dns_v_api(void); - - -/* - * E R R O R S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -enum dns_errno { - DNS_ENOBUFS = -(('d' << 24) | ('n' << 16) | ('s' << 8) | 64), - DNS_EILLEGAL, - DNS_EORDER, - DNS_ESECTION, - DNS_EUNKNOWN, -}; /* dns_errno */ - -const char *dns_strerror(int); - -extern int dns_debug; - - -/* - * E V E N T S I N T E R F A C E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#if defined(POLLIN) -#define DNS_POLLIN POLLIN -#else -#define DNS_POLLIN 1 -#endif - -#if defined(POLLOUT) -#define DNS_POLLOUT POLLOUT -#else -#define DNS_POLLOUT 2 -#endif - - -/* - * See Application Interface below for configuring libevent bitmasks instead - * of poll(2) bitmasks. - */ -#define DNS_EVREAD 2 -#define DNS_EVWRITE 4 - - -#define DNS_POLL2EV(set) \ - (((set) & DNS_POLLIN)? DNS_EVREAD : 0) | (((set) & DNS_POLLOUT)? DNS_EVWRITE : 0) - -#define DNS_EV2POLL(set) \ - (((set) & DNS_EVREAD)? DNS_POLLIN : 0) | (((set) & DNS_EVWRITE)? DNS_POLLOUT : 0) - - -/* - * E N U M E R A T I O N I N T E R F A C E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -enum dns_section { - DNS_S_QD = 0x01, -#define DNS_S_QUESTION DNS_S_QD - - DNS_S_AN = 0x02, -#define DNS_S_ANSWER DNS_S_AN - - DNS_S_NS = 0x04, -#define DNS_S_AUTHORITY DNS_S_NS - - DNS_S_AR = 0x08, -#define DNS_S_ADDITIONAL DNS_S_AR - - DNS_S_ALL = 0x0f -}; /* enum dns_section */ - - -enum dns_class { - DNS_C_IN = 1, - - DNS_C_ANY = 255 -}; /* enum dns_class */ - - -enum dns_type { - DNS_T_A = 1, - DNS_T_NS = 2, - DNS_T_CNAME = 5, - DNS_T_SOA = 6, - DNS_T_PTR = 12, - DNS_T_MX = 15, - DNS_T_TXT = 16, - DNS_T_AAAA = 28, - DNS_T_SRV = 33, - DNS_T_SSHFP = 44, - DNS_T_SPF = 99, - - DNS_T_ALL = 255 -}; /* enum dns_type */ - - -enum dns_opcode { - DNS_OP_QUERY = 0, - DNS_OP_IQUERY = 1, - DNS_OP_STATUS = 2, - DNS_OP_NOTIFY = 4, - DNS_OP_UPDATE = 5, -}; /* dns_opcode */ - - -enum dns_rcode { - DNS_RC_NOERROR = 0, - DNS_RC_FORMERR = 1, - DNS_RC_SERVFAIL = 2, - DNS_RC_NXDOMAIN = 3, - DNS_RC_NOTIMP = 4, - DNS_RC_REFUSED = 5, - DNS_RC_YXDOMAIN = 6, - DNS_RC_YXRRSET = 7, - DNS_RC_NXRRSET = 8, - DNS_RC_NOTAUTH = 9, - DNS_RC_NOTZONE = 10, -}; /* dns_rcode */ - - -/* - * NOTE: These string functions need a small buffer in case the literal - * integer value needs to be printed and returned. UNLESS this buffer is - * SPECIFIED, the returned string has ONLY BLOCK SCOPE. - */ -#define DNS_STRMAXLEN 47 /* "QUESTION|ANSWER|AUTHORITY|ADDITIONAL" */ - -const char *dns_strsection(enum dns_section, void *, size_t); -#define dns_strsection3(a, b, c) \ - dns_strsection((a), (b), (c)) -#define dns_strsection1(a) dns_strsection((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) -#define dns_strsection(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strsection, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) - -enum dns_section dns_isection(const char *); - -const char *dns_strclass(enum dns_class, void *, size_t); -#define dns_strclass3(a, b, c) dns_strclass((a), (b), (c)) -#define dns_strclass1(a) dns_strclass((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) -#define dns_strclass(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strclass, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) - -enum dns_class dns_iclass(const char *); - -const char *dns_strtype(enum dns_type, void *, size_t); -#define dns_strtype3(a, b, c) dns_strtype((a), (b), (c)) -#define dns_strtype1(a) dns_strtype((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) -#define dns_strtype(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strtype, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) - -enum dns_type dns_itype(const char *); - -const char *dns_stropcode(enum dns_opcode); - -enum dns_opcode dns_iopcode(const char *); - -const char *dns_strrcode(enum dns_rcode); - -enum dns_rcode dns_ircode(const char *); - - -/* - * A T O M I C I N T E R F A C E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -typedef unsigned long dns_atomic_t; - - -/* - * C R Y P T O I N T E R F A C E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -extern unsigned (*dns_random)(void); - - -/* - * P A C K E T I N T E R F A C E - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_header { - unsigned qid:16; - -#if BYTE_ORDER == BIG_ENDIAN - unsigned qr:1; - unsigned opcode:4; - unsigned aa:1; - unsigned tc:1; - unsigned rd:1; - - unsigned ra:1; - unsigned unused:3; - unsigned rcode:4; -#else - unsigned rd:1; - unsigned tc:1; - unsigned aa:1; - unsigned opcode:4; - unsigned qr:1; - - unsigned rcode:4; - unsigned unused:3; - unsigned ra:1; -#endif - - unsigned qdcount:16; - unsigned ancount:16; - unsigned nscount:16; - unsigned arcount:16; -}; /* struct dns_header */ - -#define dns_header(p) (&(p)->header) - - -#ifndef DNS_P_QBUFSIZ -#define DNS_P_QBUFSIZ dns_p_calcsize(256 + 4) -#endif - -#ifndef DNS_P_DICTSIZE -#define DNS_P_DICTSIZE 16 -#endif - -struct dns_packet { - unsigned short dict[DNS_P_DICTSIZE]; - - struct dns_s_memo { - unsigned short base, end; - } qd, an, ns, ar; - - struct { struct dns_packet *cqe_next, *cqe_prev; } cqe; - - size_t size, end; - - int:16; /* tcp padding */ - - union { - struct dns_header header; - unsigned char data[1]; - }; -}; /* struct dns_packet */ - -#define dns_p_calcsize(n) (offsetof(struct dns_packet, data) + DNS_PP_MAX(12, (n))) - -#define dns_p_sizeof(P) dns_p_calcsize((P)->end) - -/** takes size of maximum desired payload */ -#define dns_p_new(n) (dns_p_init((struct dns_packet *)&(union { unsigned char b[dns_p_calcsize((n))]; struct dns_packet p; }){ { 0 } }, dns_p_calcsize((n)))) - -/** takes size of entire packet structure as allocated */ -struct dns_packet *dns_p_init(struct dns_packet *, size_t); - -/** takes size of maximum desired payload */ -struct dns_packet *dns_p_make(size_t, int *); - -int dns_p_grow(struct dns_packet **); - -struct dns_packet *dns_p_copy(struct dns_packet *, const struct dns_packet *); - -#define dns_p_opcode(P) (dns_header(P)->opcode) - -#define dns_p_rcode(P) (dns_header(P)->rcode) - -unsigned dns_p_count(struct dns_packet *, enum dns_section); - -int dns_p_push(struct dns_packet *, enum dns_section, const void *, size_t, enum dns_type, enum dns_class, unsigned, const void *); - -void dns_p_dictadd(struct dns_packet *, unsigned short); - -struct dns_packet *dns_p_merge(struct dns_packet *, enum dns_section, struct dns_packet *, enum dns_section, int *); - -void dns_p_dump(struct dns_packet *, FILE *); - -int dns_p_study(struct dns_packet *); - - -/* - * D O M A I N N A M E I N T E R F A C E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#define DNS_D_MAXLABEL 63 /* + 1 '\0' */ -#define DNS_D_MAXNAME 255 /* + 1 '\0' */ - -#define DNS_D_ANCHOR 1 /* anchor domain w/ root "." */ -#define DNS_D_CLEAVE 2 /* cleave sub-domain */ -#define DNS_D_TRIM 4 /* remove superfluous dots */ - -#define dns_d_new3(a, b, f) dns_d_init(&(char[DNS_D_MAXNAME + 1]){ 0 }, DNS_D_MAXNAME + 1, (a), (b), (f)) -#define dns_d_new2(a, f) dns_d_new3((a), strlen((a)), (f)) -#define dns_d_new1(a) dns_d_new3((a), strlen((a)), DNS_D_ANCHOR) -#define dns_d_new(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_d_new, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) - -char *dns_d_init(void *, size_t, const void *, size_t, int); - -size_t dns_d_anchor(void *, size_t, const void *, size_t); - -size_t dns_d_cleave(void *, size_t, const void *, size_t); - -size_t dns_d_comp(void *, size_t, const void *, size_t, struct dns_packet *, int *); - -size_t dns_d_expand(void *, size_t, unsigned short, struct dns_packet *, int *); - -unsigned short dns_d_skip(unsigned short, struct dns_packet *); - -int dns_d_push(struct dns_packet *, const void *, size_t); - -size_t dns_d_cname(void *, size_t, const void *, size_t, struct dns_packet *, int *error); - - -/* - * R E S O U R C E R E C O R D I N T E R F A C E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_rr { - enum dns_section section; - - struct { - unsigned short p; - unsigned short len; - } dn; - - enum dns_type type; - enum dns_class class; - unsigned ttl; - - struct { - unsigned short p; - unsigned short len; - } rd; -}; /* struct dns_rr */ - - -int dns_rr_copy(struct dns_packet *, struct dns_rr *, struct dns_packet *); - -int dns_rr_parse(struct dns_rr *, unsigned short, struct dns_packet *); - -unsigned short dns_rr_skip(unsigned short, struct dns_packet *); - -int dns_rr_cmp(struct dns_rr *, struct dns_packet *, struct dns_rr *, struct dns_packet *); - -size_t dns_rr_print(void *, size_t, struct dns_rr *, struct dns_packet *, int *); - - -#define dns_rr_i_new(P, ...) dns_rr_i_init(&(struct dns_rr_i){ 0, __VA_ARGS__ }, (P)) - -struct dns_rr_i { - enum dns_section section; - const void *name; - enum dns_type type; - enum dns_class class; - const void *data; - - int follow; - - int (*sort)(); - unsigned args[2]; - - struct { - unsigned short next; - unsigned short count; - - unsigned exec; - unsigned regs[2]; - } state, saved; -}; /* struct dns_rr_i */ - -int dns_rr_i_packet(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); - -int dns_rr_i_order(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); - -int dns_rr_i_shuffle(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); - -struct dns_rr_i *dns_rr_i_init(struct dns_rr_i *, struct dns_packet *); - -#define dns_rr_i_save(i) ((i)->saved = (i)->state) -#define dns_rr_i_rewind(i) ((i)->state = (i)->saved) -#define dns_rr_i_count(i) ((i)->state.count) - -unsigned dns_rr_grep(struct dns_rr *, unsigned, struct dns_rr_i *, struct dns_packet *, int *); - -#define dns_rr_foreach_(rr, P, ...) \ - for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); ) - -#define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__) - - -/* - * A R E S O U R C E R E C O R D - */ - -struct dns_a { - struct in_addr addr; -}; /* struct dns_a */ - -int dns_a_parse(struct dns_a *, struct dns_rr *, struct dns_packet *); - -int dns_a_push(struct dns_packet *, struct dns_a *); - -int dns_a_cmp(const struct dns_a *, const struct dns_a *); - -size_t dns_a_print(void *, size_t, struct dns_a *); - - -/* - * AAAA R E S O U R C E R E C O R D - */ - -struct dns_aaaa { - struct in6_addr addr; -}; /* struct dns_aaaa */ - -int dns_aaaa_parse(struct dns_aaaa *, struct dns_rr *, struct dns_packet *); - -int dns_aaaa_push(struct dns_packet *, struct dns_aaaa *); - -int dns_aaaa_cmp(const struct dns_aaaa *, const struct dns_aaaa *); - -size_t dns_aaaa_print(void *, size_t, struct dns_aaaa *); - - -/* - * MX R E S O U R C E R E C O R D - */ - -struct dns_mx { - unsigned short preference; - char host[DNS_D_MAXNAME + 1]; -}; /* struct dns_mx */ - -int dns_mx_parse(struct dns_mx *, struct dns_rr *, struct dns_packet *); - -int dns_mx_push(struct dns_packet *, struct dns_mx *); - -int dns_mx_cmp(const struct dns_mx *, const struct dns_mx *); - -size_t dns_mx_print(void *, size_t, struct dns_mx *); - -size_t dns_mx_cname(void *, size_t, struct dns_mx *); - - -/* - * NS R E S O U R C E R E C O R D - */ - -struct dns_ns { - char host[DNS_D_MAXNAME + 1]; -}; /* struct dns_ns */ - -int dns_ns_parse(struct dns_ns *, struct dns_rr *, struct dns_packet *); - -int dns_ns_push(struct dns_packet *, struct dns_ns *); - -int dns_ns_cmp(const struct dns_ns *, const struct dns_ns *); - -size_t dns_ns_print(void *, size_t, struct dns_ns *); - -size_t dns_ns_cname(void *, size_t, struct dns_ns *); - - -/* - * CNAME R E S O U R C E R E C O R D - */ - -struct dns_cname { - char host[DNS_D_MAXNAME + 1]; -}; /* struct dns_cname */ - -int dns_cname_parse(struct dns_cname *, struct dns_rr *, struct dns_packet *); - -int dns_cname_push(struct dns_packet *, struct dns_cname *); - -int dns_cname_cmp(const struct dns_cname *, const struct dns_cname *); - -size_t dns_cname_print(void *, size_t, struct dns_cname *); - -size_t dns_cname_cname(void *, size_t, struct dns_cname *); - - -/* - * SOA R E S O U R C E R E C O R D - */ - -struct dns_soa { - char mname[DNS_D_MAXNAME + 1]; - char rname[DNS_D_MAXNAME + 1]; - unsigned serial, refresh, retry, expire, minimum; -}; /* struct dns_soa */ - -int dns_soa_parse(struct dns_soa *, struct dns_rr *, struct dns_packet *); - -int dns_soa_push(struct dns_packet *, struct dns_soa *); - -int dns_soa_cmp(const struct dns_soa *, const struct dns_soa *); - -size_t dns_soa_print(void *, size_t, struct dns_soa *); - - -/* - * PTR R E S O U R C E R E C O R D - */ - -struct dns_ptr { - char host[DNS_D_MAXNAME + 1]; -}; /* struct dns_ptr */ - -int dns_ptr_parse(struct dns_ptr *, struct dns_rr *, struct dns_packet *); - -int dns_ptr_push(struct dns_packet *, struct dns_ptr *); - -int dns_ptr_cmp(const struct dns_ptr *, const struct dns_ptr *); - -size_t dns_ptr_print(void *, size_t, struct dns_ptr *); - -size_t dns_ptr_cname(void *, size_t, struct dns_ptr *); - - -/* - * SRV R E S O U R C E R E C O R D - */ - -struct dns_srv { - unsigned short priority; - unsigned short weight; - unsigned short port; - char target[DNS_D_MAXNAME + 1]; -}; /* struct dns_srv */ - -int dns_srv_parse(struct dns_srv *, struct dns_rr *, struct dns_packet *); - -int dns_srv_push(struct dns_packet *, struct dns_srv *); - -int dns_srv_cmp(const struct dns_srv *, const struct dns_srv *); - -size_t dns_srv_print(void *, size_t, struct dns_srv *); - -size_t dns_srv_cname(void *, size_t, struct dns_srv *); - - -/* - * SSHFP R E S O U R C E R E C O R D - */ - -struct dns_sshfp { - enum dns_sshfp_key { - DNS_SSHFP_RSA = 1, - DNS_SSHFP_DSA = 2, - } algo; - - enum dns_sshfp_digest { - DNS_SSHFP_SHA1 = 1, - } type; - - union { - unsigned char sha1[20]; - } digest; -}; /* struct dns_sshfp */ - -int dns_sshfp_parse(struct dns_sshfp *, struct dns_rr *, struct dns_packet *); - -int dns_sshfp_push(struct dns_packet *, struct dns_sshfp *); - -int dns_sshfp_cmp(const struct dns_sshfp *, const struct dns_sshfp *); - -size_t dns_sshfp_print(void *, size_t, struct dns_sshfp *); - - -/* - * TXT R E S O U R C E R E C O R D - */ - -#ifndef DNS_TXT_MINDATA -#define DNS_TXT_MINDATA 1024 -#endif - -struct dns_txt { - size_t size, len; - unsigned char data[DNS_TXT_MINDATA]; -}; /* struct dns_txt */ - -struct dns_txt *dns_txt_init(struct dns_txt *, size_t); - -int dns_txt_parse(struct dns_txt *, struct dns_rr *, struct dns_packet *); - -int dns_txt_push(struct dns_packet *, struct dns_txt *); - -int dns_txt_cmp(const struct dns_txt *, const struct dns_txt *); - -size_t dns_txt_print(void *, size_t, struct dns_txt *); - - -/* - * ANY R E S O U R C E R E C O R D - */ - -union dns_any { - struct dns_a a; - struct dns_aaaa aaaa; - struct dns_mx mx; - struct dns_ns ns; - struct dns_cname cname; - struct dns_soa soa; - struct dns_ptr ptr; - struct dns_srv srv; - struct dns_sshfp sshfp; - struct dns_txt txt, spf, rdata; -}; /* union dns_any */ - -#define DNS_ANY_INIT(any) { .rdata = { .size = sizeof *(any) } } - -union dns_any *dns_any_init(union dns_any *, size_t); - -int dns_any_parse(union dns_any *, struct dns_rr *, struct dns_packet *); - -int dns_any_push(struct dns_packet *, union dns_any *, enum dns_type); - -int dns_any_cmp(const union dns_any *, enum dns_type, const union dns_any *, enum dns_type); - -size_t dns_any_print(void *, size_t, union dns_any *, enum dns_type); - -size_t dns_any_cname(void *, size_t, union dns_any *, enum dns_type); - - -/* - * H O S T S I N T E R F A C E - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_hosts; - -struct dns_hosts *dns_hosts_open(int *); - -void dns_hosts_close(struct dns_hosts *); - -unsigned dns_hosts_acquire(struct dns_hosts *); - -unsigned dns_hosts_release(struct dns_hosts *); - -struct dns_hosts *dns_hosts_mortal(struct dns_hosts *); - -struct dns_hosts *dns_hosts_local(int *); - -int dns_hosts_loadfile(struct dns_hosts *, FILE *); - -int dns_hosts_loadpath(struct dns_hosts *, const char *); - -int dns_hosts_dump(struct dns_hosts *, FILE *); - -int dns_hosts_insert(struct dns_hosts *, int, const void *, const void *, _Bool); - -struct dns_packet *dns_hosts_query(struct dns_hosts *, struct dns_packet *, int *); - - -/* - * R E S O L V . C O N F I N T E R F A C E - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_resolv_conf { - struct sockaddr_storage nameserver[3]; - - char search[4][DNS_D_MAXNAME + 1]; - - /* (f)ile, (b)ind, (c)ache */ - char lookup[3]; - - struct { - _Bool edns0; - - unsigned ndots; - - unsigned timeout; - - unsigned attempts; - - _Bool rotate; - - _Bool recurse; - - _Bool smart; - - enum { - DNS_RESCONF_TCP_ENABLE, - DNS_RESCONF_TCP_ONLY, - DNS_RESCONF_TCP_DISABLE, - } tcp; - } options; - - struct sockaddr_storage iface; - - struct { /* PRIVATE */ - dns_atomic_t refcount; - } _; -}; /* struct dns_resolv_conf */ - -struct dns_resolv_conf *dns_resconf_open(int *); - -void dns_resconf_close(struct dns_resolv_conf *); - -unsigned dns_resconf_acquire(struct dns_resolv_conf *); - -unsigned dns_resconf_release(struct dns_resolv_conf *); - -struct dns_resolv_conf *dns_resconf_mortal(struct dns_resolv_conf *); - -struct dns_resolv_conf *dns_resconf_local(int *); - -struct dns_resolv_conf *dns_resconf_root(int *); - -int dns_resconf_loadfile(struct dns_resolv_conf *, FILE *); - -int dns_resconf_loadpath(struct dns_resolv_conf *, const char *); - -int dns_resconf_dump(struct dns_resolv_conf *, FILE *); - -int dns_resconf_setiface(struct dns_resolv_conf *, const char *, unsigned short); - -typedef unsigned long dns_resconf_i_t; - -size_t dns_resconf_search(void *, size_t, const void *, size_t, struct dns_resolv_conf *, dns_resconf_i_t *); - - -/* - * H I N T S E R V E R I N T E R F A C E - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_hints; - -struct dns_hints *dns_hints_open(struct dns_resolv_conf *, int *); - -void dns_hints_close(struct dns_hints *); - -unsigned dns_hints_acquire(struct dns_hints *); - -unsigned dns_hints_release(struct dns_hints *); - -struct dns_hints *dns_hints_mortal(struct dns_hints *); - -int dns_hints_insert(struct dns_hints *, const char *, const struct sockaddr *, unsigned); - -unsigned dns_hints_insert_resconf(struct dns_hints *, const char *, const struct dns_resolv_conf *, int *); - -struct dns_hints *dns_hints_local(struct dns_resolv_conf *, int *); - -struct dns_hints *dns_hints_root(struct dns_resolv_conf *, int *); - - -struct dns_hints_i { - const char *zone; - - struct { - unsigned next; - unsigned seed; - } state; -}; /* struct dns_hints_i */ - -#define dns_hints_i_new(...) (&(struct dns_hints_i){ __VA_ARGS__ }) - -unsigned dns_hints_grep(struct sockaddr **, socklen_t *, unsigned, struct dns_hints_i *, struct dns_hints *); - - -/* - * C A C H E I N T E R F A C E - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_cache { - void *state; - - dns_atomic_t (*acquire)(struct dns_cache *); - dns_atomic_t (*release)(struct dns_cache *); - - struct dns_packet *(*query)(struct dns_packet *, struct dns_cache *, int *); - - int (*submit)(struct dns_packet *, struct dns_cache *); - int (*check)(struct dns_cache *); - struct dns_packet *(*fetch)(struct dns_cache *, int *); - - int (*pollfd)(struct dns_cache *); - short (*events)(struct dns_cache *); - void (*clear)(struct dns_cache *); - - union { - long i; - void *p; - } arg[3]; -}; /* struct dns_cache */ - - -struct dns_cache *dns_cache_init(struct dns_cache *); - -void dns_cache_close(struct dns_cache *); - - -/* - * A P P L I C A T I O N I N T E R F A C E - * - * Options to change the behavior of the API. Applies across all the - * different components. - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#define DNS_OPTS_INITIALIZER_ { 0, 0 }, 0 -#define DNS_OPTS_INITIALIZER { DNS_OPTS_INITIALIZER_ } -#define DNS_OPTS_INIT(...) { DNS_OPTS_INITIALIZER_, __VA_ARGS__ } - -#define dns_opts(...) (&(struct dns_options)DNS_OPTS_INIT(__VA_ARGS__)) - -struct dns_options { - /* - * If the callback closes *fd, it must set it to -1. Otherwise, the - * descriptor is queued and lazily closed at object destruction or - * by an explicit call to _clear(). This allows safe use of - * kqueue(2), epoll(2), et al -style persistent events. - */ - struct { - void *arg; - int (*cb)(int *fd, void *arg); - } closefd; - - /* bitmask for _events() routines */ - enum dns_events { - DNS_SYSPOLL, - DNS_LIBEVENT, - } events; -}; /* struct dns_options */ - - -/* - * S T A T S I N T E R F A C E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_stat { - size_t queries; - - struct { - struct { - size_t count, bytes; - } sent, rcvd; - } udp, tcp; -}; /* struct dns_stat */ - - -/* - * S O C K E T I N T E R F A C E - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_socket; - -struct dns_socket *dns_so_open(const struct sockaddr *, int, const struct dns_options *, int *error); - -void dns_so_close(struct dns_socket *); - -void dns_so_reset(struct dns_socket *); - -unsigned short dns_so_mkqid(struct dns_socket *so); - -struct dns_packet *dns_so_query(struct dns_socket *, struct dns_packet *, struct sockaddr *, int *); - -int dns_so_submit(struct dns_socket *, struct dns_packet *, struct sockaddr *); - -int dns_so_check(struct dns_socket *); - -struct dns_packet *dns_so_fetch(struct dns_socket *, int *); - -time_t dns_so_elapsed(struct dns_socket *); - -void dns_so_clear(struct dns_socket *); - -int dns_so_events(struct dns_socket *); - -int dns_so_pollfd(struct dns_socket *); - -int dns_so_poll(struct dns_socket *, int); - -const struct dns_stat *dns_so_stat(struct dns_socket *); - - -/* - * R E S O L V E R I N T E R F A C E - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_resolver; - -struct dns_resolver *dns_res_open(struct dns_resolv_conf *, struct dns_hosts *hosts, struct dns_hints *, struct dns_cache *, const struct dns_options *, int *); - -struct dns_resolver *dns_res_stub(const struct dns_options *, int *); - -void dns_res_reset(struct dns_resolver *); - -void dns_res_close(struct dns_resolver *); - -unsigned dns_res_acquire(struct dns_resolver *); - -unsigned dns_res_release(struct dns_resolver *); - -struct dns_resolver *dns_res_mortal(struct dns_resolver *); - -int dns_res_submit(struct dns_resolver *, const char *, enum dns_type, enum dns_class); - -int dns_res_check(struct dns_resolver *); - -struct dns_packet *dns_res_fetch(struct dns_resolver *, int *); - -time_t dns_res_elapsed(struct dns_resolver *); - -void dns_res_clear(struct dns_resolver *); - -int dns_res_events(struct dns_resolver *); - -int dns_res_pollfd(struct dns_resolver *); - -int dns_res_poll(struct dns_resolver *, int); - -struct dns_packet *dns_res_query(struct dns_resolver *, const char *, enum dns_type, enum dns_class, int, int *); - -const struct dns_stat *dns_res_stat(struct dns_resolver *); - - -/* - * A D D R I N F O I N T E R F A C E - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -struct dns_addrinfo; - -struct dns_addrinfo *dns_ai_open(const char *, const char *, enum dns_type, const struct addrinfo *, struct dns_resolver *, int *); - -void dns_ai_close(struct dns_addrinfo *); - -int dns_ai_nextent(struct addrinfo **, struct dns_addrinfo *); - -size_t dns_ai_print(void *, size_t, struct addrinfo *, struct dns_addrinfo *); - -time_t dns_ai_elapsed(struct dns_addrinfo *); - -void dns_ai_clear(struct dns_addrinfo *); - -int dns_ai_events(struct dns_addrinfo *); - -int dns_ai_pollfd(struct dns_addrinfo *); - -int dns_ai_poll(struct dns_addrinfo *, int); - -const struct dns_stat *dns_ai_stat(struct dns_addrinfo *); - -void *dns_sa_addr(int af, void *sa); -unsigned short *dns_sa_port(int af, void *sa); -#if _WIN32 -const char *dns_inet_ntop(int af, const void *src, void *dst, unsigned long lim); -#else -#define dns_inet_pton(...) inet_pton(__VA_ARGS__) -#define dns_inet_ntop(...) inet_ntop(__VA_ARGS__) -#endif -#define dns_sa_family(sa) (((struct sockaddr *)(sa))->sa_family) -/* - * U T I L I T Y I N T E R F A C E S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -size_t dns_strlcpy(char *, const char *, size_t); - -size_t dns_strlcat(char *, const char *, size_t); - - -/* - * M A C R O M A G I C S - * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#define DNS_PP_MAX(a, b) (((a) > (b))? (a) : (b)) -#define DNS_PP_NARG_(a, b, c, d, e, f, g, h, i, j, k, N,...) N -#define DNS_PP_NARG(...) DNS_PP_NARG_(__VA_ARGS__, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -#define DNS_PP_CALL(F, ...) F(__VA_ARGS__) -#define DNS_PP_PASTE(x, y) x##y -#define DNS_PP_XPASTE(x, y) DNS_PP_PASTE(x, y) -#define DNS_PP_STRINGIFY_(s) #s -#define DNS_PP_STRINGIFY(s) DNS_PP_STRINGIFY_(s) -#define DNS_PP_D1 0 -#define DNS_PP_D2 1 -#define DNS_PP_D3 2 -#define DNS_PP_D4 3 -#define DNS_PP_D5 4 -#define DNS_PP_D6 5 -#define DNS_PP_D7 6 -#define DNS_PP_D8 7 -#define DNS_PP_D9 8 -#define DNS_PP_D10 9 -#define DNS_PP_D11 10 -#define DNS_PP_DEC(N) DNS_PP_XPASTE(DNS_PP_D, N) - -#endif /* DNS_H */ diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con.c b/legacy/ecore/src/lib/ecore_con/ecore_con.c deleted file mode 100644 index 056db2eec0..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con.c +++ /dev/null @@ -1,2596 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_NETINET_TCP_H -# include -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_SYS_SOCKET_H -# include -#endif - -#ifdef HAVE_SYS_UN_H -# include -#endif - -#ifdef HAVE_WS2TCPIP_H -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" -#include "Ecore_Con.h" -#include "ecore_con_private.h" - -static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl); -static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl); -static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr); -static void _ecore_con_server_timer_update(Ecore_Con_Server *svr); - -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 void _ecore_con_cl_read(Ecore_Con_Server *svr); -static Eina_Bool _ecore_con_svr_tcp_handler(void *data, - Ecore_Fd_Handler *fd_handler); -static Eina_Bool _ecore_con_cl_handler(void *data, - Ecore_Fd_Handler *fd_handler); -static Eina_Bool _ecore_con_cl_udp_handler(void *data, - Ecore_Fd_Handler *fd_handler); -static Eina_Bool _ecore_con_svr_udp_handler(void *data, - Ecore_Fd_Handler *fd_handler); - -static void _ecore_con_svr_cl_read(Ecore_Con_Client *cl); -static Eina_Bool _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(Ecore_Con_Server *svr, - void *ev); -static void _ecore_con_event_client_del_free(Ecore_Con_Server *svr, - void *ev); -static void _ecore_con_event_client_data_free(Ecore_Con_Server *svr, - 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); -static void _ecore_con_event_server_error_free(void *data, - Ecore_Con_Event_Server_Error *e); -static void _ecore_con_event_client_error_free(Ecore_Con_Server *svr, - Ecore_Con_Event_Client_Error *e); -static void _ecore_con_event_server_write_free(void *data, - Ecore_Con_Event_Server_Write *e); -static void _ecore_con_event_client_write_free(Ecore_Con_Server *svr, - Ecore_Con_Event_Client_Write *e); - -static void _ecore_con_lookup_done(void *data, - Ecore_Con_Info *infos); - -static const char * _ecore_con_pretty_ip(struct sockaddr *client_addr); - - -void -_ecore_con_client_kill(Ecore_Con_Client *cl) -{ - if (cl->delete_me) - DBG("Multi kill request for client %p", cl); - else - { - ecore_con_event_client_del(cl); - if (cl->buf) return; - } - INF("Lost client %s", (cl->ip) ? cl->ip : ""); - if (cl->fd_handler) - ecore_main_fd_handler_del(cl->fd_handler); - - cl->fd_handler = NULL; -} - -void -_ecore_con_server_kill(Ecore_Con_Server *svr) -{ - if (svr->delete_me) - DBG("Multi kill request for svr %p", svr); - else - ecore_con_event_server_del(svr); - - if (svr->fd_handler) - ecore_main_fd_handler_del(svr->fd_handler); - - svr->fd_handler = NULL; -} - -#define _ecore_con_server_kill(svr) do { \ - DBG("KILL %p", (svr)); \ - _ecore_con_server_kill((svr)); \ -} while (0) - -#define _ecore_con_client_kill(cl) do { \ - DBG("KILL %p", (cl)); \ - _ecore_con_client_kill((cl)); \ -} while (0) - -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; -EAPI int ECORE_CON_EVENT_CLIENT_WRITE = 0; -EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0; -EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0; -EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0; -EAPI int ECORE_CON_EVENT_PROXY_BIND = 0; - -static Eina_List *servers = NULL; -static int _ecore_con_init_count = 0; -static int _ecore_con_event_count = 0; -int _ecore_con_log_dom = -1; -Ecore_Con_Socks *_ecore_con_proxy_once = NULL; -Ecore_Con_Socks *_ecore_con_proxy_global = NULL; - -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 - ("ecore_con", 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_mempool_init(); - - 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(); - ECORE_CON_EVENT_CLIENT_WRITE = ecore_event_type_new(); - ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new(); - ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new(); - ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new(); - ECORE_CON_EVENT_PROXY_BIND = ecore_event_type_new(); - - - eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server"); - eina_magic_string_set(ECORE_MAGIC_CON_CLIENT, "Ecore_Con_Client"); - eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url"); - - /* TODO Remember return value, if it fails, use gethostbyname() */ - ecore_con_socks_init(); - ecore_con_ssl_init(); - ecore_con_info_init(); - - return _ecore_con_init_count; -} - -EAPI int -ecore_con_shutdown(void) -{ - Eina_List *l, *l2; - Ecore_Con_Server *svr; - - if (--_ecore_con_init_count != 0) - return _ecore_con_init_count; - - EINA_LIST_FOREACH_SAFE(servers, l, l2, svr) - { - Ecore_Con_Event_Server_Add *ev; - - svr->delete_me = EINA_TRUE; - INF("svr %p is dead", svr); - /* some pointer hacks here to prevent double frees if people are being stupid */ - EINA_LIST_FREE(svr->event_count, ev) - ev->server = NULL; - _ecore_con_server_free(svr); - } - - ecore_con_socks_shutdown(); - if (!_ecore_con_event_count) ecore_con_mempool_shutdown(); - - 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; -} - -EAPI Eina_Bool -ecore_con_lookup(const char *name, - Ecore_Con_Dns_Cb done_cb, - const void *data) -{ - Ecore_Con_Server *svr; - Ecore_Con_Lookup *lk; - struct addrinfo hints; - - if (!name || !done_cb) - return EINA_FALSE; - - svr = calloc(1, sizeof(Ecore_Con_Server)); - if (!svr) - return EINA_FALSE; - - lk = malloc(sizeof (Ecore_Con_Lookup)); - if (!lk) - { - free(svr); - return EINA_FALSE; - } - - lk->done_cb = done_cb; - lk->data = data; - - svr->name = strdup(name); - if (!svr->name) - goto on_error; - - svr->type = ECORE_CON_REMOTE_TCP; - svr->port = 1025; - svr->data = lk; - svr->created = EINA_TRUE; - svr->reject_excess_clients = EINA_FALSE; - svr->client_limit = -1; - svr->clients = NULL; - svr->ppid = getpid(); - - 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; - - if (ecore_con_info_get(svr, _ecore_con_lookup_done, svr, - &hints)) - return EINA_TRUE; - - free(svr->name); -on_error: - free(lk); - free(svr); - return EINA_FALSE; -} - -/** - * @addtogroup Ecore_Con_Server_Group Ecore Connection Server Functions - * - * Functions that operate on Ecore server objects. - * - * @{ - */ - -/** - * @example ecore_con_server_example.c - * Shows how to write a simple server using the Ecore_Con library. - */ - -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 = EINA_TRUE; - svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT; - svr->reject_excess_clients = EINA_FALSE; - svr->client_limit = -1; - svr->clients = NULL; - svr->ppid = getpid(); - if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL)) - goto error; - - type = compl_type & ECORE_CON_TYPE; - - if ((type == ECORE_CON_LOCAL_USER) || - (type == ECORE_CON_LOCAL_SYSTEM) || - (type == ECORE_CON_LOCAL_ABSTRACT)) - /* Local */ -#ifdef _WIN32 - if (!ecore_con_local_listen(svr)) - goto error; -#else - if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr)) - goto error; -#endif - - if ((type == ECORE_CON_REMOTE_TCP) || - (type == ECORE_CON_REMOTE_NODELAY) || - (type == ECORE_CON_REMOTE_CORK)) - { - /* 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); - - - if (svr->fd_handler) - ecore_main_fd_handler_del(svr->fd_handler); - - if (svr->fd > 0) - close(svr->fd); - - if (svr->buf) - eina_binbuf_free(svr->buf); - - if (svr->ip) - eina_stringshare_del(svr->ip); - - ecore_con_ssl_server_shutdown(svr); - free(svr); - return NULL; -} - -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) || (!name[0])) - 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 = EINA_FALSE; - svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT; - svr->disable_proxy = (compl_type & ECORE_CON_SUPER_SSL & ECORE_CON_NO_PROXY) == ECORE_CON_NO_PROXY; - svr->reject_excess_clients = EINA_FALSE; - svr->clients = NULL; - svr->client_limit = -1; - - type = compl_type & ECORE_CON_TYPE; - - if ((!svr->disable_proxy) && (type > ECORE_CON_LOCAL_ABSTRACT)) - { - /* never use proxies on local connections */ - if (_ecore_con_proxy_once) - svr->ecs = _ecore_con_proxy_once; - else if (_ecore_con_proxy_global) - svr->ecs = _ecore_con_proxy_global; - _ecore_con_proxy_once = NULL; - if (svr->ecs) - { - if ((!svr->ecs->lookup) && - (!ecore_con_lookup(svr->name, (Ecore_Con_Dns_Cb)ecore_con_socks_dns_cb, svr))) - goto error; - if (svr->ecs->lookup) - svr->ecs_state = ECORE_CON_PROXY_STATE_RESOLVED; - } - } - EINA_SAFETY_ON_TRUE_GOTO(ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL), error); - - EINA_SAFETY_ON_TRUE_GOTO(((type == ECORE_CON_REMOTE_TCP) || - (type == ECORE_CON_REMOTE_NODELAY) || - (type == ECORE_CON_REMOTE_CORK) || - (type == ECORE_CON_REMOTE_UDP) || - (type == ECORE_CON_REMOTE_BROADCAST)) && - (port < 0), error); - - if ((type == ECORE_CON_LOCAL_USER) || - (type == ECORE_CON_LOCAL_SYSTEM) || - (type == ECORE_CON_LOCAL_ABSTRACT)) - /* Local */ -#ifdef _WIN32 - EINA_SAFETY_ON_FALSE_GOTO(ecore_con_local_connect(svr, _ecore_con_cl_handler), error); -#else - EINA_SAFETY_ON_FALSE_GOTO(ecore_con_local_connect(svr, _ecore_con_cl_handler, svr), error); -#endif - - if ((type == ECORE_CON_REMOTE_TCP) || - (type == ECORE_CON_REMOTE_NODELAY) || - (type == ECORE_CON_REMOTE_CORK)) - { - /* TCP */ - EINA_SAFETY_ON_FALSE_GOTO(ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, svr), error); - } - else if ((type == ECORE_CON_REMOTE_UDP) || (type == ECORE_CON_REMOTE_BROADCAST)) - /* UDP and MCAST */ - EINA_SAFETY_ON_FALSE_GOTO(ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, svr), 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_handler) - ecore_main_fd_handler_del(svr->fd_handler); - - if (svr->fd > 0) - close(svr->fd); - - ecore_con_ssl_server_shutdown(svr); - free(svr); - return NULL; -} - -EAPI void -ecore_con_server_timeout_set(Ecore_Con_Server *svr, - double timeout) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_timeout_set"); - return; - } - - if (svr->created) - svr->client_disconnect_time = timeout; - else - svr->disconnect_time = timeout; -} - -EAPI double -ecore_con_server_timeout_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_timeout_get"); - return 0; - } - - return svr->created ? svr->client_disconnect_time : svr->disconnect_time; -} - -EAPI void * -ecore_con_server_del(Ecore_Con_Server *svr) -{ - 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; - - _ecore_con_server_kill(svr); - return svr->data; -} - -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; -} - -EAPI void * -ecore_con_server_data_set(Ecore_Con_Server *svr, - void *data) -{ - void *ret = NULL; - - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get"); - return NULL; - } - - ret = svr->data; - svr->data = data; - return ret; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - - if (svr->connecting) - return EINA_FALSE; - - return EINA_TRUE; -} - -EAPI const 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; -} - -EAPI const char * -ecore_con_server_name_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_name_get"); - return NULL; - } - - return svr->name; -} - -EAPI int -ecore_con_server_port_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_port_get"); - return -1; - } - return svr->port; -} - -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; - } - - EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->delete_me, 0); - - EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); - - EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0); - - if (svr->fd_handler) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); - - if (!svr->buf) - { - svr->buf = eina_binbuf_new(); - EINA_SAFETY_ON_NULL_RETURN_VAL(svr->buf, 0); -#ifdef TCP_CORK - if ((svr->fd >= 0) && ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)) - { - int state = 1; - if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) - /* realistically this isn't anything serious so we can just log and continue */ - ERR("corking failed! %s", strerror(errno)); - } -#endif - } - eina_binbuf_append_length(svr->buf, data, size); - - return size; -} - -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; -} - -EAPI const 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; -} - -EAPI double -ecore_con_server_uptime_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_uptime_get"); - return -1; - } - - return ecore_time_get() - svr->start_time; -} - -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); -} - -/** - * @} - */ - -/** - * @addtogroup Ecore_Con_Client_Group Ecore Connection Client Functions - * - * Functions that operate on Ecore connection client objects. - * - * @{ - */ - -/** - * @example ecore_con_client_example.c - * Shows how to write a simple client that connects to the example server. - */ - -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; - } - - EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->delete_me, 0); - - EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); - - EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0); - - if (cl->fd_handler) - ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); - - if (cl->host_server && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP)) - sendto(cl->host_server->fd, data, size, 0, (struct sockaddr *)cl->client_addr, - cl->client_addr_len); - else if (!cl->buf) - { - cl->buf = eina_binbuf_new(); - EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0); -#ifdef TCP_CORK - if ((cl->fd >= 0) && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)) - { - int state = 1; - if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) - /* realistically this isn't anything serious so we can just log and continue */ - ERR("corking failed! %s", strerror(errno)); - } -#endif - } - eina_binbuf_append_length(cl->buf, data, size); - - return size; -} - -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->host_server; -} - -EAPI Eina_Bool -ecore_con_client_connected_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_connected_get"); - return EINA_FALSE; - } - - return !cl->delete_me; -} - -EAPI void -ecore_con_client_timeout_set(Ecore_Con_Client *cl, - double timeout) -{ - if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) - { - ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, - "ecore_con_client_timeout_set"); - return; - } - - cl->disconnect_time = timeout; - - _ecore_con_cl_timer_update(cl); -} - -EAPI double -ecore_con_client_timeout_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_timeout_get"); - return 0; - } - - return cl->disconnect_time; -} - -EAPI void * -ecore_con_client_del(Ecore_Con_Client *cl) -{ - if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) - { - ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); - return NULL; - } - - _ecore_con_client_kill(cl); - return cl->data; -} - -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; -} - -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; -} - -EAPI const 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; - } - if (!cl->ip) - cl->ip = _ecore_con_pretty_ip(cl->client_addr); - - return cl->ip; -} - -EAPI int -ecore_con_client_port_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_port_get"); - return -1; - } - if (cl->client_addr->sa_family == AF_INET) - return ((struct sockaddr_in*)cl->client_addr)->sin_port; -#ifdef HAVE_IPV6 - return ((struct sockaddr_in6*)cl->client_addr)->sin6_port; -#else - return -1; -#endif -} - -EAPI double -ecore_con_client_uptime_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_uptime_get"); - return -1; - } - - return ecore_time_get() - cl->start_time; -} - -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); -} - -EAPI int -ecore_con_server_fd_get(Ecore_Con_Server *svr) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); - return -1; - } - if (svr->created) return -1; - if (svr->delete_me) return -1; - return ecore_main_fd_handler_fd_get(svr->fd_handler); -} - -EAPI int -ecore_con_client_fd_get(Ecore_Con_Client *cl) -{ - if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) - { - ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__); - return -1; - } - return ecore_main_fd_handler_fd_get(cl->fd_handler); -} - -/** - * @} - */ - -void -ecore_con_event_proxy_bind(Ecore_Con_Server *svr) -{ - Ecore_Con_Event_Proxy_Bind *e; - int ev = ECORE_CON_EVENT_PROXY_BIND; - - e = ecore_con_event_proxy_bind_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - svr->event_count = eina_list_append(svr->event_count, e); - _ecore_con_server_timer_update(svr); - e->server = svr; - e->ip = svr->proxyip; - e->port = svr->proxyport; - ecore_event_add(ev, e, - _ecore_con_event_server_add_free, NULL); - _ecore_con_event_count++; -} - -void -ecore_con_event_server_add(Ecore_Con_Server *svr) -{ - /* we got our server! */ - Ecore_Con_Event_Server_Add *e; - int ev = ECORE_CON_EVENT_SERVER_ADD; - - e = ecore_con_event_server_add_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - svr->connecting = EINA_FALSE; - svr->start_time = ecore_time_get(); - svr->event_count = eina_list_append(svr->event_count, e); - _ecore_con_server_timer_update(svr); - e->server = svr; - if (svr->upgrade) ev = ECORE_CON_EVENT_SERVER_UPGRADE; - ecore_event_add(ev, e, - _ecore_con_event_server_add_free, NULL); - _ecore_con_event_count++; -} - -void -ecore_con_event_server_del(Ecore_Con_Server *svr) -{ - Ecore_Con_Event_Server_Del *e; - - svr->delete_me = EINA_TRUE; - INF("svr %p is dead", svr); - e = ecore_con_event_server_del_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - svr->event_count = eina_list_append(svr->event_count, e); - _ecore_con_server_timer_update(svr); - e->server = svr; - if (svr->ecs) - { - svr->ecs_state = svr->ecs->lookup ? ECORE_CON_PROXY_STATE_RESOLVED : ECORE_CON_PROXY_STATE_DONE; - eina_stringshare_replace(&svr->proxyip, NULL); - svr->proxyport = 0; - } - ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e, - _ecore_con_event_server_del_free, NULL); - _ecore_con_event_count++; -} - -void -ecore_con_event_server_write(Ecore_Con_Server *svr, int num) -{ - Ecore_Con_Event_Server_Write *e; - - e = ecore_con_event_server_write_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - INF("Wrote %d bytes", num); - svr->event_count = eina_list_append(svr->event_count, e); - e->server = svr; - e->size = num; - ecore_event_add(ECORE_CON_EVENT_SERVER_WRITE, e, - (Ecore_End_Cb)_ecore_con_event_server_write_free, NULL); - _ecore_con_event_count++; -} - -void -ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate) -{ - Ecore_Con_Event_Server_Data *e; - - e = ecore_con_event_server_data_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - svr->event_count = eina_list_append(svr->event_count, e); - _ecore_con_server_timer_update(svr); - e->server = svr; - if (duplicate) - { - e->data = malloc(num); - if (!e->data) - { - ERR("server data allocation failure !"); - _ecore_con_event_server_data_free(NULL, e); - return; - } - memcpy(e->data, buf, num); - } - else - e->data = buf; - e->size = num; - ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e, - _ecore_con_event_server_data_free, NULL); - _ecore_con_event_count++; -} - -void -ecore_con_event_client_add(Ecore_Con_Client *cl) -{ - Ecore_Con_Event_Client_Add *e; - int ev = ECORE_CON_EVENT_CLIENT_ADD; - - e = ecore_con_event_client_add_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - cl->event_count = eina_list_append(cl->event_count, e); - cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); - _ecore_con_cl_timer_update(cl); - e->client = cl; - if (cl->upgrade) ev = ECORE_CON_EVENT_CLIENT_UPGRADE; - ecore_event_add(ev, e, - (Ecore_End_Cb)_ecore_con_event_client_add_free, cl->host_server); - _ecore_con_event_count++; -} - -void -ecore_con_event_client_del(Ecore_Con_Client *cl) -{ - Ecore_Con_Event_Client_Del *e; - - if (!cl) return; - cl->delete_me = EINA_TRUE; - INF("cl %p is dead", cl); - e = ecore_con_event_client_del_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - cl->event_count = eina_list_append(cl->event_count, e); - - cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); - _ecore_con_cl_timer_update(cl); - e->client = cl; - ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, - (Ecore_End_Cb)_ecore_con_event_client_del_free, cl->host_server); - _ecore_con_event_count++; -} - -void -ecore_con_event_client_write(Ecore_Con_Client *cl, int num) -{ - Ecore_Con_Event_Client_Write *e; - - e = ecore_con_event_client_write_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - cl->event_count = eina_list_append(cl->event_count, e); - cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); - e->client = cl; - e->size = num; - ecore_event_add(ECORE_CON_EVENT_CLIENT_WRITE, e, - (Ecore_End_Cb)_ecore_con_event_client_write_free, cl->host_server); - _ecore_con_event_count++; -} - -void -ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate) -{ - Ecore_Con_Event_Client_Data *e; - - e = ecore_con_event_client_data_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - cl->event_count = eina_list_append(cl->event_count, e); - cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); - _ecore_con_cl_timer_update(cl); - e->client = cl; - if (duplicate) - { - e->data = malloc(num); - if (!e->data) - { - ERR("client data allocation failure !"); - _ecore_con_event_client_data_free(cl->host_server, e); - return; - } - memcpy(e->data, buf, num); - } - else - e->data = buf; - e->size = num; - ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e, - (Ecore_End_Cb)_ecore_con_event_client_data_free, cl->host_server); - _ecore_con_event_count++; -} - - -void -ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info) -{ - svr->infos = eina_list_remove(svr->infos, info); -} - -void -_ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate) -{ - Ecore_Con_Event_Server_Error *e; - - e = ecore_con_event_server_error_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - e->server = svr; - e->error = duplicate ? strdup(error) : error; - ERR("%s", error); - svr->event_count = eina_list_append(svr->event_count, e); - ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL); - _ecore_con_event_count++; -} - -void -ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error) -{ - Ecore_Con_Event_Client_Error *e; - - e = ecore_con_event_client_error_alloc(); - EINA_SAFETY_ON_NULL_RETURN(e); - - e->client = cl; - e->error = strdup(error); - ERR("%s", error); - cl->event_count = eina_list_append(cl->event_count, e); - cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); - ecore_event_add(ECORE_CON_EVENT_CLIENT_ERROR, e, (Ecore_End_Cb)_ecore_con_event_client_error_free, cl->host_server); - _ecore_con_event_count++; -} - -static void -_ecore_con_server_free(Ecore_Con_Server *svr) -{ - Ecore_Con_Client *cl; - double t_start, t; - - if (svr->event_count) return; - - while (svr->infos) - { - ecore_con_info_data_clear(svr->infos->data); - svr->infos = eina_list_remove_list(svr->infos, svr->infos); - } - - t_start = ecore_time_get(); - while (svr->buf && (!svr->delete_me)) - { - _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; - } - } - -#ifdef _WIN32 - ecore_con_local_win32_server_del(svr); -#endif - if (svr->event_count) return; - ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE); - - if (svr->buf) - eina_binbuf_free(svr->buf); - - EINA_LIST_FREE(svr->clients, cl) - { - Ecore_Con_Event_Server_Add *ev; - - /* some pointer hacks here to prevent double frees if people are being stupid */ - EINA_LIST_FREE(cl->event_count, ev) - ev->server = NULL; - cl->delete_me = EINA_TRUE; - INF("cl %p is dead", cl); - _ecore_con_client_free(cl); - } - if ((svr->created) && (svr->path) && (svr->ppid == getpid())) - unlink(svr->path); - - ecore_con_ssl_server_shutdown(svr); - free(svr->name); - - free(svr->path); - - eina_stringshare_del(svr->ip); - eina_stringshare_del(svr->verify_name); - - if (svr->ecs_buf) eina_binbuf_free(svr->ecs_buf); - if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); - - if (svr->fd_handler) - ecore_main_fd_handler_del(svr->fd_handler); - - if (svr->fd > 0) - close(svr->fd); - - if (svr->until_deletion) - ecore_timer_del(svr->until_deletion); - - servers = eina_list_remove(servers, svr); - svr->data = NULL; - free(svr); -} - -static void -_ecore_con_client_free(Ecore_Con_Client *cl) -{ - double t_start, t; - - if (cl->event_count) return; - - t_start = ecore_time_get(); - while ((cl->buf) && (!cl->delete_me)) - { - _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; - } - } - cl->host_server->clients = eina_list_remove(cl->host_server->clients, cl); - -#ifdef _WIN32 - ecore_con_local_win32_client_del(cl); -#endif - - if (cl->event_count) return; - ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE); - - if (cl->buf) eina_binbuf_free(cl->buf); - - if (cl->host_server->type & ECORE_CON_SSL) - ecore_con_ssl_client_shutdown(cl); - - if (cl->fd_handler) - ecore_main_fd_handler_del(cl->fd_handler); - - if (cl->fd > 0) - close(cl->fd); - - free(cl->client_addr); - cl->client_addr = NULL; - - if (cl->until_deletion) - ecore_timer_del(cl->until_deletion); - - eina_stringshare_del(cl->ip); - cl->data = NULL; - free(cl); - return; -} - -static Eina_Bool -_ecore_con_server_timer(Ecore_Con_Server *svr) -{ - ecore_con_server_del(svr); - - svr->until_deletion = NULL; - return ECORE_CALLBACK_CANCEL; -} - -static void -_ecore_con_server_timer_update(Ecore_Con_Server *svr) -{ - if (svr->disconnect_time) - { - if (svr->disconnect_time > 0) - { - if (svr->until_deletion) - ecore_timer_interval_set(svr->until_deletion, svr->disconnect_time); - else - svr->until_deletion = ecore_timer_add(svr->disconnect_time, (Ecore_Task_Cb)_ecore_con_server_timer, svr); - } - else if (svr->until_deletion) - { - ecore_timer_del(svr->until_deletion); - svr->until_deletion = NULL; - } - } - else - { - if (svr->until_deletion) - { - ecore_timer_del(svr->until_deletion); - svr->until_deletion = NULL; - } - } -} - -static Eina_Bool -_ecore_con_client_timer(Ecore_Con_Client *cl) -{ - ecore_con_client_del(cl); - - cl->until_deletion = NULL; - return ECORE_CALLBACK_CANCEL; -} - -static void -_ecore_con_cl_timer_update(Ecore_Con_Client *cl) -{ - if (cl->disconnect_time) - { - if (cl->disconnect_time > 0) - { - if (cl->until_deletion) - ecore_timer_interval_set(cl->until_deletion, cl->disconnect_time); - else - cl->until_deletion = ecore_timer_add(cl->disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl); - } - else if (cl->until_deletion) - { - ecore_timer_del(cl->until_deletion); - cl->until_deletion = NULL; - } - } - else - { - if (cl->host_server->client_disconnect_time > 0) - { - if (cl->until_deletion) - ecore_timer_interval_set(cl->until_deletion, cl->host_server->client_disconnect_time); - else - cl->until_deletion = ecore_timer_add(cl->host_server->client_disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl); - } - else if (cl->until_deletion) - { - ecore_timer_del(cl->until_deletion); - cl->until_deletion = NULL; - } - } -} - -static void -_ecore_con_cb_tcp_listen(void *data, - Ecore_Con_Info *net_info) -{ - Ecore_Con_Server *svr; - struct linger lin; - const char *memerr = NULL; - - svr = data; - - errno = 0; - if (!net_info) /* error message has already been handled */ - { - svr->delete_me = EINA_TRUE; - 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_TYPE) == ECORE_CON_REMOTE_NODELAY) - { -#ifdef HAVE_NETINET_TCP_H - int flag = 1; - - if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, - sizeof(int)) < 0) -#endif - { - 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_tcp_handler, svr, NULL, NULL); - if (!svr->fd_handler) - { - memerr = "Memory allocation failure"; - goto error; - } - - return; - -error: - if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); - ecore_con_ssl_server_shutdown(svr); - _ecore_con_server_kill(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; -#ifdef HAVE_IPV6 - struct ipv6_mreq mreq6; -#endif - const int on = 1; - const char *memerr = NULL; - - svr = data; - type = svr->type; - type &= ECORE_CON_TYPE; - - errno = 0; - if (!net_info) /* error message has already been handled */ - { - svr->delete_me = EINA_TRUE; - 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; - } -#ifdef HAVE_IPV6 - 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; - } -#endif - } - - 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) - { - memerr = "Memory allocation failure"; - goto error; - } - - svr->ip = eina_stringshare_add(net_info->ip); - - return; - -error: - if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); - ecore_con_ssl_server_shutdown(svr); - _ecore_con_server_kill(svr); -} - -static void -_ecore_con_cb_tcp_connect(void *data, - Ecore_Con_Info *net_info) -{ - Ecore_Con_Server *svr; - int res; - int curstate = 0; - const char *memerr = NULL; - - svr = data; - - errno = 0; - if (!net_info) /* error message has already been handled */ - { - svr->delete_me = EINA_TRUE; - 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_TYPE) == ECORE_CON_REMOTE_NODELAY) - { -#ifdef HAVE_NETINET_TCP_H - int flag = 1; - - if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0) -#endif - { - 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) - { - char *err; - err = evil_format_message(WSAGetLastError()); - _ecore_con_event_server_error(svr, err, EINA_FALSE); - ecore_con_ssl_server_shutdown(svr); - _ecore_con_server_kill(svr); - return; - } - -#else - if (res < 0) - { - if (errno != EINPROGRESS) goto error; -#endif - svr->connecting = EINA_TRUE; - 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) - { - svr->handshaking = EINA_TRUE; - svr->ssl_state = ECORE_CON_SSL_STATE_INIT; - DBG("%s ssl handshake", svr->ecs_state ? "Queuing" : "Beginning"); - if ((!svr->ecs_state) && ecore_con_ssl_server_init(svr)) - goto error; - } - - if (!svr->fd_handler) - { - memerr = "Memory allocation failure"; - goto error; - } - - if ((!svr->ecs) || (svr->ecs->lookup)) - svr->ip = eina_stringshare_add(net_info->ip); - - return; - -error: - if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); - ecore_con_ssl_server_shutdown(svr); - _ecore_con_server_kill(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; - const char *memerr = NULL; - svr = data; - - errno = 0; - if (!net_info) /* error message has already been handled */ - { - svr->delete_me = EINA_TRUE; - 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_TYPE) == ECORE_CON_REMOTE_BROADCAST) - { - if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST, - (const void *)&broadcast, - sizeof(broadcast)) < 0) - { - goto error; - } - } - 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; - - 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) - { - memerr = "Memory allocation failure"; - goto error; - } - - if ((!svr->ecs) || (svr->ecs->lookup)) - svr->ip = eina_stringshare_add(net_info->ip); - - return; - -error: - if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); - ecore_con_ssl_server_shutdown(svr); - _ecore_con_server_kill(svr); -} - -static Ecore_Con_State -svr_try_connect_plain(Ecore_Con_Server *svr) -{ - int res; - int so_err = 0; - socklen_t size = sizeof(int); - - res = getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, (void *)&so_err, &size); -#ifdef _WIN32 - if (res == SOCKET_ERROR) - so_err = WSAGetLastError(); - - if ((so_err == WSAEINPROGRESS) && !svr->delete_me) - return ECORE_CON_INPROGRESS; - -#else - if (res < 0) - so_err = errno; - - if ((so_err == EINPROGRESS) && !svr->delete_me) - return ECORE_CON_INPROGRESS; - -#endif - - if (so_err) - { - /* we lost our server! */ - ecore_con_event_server_error(svr, strerror(so_err)); - ERR("Connection lost: %s", strerror(so_err)); - _ecore_con_server_kill(svr); - return ECORE_CON_DISCONNECTED; - } - - if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting) - { - if (svr->ecs) - { - if (ecore_con_socks_svr_init(svr)) - return ECORE_CON_INPROGRESS; - } - else - ecore_con_event_server_add(svr); - } - - if (svr->fd_handler && (!svr->buf)) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); - - if (!svr->delete_me) - return ECORE_CON_CONNECTED; - else - return ECORE_CON_DISCONNECTED; -} - -static const char * -_ecore_con_pretty_ip(struct sockaddr *client_addr) -{ -#ifndef HAVE_IPV6 - char ipbuf[INET_ADDRSTRLEN + 1]; -#else - char ipbuf[INET6_ADDRSTRLEN + 1]; -#endif - int family = client_addr->sa_family; - void *src; - - switch(family) - { - case AF_INET: - src = &(((struct sockaddr_in *)client_addr)->sin_addr); - break; -#ifdef HAVE_IPV6 - case AF_INET6: - src = &(((struct sockaddr_in6 *)client_addr)->sin6_addr); - - if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) - { - family = AF_INET; - src = (char*)src + 12; - } - break; -#endif - default: - return eina_stringshare_add("0.0.0.0"); - } - - if (!inet_ntop(family, src, ipbuf, sizeof(ipbuf))) - return eina_stringshare_add("0.0.0.0"); - - ipbuf[sizeof(ipbuf) - 1] = 0; - return eina_stringshare_add(ipbuf); -} - -static Eina_Bool -_ecore_con_svr_tcp_handler(void *data, - Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - Ecore_Con_Server *svr; - Ecore_Con_Client *cl = NULL; - unsigned char client_addr[256]; - unsigned int client_addr_len; - const char *clerr = NULL; - - svr = data; - if (svr->delete_me) - return ECORE_CALLBACK_RENEW; - - if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && - (svr->client_count >= (unsigned int)svr->client_limit)) - return ECORE_CALLBACK_RENEW; - - /* a new client */ - - cl = calloc(1, sizeof(Ecore_Con_Client)); - if (!cl) - { - ecore_con_event_server_error(svr, "Memory allocation failure when attempting to add a new client"); - return ECORE_CALLBACK_RENEW; - } - cl->host_server = svr; - - client_addr_len = sizeof(client_addr); - memset(&client_addr, 0, client_addr_len); - cl->fd = accept(svr->fd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addr_len); - if (cl->fd < 0) goto error; - if ((svr->client_limit >= 0) && (svr->reject_excess_clients) && - (svr->client_count >= (unsigned int)svr->client_limit)) - { - clerr = "Maximum client limit reached"; - goto error; - } - - if (fcntl(cl->fd, F_SETFL, O_NONBLOCK) < 0) goto error; - if (fcntl(cl->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; - cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ, - _ecore_con_svr_cl_handler, cl, NULL, NULL); - if (!cl->fd_handler) goto error; - ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); - - if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL)) - { - cl->handshaking = EINA_TRUE; - cl->ssl_state = ECORE_CON_SSL_STATE_INIT; - if (ecore_con_ssl_client_init(cl)) - goto error; - } - - cl->client_addr = malloc(client_addr_len); - if (!cl->client_addr) - { - clerr = "Memory allocation failure when attempting to add a new client"; - goto error; - } - cl->client_addr_len = client_addr_len; - memcpy(cl->client_addr, &client_addr, client_addr_len); - - svr->clients = eina_list_append(svr->clients, cl); - svr->client_count++; - - if ((!cl->delete_me) && (!cl->handshaking)) - ecore_con_event_client_add(cl); - - return ECORE_CALLBACK_RENEW; - -error: - if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler); - if (cl->fd >= 0) close(cl->fd); - { - Ecore_Event *ev; - - EINA_LIST_FREE(cl->event_count, ev) - { - svr->event_count = eina_list_remove(svr->event_count, ev); - ecore_event_del(ev); - } - } - free(cl); - if (clerr || errno) ecore_con_event_server_error(svr, clerr ?: strerror(errno)); - return ECORE_CALLBACK_RENEW; -} - -static void -_ecore_con_cl_read(Ecore_Con_Server *svr) -{ - int num = 0; - Eina_Bool lost_server = EINA_TRUE; - unsigned char buf[READBUFSIZ]; - - DBG("svr=%p", svr); - - /* only possible with non-ssl connections */ - if (svr->connecting && (svr_try_connect_plain(svr) != ECORE_CON_CONNECTED)) - return; - - if (svr->handshaking && (!svr->ecs_state)) - { - DBG("Continuing ssl handshake"); - if (!ecore_con_ssl_server_init(svr)) - lost_server = EINA_FALSE; - _ecore_con_server_timer_update(svr); - } - - if (svr->ecs_state || !(svr->type & ECORE_CON_SSL)) - { - errno = 0; - num = read(svr->fd, buf, sizeof(buf)); - /* 0 is not a valid return value for a tcp socket */ - if ((num > 0) || ((num < 0) && (errno == EAGAIN))) - lost_server = EINA_FALSE; - else if (num < 0) - ecore_con_event_server_error(svr, strerror(errno)); - } - else - { - num = ecore_con_ssl_server_read(svr, buf, sizeof(buf)); - /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */ - if (num >= 0) - lost_server = EINA_FALSE; - } - - if ((!svr->delete_me) && (num > 0)) - { - if (svr->ecs_state) - ecore_con_socks_read(svr, buf, num); - else - ecore_con_event_server_data(svr, buf, num, EINA_TRUE); - } - - if (lost_server) - _ecore_con_server_kill(svr); -} - -static Eina_Bool -_ecore_con_cl_handler(void *data, - Ecore_Fd_Handler *fd_handler) -{ - Ecore_Con_Server *svr; - Eina_Bool want_read, want_write; - - svr = data; - if (svr->delete_me) - return ECORE_CALLBACK_RENEW; - - if (svr->delete_me) - return ECORE_CALLBACK_RENEW; - - want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); - want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); - - if ((!svr->ecs_state) && svr->handshaking && (want_read || want_write)) - { - DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write"); -#ifdef ISCOMFITOR - if (want_read) - { - char buf[READBUFSIZ]; - ssize_t len; - len = recv(svr->fd, buf, sizeof(buf), MSG_DONTWAIT | MSG_PEEK); - DBG("%zu bytes in buffer", len); - } -#endif - if (ecore_con_ssl_server_init(svr)) - { - ERR("ssl handshaking failed!"); - svr->handshaking = EINA_FALSE; - } - else if (!svr->ssl_state) - ecore_con_event_server_add(svr); - return ECORE_CALLBACK_RENEW; - } - if (svr->ecs && svr->ecs_state && (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) && (!svr->ecs_buf)) - { - if (svr->ecs_state < ECORE_CON_PROXY_STATE_INIT) - { - INF("PROXY STATE++"); - svr->ecs_state++; - } - if (ecore_con_socks_svr_init(svr)) return ECORE_CALLBACK_RENEW; - } - if (want_read) - _ecore_con_cl_read(svr); - else if (want_write) /* only possible with non-ssl connections */ - { - if (svr->connecting && (!svr_try_connect_plain(svr)) && (!svr->ecs_state)) - return ECORE_CALLBACK_RENEW; - - _ecore_con_server_flush(svr); - } - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_ecore_con_cl_udp_handler(void *data, - Ecore_Fd_Handler *fd_handler) -{ - unsigned char buf[READBUFSIZ]; - int num; - Ecore_Con_Server *svr; - Eina_Bool want_read, want_write; - - want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); - want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); - - svr = data; - if (svr->delete_me || ((!want_read) && (!want_write))) - return ECORE_CALLBACK_RENEW; - - if (want_write) - { - _ecore_con_server_flush(svr); - return ECORE_CALLBACK_RENEW; - } - - num = read(svr->fd, buf, READBUFSIZ); - - if ((!svr->delete_me) && (num > 0)) - ecore_con_event_server_data(svr, buf, num, EINA_TRUE); - - if (num < 0 && (errno != EAGAIN) && (errno != EINTR)) - { - ecore_con_event_server_error(svr, strerror(errno)); - _ecore_con_server_kill(svr); - } - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_ecore_con_svr_udp_handler(void *data, - Ecore_Fd_Handler *fd_handler) -{ - unsigned char buf[READBUFSIZ]; - unsigned char client_addr[256]; - socklen_t client_addr_len = sizeof(client_addr); - int num; - Ecore_Con_Server *svr; - Ecore_Con_Client *cl = NULL; - - svr = data; - - if (svr->delete_me) - return ECORE_CALLBACK_RENEW; - - if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) - { - _ecore_con_client_flush(cl); - return ECORE_CALLBACK_RENEW; - } - - if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) - return ECORE_CALLBACK_RENEW; - -#ifdef _WIN32 - num = fcntl(svr->fd, F_SETFL, O_NONBLOCK); - if (num >= 0) - num = recvfrom(svr->fd, (char *)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 && (errno != EAGAIN) && (errno != EINTR)) - { - ecore_con_event_server_error(svr, strerror(errno)); - if (!svr->delete_me) - ecore_con_event_client_del(NULL); - _ecore_con_server_kill(svr); - return ECORE_CALLBACK_CANCEL; - } - - -/* Create a new client for use in the client data event */ - cl = calloc(1, sizeof(Ecore_Con_Client)); - EINA_SAFETY_ON_NULL_RETURN_VAL(cl, ECORE_CALLBACK_RENEW); - - cl->host_server = svr; - cl->client_addr = malloc(client_addr_len); - if (!cl->client_addr) - { - free(cl); - return ECORE_CALLBACK_RENEW; - } - cl->client_addr_len = client_addr_len; - - 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); - svr->client_count++; - - ecore_con_event_client_add(cl); - ecore_con_event_client_data(cl, buf, num, EINA_TRUE); - - return ECORE_CALLBACK_RENEW; -} - -static void -_ecore_con_svr_cl_read(Ecore_Con_Client *cl) -{ - int num = 0; - Eina_Bool lost_client = EINA_TRUE; - unsigned char buf[READBUFSIZ]; - - DBG("cl=%p", cl); - - if (cl->handshaking) - { - /* add an extra handshake attempt just before read, even though - * read also attempts to handshake, to try to finish sooner - */ - if (ecore_con_ssl_client_init(cl)) - lost_client = EINA_FALSE; - - _ecore_con_cl_timer_update(cl); - } - - if (!(cl->host_server->type & ECORE_CON_SSL) && (!cl->upgrade)) - { - num = read(cl->fd, buf, sizeof(buf)); - /* 0 is not a valid return value for a tcp socket */ - if ((num > 0) || ((num < 0) && ((errno == EAGAIN) || (errno == EINTR)))) - lost_client = EINA_FALSE; - else if (num < 0) - ecore_con_event_client_error(cl, strerror(errno)); - } - else - { - num = ecore_con_ssl_client_read(cl, buf, sizeof(buf)); - /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */ - if (num >= 0) - lost_client = EINA_FALSE; - } - - if ((!cl->delete_me) && (num > 0)) - ecore_con_event_client_data(cl, buf, num, EINA_TRUE); - - if (lost_client) _ecore_con_client_kill(cl); -} - -static Eina_Bool -_ecore_con_svr_cl_handler(void *data, - Ecore_Fd_Handler *fd_handler) -{ - Ecore_Con_Client *cl; - - cl = data; - if (cl->delete_me) - return ECORE_CALLBACK_RENEW; - - if (cl->handshaking && ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ | ECORE_FD_WRITE)) - { - if (ecore_con_ssl_client_init(cl)) - { - ERR("ssl handshaking failed!"); - _ecore_con_client_kill(cl); - return ECORE_CALLBACK_RENEW; - } - else if (!cl->ssl_state) - ecore_con_event_client_add(cl); - } - else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) - _ecore_con_svr_cl_read(cl); - - else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) - _ecore_con_client_flush(cl); - - return ECORE_CALLBACK_RENEW; -} - -static void -_ecore_con_server_flush(Ecore_Con_Server *svr) -{ - int count, num; - size_t buf_len, buf_offset; - const unsigned char *buf; - - DBG("(svr=%p,buf=%p)", svr, svr->buf); -#ifdef _WIN32 - if (ecore_con_local_win32_server_flush(svr)) - return; -#endif - - if ((!svr->buf) && (!svr->ecs_buf) && svr->fd_handler) - { - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); - return; - } - - buf = svr->buf ? eina_binbuf_string_get(svr->buf) : eina_binbuf_string_get(svr->ecs_buf); - buf_len = svr->buf ? eina_binbuf_length_get(svr->buf) : eina_binbuf_length_get(svr->ecs_buf); - buf_offset = svr->buf ? svr->write_buf_offset : svr->ecs_buf_offset; - num = buf_len - buf_offset; - - /* check whether we need to write anything at all. - * we must not write zero bytes with SSL_write() since it - * causes undefined behaviour - */ - /* we thank Tommy[D] for needing to check negative buffer sizes - * here because his system is amazing. - */ - if (num <= 0) return; - - if ((!svr->ecs_state) && svr->handshaking) - { - DBG("Continuing ssl handshake"); - if (ecore_con_ssl_server_init(svr)) - _ecore_con_server_kill(svr); - _ecore_con_server_timer_update(svr); - return; - } - - if (svr->ecs_state || (!(svr->type & ECORE_CON_SSL))) - count = write(svr->fd, buf + buf_offset, num); - else - count = ecore_con_ssl_server_write(svr, buf + buf_offset, num); - - if (count < 0) - { - if ((errno != EAGAIN) && (errno != EINTR)) - { - ecore_con_event_server_error(svr, strerror(errno)); - _ecore_con_server_kill(svr); - } - return; - } - - if (count && (!svr->ecs_state)) ecore_con_event_server_write(svr, count); - if (svr->ecs_buf) - buf_offset = svr->ecs_buf_offset += count; - else - buf_offset = svr->write_buf_offset += count; - if (buf_offset >= buf_len) - { - if (svr->ecs_buf) - { - svr->ecs_buf_offset = 0; - eina_binbuf_free(svr->ecs_buf); - svr->ecs_buf = NULL; - INF("PROXY STATE++"); - svr->ecs_state++; - } - else - { - svr->write_buf_offset = 0; - eina_binbuf_free(svr->buf); - svr->buf = NULL; -#ifdef TCP_CORK - if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK) - { - int state = 0; - if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) - /* realistically this isn't anything serious so we can just log and continue */ - ERR("uncorking failed! %s", strerror(errno)); - } -#endif - } - if (svr->fd_handler) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); - } - else if ((count < num) && svr->fd_handler) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); -} - -static void -_ecore_con_client_flush(Ecore_Con_Client *cl) -{ - int num = 0, count = 0; - -#ifdef _WIN32 - if (ecore_con_local_win32_client_flush(cl)) - return; -#endif - - if (!cl->buf && cl->fd_handler) - { - ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); - return; - } - - if (cl->handshaking) - { - if (ecore_con_ssl_client_init(cl)) - count = -1; - - _ecore_con_cl_timer_update(cl); - } - - if (!count) - { - if (!cl->buf) return; - num = eina_binbuf_length_get(cl->buf) - cl->buf_offset; - if (num <= 0) return; - if (!(cl->host_server->type & ECORE_CON_SSL) && (!cl->upgrade)) - count = write(cl->fd, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); - else - count = ecore_con_ssl_client_write(cl, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); - } - - if (count < 0) - { - if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me)) - { - ecore_con_event_client_error(cl, strerror(errno)); - _ecore_con_client_kill(cl); - } - - return; - } - - if (count) ecore_con_event_client_write(cl, count); - cl->buf_offset += count, num -= count; - if (cl->buf_offset >= eina_binbuf_length_get(cl->buf)) - { - cl->buf_offset = 0; - eina_binbuf_free(cl->buf); - cl->buf = NULL; -#ifdef TCP_CORK - if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK) - { - int state = 0; - if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) - /* realistically this isn't anything serious so we can just log and continue */ - ERR("uncorking failed! %s", strerror(errno)); - } -#endif - if (cl->fd_handler) - ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); - } - else if (cl->fd_handler && (num >= 0)) - ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); -} - -static void -_ecore_con_event_client_add_free(Ecore_Con_Server *svr, - void *ev) -{ - Ecore_Con_Event_Client_Add *e; - - e = ev; - if (e->client) - { - e->client->event_count = eina_list_remove(e->client->event_count, e); - if (e->client->host_server) - { - e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); - if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); - } - if ((!e->client->event_count) && (e->client->delete_me)) - ecore_con_client_del(e->client); - } - - ecore_con_event_client_add_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_event_client_del_free(Ecore_Con_Server *svr, - void *ev) -{ - Ecore_Con_Event_Client_Del *e; - - e = ev; - if (e->client) - { - e->client->event_count = eina_list_remove(e->client->event_count, e); - if (e->client->host_server) - { - e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); - if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); - } - if (!e->client->event_count) - _ecore_con_client_free(e->client); - } - ecore_con_event_client_del_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_event_client_write_free(Ecore_Con_Server *svr, - Ecore_Con_Event_Client_Write *e) -{ - if (e->client) - { - e->client->event_count = eina_list_remove(e->client->event_count, e); - if (e->client->host_server) - { - e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); - if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); - } - if (((!e->client->event_count) && (e->client->delete_me)) || - ((e->client->host_server && - ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || - (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) - ecore_con_client_del(e->client); - } - ecore_con_event_client_write_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_event_client_data_free(Ecore_Con_Server *svr, - void *ev) -{ - Ecore_Con_Event_Client_Data *e; - - e = ev; - if (e->client) - { - e->client->event_count = eina_list_remove(e->client->event_count, e); - if (e->client->host_server) - { - e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); - } - if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); - if (((!e->client->event_count) && (e->client->delete_me)) || - ((e->client->host_server && - ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || - (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) - ecore_con_client_del(e->client); - } - free(e->data); - ecore_con_event_client_data_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_event_server_add_free(void *data EINA_UNUSED, - void *ev) -{ - Ecore_Con_Event_Server_Add *e; - - e = ev; - if (e->server) - { - e->server->event_count = eina_list_remove(e->server->event_count, ev); - if ((!e->server->event_count) && (e->server->delete_me)) - _ecore_con_server_free(e->server); - } - ecore_con_event_server_add_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_event_server_del_free(void *data EINA_UNUSED, - void *ev) -{ - Ecore_Con_Event_Server_Del *e; - - e = ev; - if (e->server) - { - e->server->event_count = eina_list_remove(e->server->event_count, ev); - if (!e->server->event_count) - _ecore_con_server_free(e->server); - } - ecore_con_event_server_del_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_event_server_write_free(void *data EINA_UNUSED, - Ecore_Con_Event_Server_Write *e) -{ - if (e->server) - { - e->server->event_count = eina_list_remove(e->server->event_count, e); - if ((!e->server->event_count) && (e->server->delete_me)) - _ecore_con_server_free(e->server); - } - - ecore_con_event_server_write_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_event_server_data_free(void *data EINA_UNUSED, - void *ev) -{ - Ecore_Con_Event_Server_Data *e; - - e = ev; - if (e->server) - { - e->server->event_count = eina_list_remove(e->server->event_count, ev); - if ((!e->server->event_count) && (e->server->delete_me)) - _ecore_con_server_free(e->server); - } - - free(e->data); - ecore_con_event_server_data_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - - -static void -_ecore_con_event_server_error_free(void *data EINA_UNUSED, Ecore_Con_Event_Server_Error *e) -{ - if (e->server) - { - e->server->event_count = eina_list_remove(e->server->event_count, e); - if ((!e->server->event_count) && (e->server->delete_me)) - _ecore_con_server_free(e->server); - } - free(e->error); - ecore_con_event_server_error_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_event_client_error_free(Ecore_Con_Server *svr, Ecore_Con_Event_Client_Error *e) -{ - if (e->client) - { - if (eina_list_data_find(svr->clients, e->client)) - { - e->client->event_count = eina_list_remove(e->client->event_count, e); - if ((!e->client->event_count) && (e->client->delete_me)) - _ecore_con_client_free(e->client); - } - svr->event_count = eina_list_remove(svr->event_count, e); - if ((!svr->event_count) && (svr->delete_me)) - _ecore_con_server_free(svr); - } - free(e->error); - ecore_con_event_client_error_free(e); - _ecore_con_event_count--; - if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) - ecore_con_mempool_shutdown(); -} - -static void -_ecore_con_lookup_done(void *data, - Ecore_Con_Info *infos) -{ - Ecore_Con_Server *svr; - Ecore_Con_Lookup *lk; - - svr = data; - lk = svr->data; - - if (infos) - lk->done_cb(infos->info.ai_canonname, infos->ip, - infos->info.ai_addr, infos->info.ai_addrlen, - (void *)lk->data); - else - lk->done_cb(NULL, NULL, NULL, 0, (void *)lk->data); - - free(svr->name); - free(lk); - free(svr); -} - diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_alloc.c b/legacy/ecore/src/lib/ecore_con/ecore_con_alloc.c deleted file mode 100644 index 324d47d100..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_alloc.c +++ /dev/null @@ -1,101 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "Ecore.h" -#include "ecore_private.h" -#include "Ecore_Con.h" -#include "ecore_con_private.h" - -typedef struct _Ecore_Con_Mempool Ecore_Con_Mempool; -struct _Ecore_Con_Mempool -{ - const char *name; - Eina_Mempool *mp; - size_t size; -}; - -#define GENERIC_ALLOC_FREE(TYPE, Type) \ - Ecore_Con_Mempool Type##_mp = { #TYPE, NULL, sizeof (TYPE) }; \ - \ - TYPE * \ - Type##_alloc(void) \ - { \ - return eina_mempool_malloc(Type##_mp.mp, sizeof (TYPE)); \ - } \ - \ - void \ - Type##_free(TYPE *e) \ - { \ - eina_mempool_free(Type##_mp.mp, e); \ - } - -GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Add, ecore_con_event_client_add); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Del, ecore_con_event_client_del); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Write, ecore_con_event_client_write); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Data, ecore_con_event_client_data); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Error, ecore_con_event_server_error); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Error, ecore_con_event_client_error); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); -GENERIC_ALLOC_FREE(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind); - -static Ecore_Con_Mempool *mempool_array[] = { - &ecore_con_event_client_add_mp, - &ecore_con_event_client_del_mp, - &ecore_con_event_client_write_mp, - &ecore_con_event_client_data_mp, - &ecore_con_event_server_error_mp, - &ecore_con_event_client_error_mp, - &ecore_con_event_server_add_mp, - &ecore_con_event_server_del_mp, - &ecore_con_event_server_write_mp, - &ecore_con_event_server_data_mp, - &ecore_con_event_proxy_bind_mp -}; - -void -ecore_con_mempool_init(void) -{ - const char *choice; - unsigned int i; - - choice = getenv("EINA_MEMPOOL"); - if (!choice || !choice[0]) - choice = "chained_mempool"; - - for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) - { - retry: - mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 16); - if (!mempool_array[i]->mp) - { - if (!(!strcmp(choice, "pass_through"))) - { - ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice); - choice = "pass_through"; - goto retry; - } - else - { - ERR("Impossible to allocate mempool '%s' !", choice); - return ; - } - } - } -} - -void -ecore_con_mempool_shutdown(void) -{ - unsigned int i; - - for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) - { - eina_mempool_del(mempool_array[i]->mp); - mempool_array[i]->mp = NULL; - } -} - diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_ares.c b/legacy/ecore/src/lib/ecore_con/ecore_con_ares.c deleted file mode 100644 index 3c0ca22c85..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_ares.c +++ /dev/null @@ -1,628 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#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 -#include - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#include - -#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; - Ecore_Timer *timer; - 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; -#ifdef HAVE_IPV6 - struct in6_addr v6; -#endif - } addr; - - Eina_Bool byaddr : 1; - Eina_Bool isv6 : 1; -}; - -static ares_channel info_channel; -static int info_init = 0; -static Eina_List *info_fds = NULL; - -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 Eina_Bool _ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf, - Ecore_Fd_Handler *fd_handler); -static Eina_Bool _ecore_con_info_cares_timeout_cb(void *data); - -static void -_ecore_con_info_cares_state_cb(void *data, - ares_socket_t fd, - int readable, - int writable); -static int -_ecore_con_info_fds_search(const Ecore_Con_FD *fd1, - const Ecore_Con_FD *fd2); - -int -ecore_con_info_init(void) -{ - struct ares_options opts; - - if (!info_init) - { - if (ares_library_init(ARES_LIB_INIT_ALL)) - return 0; - - opts.lookups = "fb"; /* hosts file then dns */ - opts.sock_state_cb = _ecore_con_info_cares_state_cb; - - if (ares_init_options(&info_channel, &opts, - ARES_OPT_LOOKUPS | ARES_OPT_SOCK_STATE_CB) != 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); - - /* 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - 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); -} - -static Eina_Bool -_ecore_con_info_ares_getnameinfo(Ecore_Con_CAres *arg, - int addrtype, - const char *name, - struct sockaddr *addr, - int addrlen) -{ - int length = 0; - - if (name) - length = strlen(name) + 1; - else - length = 1; - - arg->result = malloc(sizeof(Ecore_Con_Info) + length); - if (!arg->result) - return EINA_FALSE; - - /* 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 = addrtype; - arg->result->info.ai_addrlen = addrlen; - arg->result->info.ai_addr = addr; - arg->result->info.ai_canonname = (char *)(arg->result + 1); - - if (!name) - *arg->result->info.ai_canonname = '\0'; - else - strcpy(arg->result->info.ai_canonname, 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); - - return EINA_TRUE; -} - -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; -#ifdef HAVE_IPV6 - int ai_family = AF_INET6; -#else - int ai_family = AF_INET; -#endif - - 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->ecs ? svr->ecs->ip : svr->name, &cares->addr.v4) == 1) - { - cares->byaddr = EINA_TRUE; - cares->isv6 = EINA_FALSE; - ares_gethostbyaddr(info_channel, &cares->addr.v4, - sizeof(cares->addr.v4), - AF_INET, - (ares_host_callback)_ecore_con_info_ares_host_cb, - cares); - } -#ifdef HAVE_IPV6 - else if (inet_pton(AF_INET6, svr->ecs ? svr->ecs->ip : svr->name, &cares->addr.v6) == 1) - { - cares->byaddr = EINA_TRUE; - cares->isv6 = 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); - } -#endif - else - { - cares->byaddr = EINA_FALSE; - ares_gethostbyname(info_channel, svr->ecs ? svr->ecs->ip : svr->name, ai_family, - (ares_host_callback)_ecore_con_info_ares_host_cb, - cares); - } - - svr->infos = eina_list_append(svr->infos, cares); - return 1; -} - -void -ecore_con_info_data_clear(void *info) -{ - Ecore_Con_CAres *cares = info; - if (cares) cares->data = NULL; -} - -static Eina_Bool -_ecore_con_info_cares_timeout_cb(void *data EINA_UNUSED) -{ - ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf, - Ecore_Fd_Handler *fd_handler) -{ - ares_socket_t read_fd, write_fd; - - read_fd = write_fd = ARES_SOCKET_BAD; - - if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) - read_fd = ecf->fd; - if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) - write_fd = ecf->fd; - - ares_process_fd(info_channel, read_fd, write_fd); - - return ECORE_CALLBACK_RENEW; -} - -static int -_ecore_con_info_fds_search(const Ecore_Con_FD *fd1, - const Ecore_Con_FD *fd2) -{ - return fd1->fd - fd2->fd; -} - -static void -_ecore_con_info_cares_state_cb(void *data EINA_UNUSED, - ares_socket_t fd, - int readable, - int writable) -{ - int flags = 0; - Ecore_Con_FD *search = NULL, *ecf = NULL; - - search = eina_list_search_unsorted(info_fds, - (Eina_Compare_Cb)_ecore_con_info_fds_search, &ecf); - - if (!(readable | writable)) - { - ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); - if (search) - { - info_fds = eina_list_remove(info_fds, search); - ecore_timer_del(search->timer); - ecore_main_fd_handler_del(search->handler); - free(search); - } - return; - } - - if (!search) - { - search = malloc(sizeof(Ecore_Con_FD)); - EINA_SAFETY_ON_NULL_RETURN(search); - - search->fd = fd; - search->handler = ecore_main_fd_handler_add(fd, ECORE_FD_WRITE | ECORE_FD_READ, - (Ecore_Fd_Cb)_ecore_con_info_cares_fd_cb, search, NULL, NULL); - /* c-ares default timeout is 5 seconds */ - search->timer = ecore_timer_add(5, _ecore_con_info_cares_timeout_cb, NULL); - info_fds = eina_list_append(info_fds, search); - } - - if (readable) flags |= ECORE_FD_READ; - if (writable) flags |= ECORE_FD_WRITE; - ecore_main_fd_handler_active_set(search->handler, flags); -} - -static void -_ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, - int status, - int timeouts EINA_UNUSED, - struct hostent *hostent) -{ - struct sockaddr *addr; - int addrlen; - - /* Found something ? */ - switch (status) - { - case ARES_SUCCESS: - if (!hostent->h_addr_list[0]) - { - ERR("No IP found"); - goto on_error; - } - - switch (hostent->h_addrtype) - { - case AF_INET: - { - struct sockaddr_in *addri; - - addrlen = sizeof(struct sockaddr_in); - addri = malloc(addrlen); - - if (!addri) - goto on_mem_error; - - addri->sin_family = AF_INET; - addri->sin_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port); - - memcpy(&addri->sin_addr.s_addr, - hostent->h_addr_list[0], sizeof(struct in_addr)); - - addr = (struct sockaddr *)addri; - break; - } -#ifdef HAVE_IPV6 - case AF_INET6: - { - struct sockaddr_in6 *addri6; - - addrlen = sizeof(struct sockaddr_in6); - addri6 = malloc(addrlen); - - if (!addri6) - goto on_mem_error; - - addri6->sin6_family = AF_INET6; - addri6->sin6_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port); - addri6->sin6_flowinfo = 0; - addri6->sin6_scope_id = 0; - - memcpy(&addri6->sin6_addr.s6_addr, - hostent->h_addr_list[0], sizeof(struct in6_addr)); - - addr = (struct sockaddr *)addri6; - break; - } -#endif - default: - ERR("Unknown addrtype %i", hostent->h_addrtype); - goto on_error; - } - - if (!_ecore_con_info_ares_getnameinfo(arg, hostent->h_addrtype, - hostent->h_name, - addr, addrlen)) - goto on_error; - - break; - - case ARES_ENOTFOUND: /* address notfound */ - if (arg->byaddr) - { -#ifdef HAVE_IPV6 - /* This happen when host doesn't have a reverse. */ - if (arg->isv6) - { - struct sockaddr_in6 *addri6; - - addrlen = sizeof(struct sockaddr_in6); - addri6 = malloc(addrlen); - - if (!addri6) - goto on_mem_error; - - addri6->sin6_family = AF_INET6; - addri6->sin6_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port); - addri6->sin6_flowinfo = 0; - addri6->sin6_scope_id = 0; - - memcpy(&addri6->sin6_addr.s6_addr, - &arg->addr.v6, sizeof(struct in6_addr)); - - addr = (struct sockaddr *)addri6; - } - else -#endif - { - struct sockaddr_in *addri; - - addrlen = sizeof(struct sockaddr_in); - addri = malloc(addrlen); - - if (!addri) - goto on_mem_error; - - addri->sin_family = AF_INET; - addri->sin_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port); - - memcpy(&addri->sin_addr.s_addr, - &arg->addr.v4, sizeof(struct in_addr)); - - addr = (struct sockaddr *)addri; - } - - if (!_ecore_con_info_ares_getnameinfo(arg, -#ifdef HAVE_IPV6 - arg->isv6 ? AF_INET6 : -#endif - AF_INET, - NULL, addr, - addrlen)) - goto on_error; - - break; - } - - case ARES_ENOTIMP: /* unknown family */ - case ARES_EBADNAME: /* not a valid internet address */ - case ARES_ENOMEM: /* not enough memory */ - case ARES_EDESTRUCTION: /* request canceled, shuting down */ - case ARES_ENODATA: /* no data returned */ - case ARES_ECONNREFUSED: /* connection refused */ - case ARES_ETIMEOUT: /* connection timed out */ - ecore_con_event_server_error(arg->svr, ares_strerror(status)); - goto on_error; - - default: - ERR("Unknown status returned by c-ares: %i assuming error", status); - ecore_con_event_server_error(arg->svr, ares_strerror(status)); - goto on_error; - } - - return; - -on_mem_error: - ERR("Not enough memory"); - -on_error: - if (arg->data) - { - ecore_con_server_infos_del(arg->data, arg); - arg->done_cb(arg->data, NULL); - } - free(arg); -} - -static void -_ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg, - int status, - int timeouts EINA_UNUSED, - 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'; - - if (arg->data) arg->done_cb(arg->data, arg->result); - break; - - case ARES_ENOTIMP: - case ARES_ENOTFOUND: - case ARES_ENOMEM: - case ARES_EDESTRUCTION: - case ARES_EBADFLAGS: - ecore_con_event_server_error(arg->svr, ares_strerror(status)); - if (arg->data) arg->done_cb(arg->data, NULL); - break; - } - - free(arg->result->info.ai_addr); - free(arg->result); - if (arg->data) ecore_con_server_infos_del(arg->data, arg); - free(arg); -} - diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_dns.c b/legacy/ecore/src/lib/ecore_con/ecore_con_dns.c deleted file mode 100644 index 7851d0db82..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_dns.c +++ /dev/null @@ -1,344 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * This version of ecore_con_info uses dns.c to provide asynchronous dns lookup. - * - * dns.c is written by William Ahern: - * http://25thandclement.com/~william/projects/dns.c.html - */ - -#include -#include - -#ifdef HAVE_ERRNO_H -# include /* for EAGAIN */ -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_ERRNO_H -# include -#endif - -#include "dns.h" - -#include "Ecore.h" -#include "Ecore_Con.h" -#include "ecore_con_private.h" - -typedef struct dns_addrinfo dns_addrinfo; -typedef struct dns_resolv_conf dns_resolv_conf; -typedef struct dns_resolver dns_resolver; -typedef struct dns_hosts dns_hosts; - -typedef struct _Ecore_Con_DNS Ecore_Con_DNS; - -struct _Ecore_Con_DNS -{ - Ecore_Con_Server *svr; - Ecore_Con_Info_Cb done_cb; - void *data; - dns_addrinfo *ai; - dns_resolver *resolv; - struct addrinfo hints; - Ecore_Fd_Handler *fdh; - Ecore_Timer *timer; -}; - -static int _ecore_con_dns_init = 0; -static dns_resolv_conf *resconf = NULL; -static dns_hosts *hosts = NULL; - -static void -_ecore_con_dns_free(Ecore_Con_DNS *dns) -{ - if (dns->svr->infos) dns->svr->infos = eina_list_remove(dns->svr->infos, dns); - if (dns->timer) ecore_timer_del(dns->timer); - if (dns->fdh) ecore_main_fd_handler_del(dns->fdh); - dns_res_close(dns_res_mortal(dns->resolv)); - free(dns); -} - -static Eina_Bool -_dns_addrinfo_get(Ecore_Con_DNS *dns, const char *addr, int port) -{ - int error = 0; - char service[NI_MAXSERV]; - - snprintf(service, sizeof(service), "%d", port); - dns->ai = dns_ai_open(addr, service, DNS_T_A, (const struct addrinfo *)&dns->hints, dns->resolv, &error); - return error; -} - -static int -_ecore_con_dns_check(Ecore_Con_DNS *dns) -{ - struct addrinfo *ent = NULL; - int error = 0; - - error = dns_ai_nextent(&ent, dns->ai); - - switch (error) - { - case 0: - break; - case EAGAIN: - return 1; - default: - ERR("resolve failed: %s", dns_strerror(error)); - goto error; - } - - { - Ecore_Con_Info result = {0, .ip = {0}, .service = {0}}; -#if 0 - char pretty[512]; - dns_ai_print(pretty, sizeof(pretty), ent, dns->ai); - printf("%s\n", pretty); -#endif - result.size = 0; - dns_inet_ntop(dns_sa_family(ent->ai_addr), dns_sa_addr(dns_sa_family(ent->ai_addr), ent->ai_addr), result.ip, sizeof(result.ip)); - snprintf(result.service, sizeof(result.service), "%u", ntohs(*dns_sa_port(dns_sa_family(ent->ai_addr), ent->ai_addr))); - memcpy(&result.info, ent, sizeof(result.info)); - if (dns->fdh) ecore_main_fd_handler_del(dns->fdh); - dns->fdh = NULL; - dns->done_cb(dns->data, &result); - free(ent); - _ecore_con_dns_free(dns); - } - - return 0; -error: - dns->done_cb(dns->data, NULL); - _ecore_con_dns_free(dns); - return -1; -} - -static Eina_Bool -_dns_fd_cb(Ecore_Con_DNS *dns, Ecore_Fd_Handler *fdh EINA_UNUSED) -{ - if (_ecore_con_dns_check(dns) != 1) return ECORE_CALLBACK_RENEW; - if (ecore_main_fd_handler_fd_get(dns->fdh) != dns_ai_pollfd(dns->ai)) - { - ecore_main_fd_handler_del(dns->fdh); - dns->fdh = ecore_main_fd_handler_add(dns_ai_pollfd(dns->ai), dns_ai_events(dns->ai), (Ecore_Fd_Cb)_dns_fd_cb, dns, NULL, NULL); - } - else - ecore_main_fd_handler_active_set(dns->fdh, dns_ai_events(dns->ai)); - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_dns_timer_cb(Ecore_Con_DNS *dns) -{ - dns->done_cb(dns->data, NULL); - _ecore_con_dns_free(dns); - dns->timer = NULL; - return EINA_FALSE; -} - -int -ecore_con_info_init(void) -{ - int err; - if (_ecore_con_dns_init) return ++_ecore_con_dns_init; - - resconf = dns_resconf_local(&err); - if (!resconf) - { - ERR("resconf_open: %s", dns_strerror(err)); - return 0; - } - hosts = dns_hosts_local(&err); - if (!hosts) - { - ERR("hosts_open: %s", dns_strerror(err)); - dns_resconf_close(resconf); - resconf = NULL; - return 0; - } - /* this is super slow don't do it */ - //resconf->options.recurse = 1; - return ++_ecore_con_dns_init; -} - -int -ecore_con_info_shutdown(void) -{ - if (!_ecore_con_dns_init) return 0; - if (--_ecore_con_dns_init) return _ecore_con_dns_init; - dns_resconf_close(resconf); - resconf = NULL; - dns_hosts_close(hosts); - hosts = NULL; - return 0; -} - -void -ecore_con_info_data_clear(void *info) -{ - Ecore_Con_DNS *dns = info; - if (dns) dns->data = NULL; -} - -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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_CANONNAME; - hints.ai_protocol = IPPROTO_TCP; - - 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - hints.ai_protocol = IPPROTO_TCP; - - 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_CANONNAME; - hints.ai_protocol = IPPROTO_UDP; - - 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_PASSIVE; - hints.ai_protocol = IPPROTO_UDP; - - 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)); -#ifdef HAVE_IPV6 - hints.ai_family = AF_INET6; -#else - hints.ai_family = AF_INET; -#endif - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - - 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_DNS *dns; - int error = 0; - - dns = calloc(1, sizeof(Ecore_Con_DNS)); - if (!dns) return 0; - - dns->svr = svr; - dns->done_cb = done_cb; - dns->data = data; - - if (hints) - memcpy(&dns->hints, hints, sizeof(struct addrinfo)); - - if (!(dns->resolv = dns_res_open(resconf, hosts, dns_hints_mortal(dns_hints_local(resconf, &error)), NULL, dns_opts(), &error))) - { - ERR("res_open: %s", dns_strerror(error)); - goto reserr; - - } - - error = _dns_addrinfo_get(dns, svr->ecs ? svr->ecs->ip : svr->name, dns->svr->ecs ? dns->svr->ecs->port : dns->svr->port); - if (error && (error != EAGAIN)) - { - ERR("resolver: %s", dns_strerror(error)); - goto seterr; - } - - switch (_ecore_con_dns_check(dns)) - { - case 0: - break; - case 1: - dns->fdh = ecore_main_fd_handler_add(dns_ai_pollfd(dns->ai), dns_ai_events(dns->ai), (Ecore_Fd_Cb)_dns_fd_cb, dns, NULL, NULL); - svr->infos = eina_list_append(svr->infos, dns); - dns->timer = ecore_timer_add(5.0, (Ecore_Task_Cb)_dns_timer_cb, dns); - break; - default: - return 0; - } - - return 1; -seterr: - if (dns->resolv) dns_res_close(dns_res_mortal(dns->resolv)); -reserr: - free(dns); - return 0; -} - diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_eet.c b/legacy/ecore/src/lib/ecore_con/ecore_con_eet.c deleted file mode 100644 index f3948ca5f8..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_eet.c +++ /dev/null @@ -1,822 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include - -#include "Ecore_Con_Eet.h" - -#define ECORE_CON_EET_RAW_MAGIC 0xDEAD007 - -typedef struct _Ecore_Con_Eet_Data Ecore_Con_Eet_Data; -typedef struct _Ecore_Con_Eet_Raw_Data Ecore_Con_Eet_Raw_Data; -typedef struct _Ecore_Con_Eet_Client Ecore_Con_Eet_Client; -typedef struct _Ecore_Con_Eet_Server Ecore_Con_Eet_Server; - -struct _Ecore_Con_Reply -{ - Ecore_Con_Eet *ece; - Ecore_Con_Client *client; - - Eet_Connection *econn; - - char *buffer_section; - unsigned char *buffer; - unsigned int buffer_length; - unsigned int buffer_current; - Ecore_Con_Eet_Raw_Data *buffer_handler; -}; - -struct _Ecore_Con_Eet_Data -{ - Ecore_Con_Eet_Data_Cb func; - const char *name; - const void *data; -}; - -struct _Ecore_Con_Eet_Raw_Data -{ - Ecore_Con_Eet_Raw_Data_Cb func; - const char *name; - const void *data; -}; - -struct _Ecore_Con_Eet_Client -{ - Ecore_Con_Eet_Client_Cb func; - const void *data; -}; - -struct _Ecore_Con_Eet_Server -{ - Ecore_Con_Eet_Server_Cb func; - const void *data; -}; - -struct _Ecore_Con_Eet -{ - Ecore_Con_Server *server; - - Ecore_Event_Handler *handler_add; - Ecore_Event_Handler *handler_del; - Ecore_Event_Handler *handler_data; - - Eet_Data_Descriptor *edd; - Eet_Data_Descriptor *matching; - - Eina_Hash *data_callbacks; - Eina_Hash *raw_data_callbacks; - - union { - struct { - Eina_List *connections; - Eina_List *client_connect_callbacks; - Eina_List *client_disconnect_callbacks; - } server; - struct { - Ecore_Con_Reply *r; - Eina_List *server_connect_callbacks; - Eina_List *server_disconnect_callbacks; - } client; - } u; - - const void *data; - - Eina_Bool client : 1; -}; - -static void -_ecore_con_eet_data_free(void *data) -{ - Ecore_Con_Eet_Data *eced = data; - - eina_stringshare_del(eced->name); - free(eced); -} - -static void -_ecore_con_eet_raw_data_free(void *data) -{ - Ecore_Con_Eet_Raw_Data *eced = data; - - eina_stringshare_del(eced->name); - free(eced); -} -static void -_ecore_con_eet_reply_cleanup(Ecore_Con_Reply *n) -{ - if (n->buffer_handler) free(n->buffer); - n->buffer = NULL; - n->buffer_handler = NULL; - free(n->buffer_section); - n->buffer_section = NULL; -} - -typedef struct _Ecore_Con_Eet_Protocol Ecore_Con_Eet_Protocol; -struct _Ecore_Con_Eet_Protocol { - const char *type; - void *data; -}; - -static const char * -_ecore_con_eet_data_type_get(const void *data, Eina_Bool *unknow EINA_UNUSED) -{ - const Ecore_Con_Eet_Protocol *p = data; - - return p->type; -} - -static Eina_Bool -_ecore_con_eet_data_type_set(const char *type, void *data, Eina_Bool unknow EINA_UNUSED) -{ - Ecore_Con_Eet_Protocol *p = data; - - p->type = type; - return EINA_TRUE; -} - -static void -_ecore_con_eet_data_descriptor_setup(Ecore_Con_Eet *ece) -{ - Eet_Data_Descriptor_Class eddc; - - EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Ecore_Con_Eet_Protocol); - ece->edd = eet_data_descriptor_stream_new(&eddc); - - eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; - eddc.func.type_get = _ecore_con_eet_data_type_get; - eddc.func.type_set = _ecore_con_eet_data_type_set; - ece->matching = eet_data_descriptor_stream_new(&eddc); - - EET_DATA_DESCRIPTOR_ADD_VARIANT(ece->edd, Ecore_Con_Eet_Protocol, "data", data, type, ece->matching); -} - -/* Dealing with a server listening to connection */ -static Eina_Bool -_ecore_con_eet_read_cb(const void *eet_data, size_t size, void *user_data) -{ - Ecore_Con_Reply *n = user_data; - Ecore_Con_Eet_Protocol *protocol; - Ecore_Con_Eet_Data *cb; - - protocol = eet_data_descriptor_decode(n->ece->edd, eet_data, size); - if (!protocol) return EINA_TRUE; - - cb = eina_hash_find(n->ece->data_callbacks, protocol->type); - if (!cb) return EINA_TRUE; /* Should I report unknow protocol communication ? */ - - cb->func((void*)cb->data, n, cb->name, protocol->data); - - eina_stringshare_del(protocol->type); - free(protocol); - - return EINA_TRUE; -} - -static Eina_Bool -_ecore_con_eet_server_write_cb(const void *data, size_t size, void *user_data) -{ - Ecore_Con_Reply *n = user_data; - - if (ecore_con_client_send(n->client, data, size) != (int) size) - return EINA_FALSE; - return EINA_TRUE; -} - -static Eina_Bool -_ecore_con_eet_client_write_cb(const void *data, size_t size, void *user_data) -{ - Ecore_Con_Reply *n = user_data; - - if (ecore_con_server_send(n->ece->server, data, size) != (int) size) - return EINA_FALSE; - return EINA_TRUE; -} - -static Eina_Bool -_ecore_con_eet_server_connected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Add *ev) -{ - Ecore_Con_Eet_Client *ecec; - Eina_List *ll; - Ecore_Con_Eet *r = data; - Ecore_Con_Reply *n; - - if (ecore_con_client_server_get(ev->client) != r->server) - return EINA_TRUE; - - n = calloc(1, sizeof (Ecore_Con_Reply)); - if (!n) return EINA_TRUE; - - n->client = ev->client; - n->ece = r; - n->econn = eet_connection_new(_ecore_con_eet_read_cb, _ecore_con_eet_server_write_cb, n); - ecore_con_client_data_set(n->client, n); - - EINA_LIST_FOREACH(r->u.server.client_connect_callbacks, ll, ecec) - if (!ecec->func((void*) ecec->data, n, n->client)) - { - eet_connection_close(n->econn, NULL); - free(n); - return EINA_TRUE; - } - - r->u.server.connections = eina_list_append(r->u.server.connections, n); - - return EINA_TRUE; -} - -static Eina_Bool -_ecore_con_eet_server_disconnected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Del *ev) -{ - Ecore_Con_Eet *r = data; - Ecore_Con_Reply *n; - Eina_List *l; - - if (ecore_con_client_server_get(ev->client) != r->server) - return EINA_TRUE; - - EINA_LIST_FOREACH(r->u.server.connections, l, n) - if (n->client == ev->client) - { - Ecore_Con_Eet_Client *ecec; - Eina_List *ll; - - EINA_LIST_FOREACH(r->u.server.client_disconnect_callbacks, ll, ecec) - ecec->func((void*) ecec->data, n, n->client); - - eet_connection_close(n->econn, NULL); - free(n); - r->u.server.connections = eina_list_remove_list(r->u.server.connections, l); - return EINA_TRUE; - } - - return EINA_TRUE; -} - -static void -_ecore_con_eet_raw_data_push(Ecore_Con_Reply *n, void *data, int size) -{ - if (n->buffer_handler) - memcpy(n->buffer + n->buffer_current, data, size); - n->buffer_current += size; - - if (n->buffer_current == n->buffer_length) - { - if (n->buffer_handler) - n->buffer_handler->func((void*) n->buffer_handler->data, n, n->buffer_handler->name, n->buffer_section, n->buffer, n->buffer_length); - _ecore_con_eet_reply_cleanup(n); - } -} - -static void -_ecore_con_eet_data(Ecore_Con_Reply *n, void *data, unsigned int size) -{ - /* FIXME: Enforce detection of attack and kill connection on that case */ - if (n->buffer) - { - if (n->buffer_current + size > n->buffer_length) - { - _ecore_con_eet_reply_cleanup(n); - return ; - } - - _ecore_con_eet_raw_data_push(n, data, size); - return ; - } - else if (eet_connection_empty(n->econn) && size > (int) (4 * sizeof (unsigned int) + 2)) - { - unsigned int *tmp = data; - size -= 4 * sizeof (unsigned int); - - if (ntohl(tmp[0]) == ECORE_CON_EET_RAW_MAGIC) - { - unsigned int protocol_length = ntohl(tmp[1]); - unsigned int section_length = ntohl(tmp[2]); - unsigned int data_length = ntohl(tmp[3]); - - if (protocol_length > 1 && section_length > 1 && protocol_length + section_length <= size && data_length < 10 * 1024 * 1024) - { - char *buffer = (char*) &tmp[4]; - char *protocol; - char *section; - - protocol = buffer; - section = buffer + protocol_length; - - if (protocol[protocol_length - 1] == '\0' && - section[section_length - 1] == '\0') - { - size -= protocol_length + section_length; - buffer = section + section_length; - - n->buffer_handler = eina_hash_find(n->ece->raw_data_callbacks, protocol); - n->buffer_section = strdup(section); - n->buffer_length = data_length; - n->buffer_current = 0; - if (n->buffer_handler) - n->buffer = malloc(sizeof (char) * data_length); - else - n->buffer = (void*) 1; - if (n->buffer) - { - _ecore_con_eet_raw_data_push(n, buffer, size); - return ; - } - _ecore_con_eet_reply_cleanup(n); - - size += protocol_length + section_length; - } - } - } - - size += 4 * sizeof (unsigned int); - } - - eet_connection_received(n->econn, data, size); -} - -static Eina_Bool -_ecore_con_eet_server_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Data *ev) -{ - Ecore_Con_Eet *r = data; - Ecore_Con_Reply *n; - - if (ecore_con_client_server_get(ev->client) != r->server) - return EINA_TRUE; - - n = ecore_con_client_data_get(ev->client); - - _ecore_con_eet_data(n, ev->data, ev->size); - - return EINA_TRUE; -} - -/* Dealing connection to a server */ - -static Eina_Bool -_ecore_con_eet_client_connected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev) -{ - Ecore_Con_Eet_Server *eces; - Ecore_Con_Eet *r = data; - Ecore_Con_Reply *n; - Eina_List *ll; - - /* Client did connect */ - if (r->server != ev->server) return EINA_TRUE; - if (r->u.client.r) return EINA_TRUE; - - n = calloc(1, sizeof (Ecore_Con_Reply)); - if (!n) return EINA_TRUE; - - n->client = NULL; - n->ece = r; - n->econn = eet_connection_new(_ecore_con_eet_read_cb, _ecore_con_eet_client_write_cb, n); - - EINA_LIST_FOREACH(r->u.client.server_connect_callbacks, ll, eces) - if (!eces->func((void*) eces->data, n, n->ece->server)) - { - eet_connection_close(n->econn, NULL); - free(n); - return EINA_TRUE; - } - - r->u.client.r = n; - - return EINA_TRUE; -} - -static Eina_Bool -_ecore_con_eet_client_disconnected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Del *ev) -{ - Ecore_Con_Eet *r = data; - Ecore_Con_Eet_Server *eces; - Eina_List *ll; - - if (r->server != ev->server) return EINA_TRUE; - if (!r->u.client.r) return EINA_TRUE; - - /* Client disconnected */ - EINA_LIST_FOREACH(r->u.client.server_disconnect_callbacks, ll, eces) - eces->func((void*) eces->data, r->u.client.r, r->server); - - eet_connection_close(r->u.client.r->econn, NULL); - free(r->u.client.r); - r->u.client.r = NULL; - - return EINA_TRUE; -} - -static Eina_Bool -_ecore_con_eet_client_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Data *ev) -{ - Ecore_Con_Eet *r = data; - - if (r->server != ev->server) return EINA_TRUE; - if (!r->u.client.r) return EINA_TRUE; - - /* Got some data */ - _ecore_con_eet_data(r->u.client.r, ev->data, ev->size); - - return EINA_TRUE; -} - -/************** - * Global API * - **************/ - -EAPI Ecore_Con_Eet * -ecore_con_eet_server_new(Ecore_Con_Server *server) -{ - Ecore_Con_Eet *r; - - if (!server) return NULL; - - r = calloc(1, sizeof (Ecore_Con_Eet)); - if (!r) return NULL; - - r->server = server; - r->handler_add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, - (Ecore_Event_Handler_Cb)_ecore_con_eet_server_connected, r); - r->handler_del = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, - (Ecore_Event_Handler_Cb)_ecore_con_eet_server_disconnected, r); - r->handler_data = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, - (Ecore_Event_Handler_Cb)_ecore_con_eet_server_data, r); - r->data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_data_free); - r->raw_data_callbacks = eina_hash_string_superfast_new(_ecore_con_eet_raw_data_free); - - _ecore_con_eet_data_descriptor_setup(r); - - return r; -} - -EAPI Ecore_Con_Eet * -ecore_con_eet_client_new(Ecore_Con_Server *server) -{ - Ecore_Con_Eet *r; - - if (!server) return NULL; - - r = calloc(1, sizeof (Ecore_Con_Eet)); - if (!r) return NULL; - - r->client = EINA_TRUE; - r->server = server; - r->handler_add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, - (Ecore_Event_Handler_Cb)_ecore_con_eet_client_connected, r); - r->handler_del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, - (Ecore_Event_Handler_Cb)_ecore_con_eet_client_disconnected, r); - r->handler_data = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, - (Ecore_Event_Handler_Cb)_ecore_con_eet_client_data, r); - r->data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_data_free); - r->raw_data_callbacks = eina_hash_string_superfast_new(_ecore_con_eet_raw_data_free); - - _ecore_con_eet_data_descriptor_setup(r); - - return r; -} - -EAPI void -ecore_con_eet_server_free(Ecore_Con_Eet *r) -{ - if (!r) return ; - - eet_data_descriptor_free(r->edd); - eet_data_descriptor_free(r->matching); - eina_hash_free(r->data_callbacks); - eina_hash_free(r->raw_data_callbacks); - - if (r->client) - { - Ecore_Con_Eet_Server *s; - - if (r->u.client.r) - { - _ecore_con_eet_reply_cleanup(r->u.client.r); - eet_connection_close(r->u.client.r->econn, NULL); - free(r->u.client.r); - } - EINA_LIST_FREE(r->u.client.server_connect_callbacks, s) - free(s); - EINA_LIST_FREE(r->u.client.server_disconnect_callbacks, s) - free(s); - } - else - { - Ecore_Con_Reply *n; - Ecore_Con_Eet_Client *c; - - EINA_LIST_FREE(r->u.server.connections, n) - { - _ecore_con_eet_reply_cleanup(n); - eet_connection_close(n->econn, NULL); - free(n); - } - EINA_LIST_FREE(r->u.server.client_connect_callbacks, c) - free(c); - EINA_LIST_FREE(r->u.server.client_disconnect_callbacks, c) - free(c); - } - - ecore_event_handler_del(r->handler_add); - ecore_event_handler_del(r->handler_del); - ecore_event_handler_del(r->handler_data); - free(r); -} - -EAPI void -ecore_con_eet_register(Ecore_Con_Eet *ece, const char *name, Eet_Data_Descriptor *edd) -{ - if (!ece) return ; - - EET_DATA_DESCRIPTOR_ADD_MAPPING(ece->matching, name, edd); -} - -EAPI void -ecore_con_eet_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Data_Cb func, const void *data) -{ - Ecore_Con_Eet_Data *eced; - - if (!ece) return ; - - eced = calloc(1, sizeof (Ecore_Con_Eet_Data));; - if (!eced) return ; - - eced->func = func; - eced->data = data; - eced->name = eina_stringshare_add(name); - - eina_hash_direct_add(ece->data_callbacks, eced->name, eced); -} - -EAPI void -ecore_con_eet_data_callback_del(Ecore_Con_Eet *ece, const char *name) -{ - if (!ece) return ; - eina_hash_del(ece->data_callbacks, name, NULL); -} - -EAPI void -ecore_con_eet_raw_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Raw_Data_Cb func, const void *data) -{ - Ecore_Con_Eet_Raw_Data *eced; - - if (!ece) return ; - - eced = calloc(1, sizeof (Ecore_Con_Eet_Raw_Data));; - if (!eced) return ; - - eced->func = func; - eced->data = data; - eced->name = eina_stringshare_add(name); - - eina_hash_direct_add(ece->raw_data_callbacks, eced->name, eced); -} - -EAPI void -ecore_con_eet_raw_data_callback_del(Ecore_Con_Eet *ece, const char *name) -{ - if (!ece) return ; - - if (ece->client && ece->u.client.r->buffer_handler && !strcmp(ece->u.client.r->buffer_handler->name, name)) - { - ece->u.client.r->buffer_handler = NULL; - free(ece->u.client.r->buffer); - ece->u.client.r->buffer = (void*) 1; - } - eina_hash_del(ece->raw_data_callbacks, name, NULL); -} - -EAPI void -ecore_con_eet_client_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) -{ - Ecore_Con_Eet_Client *c; - - if (!ece || !func) return ; - - c = calloc(1, sizeof (Ecore_Con_Eet_Client)); - if (!c) return ; - - c->func = func; - c->data = data; - - ece->u.server.client_connect_callbacks = eina_list_append(ece->u.server.client_connect_callbacks, c); -} - -EAPI void -ecore_con_eet_client_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) -{ - Ecore_Con_Eet_Client *c; - Eina_List *l; - - if (!ece || !func) return ; - - EINA_LIST_FOREACH(ece->u.server.client_connect_callbacks, l, c) - if (c->func == func && c->data == data) - { - ece->u.server.client_connect_callbacks = eina_list_remove_list(ece->u.server.client_connect_callbacks, l); - free(c); - return ; - } -} - -EAPI void -ecore_con_eet_client_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) -{ - Ecore_Con_Eet_Client *c; - - if (!ece || !func) return ; - - c = calloc(1, sizeof (Ecore_Con_Eet_Client)); - if (!c) return ; - - c->func = func; - c->data = data; - - ece->u.server.client_disconnect_callbacks = eina_list_append(ece->u.server.client_disconnect_callbacks, c); -} - -EAPI void -ecore_con_eet_client_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) -{ - Ecore_Con_Eet_Client *c; - Eina_List *l; - - if (!ece || !func) return ; - - EINA_LIST_FOREACH(ece->u.server.client_disconnect_callbacks, l, c) - if (c->func == func && c->data == data) - { - ece->u.server.client_disconnect_callbacks = eina_list_remove_list(ece->u.server.client_disconnect_callbacks, - l); - free(c); - return ; - } -} - -EAPI void -ecore_con_eet_server_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) -{ - Ecore_Con_Eet_Server *s; - - if (!ece || !func) return ; - - s = calloc(1, sizeof (Ecore_Con_Eet_Server)); - if (!s) return ; - - s->func = func; - s->data = data; - - ece->u.client.server_connect_callbacks = eina_list_append(ece->u.client.server_connect_callbacks, s); -} - -EAPI void -ecore_con_eet_server_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) -{ - Ecore_Con_Eet_Server *s; - Eina_List *l; - - if (!ece || !func) return ; - - EINA_LIST_FOREACH(ece->u.client.server_connect_callbacks, l, s) - if (s->func == func && s->data == data) - { - ece->u.client.server_connect_callbacks = eina_list_remove_list(ece->u.client.server_connect_callbacks, l); - free(s); - return ; - } -} - -EAPI void -ecore_con_eet_server_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) -{ - Ecore_Con_Eet_Server *s; - - if (!ece || !func) return ; - - s = calloc(1, sizeof (Ecore_Con_Eet_Server)); - if (!s) return ; - - s->func = func; - s->data = data; - - ece->u.client.server_disconnect_callbacks = eina_list_append(ece->u.client.server_disconnect_callbacks, s); -} - -EAPI void -ecore_con_eet_server_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) -{ - Ecore_Con_Eet_Server *s; - Eina_List *l; - - if (!ece || !func) return ; - - EINA_LIST_FOREACH(ece->u.client.server_disconnect_callbacks, l, s) - if (s->func == func && s->data == data) - { - ece->u.client.server_disconnect_callbacks = eina_list_remove_list(ece->u.client.server_disconnect_callbacks, l); - free(s); - return ; - } -} - -EAPI void -ecore_con_eet_data_set(Ecore_Con_Eet *ece, const void *data) -{ - if (!ece) return; - - ece->data = data; -} - -EAPI void * -ecore_con_eet_data_get(Ecore_Con_Eet *ece) -{ - if (!ece) return NULL; - return (void*) ece->data; -} - -EAPI Ecore_Con_Eet * -ecore_con_eet_reply(Ecore_Con_Reply *reply) -{ - if (!reply) return NULL; - return reply->ece; -} - -EAPI void -ecore_con_eet_send(Ecore_Con_Reply *reply, const char *name, void *value) -{ - Ecore_Con_Eet_Protocol protocol; - - if (!reply) return ; - - protocol.type = name; - protocol.data = value; - - eet_connection_send(reply->econn, reply->ece->edd, &protocol, NULL); -} - -EAPI void -ecore_con_eet_raw_send(Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, unsigned int length) -{ - unsigned int protocol[4]; - unsigned int protocol_length; - unsigned int section_length; - unsigned int size; - char *tmp; - - if (!reply) return ; - if (!protocol_name) return ; - if (!section) return ; - - protocol_length = strlen(protocol_name) + 1; - if (protocol_length == 1) return ; - section_length = strlen(section) + 1; - - protocol[0] = htonl(ECORE_CON_EET_RAW_MAGIC); - protocol[1] = htonl(protocol_length); - protocol[2] = htonl(section_length); - protocol[3] = htonl(length); - - size = sizeof (protocol) + protocol_length + section_length; - tmp = alloca(size); - memcpy(tmp, protocol, sizeof (protocol)); - memcpy(tmp + sizeof (protocol), protocol_name, protocol_length); - memcpy(tmp + sizeof (protocol) + protocol_length, section, section_length); - - if (reply->client) - { - ecore_con_client_send(reply->client, tmp, size); - ecore_con_client_send(reply->client, value, length); - } - else - { - ecore_con_server_send(reply->ece->server, tmp, size); - ecore_con_server_send(reply->ece->server, value, length); - } -} - diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_info.c b/legacy/ecore/src/lib/ecore_con/ecore_con_info.c deleted file mode 100644 index 80e199a411..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_info.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * getaddrinfo with callback - * - * man getaddrinfo - * - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include -#include -#include -#include -#ifdef __OpenBSD__ -# include -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_ARPA_NAMESER_H -# include -#endif - -#ifdef HAVE_SYS_SOCKET_H -# include -#endif - -#ifdef HAVE_NETDB_H -# include -#endif - -#include - -#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 Eina_Bool _ecore_con_info_data_handler(void *data, - Ecore_Fd_Handler *fd_handler); -static Eina_Bool _ecore_con_info_exit_handler(void *data, - int type EINA_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) - { - ecore_con_event_server_error(svr, strerror(errno)); - 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))) - { - ecore_con_event_server_error(svr, "Memory allocation failure"); - 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] = {0}; - char hbuf[NI_MAXHOST] = {0}; - char sbuf[NI_MAXSERV] = {0}; - unsigned char *tosend = NULL; - int tosend_len; - int canonname_len = 0; - - eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, service); - /* CHILD */ - if (!getaddrinfo(svr->ecs ? svr->ecs->ip : 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; - - tosend = alloca(tosend_len); - memset(tosend, 0, tosend_len); - - container = (Ecore_Con_Info *)tosend; - container->size = tosend_len; - - memcpy(&container->info, - result, - sizeof(struct addrinfo)); - memcpy(tosend + sizeof(Ecore_Con_Info), - result->ai_addr, - result->ai_addrlen); - if (result->ai_canonname) /* FIXME: else... */ - memcpy(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)); - } - - if (write(fd[1], tosend, tosend_len) < 0) perror("write"); - } - - if (result) - freeaddrinfo(result); - - if (write(fd[1], "", 1) < 0) perror("write"); - close(fd[1]); -#if defined(__USE_ISOC99) && !defined(__UCLIBC__) - _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)); - svr->infos = eina_list_append(svr->infos, cbdata); - return 1; -} - -void -ecore_con_info_data_clear(void *info) -{ - CB_Data *cbdata = info; - cbdata->data = NULL; -} - -static void -_ecore_con_info_readdata(CB_Data *cbdata) -{ - Ecore_Con_Info container; - Ecore_Con_Info *recv_info; - unsigned char *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), - torecv + sizeof(Ecore_Con_Info), - torecv_len - sizeof(Ecore_Con_Info)); - if ((size > 0) && - ((size_t)size == torecv_len - sizeof(Ecore_Con_Info))) - { - recv_info = (Ecore_Con_Info *)torecv; - - recv_info->info.ai_addr = - (struct sockaddr *)(torecv + sizeof(Ecore_Con_Info)); - if ((size_t)torecv_len != - (sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen)) - recv_info->info.ai_canonname = (char *) - (torecv + sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen); - else - recv_info->info.ai_canonname = NULL; - - recv_info->info.ai_next = NULL; - - if (cbdata->data) - { - cbdata->cb_done(cbdata->data, recv_info); - ecore_con_server_infos_del(cbdata->data, cbdata); - } - - free(torecv); - } - else - { - if (cbdata->data) - { - cbdata->cb_done(cbdata->data, NULL); - ecore_con_server_infos_del(cbdata->data, cbdata); - } - } - } - else - { - if (cbdata->data) - { - ecore_con_event_server_error(cbdata->data, strerror(errno)); - cbdata->cb_done(cbdata->data, NULL); - ecore_con_server_infos_del(cbdata->data, cbdata); - } - } - - 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)); - ecore_main_fd_handler_del(cbdata->fdh); - ecore_event_handler_del(cbdata->handler); - close(ecore_main_fd_handler_fd_get(cbdata->fdh)); - if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata); - free(cbdata); -} - -static Eina_Bool -_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 - { - if (cbdata->data) - { - cbdata->cb_done(cbdata->data, NULL); - cbdata->cb_done = NULL; - ecore_con_server_infos_del(cbdata->data, cbdata); - } - } - } - - _ecore_con_info_slave_free(cbdata); - return ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_ecore_con_info_exit_handler(void *data, - int type EINA_UNUSED, - void *event) -{ - CB_Data *cbdata; - Ecore_Exe_Event_Del *ev; - - ev = event; - cbdata = data; - if (cbdata->pid != ev->pid) - return ECORE_CALLBACK_RENEW; - - return ECORE_CALLBACK_CANCEL; /* FIXME: Woot ??? */ - _ecore_con_info_slave_free(cbdata); - return ECORE_CALLBACK_CANCEL; -} - diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_local.c b/legacy/ecore/src/lib/ecore_con/ecore_con_local.c deleted file mode 100644 index fff0059d66..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_local.c +++ /dev/null @@ -1,325 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_ERRNO_H -# include -#endif - -#ifdef HAVE_SYS_SOCKET_H -# include -#endif - -#ifdef HAVE_SYS_UN_H -# include -#endif - -#ifdef HAVE_WS2TCPIP_H -# include -#endif - -#include -#include - -#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, - Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler), - void *data EINA_UNUSED) -{ -#ifndef HAVE_LOCAL_SOCKETS - return 0; -#else - char buf[4096]; - struct sockaddr_un socket_unix; - int curstate = 0; - const char *homedir; - int socket_unix_len; - - if ((svr->type & ECORE_CON_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_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_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_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) - { - ERR("local connection failed: %s", strerror(errno)); - 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) ecore_con_event_server_add(svr); - - return 1; -#endif -} - -int -ecore_con_local_listen( - Ecore_Con_Server *svr, - Eina_Bool (* - cb_listen)(void *data, - Ecore_Fd_Handler * - fd_handler), - void *data - EINA_UNUSED) -{ -#ifdef HAVE_LOCAL_SOCKETS - 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_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_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_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_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_TYPE) == ECORE_CON_LOCAL_USER) || - ((svr->type & ECORE_CON_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: -#endif /* HAVE_LOCAL_SOCKETS */ - return 0; -} - diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_local_win32.c b/legacy/ecore/src/lib/ecore_con/ecore_con_local_win32.c deleted file mode 100644 index 2b7e5c5bd2..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_local_win32.c +++ /dev/null @@ -1,754 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include -#include - -#include "Ecore_Con.h" -#include "ecore_con_private.h" - -#define BUFSIZE 512 - - -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; -} - - -static Eina_Bool -_ecore_con_local_win32_server_read_client_handler(void *data, Ecore_Win32_Handler *wh) -{ - Ecore_Con_Client *cl; - void *buf; - DWORD n; - Eina_Bool broken_pipe = EINA_FALSE; - - cl = (Ecore_Con_Client *)data; - - if (!ResetEvent(cl->host_server->event_read)) - return ECORE_CALLBACK_RENEW; - - buf = malloc(cl->host_server->nbr_bytes); - if (!buf) - return ECORE_CALLBACK_RENEW; - - if (ReadFile(cl->host_server->pipe, buf, cl->host_server->nbr_bytes, &n, NULL)) - { - if (!cl->delete_me) - ecore_con_event_client_data(cl, buf, cl->host_server->nbr_bytes, EINA_FALSE); - cl->host_server->want_write = 1; - } - else - { - if (GetLastError() == ERROR_BROKEN_PIPE) - broken_pipe = EINA_TRUE; - } - - if (broken_pipe) - { -#if 0 - char *msg; - - msg = evil_last_error_get(); - if (msg) - { - ecore_con_event_client_error(cl, msg); - free(msg); - } -#endif - _ecore_con_client_kill(cl); - return ECORE_CALLBACK_CANCEL; - } - - if (cl->host_server->want_write) - ecore_con_local_win32_client_flush(cl); - - ecore_main_win32_handler_del(wh); - - return ECORE_CALLBACK_DONE; -} - -static Eina_Bool -_ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh) -{ - Ecore_Con_Client *cl; -#if 0 - char *msg; -#endif - - cl = (Ecore_Con_Client *)data; - - if (!ResetEvent(cl->host_server->event_peek)) - return ECORE_CALLBACK_RENEW; - -#if 0 - msg = evil_last_error_get(); - if (msg) - { - ecore_con_event_server_error(cl->host_server, msg); - free(msg); - } -#endif - _ecore_con_server_kill(cl->host_server); - return ECORE_CALLBACK_CANCEL; - - ecore_main_win32_handler_del(wh); - - return ECORE_CALLBACK_DONE; -} - -static Eina_Bool -_ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handler *wh) -{ - Ecore_Con_Server *svr; -#if 0 - char *msg; -#endif - - svr = (Ecore_Con_Server *)data; - - if (!ResetEvent(svr->event_peek)) - return ECORE_CALLBACK_RENEW; -#if 0 - msg = evil_last_error_get(); - if (msg) - { - ecore_con_event_server_error(svr, msg); - free(msg); - } -#endif - _ecore_con_server_kill(svr); - return ECORE_CALLBACK_CANCEL; - - ecore_main_win32_handler_del(wh); - - return ECORE_CALLBACK_DONE; -} - -static Eina_Bool -_ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh) -{ - Ecore_Con_Server *svr; - void *buf; - DWORD n; - Eina_Bool broken_pipe = EINA_FALSE; - - svr = (Ecore_Con_Server *)data; - - if (!ResetEvent(svr->event_read)) - return ECORE_CALLBACK_RENEW; - - buf = malloc(svr->nbr_bytes); - if (!buf) - return ECORE_CALLBACK_RENEW; - - if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL)) - { - if (!svr->delete_me) - ecore_con_event_server_data(svr, buf, svr->nbr_bytes, EINA_FALSE); - svr->want_write = 1; - } - else - { - if (GetLastError() == ERROR_BROKEN_PIPE) - broken_pipe = EINA_TRUE; - } - - if (broken_pipe) - { -#if 0 - char *msg; - - msg = evil_last_error_get(); - if (msg) - { - ecore_con_event_server_error(svr, msg); - free(msg); - } -#endif - _ecore_con_server_kill(svr); - return ECORE_CALLBACK_CANCEL; - } - - if (svr->want_write) - ecore_con_local_win32_server_flush(svr); - - ecore_main_win32_handler_del(wh); - - return ECORE_CALLBACK_DONE; -} - -/* thread to read data sent by the server to the client */ -static unsigned int __stdcall -_ecore_con_local_win32_client_read_server_thread(void *data) -{ - Ecore_Con_Server *svr; - DWORD nbr_bytes = 0; - - svr = (Ecore_Con_Server *)data; - - svr->read_stopped = EINA_FALSE; - - while (!svr->read_stop) - { - if (PeekNamedPipe(svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL)) - { - if (nbr_bytes <= 0) - continue; - - svr->nbr_bytes = nbr_bytes; - if (!SetEvent(svr->event_read)) - continue; - } - else - { - if (GetLastError() == ERROR_BROKEN_PIPE) - { - if (!SetEvent(svr->event_peek)) - continue; - break; - } - } - } - - printf(" ### %s\n", __FUNCTION__); - svr->read_stopped = EINA_TRUE; - _endthreadex(0); - return 0; -} - -/* thread to read data sent by the client to the server */ -static unsigned int __stdcall -_ecore_con_local_win32_server_read_client_thread(void *data) -{ - Ecore_Con_Client *cl; - DWORD nbr_bytes = 0; - - cl = (Ecore_Con_Client *)data; - - cl->host_server->read_stopped = EINA_FALSE; - - while (!cl->host_server->read_stop) - { - if (PeekNamedPipe(cl->host_server->pipe, NULL, 0, NULL, &nbr_bytes, NULL)) - { - if (nbr_bytes <= 0) - continue; - - cl->host_server->nbr_bytes = nbr_bytes; - if (!SetEvent(cl->host_server->event_read)) - continue; - } - else - { - if (GetLastError() == ERROR_BROKEN_PIPE) - { - if (!SetEvent(cl->host_server->event_peek)) - continue; - break; - } - } - } - - printf(" ### %s\n", __FUNCTION__); - cl->host_server->read_stopped = EINA_TRUE; - _endthreadex(0); - return 0; -} - -static Eina_Bool -_ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh) -{ - Ecore_Con_Client *cl = NULL; - Ecore_Con_Server *svr; - Ecore_Win32_Handler *handler_read; - Ecore_Win32_Handler *handler_peek; - - svr = (Ecore_Con_Server *)data; - - if (!svr->pipe) - return ECORE_CALLBACK_CANCEL; - - if (svr->delete_me) - return ECORE_CALLBACK_CANCEL; - - if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && - (svr->client_count >= (unsigned int)svr->client_limit)) - return ECORE_CALLBACK_CANCEL; - - cl = calloc(1, sizeof(Ecore_Con_Client)); - if (!cl) - { - ERR("allocation failed"); - return ECORE_CALLBACK_CANCEL; - } - - cl->host_server = svr; - ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); - - cl->host_server->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!cl->host_server->event_read) - { - ERR("Can not create event read"); - goto free_cl; - } - - handler_read = ecore_main_win32_handler_add(cl->host_server->event_read, - _ecore_con_local_win32_server_read_client_handler, - cl); - if (!handler_read) - { - ERR("Can not create handler read"); - goto close_event_read; - } - - cl->host_server->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!cl->host_server->event_peek) - { - ERR("Can not create event peek"); - goto del_handler_read; - } - - handler_peek = ecore_main_win32_handler_add(cl->host_server->event_peek, - _ecore_con_local_win32_server_peek_client_handler, - cl); - if (!handler_peek) - { - ERR("Can not create handler peek"); - goto close_event_peek; - } - - cl->host_server->read_stopped = EINA_TRUE; - cl->host_server->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_server_read_client_thread, cl, CREATE_SUSPENDED, NULL); - if (!cl->host_server->thread_read) - { - ERR("Can not launch thread"); - goto del_handler_peek; - } - - svr->clients = eina_list_append(svr->clients, cl); - svr->client_count++; - - if (!cl->delete_me) - ecore_con_event_client_add(cl); - - ecore_main_win32_handler_del(wh); - - ResumeThread(cl->host_server->thread_read); - return ECORE_CALLBACK_DONE; - - del_handler_peek: - ecore_main_win32_handler_del(handler_peek); - close_event_peek: - CloseHandle(cl->host_server->event_peek); - del_handler_read: - ecore_main_win32_handler_del(handler_read); - close_event_read: - CloseHandle(cl->host_server->event_read); - free_cl: - free(cl); - - return ECORE_CALLBACK_CANCEL; -} - -static unsigned int __stdcall -_ecore_con_local_win32_listening(void *data) -{ - Ecore_Con_Server *svr; - BOOL res; - - svr = (Ecore_Con_Server *)data; - - while (1) - { - res = ConnectNamedPipe(svr->pipe, NULL); - if (!res) - { - ERR("Opening the connection to the client failed"); - CloseHandle(svr->pipe); - svr->pipe = NULL; - } - break; - } - - DBG("Client connected"); - - printf(" ### %s\n", __FUNCTION__); - _endthreadex(0); - return 0; -} - -Eina_Bool -ecore_con_local_listen(Ecore_Con_Server *svr) -{ - char buf[256]; - HANDLE thread_listening; - Ecore_Win32_Handler *handler; - - if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) - { - ERR("Your system does not support abstract sockets!"); - return EINA_FALSE; - } - - if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) - snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); - else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) - { - const char *computername; - - computername = getenv("CoMPUTERNAME"); - snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); - } - - svr->path = strdup(buf); - if (!svr->path) - { - ERR("Allocation failed"); - return EINA_FALSE; - } - - /* - * synchronuous - * block mode - * wait mode - */ - svr->pipe = CreateNamedPipe(svr->path, - PIPE_ACCESS_DUPLEX, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - BUFSIZE, - BUFSIZE, - 5000, - NULL); - if (svr->pipe == INVALID_HANDLE_VALUE) - { - ERR("Creation of the named pipe failed"); - goto free_path; - } - - /* - * We use ConnectNamedPipe() to wait for a client to connect. - * As the function is blocking, to let the main loop continuing - * its iterations, we call ConnectNamedPipe() in a thread - */ - thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, svr, CREATE_SUSPENDED, NULL); - if (!thread_listening) - { - ERR("Creation of the listening thread failed"); - goto close_pipe; - } - - handler = ecore_main_win32_handler_add(thread_listening, - _ecore_con_local_win32_client_add, - svr); - if (!handler) - { - ERR("Creation of the client add handler failed"); - goto del_handler; - } - - svr->read_stopped = EINA_TRUE; - ResumeThread(thread_listening); - - return EINA_TRUE; - - del_handler: - ecore_main_win32_handler_del(handler); - close_pipe: - CloseHandle(svr->pipe); - free_path: - free(svr->path); - svr->path = NULL; - - return EINA_FALSE; -} - -void -ecore_con_local_win32_server_del(Ecore_Con_Server *svr) -{ - if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) - return; - - if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && - ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) - return; - - svr->read_stop = 1; - while (!svr->read_stopped) - Sleep(100); - - if (svr->event_peek) - CloseHandle(svr->event_peek); - svr->event_peek = NULL; - if (svr->event_read) - CloseHandle(svr->event_read); - svr->event_read = NULL; - free(svr->path); - svr->path = NULL; - if (svr->pipe) - CloseHandle(svr->pipe); - svr->pipe = NULL; -} - -void -ecore_con_local_win32_client_del(Ecore_Con_Client *cl) -{ - if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) - return; - - if (((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && - ((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) - return; - - cl->host_server->read_stop = 1; - while (!cl->host_server->read_stopped) - Sleep(100); - - if (cl->host_server->event_peek) - CloseHandle(cl->host_server->event_peek); - cl->host_server->event_peek = NULL; - if (cl->host_server->event_read) - CloseHandle(cl->host_server->event_read); - cl->host_server->event_read = NULL; - free(cl->host_server->path); - cl->host_server->path = NULL; - if (cl->host_server->pipe) - CloseHandle(cl->host_server->pipe); - cl->host_server->pipe = NULL; -} - -Eina_Bool -ecore_con_local_connect(Ecore_Con_Server *svr, - Eina_Bool (*cb_done)(void *data, - Ecore_Fd_Handler *fd_handler)) -{ - char buf[256]; - Ecore_Win32_Handler *handler_read; - Ecore_Win32_Handler *handler_peek; - - if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) - { - ERR("Your system does not support abstract sockets!"); - return EINA_FALSE; - } - - if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) - snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); - else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) - { - const char *computername; - - computername = getenv("COMPUTERNAME"); - snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); - } - - while (1) - { - svr->pipe = CreateFile(buf, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (svr->pipe != INVALID_HANDLE_VALUE) - break; - - /* if pipe not busy, we exit */ - if (GetLastError() != ERROR_PIPE_BUSY) - { - ERR("Connection to a server failed"); - return EINA_FALSE; - } - - /* pipe busy, so we wait for it */ - if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER)) - { - ERR("Can not wait for a server"); - goto close_pipe; - } - } - - svr->path = strdup(buf); - if (!svr->path) - { - ERR("Allocation failed"); - goto close_pipe; - } - - svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!svr->event_read) - { - ERR("Can not create event read"); - goto free_path; - } - - handler_read = ecore_main_win32_handler_add(svr->event_read, - _ecore_con_local_win32_client_read_server_handler, - svr); - if (!handler_read) - { - ERR("Can not create handler read"); - goto close_event_read; - } - - svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!svr->event_peek) - { - ERR("Can not create event peek"); - goto del_handler_read; - } - - handler_peek = ecore_main_win32_handler_add(svr->event_peek, - _ecore_con_local_win32_client_peek_server_handler, - svr); - if (!handler_peek) - { - ERR("Can not create handler peek"); - goto close_event_peek; - } - - svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_client_read_server_thread, svr, CREATE_SUSPENDED, NULL); - if (!svr->thread_read) - { - ERR("Can not launch thread"); - goto del_handler_peek; - } - - if (!svr->delete_me) ecore_con_event_server_add(svr); - - ResumeThread(svr->thread_read); - - return EINA_TRUE; - - del_handler_peek: - ecore_main_win32_handler_del(handler_peek); - close_event_peek: - CloseHandle(svr->event_peek); - del_handler_read: - ecore_main_win32_handler_del(handler_read); - close_event_read: - CloseHandle(svr->event_read); - free_path: - free(svr->path); - svr->path = NULL; - close_pipe: - CloseHandle(svr->pipe); - - return EINA_FALSE; -} - -Eina_Bool -ecore_con_local_win32_server_flush(Ecore_Con_Server *svr) -{ - int num; - BOOL res; - DWORD written; - - /* This check should never be true */ - if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) - return EINA_TRUE; - - if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && - ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) - return EINA_FALSE; - - num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset; - if (num <= 0) return EINA_TRUE; - - res = WriteFile(svr->pipe, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num, &written, NULL); - if (!res) - { - char *msg; - - msg = evil_last_error_get(); - if (msg) - { - ecore_con_event_server_error(svr, msg); - free(msg); - } - _ecore_con_server_kill(svr); - } - - svr->write_buf_offset += written; - if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) - { - svr->write_buf_offset = 0; - eina_binbuf_free(svr->buf); - svr->buf = NULL; - svr->want_write = 0; - } - else if (written < (DWORD)num) - svr->want_write = 1; - - return EINA_TRUE; -} - -Eina_Bool -ecore_con_local_win32_client_flush(Ecore_Con_Client *cl) -{ - Ecore_Con_Type type; - int num; - BOOL res; - DWORD written; - - type = cl->host_server->type & ECORE_CON_TYPE; - - /* This check should never be true */ - if (type == ECORE_CON_LOCAL_ABSTRACT) - return EINA_TRUE; - - if ((type != ECORE_CON_LOCAL_USER) && - (type != ECORE_CON_LOCAL_SYSTEM)) - return EINA_FALSE; - - num = eina_binbuf_length_get(cl->buf) - cl->buf_offset; - if (num <= 0) return EINA_TRUE; - - res = WriteFile(cl->host_server->pipe, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num, &written, NULL); - if (!res) - { - char *msg; - - msg = evil_last_error_get(); - if (msg) - { - ecore_con_event_client_error(cl, msg); - free(msg); - } - _ecore_con_client_kill(cl); - } - - cl->buf_offset += written; - if (cl->buf_offset >= eina_binbuf_length_get(cl->buf)) - { - cl->buf_offset = 0; - eina_binbuf_free(cl->buf); - cl->buf = NULL; - cl->host_server->want_write = 0; - } - else if (written < (DWORD)num) - cl->host_server->want_write = 1; - - return EINA_TRUE; -} diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_private.h b/legacy/ecore/src/lib/ecore_con/ecore_con_private.h deleted file mode 100644 index d8b0abb5c3..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_private.h +++ /dev/null @@ -1,390 +0,0 @@ -#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 -#define ECORE_CON_SUPER_SSL 0xf00 - -#if USE_GNUTLS -# include -#elif USE_OPENSSL -# include -#endif -#ifdef HAVE_CURL -#include -#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 struct _Ecore_Con_Lookup Ecore_Con_Lookup; -typedef struct _Ecore_Con_Info Ecore_Con_Info; -typedef struct Ecore_Con_Socks Ecore_Con_Socks_v4; -typedef struct Ecore_Con_Socks_v5 Ecore_Con_Socks_v5; -typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos); - -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; - -typedef enum _Ecore_Con_Ssl_Handshake -{ - ECORE_CON_SSL_STATE_DONE = 0, - ECORE_CON_SSL_STATE_HANDSHAKING, - ECORE_CON_SSL_STATE_INIT -} Ecore_Con_Ssl_State; - -typedef enum Ecore_Con_Proxy_State -{ /* named PROXY instead of SOCKS in case some handsome and enterprising - * developer decides to add HTTP CONNECT support - */ - ECORE_CON_PROXY_STATE_DONE = 0, - ECORE_CON_PROXY_STATE_RESOLVED, - ECORE_CON_PROXY_STATE_INIT, - ECORE_CON_PROXY_STATE_READ, - ECORE_CON_PROXY_STATE_AUTH, - ECORE_CON_PROXY_STATE_REQUEST, - ECORE_CON_PROXY_STATE_CONFIRM, -} Ecore_Con_Proxy_State; - -struct _Ecore_Con_Client -{ - ECORE_MAGIC; - int fd; - Ecore_Con_Server *host_server; - void *data; - Ecore_Fd_Handler *fd_handler; - unsigned int buf_offset; - Eina_Binbuf *buf; - const char *ip; - Eina_List *event_count; - struct sockaddr *client_addr; - int client_addr_len; - double start_time; - Ecore_Timer *until_deletion; - double disconnect_time; -#if USE_GNUTLS - gnutls_datum_t session_ticket; - gnutls_session_t session; -#elif USE_OPENSSL - SSL *ssl; - int ssl_err; -#endif - Ecore_Con_Ssl_State ssl_state; - Eina_Bool handshaking : 1; - Eina_Bool upgrade : 1; /* STARTTLS queued */ - Eina_Bool delete_me : 1; /* del event has been queued */ -}; - -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; - unsigned int client_count; - Eina_Binbuf *buf; - unsigned int write_buf_offset; - Eina_List *infos; - Eina_List *event_count; - int client_limit; - pid_t ppid; - /* socks */ - Ecore_Con_Socks *ecs; - Ecore_Con_Proxy_State ecs_state; - int ecs_addrlen; - unsigned char ecs_addr[16]; - unsigned int ecs_buf_offset; - Eina_Binbuf *ecs_buf; - Eina_Binbuf *ecs_recvbuf; - const char *proxyip; - int proxyport; - /* endsocks */ - const char *verify_name; -#if USE_GNUTLS - gnutls_session_t session; - gnutls_anon_client_credentials_t anoncred_c; - gnutls_anon_server_credentials_t anoncred_s; - gnutls_psk_client_credentials_t pskcred_c; - gnutls_psk_server_credentials_t pskcred_s; - gnutls_certificate_credentials_t cert; - char *cert_file; - gnutls_dh_params_t dh_params; -#elif USE_OPENSSL - SSL_CTX *ssl_ctx; - SSL *ssl; - int ssl_err; -#endif - double start_time; - Ecore_Timer *until_deletion; - double disconnect_time; - double client_disconnect_time; - const char *ip; - Eina_Bool created : 1; /* @c EINA_TRUE if server is our listening server */ - Eina_Bool connecting : 1; /* @c EINA_FALSE if just initialized or connected */ - Eina_Bool handshaking : 1; /* @c EINA_TRUE if server is ssl handshaking */ - Eina_Bool upgrade : 1; /* STARTTLS queued */ - Eina_Bool disable_proxy : 1; /* proxy should never be used with this connection */ - Eina_Bool ssl_prepared : 1; - Eina_Bool use_cert : 1; /* @c EINA_TRUE if using certificate auth */ - Ecore_Con_Ssl_State ssl_state; /* current state of ssl handshake on the server */ - Eina_Bool verify : 1; /* @c EINA_TRUE if certificates will be verified */ - Eina_Bool verify_basic : 1; /* @c EINA_TRUE if certificates will be verified only against the hostname */ - Eina_Bool reject_excess_clients : 1; - Eina_Bool delete_me : 1; /* del event has been queued */ -#ifdef _WIN32 - Eina_Bool want_write : 1; - Eina_Bool read_stop : 1; - Eina_Bool read_stopped : 1; - HANDLE pipe; - HANDLE thread_read; - HANDLE event_read; - HANDLE event_peek; - DWORD nbr_bytes; -#endif -}; - -#ifdef HAVE_CURL -struct _Ecore_Con_Url -{ - ECORE_MAGIC; - CURL *curl_easy; - struct curl_slist *headers; - Eina_List *additional_headers; - Eina_List *response_headers; - const char *url; - long proxy_type; - int status; - - Ecore_Timer *timer; - - Ecore_Con_Url_Time time_condition; - double timestamp; - void *data; - - void *post_data; - - int received; - int write_fd; - - unsigned int event_count; - Eina_Bool dead : 1; - Eina_Bool multi : 1; -}; -#endif - -struct _Ecore_Con_Info -{ - unsigned int size; - struct addrinfo info; - char ip[NI_MAXHOST]; - char service[NI_MAXSERV]; -}; - -struct _Ecore_Con_Lookup -{ - Ecore_Con_Dns_Cb done_cb; - const void *data; -}; - -struct Ecore_Con_Socks /* v4 */ -{ - unsigned char version; - - const char *ip; - int port; - const char *username; - unsigned int ulen; - Eina_Bool lookup : 1; - Eina_Bool bind : 1; -}; - -struct Ecore_Con_Socks_v5 -{ - unsigned char version; - - const char *ip; - int port; - const char *username; - unsigned int ulen; - Eina_Bool lookup : 1; - Eina_Bool bind : 1; - /* v5 only */ - unsigned char method; - const char *password; - unsigned int plen; -}; - -extern Ecore_Con_Socks *_ecore_con_proxy_once; -extern Ecore_Con_Socks *_ecore_con_proxy_global; -void ecore_con_socks_init(void); -void ecore_con_socks_shutdown(void); -Eina_Bool ecore_con_socks_svr_init(Ecore_Con_Server *svr); -void ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num); -void ecore_con_socks_dns_cb(const char *canonname, const char *ip, struct sockaddr *addr, int addrlen, Ecore_Con_Server *svr); -/* from ecore_con.c */ -void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info); -void ecore_con_event_proxy_bind(Ecore_Con_Server *svr); -void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate); -void ecore_con_event_server_del(Ecore_Con_Server *svr); -#define ecore_con_event_server_error(svr, error) _ecore_con_event_server_error((svr), (char*)(error), EINA_TRUE) -void _ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate); -void ecore_con_event_client_add(Ecore_Con_Client *cl); -void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate); -void ecore_con_event_client_del(Ecore_Con_Client *cl); -void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error); -void _ecore_con_server_kill(Ecore_Con_Server *svr); -void _ecore_con_client_kill(Ecore_Con_Client *cl); -/* from ecore_local_win32.c */ -#ifdef _WIN32 -Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr); -Eina_Bool ecore_con_local_connect(Ecore_Con_Server *svr, - Eina_Bool (*cb_done)(void *data, - Ecore_Fd_Handler *fd_handler)); -Eina_Bool ecore_con_local_win32_server_flush(Ecore_Con_Server *svr); -Eina_Bool ecore_con_local_win32_client_flush(Ecore_Con_Client *cl); -void ecore_con_local_win32_server_del(Ecore_Con_Server *svr); -void ecore_con_local_win32_client_del(Ecore_Con_Client *cl); -#else -/* 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, - Eina_Bool (*cb_done)( - void *data, - Ecore_Fd_Handler *fd_handler), - void *data); -int ecore_con_local_listen(Ecore_Con_Server *svr, - Eina_Bool (*cb_listen)( - void *data, - Ecore_Fd_Handler *fd_handler), - void *data); -#endif - -/* 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); -void ecore_con_info_data_clear(void *info); - -void ecore_con_event_server_add(Ecore_Con_Server *svr); - - -/* from ecore_con_ssl.c */ -Ecore_Con_Ssl_Error ecore_con_ssl_init(void); -Ecore_Con_Ssl_Error ecore_con_ssl_shutdown(void); -Ecore_Con_Ssl_Error ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, int ssl_type); -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); -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, - const 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); -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, - const unsigned char *buf, - int size); - -int ecore_con_info_get(Ecore_Con_Server *svr, - Ecore_Con_Info_Cb done_cb, - void *data, - struct addrinfo *hints); - - -#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \ - TYPE *Type##_alloc(void); \ - void Type##_free(TYPE *e); - -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Add, ecore_con_event_client_add); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Del, ecore_con_event_client_del); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Write, ecore_con_event_client_write); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Data, ecore_con_event_client_data); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Error, ecore_con_event_server_error); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Error, ecore_con_event_client_error); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Add, ecore_con_event_server_add); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); -GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind); - -void ecore_con_mempool_init(void); -void ecore_con_mempool_shutdown(void); - -#undef GENERIC_ALLOC_FREE_HEADER - -#endif diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_socks.c b/legacy/ecore/src/lib/ecore_con/ecore_con_socks.c deleted file mode 100644 index a6df8a9640..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_socks.c +++ /dev/null @@ -1,962 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_SOCKET_H -# include -#endif - -#ifdef HAVE_NETINET_TCP_H -# include -#endif - -#ifdef HAVE_NET_IF_H -# include -#endif - -/* if net/if.h is not found or if an older versions of net/if.h is provided - which does not define IF_NAMESIZE. We must define it ourselves */ -#ifndef IF_NAMESIZE -# ifdef IFNAMSIZ -# define IF_NAMESIZE IFNAMSIZ -# else -# define IF_NAMESIZE 16 -# endif -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_SYS_UN_H -# include -#endif - -#ifdef HAVE_WS2TCPIP_H -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" -#include "Ecore_Con.h" -#include "ecore_con_private.h" - -/* http://tools.ietf.org/html/rfc1928 - o X'00' NO AUTHENTICATION REQUIRED - o X'01' GSSAPI - o X'02' USERNAME/PASSWORD - o X'03' to X'7F' IANA ASSIGNED - o X'80' to X'FE' RESERVED FOR PRIVATE METHODS - o X'FF' NO ACCEPTABLE METHODS -*/ -#define ECORE_CON_SOCKS_V5_METHOD_NONE 0 -#define ECORE_CON_SOCKS_V5_METHOD_GSSAPI 1 -#define ECORE_CON_SOCKS_V5_METHOD_USERPASS 2 - -static int ECORE_CON_SOCKS_V5_METHODS[] = -{ - ECORE_CON_SOCKS_V5_METHOD_NONE, -// ECORE_CON_SOCKS_V5_METHOD_GSSAPI, TODO - ECORE_CON_SOCKS_V5_METHOD_USERPASS -}; - -#define ECORE_CON_SOCKS_V5_TOTAL_METHODS sizeof(ECORE_CON_SOCKS_V5_METHODS) - -#define _ecore_con_server_kill(svr) do { \ - DBG("KILL %p", (svr)); \ - _ecore_con_server_kill((svr)); \ -} while (0) - -#define ECORE_CON_SOCKS_VERSION_CHECK(X) do { \ - if (!(X) || ((X)->version < 4) || ((X)->version > 5)) \ - return; \ -} while (0) -#define ECORE_CON_SOCKS_VERSION_CHECK_RETURN(X, ret) do { \ - if (!(X) || ((X)->version < 4) || ((X)->version > 5)) \ - return (ret); \ -} while (0) - -#define ECORE_CON_SOCKS_CAST(X) \ - Ecore_Con_Socks_v4 *v4 = NULL; \ - Ecore_Con_Socks_v5 *v5 = NULL; \ - if ((X) && ((X)->version == 4)) \ - v4 = (Ecore_Con_Socks_v4 *)(X); \ - else if ((X) && ((X)->version == 5)) \ - v5 = (Ecore_Con_Socks_v5 *)(X); - -Eina_List *ecore_con_socks_proxies = NULL; - -static Ecore_Con_Socks * -_ecore_con_socks_find(unsigned char version, const char *ip, int port, const char *username, size_t ulen, const char *password, size_t plen) -{ - Eina_List *l; - Ecore_Con_Socks_v5 *ecs; - - if (!ecore_con_socks_proxies) return NULL; - - EINA_LIST_FOREACH(ecore_con_socks_proxies, l, ecs) - { - if (ecs->version != version) continue; - if (strcmp(ecs->ip, ip)) continue; - if ((port != -1) && (port != ecs->port)) continue; - if (ulen != ecs->ulen) continue; - if (username && strcmp(ecs->username, username)) continue; - if (version == 5) - { - if (plen != ecs->plen) continue; - if (password && strcmp(ecs->password, password)) continue; - } - return (Ecore_Con_Socks*)ecs; - } - return NULL; -} - -static void -_ecore_con_socks_free(Ecore_Con_Socks *ecs) -{ - ECORE_CON_SOCKS_VERSION_CHECK(ecs); - - if (_ecore_con_proxy_once == ecs) _ecore_con_proxy_once = NULL; - if (_ecore_con_proxy_global == ecs) _ecore_con_proxy_global = NULL; - eina_stringshare_del(ecs->ip); - eina_stringshare_del(ecs->username); - free(ecs); -} - -static Eina_Bool -_ecore_con_socks_svr_init_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4) -{ - size_t addrlen, buflen, ulen = 1; - unsigned char *sbuf; - - addrlen = v4->lookup ? strlen(svr->name) + 1 : 0; - if (v4->username) ulen += v4->ulen; - buflen = sizeof(char) * (8 + ulen + addrlen); - sbuf = malloc(buflen); - if (!sbuf) - { - ecore_con_event_server_error(svr, "Memory allocation failure!"); - _ecore_con_server_kill(svr); - return EINA_FALSE; - } - /* http://en.wikipedia.org/wiki/SOCKS */ - sbuf[0] = 4; - sbuf[1] = v4->bind ? 2 : 1; - sbuf[2] = svr->port >> 8; - sbuf[3] = svr->port & 0xff; - if (addrlen) - { - sbuf[4] = sbuf[5] = sbuf[6] = 0; - sbuf[7] = 1; - } - else - /* SOCKSv4 only handles IPV4, so addrlen is always 4 */ - memcpy(sbuf + 4, svr->ecs_addr, 4); - if (v4->username) - memcpy(sbuf + 8, v4->username, ulen); - else - sbuf[8] = 0; - if (addrlen) memcpy(sbuf + 8 + ulen, svr->name, addrlen); - - svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); - return EINA_TRUE; -} - -static Eina_Bool -_ecore_con_socks_svr_init_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5) -{ - size_t buflen; - unsigned int x; - unsigned char *sbuf; - - if (v5->username) - buflen = sizeof(char) * (2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS); - else - buflen = 3; - sbuf = malloc(buflen); - if (!sbuf) - { - ecore_con_event_server_error(svr, "Memory allocation failure!"); - _ecore_con_server_kill(svr); - return EINA_FALSE; - } - /* http://en.wikipedia.org/wiki/SOCKS - * http://tools.ietf.org/html/rfc1928 - */ - sbuf[0] = 5; - if (v5->username) - { - sbuf[1] = ECORE_CON_SOCKS_V5_TOTAL_METHODS; - for (x = 2; x < 2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS; x++) - sbuf[x] = ECORE_CON_SOCKS_V5_METHODS[x - 2]; - } - else - { - sbuf[1] = 1; - sbuf[2] = ECORE_CON_SOCKS_V5_METHOD_NONE; - } - - svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); - return EINA_TRUE; -} - -#define ECORE_CON_SOCKS_READ(EXACT) \ - if (num < EXACT) \ - { \ - if (!svr->ecs_recvbuf) svr->ecs_recvbuf = eina_binbuf_new(); \ - if (!svr->ecs_recvbuf) goto error; \ - eina_binbuf_append_length(svr->ecs_recvbuf, buf, num); \ - /* the slowest connection on earth */ \ - if (eina_binbuf_length_get(svr->ecs_recvbuf) != EXACT) return; \ - data = eina_binbuf_string_get(svr->ecs_recvbuf); \ - } \ - else if (num > EXACT) goto error; \ - else \ - data = buf - -static void -_ecore_con_socks_read_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4 EINA_UNUSED, const unsigned char *buf, unsigned int num) -{ - const unsigned char *data; - DBG("SOCKS: %d bytes", num); - ECORE_CON_SOCKS_READ(8); - -/* http://ufasoft.com/doc/socks4_protocol.htm */ - if (data[0]) goto error; - switch (data[1]) - { - case 90: - /* success! */ - break; - case 91: - ecore_con_event_server_error(svr, "proxy request rejected or failed"); - goto error; - case 92: - ecore_con_event_server_error(svr, "proxying SOCKS server could not perform authentication"); - goto error; - case 93: - ecore_con_event_server_error(svr, "proxy request authentication rejected"); - goto error; - default: - ecore_con_event_server_error(svr, "garbage data from proxy"); - goto error; - } - if (svr->ecs->bind) - { - unsigned int nport; - char naddr[IF_NAMESIZE]; - - memcpy(&nport, &data[2], 2); - svr->proxyport = ntohl(nport); - - if (!inet_ntop(AF_INET, &data[4], naddr, sizeof(naddr))) goto error; - svr->proxyip = eina_stringshare_add(naddr); - ecore_con_event_proxy_bind(svr); - } - svr->ecs_state = ECORE_CON_PROXY_STATE_DONE; - INF("PROXY CONNECTED"); - if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); - svr->ecs_recvbuf = NULL; - svr->ecs_buf_offset = svr->ecs_addrlen = 0; - memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr)); - if (!svr->ssl_state) - ecore_con_event_server_add(svr); - if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf))) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); - return; -error: - _ecore_con_server_kill(svr); -} - -static Eina_Bool -_ecore_con_socks_auth_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5) -{ - size_t size; - unsigned char *data; - switch (v5->method) - { - case ECORE_CON_SOCKS_V5_METHOD_NONE: - svr->ecs_state = ECORE_CON_PROXY_STATE_REQUEST; - return EINA_TRUE; - case ECORE_CON_SOCKS_V5_METHOD_GSSAPI: - return EINA_TRUE; - case ECORE_CON_SOCKS_V5_METHOD_USERPASS: - if (!v5->username) return EINA_FALSE; - if (!v5->password) v5->plen = 1; - /* http://tools.ietf.org/html/rfc1929 */ - size = sizeof(char) * (3 + v5->ulen + v5->plen); - data = malloc(size); - if (!data) break; - data[0] = 1; - data[1] = v5->ulen; - memcpy(&data[2], v5->username, v5->ulen); - data[1 + v5->ulen] = v5->plen; - if (v5->password) - memcpy(&data[2 + v5->ulen], v5->password, v5->plen); - else - data[2 + v5->ulen] = 0; - svr->ecs_buf = eina_binbuf_manage_new_length(data, size); - return EINA_TRUE; - default: - break; - } - return EINA_FALSE; -} - -static void -_ecore_con_socks_read_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5, const unsigned char *buf, unsigned int num) -{ - const unsigned char *data; - - DBG("SOCKS: %d bytes", num); - switch (svr->ecs_state) - { - - case ECORE_CON_PROXY_STATE_READ: - ECORE_CON_SOCKS_READ(2); - /* http://en.wikipedia.org/wiki/SOCKS */ - if (data[0] != 5) goto error; - if (data[1] == 0xFF) - { - ecore_con_event_server_error(svr, "proxy authentication methods rejected"); - goto error; - } - v5->method = data[1]; - if (!_ecore_con_socks_auth_v5(svr, v5)) goto error; - if (svr->ecs_state == ECORE_CON_PROXY_STATE_REQUEST) - { - /* run again to skip auth reading */ - _ecore_con_socks_read_v5(svr, v5, NULL, 0); - return; - } - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); - svr->ecs_state = ECORE_CON_PROXY_STATE_AUTH; - break; - case ECORE_CON_PROXY_STATE_AUTH: - ECORE_CON_SOCKS_READ(2); - switch (v5->method) - { - case ECORE_CON_SOCKS_V5_METHOD_NONE: - CRIT("HOW DID THIS HAPPEN?????????"); - goto error; - case ECORE_CON_SOCKS_V5_METHOD_GSSAPI: - /* TODO: this */ - break; - case ECORE_CON_SOCKS_V5_METHOD_USERPASS: - if (data[0] != 1) - { - ecore_con_event_server_error(svr, "protocol error"); - goto error; /* wrong version */ - } - if (data[1]) - { - ecore_con_event_server_error(svr, "proxy request authentication rejected"); - goto error; - } - default: - break; - } - case ECORE_CON_PROXY_STATE_REQUEST: - { - size_t addrlen, buflen; - unsigned char *sbuf; - addrlen = v5->lookup ? strlen(svr->name) + 1 : (unsigned int)svr->ecs_addrlen; - buflen = sizeof(char) * (6 + addrlen); - sbuf = malloc(buflen); - if (!sbuf) - { - ecore_con_event_server_error(svr, "Memory allocation failure!"); - goto error; - } - sbuf[0] = 5; - sbuf[1] = v5->bind ? 2 : 1; /* TODO: 0x03 for UDP port association */ - sbuf[2] = 0; - if (v5->lookup) /* domain name */ - { - sbuf[3] = 3; - sbuf[4] = addrlen - 1; - memcpy(sbuf + 5, svr->name, addrlen - 1); - } - else - { - sbuf[3] = (svr->ecs_addrlen == 4) ? 1 : 4; - memcpy(sbuf + 4, svr->ecs_addr, addrlen); - } - sbuf[addrlen + 4] = svr->port >> 8; - sbuf[addrlen + 5] = svr->port & 0xff; - - svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); - break; - } - case ECORE_CON_PROXY_STATE_CONFIRM: - { - /* this is ugly because we have to read an exact number of bytes, - * but we don't know what that number is until we've already read - * at least 5 bytes to determine the length of the unknown stream. - * yep. - */ - size_t to_read, len = svr->ecs_recvbuf ? eina_binbuf_length_get(svr->ecs_recvbuf) : 0; - if (num + len < 5) - { - /* guarantees we get called again */ - ECORE_CON_SOCKS_READ(5); - } - if (len >= 5) - { - data = eina_binbuf_string_get(svr->ecs_recvbuf); - data += 3; - } - else - data = buf + 3 - len; - switch (data[0]) - { - case 1: - to_read = 4; - break; - case 3: - to_read = data[1] + 1; - break; - case 4: - to_read = 16; - /* lazy debugging stub comment */ - break; - default: - ecore_con_event_server_error(svr, "protocol error"); - goto error; - } - /* at this point, we finally know exactly how much we need to read */ - ECORE_CON_SOCKS_READ(6 + to_read); - - if (data[0] != 5) - { - ecore_con_event_server_error(svr, "protocol error"); - goto error; /* wrong version */ - } - switch (data[1]) - { - case 0: - break; - case 1: - ecore_con_event_server_error(svr, "general proxy failure"); - goto error; - case 2: - ecore_con_event_server_error(svr, "connection not allowed by ruleset"); - goto error; - case 3: - ecore_con_event_server_error(svr, "network unreachable"); - goto error; - case 4: - ecore_con_event_server_error(svr, "host unreachable"); - goto error; - case 5: - ecore_con_event_server_error(svr, "connection refused by destination host"); - goto error; - case 6: - ecore_con_event_server_error(svr, "TTL expired"); - goto error; - case 7: - ecore_con_event_server_error(svr, "command not supported / protocol error"); - goto error; - case 8: - ecore_con_event_server_error(svr, "address type not supported"); - default: - goto error; - } - if (data[2]) - { - ecore_con_event_server_error(svr, "protocol error"); - goto error; - } - memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr)); - if (!svr->ssl_state) - ecore_con_event_server_add(svr); - if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf))) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); - svr->ecs_buf_offset = svr->ecs_addrlen = 0; - svr->ecs_state = ECORE_CON_PROXY_STATE_DONE; - INF("PROXY CONNECTED"); - break; - } - default: - break; - } - if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); - svr->ecs_recvbuf = NULL; - - return; -error: - _ecore_con_server_kill(svr); -} - -///////////////////////////////////////////////////////////////////////////////////// -void -ecore_con_socks_shutdown(void) -{ - Ecore_Con_Socks *ecs; - EINA_LIST_FREE(ecore_con_socks_proxies, ecs) - _ecore_con_socks_free(ecs); - _ecore_con_proxy_once = NULL; - _ecore_con_proxy_global = NULL; -} - -void -ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num) -{ - ECORE_CON_SOCKS_VERSION_CHECK(svr->ecs); - ECORE_CON_SOCKS_CAST(svr->ecs); - - if (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) return; - - if (v4) _ecore_con_socks_read_v4(svr, v4, buf, (unsigned int)num); - else _ecore_con_socks_read_v5(svr, v5, buf, (unsigned int)num); -} - -Eina_Bool -ecore_con_socks_svr_init(Ecore_Con_Server *svr) -{ - ECORE_CON_SOCKS_VERSION_CHECK_RETURN(svr->ecs, EINA_FALSE); - ECORE_CON_SOCKS_CAST(svr->ecs); - - if (!svr->ip) return EINA_FALSE; - if (svr->ecs_buf) return EINA_FALSE; - if (svr->ecs_state != ECORE_CON_PROXY_STATE_INIT) return EINA_FALSE; - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); - if (v4) return _ecore_con_socks_svr_init_v4(svr, v4); - return _ecore_con_socks_svr_init_v5(svr, v5); -} - -void -ecore_con_socks_dns_cb(const char *canonname EINA_UNUSED, const char *ip, struct sockaddr *addr, int addrlen EINA_UNUSED, Ecore_Con_Server *svr) -{ - svr->ip = eina_stringshare_add(ip); - svr->ecs_state++; - if (addr->sa_family == AF_INET) - { - memcpy(svr->ecs_addr, &((struct sockaddr_in *)addr)->sin_addr.s_addr, 4); - svr->ecs_addrlen = 4; - } -#ifdef HAVE_IPV6 - else - { - memcpy(svr->ecs_addr, &((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, 16); - svr->ecs_addrlen = 16; - } -#endif - ecore_con_socks_svr_init(svr); -} - -void -ecore_con_socks_init(void) -{ - const char *socks; - char *h, *p, *l, *u = NULL; - char buf[512]; - int port, lookup = 0; - Eina_Bool v5 = EINA_FALSE; - Ecore_Con_Socks *ecs; - unsigned char addr[sizeof(struct in_addr)]; -#ifdef HAVE_IPV6 - unsigned char addr6[sizeof(struct in6_addr)]; -#endif - - /* ECORE_CON_SOCKS_V4=[user@]host-port:[1|0] */ - socks = getenv("ECORE_CON_SOCKS_V4"); - if (!socks) - { - /* ECORE_CON_SOCKS_V5=[user@]host-port:[1|0] */ - socks = getenv("ECORE_CON_SOCKS_V5"); - v5 = EINA_TRUE; - } - if ((!socks) || (!socks[0]) || (strlen(socks) > 512)) return; - strncpy(buf, socks, sizeof(buf)); - h = strchr(buf, '@'); - /* username */ - if (h && (h - buf > 0)) *h++ = 0, u = buf; - else h = buf; - - /* host ip; I ain't resolvin shit here */ - p = strchr(h, '-'); - if (!p) return; - *p++ = 0; - if (!inet_pton(AF_INET, h, addr)) -#ifdef HAVE_IPV6 - { - if (!v5) return; - if (!inet_pton(AF_INET6, h, addr6)) - return; - } -#else - return; -#endif - - errno = 0; - port = strtol(p, &l, 10); - if (errno || (port < 0) || (port > 65535)) return; - if (l && (l[0] == ':')) - lookup = (l[1] == '1'); - if (v5) - ecs = ecore_con_socks5_remote_add(h, port, u, NULL); - else - ecs = ecore_con_socks4_remote_add(h, port, u); - if (!ecs) return; - ecore_con_socks_lookup_set(ecs, lookup); - ecore_con_socks_apply_always(ecs); - INF("Added global proxy server %s%s%s:%d - DNS lookup %s", - u ?: "", u ? "@" : "", h, port, lookup ? "ENABLED" : "DISABLED"); -} - -///////////////////////////////////////////////////////////////////////////////////// - -/** - * @defgroup Ecore_Con_Socks_Group Ecore Connection SOCKS functions - * @{ - */ - -/** - * Add a SOCKS v4 proxy to the proxy list - * - * Use this to create (or return, if previously added) a SOCKS proxy - * object which can be used by any ecore_con servers. - * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) - * @param port The port to connect to on the proxy - * @param username The username to use for the proxy (OPTIONAL) - * @return An allocated proxy object, or NULL on failure - * @note This object NEVER needs to be explicitly freed. - * @since 1.2 - */ -EAPI Ecore_Con_Socks * -ecore_con_socks4_remote_add(const char *ip, int port, const char *username) -{ - Ecore_Con_Socks *ecs; - size_t ulen = 0; - - if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL; - - if (username) - { - ulen = strlen(username); - /* max length for protocol */ - if ((!ulen) || (ulen > 255)) return NULL; - } - ecs = _ecore_con_socks_find(4, ip, port, username, ulen, NULL, 0); - if (ecs) return ecs; - - ecs = calloc(1, sizeof(Ecore_Con_Socks_v4)); - if (!ecs) return NULL; - - ecs->version = 4; - ecs->ip = eina_stringshare_add(ip); - ecs->port = port; - ecs->username = eina_stringshare_add(username); - ecs->ulen = ulen; - ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs); - return ecs; -} - -/** - * Find a SOCKS v4 proxy in the proxy list - * - * Use this to determine if a SOCKS proxy was previously added by checking - * the proxy list against the parameters given. - * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) - * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip - * @param username The username used for the proxy (OPTIONAL) - * @return true only if a proxy exists matching the given params - * @note This function matches slightly more loosely than ecore_con_socks4_remote_add(), and - * ecore_con_socks4_remote_add() should be used to return the actual object. - * @since 1.2 - */ -EAPI Eina_Bool -ecore_con_socks4_remote_exists(const char *ip, int port, const char *username) -{ - if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0]))) - return EINA_FALSE; - return !!_ecore_con_socks_find(4, ip, port, username, username ? strlen(username) : 0, NULL, 0); -} - -/** - * Remove a SOCKS v4 proxy from the proxy list and delete it - * - * Use this to remove a SOCKS proxy from the proxy list by checking - * the list against the parameters given. The proxy will then be deleted. - * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) - * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip - * @param username The username used for the proxy (OPTIONAL) - * @note This function matches in the same way as ecore_con_socks4_remote_exists(). - * @warning Be aware that deleting a proxy which is being used WILL ruin your life. - * @since 1.2 - */ -EAPI void -ecore_con_socks4_remote_del(const char *ip, int port, const char *username) -{ - Ecore_Con_Socks_v4 *v4; - - if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0]))) return; - if (!ecore_con_socks_proxies) return; - - v4 = (Ecore_Con_Socks_v4*)_ecore_con_socks_find(4, ip, port, username, username ? strlen(username) : 0, NULL, 0); - if (!v4) return; - ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v4); - _ecore_con_socks_free((Ecore_Con_Socks*)v4); -} -/** - * Add a SOCKS v5 proxy to the proxy list - * - * Use this to create (or return, if previously added) a SOCKS proxy - * object which can be used by any ecore_con servers. - * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) - * @param port The port to connect to on the proxy - * @param username The username to use for the proxy (OPTIONAL) - * @param password The password to use for the proxy (OPTIONAL) - * @return An allocated proxy object, or NULL on failure - * @note This object NEVER needs to be explicitly freed. - * @since 1.2 - */ -EAPI Ecore_Con_Socks * -ecore_con_socks5_remote_add(const char *ip, int port, const char *username, const char *password) -{ - Ecore_Con_Socks_v5 *ecs5; - size_t ulen = 0, plen = 0; - - if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL; - - if (username) - { - ulen = strlen(username); - /* max length for protocol */ - if ((!ulen) || (ulen > 255)) return NULL; - } - if (password) - { - plen = strlen(password); - /* max length for protocol */ - if ((!plen) || (plen > 255)) return NULL; - } - ecs5 = (Ecore_Con_Socks_v5*)_ecore_con_socks_find(5, ip, port, username, ulen, password, plen); - if (ecs5) return (Ecore_Con_Socks*)ecs5; - - ecs5 = calloc(1, sizeof(Ecore_Con_Socks_v5)); - if (!ecs5) return NULL; - - ecs5->version = 5; - ecs5->ip = eina_stringshare_add(ip); - ecs5->port = port; - ecs5->username = eina_stringshare_add(username); - ecs5->ulen = ulen; - ecs5->password = eina_stringshare_add(password); - ecs5->plen = plen; - ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs5); - return (Ecore_Con_Socks*)ecs5; -} - -/** - * Find a SOCKS v5 proxy in the proxy list - * - * Use this to determine if a SOCKS proxy was previously added by checking - * the proxy list against the parameters given. - * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) - * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip - * @param username The username used for the proxy (OPTIONAL) - * @param password The password used for the proxy (OPTIONAL) - * @return true only if a proxy exists matching the given params - * @note This function matches slightly more loosely than ecore_con_socks5_remote_add(), and - * ecore_con_socks5_remote_add() should be used to return the actual object. - * @since 1.2 - */ -EAPI Eina_Bool -ecore_con_socks5_remote_exists(const char *ip, int port, const char *username, const char *password) -{ - if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])) || (password && (!password[0]))) - return EINA_FALSE; - return !!_ecore_con_socks_find(5, ip, port, username, username ? strlen(username) : 0, password, password ? strlen(password) : 0); -} - -/** - * Remove a SOCKS v5 proxy from the proxy list and delete it - * - * Use this to remove a SOCKS proxy from the proxy list by checking - * the list against the parameters given. The proxy will then be deleted. - * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) - * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip - * @param username The username used for the proxy (OPTIONAL) - * @param password The password used for the proxy (OPTIONAL) - * @note This function matches in the same way as ecore_con_socks4_remote_exists(). - * @warning Be aware that deleting a proxy which is being used WILL ruin your life. - * @since 1.2 - */ -EAPI void -ecore_con_socks5_remote_del(const char *ip, int port, const char *username, const char *password) -{ - Ecore_Con_Socks_v5 *v5; - - if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])) || (password && (!password[0]))) - return; - if (!ecore_con_socks_proxies) return; - - v5 = (Ecore_Con_Socks_v5*)_ecore_con_socks_find(5, ip, port, username, username ? strlen(username) : 0, password, password ? strlen(password) : 0); - if (!v5) return; - ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v5); - _ecore_con_socks_free((Ecore_Con_Socks*)v5); -} - -/** - * Set DNS lookup mode on an existing SOCKS proxy - * - * According to RFC, SOCKS v4 does not require that a proxy perform - * its own DNS lookups for addresses. SOCKS v4a specifies the protocol - * for this. SOCKS v5 allows DNS lookups. - * If you want to enable remote DNS lookup and are sure that your - * proxy supports it, use this function. - * @param ecs The proxy object - * @param enable If true, the proxy will perform the dns lookup - * @note By default, this setting is DISABLED. - * @since 1.2 - */ -EAPI void -ecore_con_socks_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable) -{ - ECORE_CON_SOCKS_VERSION_CHECK(ecs); - ecs->lookup = !!enable; -} - -/** - * Get DNS lookup mode on an existing SOCKS proxy - * - * According to RFC, SOCKS v4 does not require that a proxy perform - * its own DNS lookups for addresses. SOCKS v4a specifies the protocol - * for this. SOCKS v5 allows DNS lookups. - * This function returns whether lookups are enabled on a proxy object. - * @param ecs The proxy object - * @return If true, the proxy will perform the dns lookup - * @note By default, this setting is DISABLED. - * @since 1.2 - */ -EAPI Eina_Bool -ecore_con_socks_lookup_get(Ecore_Con_Socks *ecs) -{ - ECORE_CON_SOCKS_VERSION_CHECK_RETURN(ecs, EINA_FALSE); - return ecs->lookup; -} - -/** - * Enable bind mode on a SOCKS proxy - * - * Use this function to enable binding a remote port for use with a remote server. - * For more information, see http://ufasoft.com/doc/socks4_protocol.htm - * @param ecs The proxy object - * @param is_bind If true, the connection established will be a port binding - * @warning Be aware that changing the operation mode of an active proxy may result in undefined behavior - * @since 1.2 - */ -EAPI void -ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind) -{ - EINA_SAFETY_ON_NULL_RETURN(ecs); - ECORE_CON_SOCKS_VERSION_CHECK(ecs); - ecs->bind = !!is_bind; -} - -/** - * Return bind mode of a SOCKS proxy - * - * Use this function to return bind mode of a proxy (binding a remote port for use with a remote server). - * For more information, see http://ufasoft.com/doc/socks4_protocol.htm - * @param ecs The proxy object - * @return If true, the connection established will be a port binding - * @since 1.2 - */ -EAPI Eina_Bool -ecore_con_socks_bind_get(Ecore_Con_Socks *ecs) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, EINA_FALSE); - ECORE_CON_SOCKS_VERSION_CHECK_RETURN(ecs, EINA_FALSE); - return ecs->bind; -} - -/** - * Return SOCKS version of a SOCKS proxy - * - * Use this function to return the SOCKS protocol version of a proxy - * @param ecs The proxy object - * @return 0 on error, else 4/5 - * @since 1.2 - */ -EAPI unsigned int -ecore_con_socks_version_get(Ecore_Con_Socks *ecs) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, 0); - ECORE_CON_SOCKS_VERSION_CHECK_RETURN(ecs, 0); - return ecs->version; -} - -/** - * Remove a SOCKS v4 proxy from the proxy list and delete it - * - * Use this to remove a SOCKS proxy from the proxy list by directly deleting the object given. - * @param ecs The proxy object to delete - * @warning Be aware that deleting a proxy which is being used WILL ruin your life. - * @since 1.2 - */ -EAPI void -ecore_con_socks_remote_del(Ecore_Con_Socks *ecs) -{ - EINA_SAFETY_ON_NULL_RETURN(ecs); - if (!ecore_con_socks_proxies) return; - - ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, ecs); - _ecore_con_socks_free(ecs); -} - -/** - * Set a proxy object to be used with the next server created with ecore_con_server_connect() - * - * This function sets a proxy for the next ecore_con connection. After the next server is created, - * the proxy will NEVER be applied again unless explicitly enabled. - * @param ecs The proxy object - * @see ecore_con_socks_apply_always() - * @since 1.2 - */ -EAPI void -ecore_con_socks_apply_once(Ecore_Con_Socks *ecs) -{ - _ecore_con_proxy_once = ecs; -} - -/** - * Set a proxy object to be used with all servers created with ecore_con_server_connect() - * - * This function sets a proxy for all ecore_con connections. It will always be used. - * @param ecs The proxy object - * @see ecore_con_socks_apply_once() - * @since 1.2 - * @note ecore-con supports setting this through environment variables like so: - * ECORE_CON_SOCKS_V4=[user@]server-port:lookup - * ECORE_CON_SOCKS_V5=[user@]server-port:lookup - * user is the OPTIONAL string that would be passed to the proxy as the username - * server is the IP_ADDRESS of the proxy server - * port is the port to connect to on the proxy server - * lookup is 1 if the proxy should perform all DNS lookups, otherwise 0 or omitted - */ -EAPI void -ecore_con_socks_apply_always(Ecore_Con_Socks *ecs) -{ - _ecore_con_proxy_global = ecs; -} -/** @} */ diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_ssl.c b/legacy/ecore/src/lib/ecore_con/ecore_con_ssl.c deleted file mode 100644 index 609d29161a..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_ssl.c +++ /dev/null @@ -1,2141 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#if USE_GNUTLS -# include -# include -# include -#elif USE_OPENSSL -# include -# include -# include -#endif - -#ifdef HAVE_WS2TCPIP_H -# include -#endif - -#include -#include "Ecore.h" -#include "ecore_con_private.h" - -EAPI int ECORE_CON_EVENT_CLIENT_UPGRADE = 0; -EAPI int ECORE_CON_EVENT_SERVER_UPGRADE = 0; - -static int _init_con_ssl_init_count = 0; - -#ifdef USE_GNUTLS -# ifdef EINA_HAVE_THREADS -GCRY_THREAD_OPTION_PTHREAD_IMPL; -# endif - -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 - -#if USE_GNUTLS -static void -_gnutls_print_errors(void *conn, int type, int ret) -{ - char buf[1024]; - - if (!ret) return; - - snprintf(buf, sizeof(buf), "GNUTLS error: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret)); - if (type == ECORE_CON_EVENT_CLIENT_ERROR) - ecore_con_event_client_error(conn, buf); - else - ecore_con_event_server_error(conn, buf); -} - -static void -_gnutls_print_session(const gnutls_datum_t *cert_list, unsigned int cert_list_size) -{ - char *c = NULL; - gnutls_x509_crt_t crt; - unsigned int x; - - if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return; - for (x = 0; x < cert_list_size; x++) - { - gnutls_x509_crt_init(&crt); - gnutls_x509_crt_import(crt, &cert_list[x], GNUTLS_X509_FMT_DER); - gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, (gnutls_datum_t*)&c); - INF("CERTIFICATE:\n%s", c); - gnutls_free(c); - gnutls_x509_crt_deinit(crt); - crt = NULL; - } -} - -#ifdef ISCOMFITOR -static void -_gnutls_log_func(int level, - const char *str) -{ - char buf[128]; - strncat(buf, str, strlen(str) - 1); - DBG("|<%d>| %s", level, buf); -} -#endif - -static const char * -SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status) -{ - switch (status) - { - case GNUTLS_HANDSHAKE_HELLO_REQUEST: - return "Hello request"; - - case GNUTLS_HANDSHAKE_CLIENT_HELLO: - return "Client hello"; - - case GNUTLS_HANDSHAKE_SERVER_HELLO: - return "Server hello"; - - case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: - return "New session ticket"; - - case GNUTLS_HANDSHAKE_CERTIFICATE_PKT: - return "Certificate packet"; - - case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE: - return "Server key exchange"; - - case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST: - return "Certificate request"; - - case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE: - return "Server hello done"; - - case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY: - return "Certificate verify"; - - case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE: - return "Client key exchange"; - - case GNUTLS_HANDSHAKE_FINISHED: - return "Finished"; - - case GNUTLS_HANDSHAKE_SUPPLEMENTAL: - return "Supplemental"; - } - return NULL; -} - -#elif USE_OPENSSL - -static void -_openssl_print_verify_error(int error) -{ - switch (error) - { -#define ERROR(X) \ - case (X): \ - ERR("%s", #X); \ - break -#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT - ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT); -#endif -#ifdef X509_V_ERR_UNABLE_TO_GET_CRL - ERROR(X509_V_ERR_UNABLE_TO_GET_CRL); -#endif -#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE - ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE); -#endif -#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE - ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE); -#endif -#ifdef X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY - ERROR(X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY); -#endif -#ifdef X509_V_ERR_CERT_SIGNATURE_FAILURE - ERROR(X509_V_ERR_CERT_SIGNATURE_FAILURE); -#endif -#ifdef X509_V_ERR_CRL_SIGNATURE_FAILURE - ERROR(X509_V_ERR_CRL_SIGNATURE_FAILURE); -#endif -#ifdef X509_V_ERR_CERT_NOT_YET_VALID - ERROR(X509_V_ERR_CERT_NOT_YET_VALID); -#endif -#ifdef X509_V_ERR_CERT_HAS_EXPIRED - ERROR(X509_V_ERR_CERT_HAS_EXPIRED); -#endif -#ifdef X509_V_ERR_CRL_NOT_YET_VALID - ERROR(X509_V_ERR_CRL_NOT_YET_VALID); -#endif -#ifdef X509_V_ERR_CRL_HAS_EXPIRED - ERROR(X509_V_ERR_CRL_HAS_EXPIRED); -#endif -#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD - ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD); -#endif -#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD - ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD); -#endif -#ifdef X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD - ERROR(X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD); -#endif -#ifdef X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD - ERROR(X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); -#endif -#ifdef X509_V_ERR_OUT_OF_MEM - ERROR(X509_V_ERR_OUT_OF_MEM); -#endif -#ifdef X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT - ERROR(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT); -#endif -#ifdef X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN - ERROR(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN); -#endif -#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY - ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); -#endif -#ifdef X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE - ERROR(X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); -#endif -#ifdef X509_V_ERR_CERT_CHAIN_TOO_LONG - ERROR(X509_V_ERR_CERT_CHAIN_TOO_LONG); -#endif -#ifdef X509_V_ERR_CERT_REVOKED - ERROR(X509_V_ERR_CERT_REVOKED); -#endif -#ifdef X509_V_ERR_INVALID_CA - ERROR(X509_V_ERR_INVALID_CA); -#endif -#ifdef X509_V_ERR_PATH_LENGTH_EXCEEDED - ERROR(X509_V_ERR_PATH_LENGTH_EXCEEDED); -#endif -#ifdef X509_V_ERR_INVALID_PURPOSE - ERROR(X509_V_ERR_INVALID_PURPOSE); -#endif -#ifdef X509_V_ERR_CERT_UNTRUSTED - ERROR(X509_V_ERR_CERT_UNTRUSTED); -#endif -#ifdef X509_V_ERR_CERT_REJECTED - ERROR(X509_V_ERR_CERT_REJECTED); -#endif - /* These are 'informational' when looking for issuer cert */ -#ifdef X509_V_ERR_SUBJECT_ISSUER_MISMATCH - ERROR(X509_V_ERR_SUBJECT_ISSUER_MISMATCH); -#endif -#ifdef X509_V_ERR_AKID_SKID_MISMATCH - ERROR(X509_V_ERR_AKID_SKID_MISMATCH); -#endif -#ifdef X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH - ERROR(X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH); -#endif -#ifdef X509_V_ERR_KEYUSAGE_NO_CERTSIGN - ERROR(X509_V_ERR_KEYUSAGE_NO_CERTSIGN); -#endif - -#ifdef X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER - ERROR(X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER); -#endif -#ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION - ERROR(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION); -#endif -#ifdef X509_V_ERR_KEYUSAGE_NO_CRL_SIGN - ERROR(X509_V_ERR_KEYUSAGE_NO_CRL_SIGN); -#endif -#ifdef X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION - ERROR(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION); -#endif -#ifdef X509_V_ERR_INVALID_NON_CA - ERROR(X509_V_ERR_INVALID_NON_CA); -#endif -#ifdef X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED - ERROR(X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED); -#endif -#ifdef X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE - ERROR(X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE); -#endif -#ifdef X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED - ERROR(X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED); -#endif - -#ifdef X509_V_ERR_INVALID_EXTENSION - ERROR(X509_V_ERR_INVALID_EXTENSION); -#endif -#ifdef X509_V_ERR_INVALID_POLICY_EXTENSION - ERROR(X509_V_ERR_INVALID_POLICY_EXTENSION); -#endif -#ifdef X509_V_ERR_NO_EXPLICIT_POLICY - ERROR(X509_V_ERR_NO_EXPLICIT_POLICY); -#endif -#ifdef X509_V_ERR_DIFFERENT_CRL_SCOPE - ERROR(X509_V_ERR_DIFFERENT_CRL_SCOPE); -#endif -#ifdef X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE - ERROR(X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE); -#endif - -#ifdef X509_V_ERR_UNNESTED_RESOURCE - ERROR(X509_V_ERR_UNNESTED_RESOURCE); -#endif - -#ifdef X509_V_ERR_PERMITTED_VIOLATION - ERROR(X509_V_ERR_PERMITTED_VIOLATION); -#endif -#ifdef X509_V_ERR_EXCLUDED_VIOLATION - ERROR(X509_V_ERR_EXCLUDED_VIOLATION); -#endif -#ifdef X509_V_ERR_SUBTREE_MINMAX - ERROR(X509_V_ERR_SUBTREE_MINMAX); -#endif -#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE - ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE); -#endif -#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX - ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX); -#endif -#ifdef X509_V_ERR_UNSUPPORTED_NAME_SYNTAX - ERROR(X509_V_ERR_UNSUPPORTED_NAME_SYNTAX); -#endif -#ifdef X509_V_ERR_CRL_PATH_VALIDATION_ERROR - ERROR(X509_V_ERR_CRL_PATH_VALIDATION_ERROR); -#endif - - /* The application is not happy */ -#ifdef X509_V_ERR_APPLICATION_VERIFICATION - ERROR(X509_V_ERR_APPLICATION_VERIFICATION); -#endif - } -#undef ERROR -} - -static void -_openssl_print_errors(void *conn, int type) -{ - char buf[1024]; - do - { - unsigned long err; - - err = ERR_get_error(); - if (!err) break; - snprintf(buf, sizeof(buf), "OpenSSL error: %s", ERR_reason_error_string(err)); - if (type == ECORE_CON_EVENT_CLIENT_ERROR) - ecore_con_event_client_error(conn, buf); - else - ecore_con_event_server_error(conn, buf); - - } while (1); -} - -static Eina_Bool -_openssl_name_verify(const char *name, const char *svrname) -{ - if (name[0] == '*') - { - /* we allow *.domain.TLD with a wildcard, but nothing else */ - const char *p, *s; - - EINA_SAFETY_ON_TRUE_RETURN_VAL((name[1] != '.') || (!name[2]), EINA_FALSE); - p = strchr(name + 1, '*'); - EINA_SAFETY_ON_TRUE_RETURN_VAL(!!p, EINA_FALSE); - /* verify that we have a domain of at least *.X.TLD and not *.TLD */ - p = strchr(name + 2, '.'); - EINA_SAFETY_ON_TRUE_RETURN_VAL(!p, EINA_FALSE); - s = strchr(svrname, '.'); - EINA_SAFETY_ON_TRUE_RETURN_VAL(!s, EINA_FALSE); - /* same as above for the stored name */ - EINA_SAFETY_ON_TRUE_RETURN_VAL(!strchr(s + 1, '.'), EINA_FALSE); - if (strcasecmp(s, name + 1)) - { - ERR("%s != %s", s, name + 1); - return EINA_FALSE; - } - } - else - if (strcasecmp(name, svrname)) - { - ERR("%s != %s", name, svrname); - return EINA_FALSE; - } - return EINA_TRUE; -} - -static void -_openssl_print_session(SSL *ssl) -{ - /* print session info into DBG */ - SSL_SESSION *s; - STACK_OF(X509) *sk; - BIO *b; - char log[4096], *p; - int x; - - if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return; - - memset(log, 0, sizeof(log)); - b = BIO_new(BIO_s_mem()); - sk = SSL_get_peer_cert_chain(ssl); - if (sk) - { - DBG("CERTIFICATES:"); - for (x = 0; x < sk_X509_num(sk); x++) - { - p = X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, x)), log, sizeof(log)); - DBG("%2d s:%s", x, p); - p = X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, x)), log, sizeof(log)); - DBG(" i:%s", p); - PEM_write_X509(stderr, sk_X509_value(sk, x)); - } - } - s = SSL_get_session(ssl); - SSL_SESSION_print(b, s); - fprintf(stderr, "\n"); - while (BIO_read(b, log, sizeof(log)) > 0) - fprintf(stderr, "%s", log); - - BIO_free(b); -} - -#endif - -#define SSL_ERROR_CHECK_GOTO_ERROR(X) \ - do \ - { \ - if ((X)) \ - { \ - ERR("Error at %s:%s:%d!", __FILE__, __PRETTY_FUNCTION__, __LINE__); \ - goto error; \ - } \ - } \ - while (0) - -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 Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (Ecore_Con_Server * svr, const char *ca_file); -static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (Ecore_Con_Server * svr, const char *crl_file); -static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (Ecore_Con_Server * svr, const char *cert); -static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (Ecore_Con_Server * svr, const char *key_file); - -static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_prepare) (Ecore_Con_Server * svr, int ssl_type); -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 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, const unsigned char *buf, int size); - -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, - const 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) (); -#if _ECORE_CON_SSL_AVAILABLE != 0 - ECORE_CON_EVENT_CLIENT_UPGRADE = ecore_event_type_new(); - ECORE_CON_EVENT_SERVER_UPGRADE = ecore_event_type_new(); -#endif - } - - 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; -} - -Ecore_Con_Ssl_Error -ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, - int ssl_type) -{ - if (!ssl_type) - return ECORE_CON_SSL_ERROR_NONE; - return SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr, ssl_type); -} - -Ecore_Con_Ssl_Error -ecore_con_ssl_server_init(Ecore_Con_Server *svr) -{ - if (!(svr->type & ECORE_CON_SSL)) - return ECORE_CON_SSL_ERROR_NONE; - return SSL_SUFFIX(_ecore_con_ssl_server_init) (svr); -} - -Ecore_Con_Ssl_Error -ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr) -{ - if (!(svr->type & ECORE_CON_SSL)) - return ECORE_CON_SSL_ERROR_NONE; - return SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (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, - const 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) -{ - if (!(cl->host_server->type & ECORE_CON_SSL)) - return ECORE_CON_SSL_ERROR_NONE; - return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl); -} - -Ecore_Con_Ssl_Error -ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl) -{ - if (!(cl->host_server->type & ECORE_CON_SSL)) - return ECORE_CON_SSL_ERROR_NONE; - 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, - const unsigned char *buf, - int size) -{ - return SSL_SUFFIX(_ecore_con_ssl_client_write) (cl, buf, size); -} - -/** - * Returns if SSL support is available - * @return 1 if SSL is available and provided by gnutls, 2 if provided by openssl, - * 0 if it is not available. - * @ingroup Ecore_Con_Client_Group - */ -EAPI int -ecore_con_ssl_available_get(void) -{ - return _ECORE_CON_SSL_AVAILABLE; -} - -/** - * @addtogroup Ecore_Con_SSL_Group Ecore Connection SSL Functions - * - * Functions that operate on Ecore connection objects pertaining to SSL. - * - * @{ - */ - -/** - * @brief Enable certificate verification on a server object - * - * Call this function on a server object before main loop has started - * to enable verification of certificates against loaded certificates. - * @param svr The server object - */ -EAPI void -ecore_con_ssl_server_verify(Ecore_Con_Server *svr) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_verify"); - return; - } - svr->verify = EINA_TRUE; -} - -/** - * @brief Enable hostname-based certificate verification on a server object - * - * Call this function on a server object before main loop has started - * to enable verification of certificates using ONLY their hostnames. - * @param svr The server object - * @note This function has no effect when used on a listening server created by - * ecore_con_server_add - * @since 1.1 - */ -EAPI void -ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); - return; - } - svr->verify_basic = EINA_TRUE; -} - -/** - * @brief Set the hostname to verify against in certificate verification - * - * Sometimes the certificate hostname will not match the hostname that you are - * connecting to, and will instead match a different name. An example of this is - * that if you connect to talk.google.com to use Google Talk, you receive Google's - * certificate for gmail.com. This certificate should be trusted, and so you must call - * this function with "gmail.com" as @p name. - * See RFC2818 for more details. - * @param svr The server object - * @param name The hostname to verify against - * @since 1.2 - */ -EAPI void -ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); - return; - } - eina_stringshare_replace(&svr->verify_name, name); -} - -/** - * @brief Get the hostname to verify against in certificate verification - * - * This function returns the name which will be used to validate the SSL certificate - * common name (CN) or alt name (subjectAltName). It will default to the @p name - * param in ecore_con_server_connect(), but can be changed with ecore_con_ssl_server_verify_name_set(). - * @param svr The server object - * @return The hostname which will be used - * @since 1.2 - */ -EAPI const char * -ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); - return NULL; - } - return svr->verify_name ?: svr->name; -} - -/** - * @brief Add an ssl certificate for use in ecore_con functions. - * - * Use this function to add a SSL PEM certificate. - * Simply specify the cert here to use it in the server object for connecting or listening. - * If there is an error loading the certificate, an error will automatically be logged. - * @param svr The server object - * @param cert The path to the certificate. - * @return @c EINA_FALSE if the file cannot be loaded, otherwise @c EINA_TRUE. - */ - -EAPI Eina_Bool -ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr, - const char *cert) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cert_add"); - return EINA_FALSE; - } - - if (!svr->ssl_prepared) - { - svr->use_cert = EINA_TRUE; - svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT; - if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL)) - return EINA_FALSE; - } - - return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (svr, cert); -} - -/** - * @brief Add an ssl CA file for use in ecore_con functions. - * - * Use this function to add a SSL PEM CA file. - * Simply specify the file here to use it in the server object for connecting or listening. - * If there is an error loading the CAs, an error will automatically be logged. - * @param svr The server object - * @param ca_file The path to the CA file. - * @return @c EINA_FALSE if the file cannot be loaded, otherwise @c EINA_TRUE. - * @note since 1.2, this function can load directores - */ - -EAPI Eina_Bool -ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, - const char *ca_file) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cafile_add"); - return EINA_FALSE; - } - - if (!svr->ssl_prepared) - { - svr->use_cert = EINA_TRUE; - svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT; - if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL)) - return EINA_FALSE; - } - - return SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (svr, ca_file); -} - -/** - * @brief Add an ssl private key for use in ecore_con functions. - * - * Use this function to add a SSL PEM private key - * Simply specify the key file here to use it in the server object for connecting or listening. - * If there is an error loading the key, an error will automatically be logged. - * @param svr The server object - * @param key_file The path to the key file. - * @return @c EINA_FALSE if the file cannot be loaded, otherwise @c EINA_TRUE. - */ - -EAPI Eina_Bool -ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr, - const char *key_file) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_privkey_add"); - return EINA_FALSE; - } - - if (!svr->ssl_prepared) - { - svr->use_cert = EINA_TRUE; - svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT; - if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL)) - return EINA_FALSE; - } - - return SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (svr, key_file); -} - -/** - * @brief Add an ssl CRL for use in ecore_con functions. - * - * Use this function to add a SSL PEM CRL file - * Simply specify the CRL file here to use it in the server object for connecting or listening. - * If there is an error loading the CRL, an error will automatically be logged. - * @param svr The server object - * @param crl_file The path to the CRL file. - * @return @c EINA_FALSE if the file cannot be loaded, otherwise @c EINA_TRUE. - */ - -EAPI Eina_Bool -ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, - const char *crl_file) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_crl_add"); - return EINA_FALSE; - } - - if (!svr->ssl_prepared) - { - svr->use_cert = EINA_TRUE; - svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT; - if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL)) - return EINA_FALSE; - } - - return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file); -} - -/** - * @brief Upgrade a connection to a specified level of encryption - * - * Use this function to begin an SSL handshake on a connection (STARTTLS or similar). - * Once the upgrade has been completed, an ECORE_CON_EVENT_SERVER_UPGRADE event will be emitted. - * The connection should be treated as disconnected until the next event. - * @param svr The server object - * @param ssl_type The SSL connection type (ONLY). - * @return @c EINA_FALSE if the connection cannot be upgraded, otherwise @c EINA_TRUE. - * @note This function is NEVER to be used on a server object created with ecore_con_server_add - * @warning Setting a wrong value for @p compl_type WILL mess up your program. - * @since 1.1 - */ - -EAPI Eina_Bool -ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type) -{ - if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) - { - ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); - return EINA_FALSE; - } -#if _ECORE_CON_SSL_AVAILABLE == 0 - return EINA_FALSE; -#endif - - if (!svr->ssl_prepared) - { - if (ecore_con_ssl_server_prepare(svr, ssl_type)) - return EINA_FALSE; - } - if (!svr->use_cert) - svr->type |= ssl_type; - svr->upgrade = EINA_TRUE; - svr->handshaking = EINA_TRUE; - svr->ssl_state = ECORE_CON_SSL_STATE_INIT; - return !SSL_SUFFIX(_ecore_con_ssl_server_init) (svr); -} - -/** - * @brief Upgrade a connection to a specified level of encryption - * - * Use this function to begin an SSL handshake on a connection (STARTTLS or similar). - * Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted. - * The connection should be treated as disconnected until the next event. - * @param cl The client object - * @param ssl_type The SSL connection type (ONLY). - * @return @c EINA_FALSE if the connection cannot be upgraded, otherwise @c EINA_TRUE. - * @warning Setting a wrong value for @p compl_type WILL mess up your program. - * @since 1.1 - */ - -EAPI Eina_Bool -ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type ssl_type) -{ - if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) - { - ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__); - return EINA_FALSE; - } -#if _ECORE_CON_SSL_AVAILABLE == 0 - return EINA_FALSE; -#endif - - if (!cl->host_server->ssl_prepared) - { - if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type)) - return EINA_FALSE; - } - if (!cl->host_server->use_cert) - cl->host_server->type |= ssl_type; - cl->upgrade = EINA_TRUE; - cl->host_server->upgrade = EINA_TRUE; - cl->handshaking = EINA_TRUE; - cl->ssl_state = ECORE_CON_SSL_STATE_INIT; - return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl); -} - -/** - * @} - */ - -#if USE_GNUTLS - -/* - * GnuTLS - */ - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_init_gnutls(void) -{ -#ifdef EINA_HAVE_THREADS - if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)) - WRN("YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!"); -#endif - if (gnutls_global_init()) - return ECORE_CON_SSL_ERROR_INIT_FAILED; - -#ifdef ISCOMFITOR - if (eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) - { - gnutls_global_set_log_level(9); - gnutls_global_set_log_function(_gnutls_log_func); - } -#endif - 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 Ecore_Con_Ssl_Error -_ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr, - int ssl_type) -{ - int ret; - - if (ssl_type & ECORE_CON_USE_SSL2) - return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; - - switch (ssl_type) - { - case ECORE_CON_USE_SSL3: - case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: - case ECORE_CON_USE_TLS: - case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: - case ECORE_CON_USE_MIXED: - case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: - break; - - default: - return ECORE_CON_SSL_ERROR_NONE; - } - - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_allocate_credentials(&svr->cert)); - - if (svr->use_cert) - { - if (svr->created) - { - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_init(&svr->dh_params)); - INF("Generating DH params"); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_generate2(svr->dh_params, 1024)); - - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_server_credentials(&svr->anoncred_s)); - /* TODO: implement PSK */ - // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_server_credentials(&svr->pskcred_s)); - - gnutls_anon_set_server_dh_params(svr->anoncred_s, svr->dh_params); - gnutls_certificate_set_dh_params(svr->cert, svr->dh_params); - //gnutls_psk_set_server_dh_params(svr->pskcred_s, svr->dh_params); - INF("DH params successfully generated and applied!"); - } - else - { - //SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_client_credentials(&svr->pskcred_c)); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_client_credentials(&svr->anoncred_c)); - } - } - - svr->ssl_prepared = EINA_TRUE; - return ECORE_CON_SSL_ERROR_NONE; - -error: - _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret); - _ecore_con_ssl_server_shutdown_gnutls(svr); - return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; -} - - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr) -{ - const gnutls_datum_t *cert_list; - unsigned int iter, cert_list_size; - gnutls_x509_crt_t cert = NULL; - const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; - int ret = 0; - - switch (svr->ssl_state) - { - case ECORE_CON_SSL_STATE_DONE: - return ECORE_CON_SSL_ERROR_NONE; - - case ECORE_CON_SSL_STATE_INIT: - if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */ - return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; - - switch (svr->type & ECORE_CON_SSL) - { - case ECORE_CON_USE_SSL3: - case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: - priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1"; - break; - - case ECORE_CON_USE_TLS: - case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: - priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0"; - break; - - case ECORE_CON_USE_MIXED: - case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: - break; - - default: - return ECORE_CON_SSL_ERROR_NONE; - } - - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&svr->session, GNUTLS_CLIENT)); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_client(svr->session)); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_server_name_set(svr->session, GNUTLS_NAME_DNS, svr->name, strlen(svr->name))); - INF("Applying priority string: %s", priority); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(svr->session, priority, NULL)); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE, svr->cert)); - // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_PSK, svr->pskcred_c)); - if (!svr->use_cert) - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c)); - - gnutls_dh_set_prime_bits(svr->session, 512); - gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)((intptr_t)svr->fd)); - svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; - - case ECORE_CON_SSL_STATE_HANDSHAKING: - if (!svr->session) - { - DBG("Server was previously lost, going to error condition"); - goto error; - } - ret = gnutls_handshake(svr->session); - DBG("calling gnutls_handshake(): returned with '%s'", gnutls_strerror_name(ret)); - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret)); - if (!ret) - { - svr->handshaking = EINA_FALSE; - svr->ssl_state = ECORE_CON_SSL_STATE_DONE; - } - else - { - if (gnutls_record_get_direction(svr->session)) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); - else - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); - return ECORE_CON_SSL_ERROR_NONE; - } - - default: - break; - } - - if ((!svr->verify) && (!svr->verify_basic)) - /* not verifying certificates, so we're done! */ - return ECORE_CON_SSL_ERROR_NONE; - if (svr->verify) - { - /* use CRL/CA lists to verify */ - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(svr->session, &iter)); - if (iter & GNUTLS_CERT_INVALID) - ERR("The certificate is not trusted."); - else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND) - ERR("The certificate hasn't got a known issuer."); - else if (iter & GNUTLS_CERT_REVOKED) - ERR("The certificate has been revoked."); - else if (iter & GNUTLS_CERT_EXPIRED) - ERR("The certificate has expired"); - else if (iter & GNUTLS_CERT_NOT_ACTIVATED) - ERR("The certificate is not yet activated"); - - if (iter) - goto error; - } - if (gnutls_certificate_type_get(svr->session) != GNUTLS_CRT_X509) - { - ERR("Warning: PGP certificates are not yet supported!"); - goto error; - } - - SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(svr->session, &cert_list_size))); - SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size); - - _gnutls_print_session(cert_list, cert_list_size); - - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert)); - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); - - SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->verify_name ?: svr->name)); - gnutls_x509_crt_deinit(cert); - DBG("SSL certificate verification succeeded!"); - return ECORE_CON_SSL_ERROR_NONE; - -error: - _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret); - if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) - ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(svr->session))); - if (svr->session && (svr->ssl_state != ECORE_CON_SSL_STATE_DONE)) - { - ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(svr->session))); - ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(svr->session))); - } - if (cert) - gnutls_x509_crt_deinit(cert); - _ecore_con_ssl_server_shutdown_gnutls(svr); - return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; -} - -static Eina_Bool -_ecore_con_ssl_server_cafile_add_gnutls(Ecore_Con_Server *svr, - const char *ca_file) -{ - struct stat st; - Eina_Iterator *it; - const char *file; - Eina_Bool error = EINA_FALSE; - - if (stat(ca_file, &st)) return EINA_FALSE; - if (S_ISDIR(st.st_mode)) - { - it = eina_file_ls(ca_file); - SSL_ERROR_CHECK_GOTO_ERROR(!it); - EINA_ITERATOR_FOREACH(it, file) - { - if (!error) - { - if (gnutls_certificate_set_x509_trust_file(svr->cert, file, GNUTLS_X509_FMT_PEM) < 1) - error++; - } - eina_stringshare_del(file); - } - eina_iterator_free(it); - } - else - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_trust_file(svr->cert, ca_file, - GNUTLS_X509_FMT_PEM) < 1); - - return !error; -error: - ERR("Could not load CA file!"); - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_crl_add_gnutls(Ecore_Con_Server *svr, - const char *crl_file) -{ - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_crl_file(svr->cert, crl_file, - GNUTLS_X509_FMT_PEM) < 1); - - return EINA_TRUE; -error: - ERR("Could not load CRL file!"); - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_privkey_add_gnutls(Ecore_Con_Server *svr, - const char *key_file) -{ - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_key_file(svr->cert, svr->cert_file, key_file, - GNUTLS_X509_FMT_PEM)); - - return EINA_TRUE; -error: - ERR("Could not load certificate/key file!"); - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_cert_add_gnutls(Ecore_Con_Server *svr, - const char *cert_file) -{ - if (!(svr->cert_file = strdup(cert_file))) - return EINA_FALSE; - - return EINA_TRUE; -} - -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); - } - - free(svr->cert_file); - svr->cert_file = NULL; - if (svr->cert) - gnutls_certificate_free_credentials(svr->cert); - svr->cert = NULL; - - if ((svr->type & ECORE_CON_SSL) && svr->created) - { - if (svr->dh_params) - { - gnutls_dh_params_deinit(svr->dh_params); - svr->dh_params = NULL; - } - if (svr->anoncred_s) - gnutls_anon_free_server_credentials(svr->anoncred_s); - // if (svr->pskcred_s) - // gnutls_psk_free_server_credentials(svr->pskcred_s); - - svr->anoncred_s = NULL; - svr->pskcred_s = NULL; - } - else if (svr->type & ECORE_CON_SSL) - { - if (svr->anoncred_c) - gnutls_anon_free_client_credentials(svr->anoncred_c); - // if (svr->pskcred_c) - // gnutls_psk_free_client_credentials(svr->pskcred_c); - - svr->anoncred_c = NULL; - svr->pskcred_c = NULL; - } - - svr->session = NULL; - - return ECORE_CON_SSL_ERROR_NONE; -} - -static int -_ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr, - unsigned char *buf, - int size) -{ - int num; - - if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) - { - DBG("Continuing gnutls handshake"); - if (!_ecore_con_ssl_server_init_gnutls(svr)) - return 0; - return -1; - } - - num = gnutls_record_recv(svr->session, buf, size); - if (num > 0) - return num; - - if (num == GNUTLS_E_REHANDSHAKE) - { - WRN("Rehandshake request ignored"); - return 0; - - svr->handshaking = EINA_TRUE; - svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; - if (!_ecore_con_ssl_server_init_gnutls(svr)) - return 0; - } - else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS)) - return 0; - - return -1; -} - -static int -_ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, - const unsigned char *buf, - int size) -{ - int num; - - if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) - { - DBG("Continuing gnutls handshake"); - if (!_ecore_con_ssl_server_init_gnutls(svr)) - return 0; - return -1; - } - - num = gnutls_record_send(svr->session, buf, size); - if (num > 0) - return num; - - if (num == GNUTLS_E_REHANDSHAKE) - { - WRN("Rehandshake request ignored"); - return 0; -/* this is only partly functional I think? */ - svr->handshaking = EINA_TRUE; - svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; - if (!_ecore_con_ssl_server_init_gnutls(svr)) - return 0; - } - else if (!gnutls_error_is_fatal(num)) - return 0; - - return -1; -} - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl) -{ - const gnutls_datum_t *cert_list; - unsigned int iter, cert_list_size; - const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; - int ret = 0; - - switch (cl->ssl_state) - { - case ECORE_CON_SSL_STATE_DONE: - return ECORE_CON_SSL_ERROR_NONE; - - case ECORE_CON_SSL_STATE_INIT: - if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */ - return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; - - switch (cl->host_server->type & ECORE_CON_SSL) - { - case ECORE_CON_USE_SSL3: - case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: - priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1"; - break; - - case ECORE_CON_USE_TLS: - case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: - priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0"; - break; - - case ECORE_CON_USE_MIXED: - case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: - break; - - default: - return ECORE_CON_SSL_ERROR_NONE; - } - - _client_connected++; - - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER)); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_key_generate(&cl->session_ticket)); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_server(cl->session, &cl->session_ticket)); - INF("Applying priority string: %s", priority); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(cl->session, priority, NULL)); - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert)); - // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s)); - if (!cl->host_server->use_cert) - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s)); - - gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST); - - gnutls_dh_set_prime_bits(cl->session, 2048); - gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)((intptr_t)cl->fd)); - cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; - - case ECORE_CON_SSL_STATE_HANDSHAKING: - if (!cl->session) - { - DBG("Client was previously lost, going to error condition"); - goto error; - } - DBG("calling gnutls_handshake()"); - ret = gnutls_handshake(cl->session); - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret)); - - if (!ret) - { - cl->handshaking = EINA_FALSE; - cl->ssl_state = ECORE_CON_SSL_STATE_DONE; - } - else - { - if (gnutls_record_get_direction(cl->session)) - ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); - else - ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); - return ECORE_CON_SSL_ERROR_NONE; - } - - default: - break; - } - - if (!cl->host_server->verify) - /* not verifying certificates, so we're done! */ - return ECORE_CON_SSL_ERROR_NONE; - /* use CRL/CA lists to verify */ - SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(cl->session, &iter)); - if (iter & GNUTLS_CERT_INVALID) - ERR("The certificate is not trusted."); - else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND) - ERR("The certificate hasn't got a known issuer."); - else if (iter & GNUTLS_CERT_REVOKED) - ERR("The certificate has been revoked."); - else if (iter & GNUTLS_CERT_EXPIRED) - ERR("The certificate has expired"); - else if (iter & GNUTLS_CERT_NOT_ACTIVATED) - ERR("The certificate is not yet activated"); - - if (iter) - goto error; - if (gnutls_certificate_type_get(cl->session) != GNUTLS_CRT_X509) - { - ERR("Warning: PGP certificates are not yet supported!"); - goto error; - } - - SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size))); - SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size); - - _gnutls_print_session(cert_list, cert_list_size); -/* - gnutls_x509_crt_t cert = NULL; - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert)); - SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); - - SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, cl->host_server->name)); - gnutls_x509_crt_deinit(cert); -*/ - DBG("SSL certificate verification succeeded!"); - return ECORE_CON_SSL_ERROR_NONE; - -error: - _gnutls_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR, ret); - if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) - ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(cl->session))); - if (cl->session && (cl->ssl_state != ECORE_CON_SSL_STATE_DONE)) - { - ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(cl->session))); - ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(cl->session))); - } -/* - if (cert) - gnutls_x509_crt_deinit(cert); -*/ - _ecore_con_ssl_client_shutdown_gnutls(cl); - return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; -} - -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); - gnutls_free(cl->session_ticket.data); - cl->session_ticket.data = NULL; - } - - cl->session = NULL; - - 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; - - if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) - { - if (!_ecore_con_ssl_client_init_gnutls(cl)) - return 0; - return -1; - } - - num = gnutls_record_recv(cl->session, buf, size); - if (num > 0) - return num; - - if (num == GNUTLS_E_REHANDSHAKE) - { - WRN("Rehandshake request ignored"); - return 0; - cl->handshaking = EINA_TRUE; - cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; - if (!_ecore_con_ssl_client_init_gnutls(cl)) - return 0; - WRN("Rehandshake request ignored"); - return 0; - } - else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS)) - return 0; - - return -1; -} - -static int -_ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl, - const unsigned char *buf, - int size) -{ - int num; - - if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) - { - if (!_ecore_con_ssl_client_init_gnutls(cl)) - return 0; - return -1; - } - - num = gnutls_record_send(cl->session, buf, size); - if (num > 0) - return num; - - if (num == GNUTLS_E_REHANDSHAKE) - { - WRN("Rehandshake request ignored"); - return 0; - cl->handshaking = EINA_TRUE; - cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; - if (!_ecore_con_ssl_client_init_gnutls(cl)) - return 0; - } - else if (!gnutls_error_is_fatal(num)) - return 0; - - return -1; -} - -#elif USE_OPENSSL && !USE_GNUTLS - -/* - * OpenSSL - */ - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_init_openssl(void) -{ - SSL_library_init(); - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); - - return ECORE_CON_SSL_ERROR_NONE; -} - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_shutdown_openssl(void) -{ - ERR_free_strings(); - EVP_cleanup(); - return ECORE_CON_SSL_ERROR_NONE; -} - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr, - int ssl_type) -{ - long options; - int dh = 0; - - if (ssl_type & ECORE_CON_USE_SSL2) - return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; - - switch (ssl_type) - { - case ECORE_CON_USE_SSL3: - case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: - if (!svr->created) - SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method()))); - else - SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_server_method()))); - break; - - case ECORE_CON_USE_TLS: - case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: - if (!svr->created) - SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method()))); - else - SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_server_method()))); - break; - - case ECORE_CON_USE_MIXED: - case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: - if (!svr->created) - SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method()))); - else - SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))); - options = SSL_CTX_get_options(svr->ssl_ctx); - SSL_CTX_set_options(svr->ssl_ctx, options | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE); - break; - - default: - svr->ssl_prepared = EINA_TRUE; - return ECORE_CON_SSL_ERROR_NONE; - } - - if ((!svr->use_cert) && svr->created) - { - DH *dh_params; - INF("Generating DH params"); - SSL_ERROR_CHECK_GOTO_ERROR(!(dh_params = DH_new())); - SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_parameters_ex(dh_params, 1024, DH_GENERATOR_5, NULL)); - SSL_ERROR_CHECK_GOTO_ERROR(!DH_check(dh_params, &dh)); - SSL_ERROR_CHECK_GOTO_ERROR((dh & DH_CHECK_P_NOT_PRIME) || (dh & DH_CHECK_P_NOT_SAFE_PRIME)); - SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_key(dh_params)); - SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_tmp_dh(svr->ssl_ctx, dh_params)); - DH_free(dh_params); - INF("DH params successfully generated and applied!"); - SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:@STRENGTH")); - } - else if (!svr->use_cert) - SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:!ECDH:RSA:AES:!PSK:@STRENGTH")); - - svr->ssl_prepared = EINA_TRUE; - return ECORE_CON_SSL_ERROR_NONE; - -error: - if (dh) - { - if (dh & DH_CHECK_P_NOT_PRIME) - ERR("openssl error: dh_params could not generate a prime!"); - else - ERR("openssl error: dh_params could not generate a safe prime!"); - } - else - _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); - _ecore_con_ssl_server_shutdown_openssl(svr); - return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; -} - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr) -{ - int ret = -1; - - switch (svr->ssl_state) - { - case ECORE_CON_SSL_STATE_DONE: - return ECORE_CON_SSL_ERROR_NONE; - - case ECORE_CON_SSL_STATE_INIT: - SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx))); - - SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd)); - SSL_set_connect_state(svr->ssl); - svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; - - case ECORE_CON_SSL_STATE_HANDSHAKING: - if (!svr->ssl) - { - DBG("Server was previously lost, going to error condition"); - goto error; - } - ret = SSL_do_handshake(svr->ssl); - svr->ssl_err = SSL_get_error(svr->ssl, ret); - SSL_ERROR_CHECK_GOTO_ERROR((svr->ssl_err == SSL_ERROR_SYSCALL) || (svr->ssl_err == SSL_ERROR_SSL)); - - if (ret == 1) - { - svr->handshaking = EINA_FALSE; - svr->ssl_state = ECORE_CON_SSL_STATE_DONE; - } - else - { - if (svr->ssl_err == SSL_ERROR_WANT_READ) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); - else if (svr->ssl_err == SSL_ERROR_WANT_WRITE) - ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); - return ECORE_CON_SSL_ERROR_NONE; - } - - default: - break; - } - - _openssl_print_session(svr->ssl); - if ((!svr->verify) && (!svr->verify_basic)) - /* not verifying certificates, so we're done! */ - return ECORE_CON_SSL_ERROR_NONE; - - { - X509 *cert; - SSL_set_verify(svr->ssl, SSL_VERIFY_PEER, NULL); - /* use CRL/CA lists to verify */ - cert = SSL_get_peer_certificate(svr->ssl); - if (cert) - { - char *c; - int clen; - int name = 0; - - if (svr->verify) - { - int err; - - err = SSL_get_verify_result(svr->ssl); - _openssl_print_verify_error(err); - SSL_ERROR_CHECK_GOTO_ERROR(err); - } - clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, NULL, 0); - if (clen > 0) - name = NID_subject_alt_name; - else - clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, NULL, 0); - SSL_ERROR_CHECK_GOTO_ERROR(clen < 1); - if (!name) name = NID_commonName; - c = alloca(++clen); - X509_NAME_get_text_by_NID(X509_get_subject_name(cert), name, c, clen); - INF("CERT NAME: %s\n", c); - SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(c, svr->verify_name ?: svr->name)); - } - } - - DBG("SSL certificate verification succeeded!"); - - return ECORE_CON_SSL_ERROR_NONE; - -error: - _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); - _ecore_con_ssl_server_shutdown_openssl(svr); - return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; -} - -static Eina_Bool -_ecore_con_ssl_server_cafile_add_openssl(Ecore_Con_Server *svr, - const char *ca_file) -{ - struct stat st; - - if (stat(ca_file, &st)) return EINA_FALSE; - if (S_ISDIR(st.st_mode)) - SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, NULL, ca_file)); - else - SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, ca_file, NULL)); - return EINA_TRUE; - -error: - _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_crl_add_openssl(Ecore_Con_Server *svr, - const char *crl_file) -{ - X509_STORE *st; - X509_LOOKUP *lu; - static Eina_Bool flag = EINA_FALSE; - - SSL_ERROR_CHECK_GOTO_ERROR(!(st = SSL_CTX_get_cert_store(svr->ssl_ctx))); - SSL_ERROR_CHECK_GOTO_ERROR(!(lu = X509_STORE_add_lookup(st, X509_LOOKUP_file()))); - SSL_ERROR_CHECK_GOTO_ERROR(X509_load_crl_file(lu, crl_file, X509_FILETYPE_PEM) < 1); - if (!flag) - { - X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); - flag = EINA_TRUE; - } - - return EINA_TRUE; - -error: - _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_privkey_add_openssl(Ecore_Con_Server *svr, - const char *key_file) -{ - FILE *fp = NULL; - EVP_PKEY *privkey = NULL; - - if (!(fp = fopen(key_file, "r"))) - goto error; - - SSL_ERROR_CHECK_GOTO_ERROR(!(privkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL))); - - fclose(fp); - fp = NULL; - SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(svr->ssl_ctx, privkey) < 1); - SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(svr->ssl_ctx) < 1); - - return EINA_TRUE; - -error: - if (fp) - fclose(fp); - _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_cert_add_openssl(Ecore_Con_Server *svr, - const char *cert_file) -{ - FILE *fp = NULL; - X509 *cert = NULL; - - if (!(fp = fopen(cert_file, "r"))) - goto error; - - SSL_ERROR_CHECK_GOTO_ERROR(!(cert = PEM_read_X509(fp, NULL, NULL, NULL))); - - fclose(fp); - fp = NULL; - SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, cert) < 1); - - return EINA_TRUE; - -error: - if (fp) - fclose(fp); - _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); - return EINA_FALSE; -} - -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); - - svr->ssl = NULL; - svr->ssl_ctx = NULL; - svr->ssl_err = SSL_ERROR_NONE; - - return ECORE_CON_SSL_ERROR_NONE; -} - -static int -_ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr, - unsigned char *buf, - int size) -{ - int num; - - if (!svr->ssl) return -1; - 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, - const 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 Ecore_Con_Ssl_Error -_ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl) -{ - int ret = -1; - switch (cl->ssl_state) - { - case ECORE_CON_SSL_STATE_DONE: - return ECORE_CON_SSL_ERROR_NONE; - - case ECORE_CON_SSL_STATE_INIT: - SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx))); - - SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd)); - SSL_set_accept_state(cl->ssl); - cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; - - case ECORE_CON_SSL_STATE_HANDSHAKING: - if (!cl->ssl) - { - DBG("Client was previously lost, going to error condition"); - goto error; - } - ret = SSL_do_handshake(cl->ssl); - cl->ssl_err = SSL_get_error(cl->ssl, ret); - SSL_ERROR_CHECK_GOTO_ERROR((cl->ssl_err == SSL_ERROR_SYSCALL) || (cl->ssl_err == SSL_ERROR_SSL)); - if (ret == 1) - { - cl->handshaking = EINA_FALSE; - cl->ssl_state = ECORE_CON_SSL_STATE_DONE; - } - else - { - if (cl->ssl_err == SSL_ERROR_WANT_READ) - ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); - else if (cl->ssl_err == SSL_ERROR_WANT_WRITE) - ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); - return ECORE_CON_SSL_ERROR_NONE; - } - - default: - break; - } - - _openssl_print_session(cl->ssl); - if (!cl->host_server->verify) - /* not verifying certificates, so we're done! */ - return ECORE_CON_SSL_ERROR_NONE; - SSL_set_verify(cl->ssl, SSL_VERIFY_PEER, NULL); - /* use CRL/CA lists to verify */ - if (SSL_get_peer_certificate(cl->ssl)) - { - int err; - - err = SSL_get_verify_result(cl->ssl); - _openssl_print_verify_error(err); - SSL_ERROR_CHECK_GOTO_ERROR(err); - } - - return ECORE_CON_SSL_ERROR_NONE; - -error: - _openssl_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR); - _ecore_con_ssl_client_shutdown_openssl(cl); - return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; -} - -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); - } - - cl->ssl = NULL; - cl->ssl_err = SSL_ERROR_NONE; - - 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; - - if (!cl->ssl) return -1; - 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, - const 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 Ecore_Con_Ssl_Error -_ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr EINA_UNUSED, - int ssl_type EINA_UNUSED) -{ - return ECORE_CON_SSL_ERROR_NONE; -} - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr EINA_UNUSED) -{ - return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; -} - -static Eina_Bool -_ecore_con_ssl_server_cafile_add_none(Ecore_Con_Server *svr EINA_UNUSED, - const char *ca_file EINA_UNUSED) -{ - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_cert_add_none(Ecore_Con_Server *svr EINA_UNUSED, - const char *cert_file EINA_UNUSED) -{ - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_privkey_add_none(Ecore_Con_Server *svr EINA_UNUSED, - const char *key_file EINA_UNUSED) -{ - return EINA_FALSE; -} - -static Eina_Bool -_ecore_con_ssl_server_crl_add_none(Ecore_Con_Server *svr EINA_UNUSED, - const char *crl_file EINA_UNUSED) -{ - return EINA_FALSE; -} - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr EINA_UNUSED) -{ - return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; -} - -static int -_ecore_con_ssl_server_read_none(Ecore_Con_Server *svr EINA_UNUSED, - unsigned char *buf EINA_UNUSED, - int size EINA_UNUSED) -{ - return -1; -} - -static int -_ecore_con_ssl_server_write_none(Ecore_Con_Server *svr EINA_UNUSED, - const unsigned char *buf EINA_UNUSED, - int size EINA_UNUSED) -{ - return -1; -} - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl EINA_UNUSED) -{ - return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; -} - -static Ecore_Con_Ssl_Error -_ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl EINA_UNUSED) -{ - return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; -} - -static int -_ecore_con_ssl_client_read_none(Ecore_Con_Client *cl EINA_UNUSED, - unsigned char *buf EINA_UNUSED, - int size EINA_UNUSED) -{ - return -1; -} - -static int -_ecore_con_ssl_client_write_none(Ecore_Con_Client *cl EINA_UNUSED, - const unsigned char *buf EINA_UNUSED, - int size EINA_UNUSED) -{ - return -1; -} - -#endif diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_url.c b/legacy/ecore/src/lib/ecore_con/ecore_con_url.c deleted file mode 100644 index 467f3f113b..0000000000 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_url.c +++ /dev/null @@ -1,1683 +0,0 @@ -/* - * For info on how to use libcurl, see: - * http://curl.haxx.se/libcurl/c/libcurl-tutorial.html - */ - -/* - * FIXME: Support more CURL features... - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include - -#ifdef HAVE_WS2TCPIP_H -# include -#endif - -#ifdef HAVE_ESCAPE -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" -#include "Ecore_Con.h" -#include "ecore_con_private.h" - -#define CURL_MIN_TIMEOUT 100 - -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 void _ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg); -static void _ecore_con_url_multi_remove(Ecore_Con_Url *url_con); -static Eina_Bool _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(Ecore_Con_Url *url_con, void *ev); -static Eina_Bool _ecore_con_url_timer(void *data); -static Eina_Bool _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); -static Eina_Bool _ecore_con_url_timeout_cb(void *data); -static void _ecore_con_url_status_get(Ecore_Con_Url *url_con); - -static Eina_List *_url_con_list = NULL; -static Eina_List *_fd_hd_list = NULL; -static CURLM *_curlm = NULL; -static int _init_count = 0; -static Ecore_Timer *_curl_timer = NULL; -static Eina_Bool pipelining = EINA_FALSE; -static Ecore_Idler *_curl_idler = NULL; -#endif - -/** - * @addtogroup Ecore_Con_Url_Group Ecore URL Connection Functions - * - * @{ - */ - -EAPI int -ecore_con_url_init(void) -{ -#ifdef HAVE_CURL - long ms; - if (++_init_count > 1) return _init_count; - - 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(); - - // curl_global_init() is not thread safe! - if (curl_global_init(CURL_GLOBAL_ALL)) return --_init_count; - - _curlm = curl_multi_init(); - if (!_curlm) - { - curl_global_cleanup(); - return --_init_count; - } - - curl_multi_timeout(_curlm, &ms); - if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; - - _curl_timer = ecore_timer_add((double)ms / 1000.0, - _ecore_con_url_timer, NULL); - ecore_timer_freeze(_curl_timer); - - return _init_count; -#else - return 0; -#endif -} - -EAPI int -ecore_con_url_shutdown(void) -{ -#ifdef HAVE_CURL - Ecore_Con_Url *url_con; - Ecore_Fd_Handler *fd_handler; - if (_init_count == 0) return 0; - --_init_count; - if (_init_count) return _init_count; - - if (_curl_timer) - { - ecore_timer_del(_curl_timer); - _curl_timer = NULL; - } - - if (_curl_idler) - { - ecore_idler_del(_curl_idler); - _curl_idler = NULL; - } - - EINA_LIST_FREE(_url_con_list, url_con) - ecore_con_url_free(url_con); - EINA_LIST_FREE(_fd_hd_list, fd_handler) - ecore_main_fd_handler_del(fd_handler); - - if (_curlm) - { - curl_multi_cleanup(_curlm); - _curlm = NULL; - } - curl_global_cleanup(); - return 0; -#endif - return 1; -} - -EAPI void -ecore_con_url_pipeline_set(Eina_Bool enable) -{ -#ifdef HAVE_CURL - if (enable == pipelining) return; - curl_multi_setopt(_curlm, CURLMOPT_PIPELINING, !!enable); - pipelining = enable; -#else - return; - (void)enable; -#endif -} - -EAPI Eina_Bool -ecore_con_url_pipeline_get(void) -{ -#ifdef HAVE_CURL - return pipelining; -#endif - return EINA_FALSE; -} - -extern Ecore_Con_Socks *_ecore_con_proxy_global; - -EAPI Ecore_Con_Url * -ecore_con_url_new(const char *url) -{ -#ifdef HAVE_CURL - Ecore_Con_Url *url_con; - CURLcode ret; - - if (!_init_count) - return NULL; - - url_con = calloc(1, sizeof(Ecore_Con_Url)); - if (!url_con) - return NULL; - - url_con->write_fd = -1; - - 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); - - if (!ecore_con_url_url_set(url_con, url)) - { - ecore_con_url_free(url_con); - return NULL; - } - - // Read socks proxy - url_con->proxy_type = -1; - if (_ecore_con_proxy_global && _ecore_con_proxy_global->ip && - (_ecore_con_proxy_global->version == 4 || - _ecore_con_proxy_global->version == 5)) - { - char proxy[256]; - char host[256]; - - if (_ecore_con_proxy_global->version == 5) - { - if (_ecore_con_proxy_global->lookup) - snprintf(host, sizeof(host), "socks5h://%s", - _ecore_con_proxy_global->ip); - else snprintf(host, sizeof(host), "socks5://%s", - _ecore_con_proxy_global->ip); - } - else if (_ecore_con_proxy_global->version == 4) - { - if (_ecore_con_proxy_global->lookup) - snprintf(host, sizeof(host), "socks4a://%s", - _ecore_con_proxy_global->ip); - else snprintf(host, sizeof(host), "socks4://%s", - _ecore_con_proxy_global->ip); - } - - if (_ecore_con_proxy_global->port > 0 && - _ecore_con_proxy_global->port <= 65535) - snprintf(proxy, sizeof(proxy), "%s:%d", host, - _ecore_con_proxy_global->port); - else snprintf(proxy, sizeof(proxy), "%s", host); - - ecore_con_url_proxy_set(url_con, proxy); - ecore_con_url_proxy_username_set(url_con, - _ecore_con_proxy_global->username); - } - - ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate"); - if (ret != CURLE_OK) - { - ERR("Could not set CURLOPT_ENCODING to \"gzip,deflate\": %s", - curl_easy_strerror(ret)); - ecore_con_url_free(url_con); - return NULL; - } - - 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_FOLLOWLOCATION, 1); - - return url_con; -#else - return NULL; - url = NULL; -#endif -} - -EAPI Ecore_Con_Url * -ecore_con_url_custom_new(const char *url, - const char *custom_request) -{ -#ifdef HAVE_CURL - Ecore_Con_Url *url_con; - CURLcode ret; - - if (!url) - return NULL; - - if (!custom_request) - return NULL; - - url_con = ecore_con_url_new(url); - - if (!url_con) - return NULL; - - ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_CUSTOMREQUEST, custom_request); - if (ret != CURLE_OK) - { - ERR("Could not set a custom request string: %s", - curl_easy_strerror(ret)); - ecore_con_url_free(url_con); - return NULL; - } - - return url_con; -#else - return NULL; - url = NULL; - custom_request = NULL; -#endif -} - -EAPI void -ecore_con_url_free(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_free"); - return; - } - - if (url_con->curl_easy) - { - // FIXME : How can we delete curl_easy's fds ?? (Curl do not give this info.) - // This cause "Failed to delete epoll fd xx!" error messages - curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL); - curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE); - - if (url_con->multi) - { - _ecore_con_url_multi_remove(url_con); - _url_con_list = eina_list_remove(_url_con_list, url_con); - } - - curl_easy_cleanup(url_con->curl_easy); - } - if (url_con->timer) ecore_timer_del(url_con->timer); - - url_con->curl_easy = NULL; - url_con->timer = NULL; - url_con->dead = EINA_TRUE; - if (url_con->event_count) return; - ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE); - - 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); - eina_stringshare_del(url_con->url); - if (url_con->post_data) free(url_con->post_data); - free(url_con); -#else - return; - (void)url_con; -#endif -} - -EAPI const char * -ecore_con_url_url_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, __func__); - return NULL; - } - return url_con->url; -#else - return NULL; - (void)url_con; -#endif -} - -EAPI int -ecore_con_url_status_code_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, __func__); - return 0; - } - - if (url_con->status) return url_con->status; - _ecore_con_url_status_get(url_con); - return url_con->status; -#else - return -1; - (void)url_con; -#endif -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - - if (url_con->dead) return EINA_FALSE; - eina_stringshare_replace(&url_con->url, 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 EINA_TRUE; -#else - return EINA_FALSE; - (void)url; - (void)url_con; -#endif -} - -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 -} - -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 (url_con->dead) return; - 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; - } - - if (url_con->dead) 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 -} - -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 -} - -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 -} - -EAPI void -ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, double timestamp) -{ -#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; - } - - if (url_con->dead) return; - url_con->time_condition = condition; - url_con->timestamp = timestamp; -#else - return; - (void)url_con; - (void)condition; - (void)timestamp; -#endif -} - -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; - } - - if (url_con->dead) return; - url_con->write_fd = fd; -#else - return; - (void)url_con; - (void)fd; -#endif -} - -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; - (void)url_con; -#endif -} - -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; - (void)url_con; -#endif -} - -EAPI Eina_Bool -ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, const char *username, const char *password, Eina_Bool safe) -{ -#ifdef HAVE_CURL - CURLcode ret; - - 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 EINA_FALSE; - } - - if (url_con->dead) return EINA_FALSE; -# if LIBCURL_VERSION_NUM >= 0x071301 - if ((username) && (password)) - { - 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); - - ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username); - if (ret != CURLE_OK) - { - ERR("Could not set username for HTTP authentication: %s", - curl_easy_strerror(ret)); - return EINA_FALSE; - } - - ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password); - if (ret != CURLE_OK) - { - ERR("Could not set password for HTTP authentication: %s", - curl_easy_strerror(ret)); - return EINA_FALSE; - } - - return EINA_TRUE; - } -# endif -#else - return EINA_FALSE; - (void)url_con; - (void)username; - (void)password; - (void)safe; -#endif - - return EINA_FALSE; -} - -#define MODE_AUTO 0 -#define MODE_GET 1 -#define MODE_POST 2 - -static Eina_Bool -_ecore_con_url_send(Ecore_Con_Url *url_con, int mode, const void *data, long length, const char *content_type) -{ -#ifdef HAVE_CURL - Eina_List *l; - const char *s; - char tmp[512]; - - if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) - { - ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_send"); - return EINA_FALSE; - } - - if (!url_con->url) return EINA_FALSE; - if (url_con->dead) return EINA_FALSE; - - /* Free response headers from previous send() calls */ - EINA_LIST_FREE(url_con->response_headers, s) - free((char *)s); - url_con->response_headers = NULL; - url_con->status = 0; - - curl_slist_free_all(url_con->headers); - url_con->headers = NULL; - - if ((mode == MODE_POST) || (mode == MODE_AUTO)) - { - if (url_con->post_data) free(url_con->post_data); - url_con->post_data = NULL; - if ((data) && (length > 0)) - { - url_con->post_data = malloc(length); - if (url_con->post_data) - { - memcpy(url_con->post_data, data, length); - if ((content_type) && (strlen(content_type) < 450)) - { - snprintf(tmp, sizeof(tmp), "Content-Type: %s", content_type); - url_con->headers = curl_slist_append(url_con->headers, tmp); - } - curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, url_con->post_data); - curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length); - } - else - return EINA_FALSE; - } - else curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, 0); - if (mode == MODE_POST) - curl_easy_setopt(url_con->curl_easy, CURLOPT_POST, 1); - } - - switch (url_con->time_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, - (long)url_con->timestamp); - 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, - (long)url_con->timestamp); - 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; - - return _ecore_con_url_perform(url_con); -#else - return EINA_FALSE; - (void)url_con; - (void)mode; - (void)data; - (void)length; - (void)content_type; -#endif -} - -EAPI Eina_Bool -ecore_con_url_get(Ecore_Con_Url *url_con) -{ - return _ecore_con_url_send(url_con, MODE_GET, NULL, 0, NULL); -} - -EAPI Eina_Bool -ecore_con_url_post(Ecore_Con_Url *url_con, const void *data, long length, const char *content_type) -{ - return _ecore_con_url_send(url_con, MODE_POST, data, length, content_type); -} - -EAPI Eina_Bool -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; - CURLcode ret; - - 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 EINA_FALSE; - } - - if (url_con->dead) return EINA_FALSE; - if (!url_con->url) return EINA_FALSE; - if ((!filename) || (!filename[0])) return EINA_FALSE; - - if (stat(filename, &file_info)) - return EINA_FALSE; - - snprintf(userpwd, sizeof(userpwd), "%s:%s", user, pass); - ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERPWD, userpwd); - if (ret != CURLE_OK) - { - ERR("Could not set username and password for FTP upload: %s", - curl_easy_strerror(ret)); - return EINA_FALSE; - } - - char tmp[PATH_MAX]; - snprintf(tmp, PATH_MAX, "%s", filename); - - 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)); - - if (!ecore_con_url_url_set(url_con, url)) - return EINA_FALSE; - - 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_UPLOAD, 1); - curl_easy_setopt(url_con->curl_easy, CURLOPT_READFUNCTION, - _ecore_con_url_read_cb); - - fd = fopen(filename, "rb"); - if (!fd) - { - ERR("Could not open \"%s\" for FTP upload", filename); - return EINA_FALSE; - } - curl_easy_setopt(url_con->curl_easy, CURLOPT_READDATA, fd); - - return _ecore_con_url_perform(url_con); -#else - return EINA_FALSE; - (void)url_con; - (void)filename; - (void)user; - (void)pass; - (void)upload_dir; -#endif -} - -EAPI void -ecore_con_url_cookies_init(Ecore_Con_Url *url_con) -{ -#ifdef HAVE_CURL - 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_cookies_init"); - return; - } - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, ""); -#else - return; - (void)url_con; -#endif -} - -EAPI void -ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, Eina_Bool ignore) -{ -#ifdef HAVE_CURL - 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_cookies_ignore_old_session_set"); - return; - } - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIESESSION, ignore); -#else - return; - (void)url_con; - (void)ignore; -#endif -} - -EAPI void -ecore_con_url_cookies_clear(Ecore_Con_Url *url_con) -{ -#ifdef HAVE_CURL - 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_cookies_clear"); - return; - } - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "ALL"); -#else - return; - (void)url_con; -#endif -} - -EAPI void -ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con) -{ -#ifdef HAVE_CURL - 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_cookies_session_clear"); - return; - } - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "SESS"); -#else - return; - (void)url_con; -#endif -} - -EAPI void -ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, const char *const file_name) -{ -#ifdef HAVE_CURL - 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_cookies_file_add"); - return; - } - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, file_name); -#else - return; - (void)url_con; - (void)file_name; -#endif -} - -EAPI Eina_Bool -ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, const char *const cookiejar_file) -{ -#ifdef HAVE_CURL - CURLcode ret; - - if (!url_con) - return EINA_FALSE; - - if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) - { - ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, - "ecore_con_url_cookies_jar_file_set"); - return EINA_FALSE; - } - - if (url_con->dead) return EINA_FALSE; - ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEJAR, - cookiejar_file); - if (ret != CURLE_OK) - { - ERR("Setting the cookie-jar name failed: %s", - curl_easy_strerror(ret)); - return EINA_FALSE; - } - - return EINA_TRUE; -#else - return EINA_FALSE; - (void)url_con; - (void)cookiejar_file; -#endif -} - -EAPI void -ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con) -{ -#ifdef HAVE_CURL - 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_cookies_jar_write"); - return; - } - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "FLUSH"); -#else - return; - (void)url_con; -#endif -} - -EAPI void -ecore_con_url_verbose_set(Ecore_Con_Url *url_con, Eina_Bool 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->url) - return; - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_VERBOSE, (int)verbose); -#else - return; - (void)url_con; - (void)verbose; -#endif -} - -EAPI void -ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, Eina_Bool 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->url) - return; - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_FTP_USE_EPSV, (int)use_epsv); -#else - return; - (void)url_con; - (void)use_epsv; -#endif -} - -/** - * Toggle libcurl's verify peer's certificate option. - * - * If @p verify is @c EINA_TRUE, libcurl will verify - * the authenticity of the peer's certificate, otherwise - * it will not. Default behavior of libcurl is to check - * peer's certificate. - * - * @param url_con Ecore_Con_Url instance which will be acted upon. - * @param verify Whether or not libcurl will check peer's certificate. - * @since 1.1.0 - */ -EAPI void -ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con, Eina_Bool verify) -{ -#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_ssl_verify_peer_set"); - return; - } - - if (!url_con->url) - return; - - if (url_con->dead) return; - curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, (int)verify); -#else - return; - (void)url_con; - (void)verify; -#endif -} - -/** - * Set a custom CA to trust for SSL/TLS connections. - * - * Specify the path of a file (in PEM format) containing one or more - * CA certificate(s) to use for the validation of the server certificate. - * - * This function can also disable CA validation if @p ca_path is @c NULL. - * However, the server certificate still needs to be valid for the connection - * to succeed (i.e., the certificate must concern the server the - * connection is made to). - * - * @param url_con Connection object that will use the custom CA. - * @param ca_path Path to a CA certificate(s) file or @c NULL to disable - * CA validation. - * - * @return @c 0 on success. When cURL is used, non-zero return values - * are equal to cURL error codes. - */ -EAPI int -ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path) -{ - int res = -1; - -#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_ssl_ca_set"); - return -1; - } - - if (!url_con->url) return -1; - if (url_con->dead) return -1; - if (ca_path == NULL) - res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0); - else - { - res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 1); - if (!res) - res = curl_easy_setopt(url_con->curl_easy, CURLOPT_CAINFO, ca_path); - } -#else - return -1; - (void)url_con; - (void)ca_path; -#endif - - return res; -} - -EAPI Eina_Bool -ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Version version) -{ -#ifdef HAVE_CURL - int res = -1; - if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) - { - ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_http_version_set"); - return EINA_FALSE; - } - if (url_con->dead) return EINA_FALSE; - switch (version) - { - case ECORE_CON_URL_HTTP_VERSION_1_0: - res = curl_easy_setopt(url_con->curl_easy, - CURLOPT_HTTP_VERSION, - CURL_HTTP_VERSION_1_0); - break; - - case ECORE_CON_URL_HTTP_VERSION_1_1: - res = curl_easy_setopt(url_con->curl_easy, - CURLOPT_HTTP_VERSION, - CURL_HTTP_VERSION_1_1); - break; - - default: - break; - } - if (res != CURLE_OK) - { - ERR("curl http version setting failed: %s", curl_easy_strerror(res)); - return EINA_FALSE; - } - return EINA_TRUE; -#else - (void)url_con; - (void)version; - return EINA_FALSE; -#endif -} - -EAPI Eina_Bool -ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy) -{ -#ifdef HAVE_CURL - int res = -1; - curl_version_info_data *vers = NULL; - - if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) - { - ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_set"); - return EINA_FALSE; - } - - if (!url_con->url) return EINA_FALSE; - if (url_con->dead) return EINA_FALSE; - - if (!proxy) res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, ""); - else - { - // before curl version 7.21.7, socks protocol:// prefix is not supported - // (e.g. socks4://, socks4a://, socks5:// or socks5h://, etc.) - vers = curl_version_info(CURLVERSION_NOW); - if (vers->version_num < 0x71507) - { - url_con->proxy_type = CURLPROXY_HTTP; - if (strstr(proxy, "socks4a")) - url_con->proxy_type = CURLPROXY_SOCKS4A; - else if (strstr(proxy, "socks4")) - url_con->proxy_type = CURLPROXY_SOCKS4; - else if (strstr(proxy, "socks5h")) - url_con->proxy_type = CURLPROXY_SOCKS5_HOSTNAME; - else if (strstr(proxy, "socks5")) - url_con->proxy_type = CURLPROXY_SOCKS5; - res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXYTYPE, - url_con->proxy_type); - if (res != CURLE_OK) - { - ERR("curl proxy type setting failed: %s", - curl_easy_strerror(res)); - url_con->proxy_type = -1; - return EINA_FALSE; - } - } - res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, proxy); - } - if (res != CURLE_OK) - { - ERR("curl proxy setting failed: %s", curl_easy_strerror(res)); - url_con->proxy_type = -1; - return EINA_FALSE; - } - return EINA_TRUE; -#else - return EINA_FALSE; - (void)url_con; - (void)proxy; -#endif -} - -EAPI void -ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout) -{ -#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_timeout_set"); - return; - } - - if (url_con->dead) return; - if (!url_con->url || timeout < 0) return; - if (url_con->timer) ecore_timer_del(url_con->timer); - url_con->timer = ecore_timer_add(timeout, _ecore_con_url_timeout_cb, url_con); -#else - return; - (void)url_con; - (void)timeout; -#endif -} - -EAPI Eina_Bool -ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username) -{ -#ifdef HAVE_CURL - int res = -1; - if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) - { - ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_username_set"); - return EINA_FALSE; - } - - if (url_con->dead) return EINA_FALSE; - if (!url_con->url) return EINA_FALSE; - if ((!username) || (!username[0])) return EINA_FALSE; - if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A) - { - ERR("Proxy type should be socks5 and above"); - return EINA_FALSE; - } - - res = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username); - if (res != CURLE_OK) - { - ERR("curl_easy_setopt() failed: %s", curl_easy_strerror(res)); - return EINA_FALSE; - } - return EINA_TRUE; -#else - return EINA_FALSE; - (void)url_con; - (void)username; -#endif -} - -EAPI Eina_Bool -ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password) -{ -#ifdef HAVE_CURL - int res = -1; - if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) - { - ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_password_set"); - return EINA_FALSE; - } - if (!url_con->url) return EINA_FALSE; - if (url_con->dead) return EINA_FALSE; - if (!password) return EINA_FALSE; - if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A) - { - ERR("Proxy type should be socks5 and above"); - return EINA_FALSE; - } - - res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password); - if (res != CURLE_OK) - { - ERR("curl_easy_setopt() failed: %s", curl_easy_strerror(res)); - return EINA_FALSE; - } - return EINA_TRUE; -#else - return EINA_FALSE; - (void)url_con; - (void)password; -#endif -} - -/** - * @} - */ - -#ifdef HAVE_CURL -static void -_ecore_con_url_status_get(Ecore_Con_Url *url_con) -{ - long status = 0; - - if (!url_con->curl_easy) return; - if (!curl_easy_getinfo(url_con->curl_easy, CURLINFO_RESPONSE_CODE, &status)) - url_con->status = status; - else - url_con->status = 0; -} - -static void -_ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg) -{ - Ecore_Con_Event_Url_Complete *e; - int status = url_con->status; - - e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete)); - if (!e) return; - - if (!curlmsg) - { - ERR("Event completed without CURL message handle. Shouldn't happen"); - } - else if ((curlmsg->msg == CURLMSG_DONE) && - (curlmsg->data.result == CURLE_OPERATION_TIMEDOUT) && - (!curlmsg->easy_handle)) - { - /* easy_handle is set to NULL on timeout messages */ - status = 408; /* Request Timeout */ - } - else if (curlmsg->data.result == CURLE_OK) - { - if (!status) - { - _ecore_con_url_status_get(url_con); - status = url_con->status; - } - } - else - { - ERR("Curl message have errors: %d (%s)", - curlmsg->data.result, curl_easy_strerror(curlmsg->data.result)); - } - - e->status = status; - e->url_con = url_con; - - url_con->event_count++; - ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con); -} - -static void -_ecore_con_url_multi_remove(Ecore_Con_Url *url_con) -{ - CURLMcode ret; - - ret = curl_multi_remove_handle(_curlm, url_con->curl_easy); - url_con->multi = EINA_FALSE; - if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret)); -} - -static Eina_Bool -_ecore_con_url_timeout_cb(void *data) -{ - Ecore_Con_Url *url_con = data; - CURLMsg timeout_msg; - - if (!url_con) return ECORE_CALLBACK_CANCEL; - if (!url_con->curl_easy) return ECORE_CALLBACK_CANCEL; - - _ecore_con_url_multi_remove(url_con); - _url_con_list = eina_list_remove(_url_con_list, url_con); - - curl_slist_free_all(url_con->headers); - url_con->headers = NULL; - - url_con->timer = NULL; - - timeout_msg.msg = CURLMSG_DONE; - timeout_msg.easy_handle = NULL; - timeout_msg.data.result = CURLE_OPERATION_TIMEDOUT; - - _ecore_con_url_event_url_complete(url_con, &timeout_msg); - return ECORE_CALLBACK_CANCEL; -} - -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; - - INF("reading from %s", url_con->url); - 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); - url_con->event_count++; - ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con); - } - } - 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; -} - -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; - url_con->event_count++; - ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con); - } - - 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) - { - fclose((FILE *)stream); - return 0; - } - -#ifdef _WIN32 - INF("*** We read %Iu bytes from file", retcode); -#else - INF("*** We read %zu bytes from file", retcode); -#endif - return retcode; -} - -static void -_ecore_con_url_info_read(void) -{ - CURLMsg *curlmsg; - int n_remaining; - - while ((curlmsg = curl_multi_info_read(_curlm, &n_remaining))) - { - Eina_List *l, *ll; - Ecore_Con_Url *url_con = NULL; - DBG("Curl message: %d", curlmsg->msg); - - if (curlmsg->msg == CURLMSG_DONE) - { - EINA_LIST_FOREACH_SAFE(_url_con_list, l, ll, url_con) - { - if (curlmsg->easy_handle == url_con->curl_easy) - _ecore_con_url_event_url_complete(url_con, curlmsg); - } - } - } -} - -static void -_ecore_con_url_curl_clear(void) -{ - Ecore_Fd_Handler *fdh; - Ecore_Con_Url *url_con; - - EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh); - EINA_LIST_FREE(_url_con_list, url_con) _ecore_con_url_multi_remove(url_con); -} - -static Eina_Bool -_ecore_con_url_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - Ecore_Fd_Handler *fdh; - long ms; - - EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh); - - curl_multi_timeout(_curlm, &ms); - if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; - ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0); - - if (!_curl_idler) - _curl_idler = ecore_idler_add(_ecore_con_url_timer, NULL); - - return ECORE_CALLBACK_CANCEL; -} - -static void -_ecore_con_url_fdset(void) -{ - CURLMcode ret; - fd_set read_set, write_set, exc_set; - int fd, fd_max; - - FD_ZERO(&read_set); - FD_ZERO(&write_set); - FD_ZERO(&exc_set); - - ret = curl_multi_fdset(_curlm, &read_set, &write_set, &exc_set, &fd_max); - if (ret != CURLM_OK) - { - ERR("curl_multi_fdset failed: %s", curl_multi_strerror(ret)); - return; - } - - for (fd = 0; fd <= fd_max; fd++) - { - int 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) - { - // FIXME: Who is owner (easy_handle) of this fd?? (Curl do not give this info.) - // This cause "Failed to delete epoll fd xx!" error messages - Ecore_Fd_Handler *fd_handler; - fd_handler = ecore_main_fd_handler_add(fd, flags, - _ecore_con_url_fd_handler, - NULL, NULL, NULL); - if (fd_handler) - _fd_hd_list = eina_list_append(_fd_hd_list, fd_handler); - } - } -} - -static Eina_Bool -_ecore_con_url_timer(void *data EINA_UNUSED) -{ - Ecore_Fd_Handler *fdh; - int still_running; - CURLMcode ret; - - EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh); - _ecore_con_url_info_read(); - - ret = curl_multi_perform(_curlm, &still_running); - if (ret == CURLM_CALL_MULTI_PERFORM) - { - DBG("curl_multi_perform() again immediately"); - return ECORE_CALLBACK_RENEW; - } - else if (ret != CURLM_OK) - { - ERR("curl_multi_perform() failed: %s", curl_multi_strerror(ret)); - _ecore_con_url_curl_clear(); - ecore_timer_freeze(_curl_timer); - if (_curl_idler) - { - ecore_idler_del(_curl_idler); - _curl_idler = NULL; - } - } - - if (still_running) - { - long ms; - _ecore_con_url_fdset(); - curl_multi_timeout(_curlm, &ms); - DBG("multiperform is still running: %d, timeout: %ld", still_running, ms); - if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; - ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0); - } - else - { - DBG("multiperform ended"); - _ecore_con_url_info_read(); - _ecore_con_url_curl_clear(); - ecore_timer_freeze(_curl_timer); - if (_curl_idler) - { - ecore_idler_del(_curl_idler); - _curl_idler = NULL; - } - } - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_ecore_con_url_perform(Ecore_Con_Url *url_con) -{ - CURLMcode ret; - - ret = curl_multi_add_handle(_curlm, url_con->curl_easy); - if (ret != CURLM_OK) - { - ERR("curl_multi_add_handle() failed: %s", curl_multi_strerror(ret)); - return EINA_FALSE; - } - - url_con->multi = EINA_TRUE; - _url_con_list = eina_list_append(_url_con_list, url_con); - ecore_timer_thaw(_curl_timer); - - return EINA_TRUE; -} - -static void -_ecore_con_event_url_free(Ecore_Con_Url *url_con, void *ev) -{ - free(ev); - url_con->event_count--; - if (url_con->dead && (!url_con->event_count)) - ecore_con_url_free(url_con); -} - -#endif diff --git a/legacy/ecore/src/lib/ecore_directfb/Ecore_DirectFB.h b/legacy/ecore/src/lib/ecore_directfb/Ecore_DirectFB.h deleted file mode 100644 index 3b94816d96..0000000000 --- a/legacy/ecore/src/lib/ecore_directfb/Ecore_DirectFB.h +++ /dev/null @@ -1,181 +0,0 @@ -#ifndef _ECORE_DIRECTFB_H -#define _ECORE_DIRECTFB_H - -#include - -#include - -#ifdef EAPI -# undef EAPI -#endif /* ifdef EAPI */ - -#ifdef __GNUC__ -# if __GNUC__ >= 4 -# define EAPI __attribute__ ((visibility("default"))) -# else /* if __GNUC__ >= 4 */ -# define EAPI -# endif /* if __GNUC__ >= 4 */ -#else /* ifdef __GNUC__ */ -# define EAPI -#endif /* ifdef __GNUC__ */ - -#ifdef __cplusplus -extern "C" { -#endif /* ifdef __cplusplus */ - -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 /* ifndef _ECORE_DIRECTFB_WINDOW_PREDEF */ -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; - int double_click : 1; - int triple_click : 1; -}; -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, Eina_Bool set); -EAPI void ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *window, Eina_Bool 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, Eina_Bool show); - -#ifdef __cplusplus -} -#endif /* ifdef __cplusplus */ - -#endif /* ifndef _ECORE_DIRECTFB_H */ diff --git a/legacy/ecore/src/lib/ecore_directfb/ecore_directfb.c b/legacy/ecore/src/lib/ecore_directfb/ecore_directfb.c deleted file mode 100644 index 008fa1d6f9..0000000000 --- a/legacy/ecore/src/lib/ecore_directfb/ecore_directfb.c +++ /dev/null @@ -1,758 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include -#include -#include - -#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; // useful for DFBCHECK - -/*******************/ -/* local functions */ -/*******************/ - -/* free ecore directfb events functions */ -/****************************************/ - -static void -_ecore_directfb_event_free_key_down(void *data EINA_UNUSED, void *ev) -{ - Ecore_DirectFB_Event_Key_Down *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 EINA_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("Symbol %0X of class DFEC_INPUT not found.", 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("Symbol %0X of class DFEC_WINDOW not found.", 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("Symbol %0X of class DFEC_INPUT not found.", 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("Symbol %0X of class DFEC_WINDOW not found.", 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 Eina_Bool -_ecore_directfb_input_event_fd_handler(void *data EINA_UNUSED,Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - DFBEvent evt; - int v = 0; - - v = read(_input_event_fd, &evt, sizeof(DFBEvent)); - if (v < 0) - return EINA_TRUE; - - if (v < 1) - return EINA_TRUE; - - /* 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 EINA_TRUE; -} - -static Eina_Bool -_ecore_directfb_window_event_fd_handler(void *data EINA_UNUSED,Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - DFBEvent evt; - int v = 0; - - v = read(_window_event_fd, &evt, sizeof(DFBEvent)); - if (v < 0) - return EINA_TRUE; - - if (v < 1) - return EINA_TRUE; - - 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 EINA_TRUE; -} - -/* 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, Eina_Bool 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, Eina_Bool 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, Eina_Bool 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 - { - ecore_main_fd_handler_del(_input_event_fd_handler_handle); - DFBCHECK(_input_event->Release(_input_event)); - DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_SHARED)); - DFBCHECK(ecore_window->window->GetSurface(ecore_window->window, &ecore_window->surface)); - _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 EINA_UNUSED) -{ - int i = 0; - - if (++_ecore_directfb_init_count != 1) - return _ecore_directfb_init_count; - - _ecore_directfb_log_dom = eina_log_domain_register - ("ecore_directfb", 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; -} - diff --git a/legacy/ecore/src/lib/ecore_directfb/ecore_directfb_keys.h b/legacy/ecore/src/lib/ecore_directfb/ecore_directfb_keys.h deleted file mode 100644 index 19cca46e57..0000000000 --- a/legacy/ecore/src/lib/ecore_directfb/ecore_directfb_keys.h +++ /dev/null @@ -1,184 +0,0 @@ -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); diff --git a/legacy/ecore/src/lib/ecore_directfb/ecore_directfb_private.h b/legacy/ecore/src/lib/ecore_directfb/ecore_directfb_private.h deleted file mode 100644 index ed34587ab5..0000000000 --- a/legacy/ecore/src/lib/ecore_directfb/ecore_directfb_private.h +++ /dev/null @@ -1,52 +0,0 @@ -#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 /* ifdef ECORE_DIRECTFB_DEFAULT_LOG_COLOR */ -#define ECORE_DIRECTFB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE - -#ifdef ERR -# undef ERR -#endif /* ifdef ERR */ -#define ERR(...) EINA_LOG_DOM_ERR(_ecore_directfb_log_dom, __VA_ARGS__) - -#ifdef DBG -# undef DBG -#endif /* ifdef DBG */ -#define DBG(...) EINA_LOG_DOM_DBG(_ecore_directfb_log_dom, __VA_ARGS__) - -#ifdef INF -# undef INF -#endif /* ifdef INF */ -#define INF(...) EINA_LOG_DOM_INFO(_ecore_directfb_log_dom, __VA_ARGS__) - -#ifdef WRN -# undef WRN -#endif /* ifdef WRN */ -#define WRN(...) EINA_LOG_DOM_WARN(_ecore_directfb_log_dom, __VA_ARGS__) - -#ifdef CRIT -# undef CRIT -#endif /* ifdef CRIT */ -#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 /* ifndef _ECORE_DIRECTFB_PRIVATE_H */ diff --git a/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h b/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h deleted file mode 100644 index 3c59c80c84..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h +++ /dev/null @@ -1,2256 +0,0 @@ -#ifndef _ECORE_EVAS_H -#define _ECORE_EVAS_H - -#include -#include -#include - -#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 - * - * The following is a list of example that partially exemplify Ecore_Evas's API: - * @li @ref ecore_evas_callbacks_example_c - * @li @ref ecore_evas_object_example_c - * @li @ref ecore_evas_basics_example_c - * @li @ref Ecore_Evas_Window_Sizes_Example_c - * @li @ref Ecore_Evas_Buffer_Example_01_c - * @li @ref Ecore_Evas_Buffer_Example_02_c - */ - -/* 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 - -/** - * @defgroup Ecore_Evas_Group Ecore_Evas wrapper/helper set of functions - * - * Ecore evas is a set of functions that makes it easy to tie together ecore's - * main loop and input handling to evas. As such it's a natural base for EFL - * applications. While this combination makes it easy to create the basic - * aspects all applications need, for normal applications(ones with buttons, - * checkboxes and layouts) one should consider using Elementary. - * - * Ecore evas is extremely well suited for applications that are not based on - * widgets. It has a main loop that delivers events, does basic window handling - * and leaves all of the drawing up to the user. This works very well if used - * in conjunction with Edje or if doing custom drawing as, for example, is done - * in games. - * - * This is a list of examples of these functions: - * @li @ref ecore_evas_basics_example_c - * @li @ref ecore_evas_object_example_c - * @li @ref ecore_evas_callbacks_example_c - * @li @ref Ecore_Evas_Window_Sizes_Example_c - * @li @ref Ecore_Evas_Buffer_Example_01_c - * @li @ref Ecore_Evas_Buffer_Example_02_c - * - * @{ - */ - -/* 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 -#define HAVE_ECORE_EVAS_EWS 1 -#define HAVE_ECORE_EVAS_PSL1GHT 1 -#define HAVE_ECORE_EVAS_WAYLAND_SHM 1 -#define HAVE_ECORE_EVAS_WAYLAND_EGL 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_OPENGL_COCOA, - ECORE_EVAS_ENGINE_SOFTWARE_SDL, - ECORE_EVAS_ENGINE_DIRECTFB, - ECORE_EVAS_ENGINE_SOFTWARE_FB, - ECORE_EVAS_ENGINE_SOFTWARE_8_X11, - 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_EWS, - ECORE_EVAS_ENGINE_PSL1GHT, - ECORE_EVAS_ENGINE_WAYLAND_SHM, - ECORE_EVAS_ENGINE_WAYLAND_EGL -} 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 struct _Ecore_WinCE_Window Ecore_WinCE_Window; -#endif - -#ifndef __ECORE_COCOA_H__ -typedef struct _Ecore_Cocoa_Window Ecore_Cocoa_Window; -#endif - -#ifndef _ECORE_EVAS_PRIVATE_H -/* basic data types */ -typedef struct _Ecore_Evas Ecore_Evas; -typedef void (*Ecore_Evas_Event_Cb) (Ecore_Evas *ee); /**< Callback used for several ecore evas events @since 1.2 */ -#endif - -#ifndef _ECORE_WAYLAND_H_ -#define _ECORE_WAYLAND_WINDOW_PREDEF -typedef struct _Ecore_Wl_Window Ecore_Wl_Window; -#endif - -/* module setup/shutdown calls */ - -EAPI int ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine); - -/** - * @brief Init the Ecore_Evas system. - * - * @return How many times the lib has been initialized, 0 indicates failure. - * - * Set up the Evas wrapper system. Init Evas and Ecore libraries. - * - * @see ecore_evas_shutdown() - */ -EAPI int ecore_evas_init(void); -/** - * @brief Shut down the Ecore_Evas system. - * - * @return 0 if ecore evas is fully shut down, or > 0 if it still being used. - * - * This closes the Evas wrapper system down. Shut down Evas and Ecore libraries. - * - * @see ecore_evas_init() - */ -EAPI int ecore_evas_shutdown(void); - -EAPI void ecore_evas_app_comp_sync_set(Eina_Bool do_sync); -EAPI Eina_Bool ecore_evas_app_comp_sync_get(void); - -/** - * @brief 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 or modify them, to free the list use ecore_evas_engines_free(). - */ -EAPI Eina_List *ecore_evas_engines_get(void); -/** - * @brief Free list returned by ecore_evas_engines_get() - * - * @param engines list with engines names - */ -EAPI void ecore_evas_engines_free(Eina_List *engines); -/** - * @brief 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 @c 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 @c 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); -/** - * @brief Set whether an Ecore_Evas has an alpha channel or not. - * - * @param ee The Ecore_Evas to shape - * @param alpha @c EINA_TRUE to enable the alpha channel, @c EINA_FALSE 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 transparency, as opposed to - * the 1 bit transparency of a shaped window (a pixel is either opaque, or - * it's transparent). - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_alpha_set(Ecore_Evas *ee, Eina_Bool alpha); -/** - * @brief Query whether an Ecore_Evas has an alpha channel. - * @param ee The Ecore_Evas to query. - * @return @c EINA_TRUE if ee has an alpha channel, @c EINA_FALSE if it does - * not. - * - * This function returns @c EINA_TRUE if @p ee has an alpha channel, and - * @c EINA_FALSE if it does not. - * - * @see ecore_evas_alpha_set() - */ -EAPI Eina_Bool ecore_evas_alpha_get(const Ecore_Evas *ee); -/** - * @brief Set whether an Ecore_Evas has an transparent window or not. - * - * @param ee The Ecore_Evas to shape - * @param transparent @c EINA_TRUE to enable the transparent window, - * @c EINA_FALSE to disable it - * - * This function sets some translucency options, for more complete support see - * ecore_evas_alpha_set(). - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_alpha_set() - */ -EAPI void ecore_evas_transparent_set(Ecore_Evas *ee, Eina_Bool transparent); -/** - * @brief Query whether an Ecore_Evas is transparent. - * - * @param ee The Ecore_Evas to query. - * @return @c EINA_TRUE if ee is transparent, @c EINA_FALSE if it isn't. - * - * @see ecore_evas_transparent_set() - */ -EAPI Eina_Bool ecore_evas_transparent_get(const Ecore_Evas *ee); -/** - * @brief 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. If any of the parameters is not desired you - * may pass @c NULL on them. - * - * @code - * int x, y, w, h; - * ecore_evas_geometry_get(ee, &x, &y, &w, &h); - * @endcode - * - * @see ecore_evas_new() - * @see ecore_evas_resize() - * @see ecore_evas_move() - * @see ecore_evas_move_resize() - */ -EAPI void ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); -/** - * @brief Get the geometry which an Ecore_Evas was latest recently requested. - * - * @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 which @p ee was latest recently requested . If any of the - * parameters is not desired you may pass @c NULL on them. - * This function can represent recently requested geometry. - * ecore_evas_geometry_get function returns the value is updated after engine - * finished request. By comparison, ecore_evas_request_geometry_get returns - * recently requested value. - * - * @code - * int x, y, w, h; - * ecore_evas_request_geometry_get(ee, &x, &y, &w, &h); - * @endcode - * - * @since 1.1 - */ -EAPI void ecore_evas_request_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); -/** - * @brief Set the focus of an Ecore_Evas' window. - * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE for focus, @c EINA_FALSE to defocus. - * - * This function focuses @p ee if @p on is @c EINA_TRUE, or unfocuses @p ee if - * @p on is @c EINA_FALSE. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool on); -/** - * @brief Query whether an Ecore_Evas' window is focused or not. - * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee if focused, @c EINA_FALSE if not. - * - * @see ecore_evas_focus_set() - */ -EAPI Eina_Bool ecore_evas_focus_get(const Ecore_Evas *ee); -/** - * @brief Iconify or uniconify an Ecore_Evas' window. - * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE to iconify, @c EINA_FALSE to uniconify. - * - * This function iconifies @p ee if @p on is @c EINA_TRUE, or uniconifies @p ee - * if @p on is @c EINA_FALSE. - * - * @note Iconify and minimize are synonyms. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_iconified_set(Ecore_Evas *ee, Eina_Bool on); -/** - * @brief Query whether an Ecore_Evas' window is iconified or not. - * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee is iconified, @c EINA_FALSE if not. - * - * @note Iconify and minimize are synonyms. - * - * @see ecore_evas_iconified_set() - */ -EAPI Eina_Bool ecore_evas_iconified_get(const Ecore_Evas *ee); -/** - * @brief Set whether an Ecore_Evas' window is borderless or not. - * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE for borderless, @c EINA_FALSE for bordered. - * - * This function makes @p ee borderless if @p on is @c EINA_TRUE, or bordered - * if @p on is @c EINA_FALSE. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_borderless_set(Ecore_Evas *ee, Eina_Bool on); -/** - * @brief Query whether an Ecore_Evas' window is borderless or not. - * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee is borderless, @c EINA_FALSE if not. - * - * @see ecore_evas_borderless_set() - */ -EAPI Eina_Bool ecore_evas_borderless_get(const Ecore_Evas *ee); -/** - * @brief Set whether or not an Ecore_Evas' window is fullscreen. - * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE fullscreen, @c EINA_FALSE not. - * - * This function causes @p ee to be fullscreen if @p on is @c EINA_TRUE, or - * not if @p on is @c EINA_FALSE. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on); -/** - * @brief Query whether an Ecore_Evas' window is fullscreen or not. - * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee is fullscreen, @c EINA_FALSE if not. - * - * @see ecore_evas_fullscreen_set() - */ -EAPI Eina_Bool ecore_evas_fullscreen_get(const Ecore_Evas *ee); -/** - * @brief Set another window that this window is a group member of - * - * @param ee The Ecore_Evas - * @param ee_group The other group member - * - * If @p ee_group is @c NULL, @p ee is removed from the group, otherwise it is - * added. Note that if you free the @p ee_group canvas before @p ee, then - * getting the group canvas with ecore_evas_window_group_get() will return - * an invalid handle. - * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 - */ -EAPI void ecore_evas_window_group_set(Ecore_Evas *ee, const Ecore_Evas *ee_group); -/** - * @brief Get the canvas group set. - * - * This returns the handle set by ecore_evas_window_group_set(). - * - * @param ee The Ecore_Evas to set - * @return The Canvas group handle - * - * @see ecore_evas_window_group_set() - * @since 1.2 - */ -EAPI const Ecore_Evas *ecore_evas_window_group_get(const Ecore_Evas *ee); -/** - * @brief Set the aspect ratio of a canvas window - * - * @param ee The Ecore_Evas - * @param aspect The aspect ratio (width divided by height), or 0 to disable - * - * This sets the desired aspect ratio of a canvas window - * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 - */ -EAPI void ecore_evas_aspect_set(Ecore_Evas *ee, double aspect); -/** - * @brief Get the aspect ratio of a canvas window - * - * This returns the value set by ecore_evas_aspect_set(). - * - * @param ee The Ecore_Evas to set - * @return The aspect ratio - * - * @see ecore_evas_aspect_set() - * @since 1.2 - */ -EAPI double ecore_evas_aspect_get(const Ecore_Evas *ee); -/** - * @brief Set The urgent hint flag - * - * @param ee The Ecore_Evas - * @param urgent The urgent state flag - * - * This sets the "urgent" state hint on a window so the desktop environment - * can highlight it somehow. - * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 - */ -EAPI void ecore_evas_urgent_set(Ecore_Evas *ee, Eina_Bool urgent); -/** - * @brief Get the urgent state on the cavas window - * - * This returns the value set by ecore_evas_urgent_set() - * - * @param ee The Ecore_Evas to set - * @return The urgent state set - * - * @see ecore_evas_urgent_set() - * @since 1.2 - */ -EAPI Eina_Bool ecore_evas_urgent_get(const Ecore_Evas *ee); -/** - * @brief Set the modal state flag on the canvas window - * - * @param ee The Ecore_Evas - * @param modal The modal hint flag - * - * This hints if the window should be modal (eg if it is also transient - * for another window, the other window will maybe be denied focus by - * the desktop window manager). - * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 - */ -EAPI void ecore_evas_modal_set(Ecore_Evas *ee, Eina_Bool modal); -/** - * @brief Get The modal flag - * - * This returns the value set by ecore_evas_modal_set(). - * - * @param ee The Ecore_Evas to set - * @return The modal flag - * - * @see ecore_evas_modal_set() - * @since 1.2 - */ -EAPI Eina_Bool ecore_evas_modal_get(const Ecore_Evas *ee); -/** - * @brief Set the "i demand attention" flag on a canvas window - * - * @param ee The Ecore_Evas - * @param demand The flag state to set - * - * A window may demand attention now (eg you must enter a password before - * continuing), and so it may flag a window with this. - * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 - */ -EAPI void ecore_evas_demand_attention_set(Ecore_Evas *ee, Eina_Bool demand); -/** - * @brief Get the "i demand attention" flag - * - * This returns the value set by ecore_evas_demand_attention_set(). - * - * @param ee The Ecore_Evas to set - * @return The "i demand attention" flag. - * - * @see ecore_evas_demand_attention_set() - * @since 1.2 - */ -EAPI Eina_Bool ecore_evas_demand_attention_get(const Ecore_Evas *ee); -/** - * @brief Set the "focus skip" flag - * - * @param ee The Ecore_Evas - * @param skip The "focus skip" state to set. - * - * A window may not want to accept focus, be in the taskbar, pager etc. - * sometimes (example for a small notification window that hovers around - * a taskbar or panel, or hovers around a window until some activity - * dismisses it). - * - * @warning Support for this depends on the underlying windowing system. - * @since 1.2 - */ -EAPI void ecore_evas_focus_skip_set(Ecore_Evas *ee, Eina_Bool skip); -/** - * @brief Get the "focus skip" flag - * - * This returns the value set by ecore_evas_focus_skip_set(). - * - * @param ee The Ecore_Evas to set - * @return The "focus skip" flag. - * - * @see ecore_evas_focus_skip_set() - * @since 1.2 - */ -EAPI Eina_Bool ecore_evas_focus_skip_get(const Ecore_Evas *ee); - -/** - * @brief Set if this evas should ignore @b all events. - * - * @param ee The Ecore_Evas whose window's to ignore events. - * @param ignore The Ecore_Evas new ignore state. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_ignore_events_set(Ecore_Evas *ee, Eina_Bool ignore); -/** - * @brief 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. - * - * @see ecore_evas_ignore_events_set() - */ -EAPI Eina_Bool ecore_evas_ignore_events_get(const Ecore_Evas *ee); -/** - * @brief 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. - * - * @see ecore_evas_show() - * @see ecore_evas_hide() - */ -EAPI int ecore_evas_visibility_get(const Ecore_Evas *ee); -/** - * @brief 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. - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_lower() - * @see ecore_evas_raise() - */ -EAPI void ecore_evas_layer_set(Ecore_Evas *ee, int layer); -/** - * @brief Get the layer of an Ecore_Evas' window. - * - * @param ee The Ecore_Evas to set - * @return the layer @p ee's window is on. - * - * @see ecore_evas_layer_set() - * @see ecore_evas_lower() - * @see ecore_evas_raise() - */ -EAPI int ecore_evas_layer_get(const Ecore_Evas *ee); -/** - * @brief Maximize (or unmaximize) an Ecore_Evas' window. - * - * @param ee The Ecore_Evas - * @param on @c EINA_TRUE to maximize, @c EINA_FALSE to unmaximize. - * - * This function maximizes @p ee if @p on is @c EINA_TRUE, or unmaximizes @p ee - * if @p on is @c EINA_FALSE. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_maximized_set(Ecore_Evas *ee, Eina_Bool on); -/** - * @brief Query whether an Ecore_Evas' window is maximized or not. - * - * @param ee The Ecore_Evas to set - * @return @c EINA_TRUE if @p ee is maximized, @c EINA_FALSE if not. - * - * @see ecore_evas_maximized_set() - */ -EAPI Eina_Bool ecore_evas_maximized_get(const Ecore_Evas *ee); -/** - * @brief 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) - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_new() - * @see ecore_evas_resize() - * @see ecore_evas_move_resize() - */ -EAPI void ecore_evas_move(Ecore_Evas *ee, int x, int y); -/** - * @brief 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. - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_new() - * @see ecore_evas_move() - * @see ecore_evas_move_resize() - */ -EAPI void ecore_evas_resize(Ecore_Evas *ee, int w, int h); -/** - * @brief Move and resize an Ecore_Evas - * - * @param ee The Ecore_Evas to move and resize - * @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. - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_new() - * @see ecore_evas_move() - * @see ecore_evas_resize() - */ -EAPI void ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); -/** - * @brief 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. - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_rotation_with_resize_set() - */ -EAPI void ecore_evas_rotation_set(Ecore_Evas *ee, int rot); -/** - * @brief Set the rotation of an Ecore_Evas' window - * - * @param ee The Ecore_Evas - * @param rot the angle (in degrees) of rotation. - * - * Like ecore_evas_rotation_set(), but it also resizes the window's contents so - * that they fit inside the current window geometry. - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_rotation_set() - */ -EAPI void ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot); -/** - * @brief Get the rotation of an Ecore_Evas' window - * - * @param ee The Ecore_Evas - * @return the angle (in degrees) of rotation. - * - * @see ecore_evas_rotation_set() - * @see ecore_evas_rotation_with_resize_set() - */ -EAPI int ecore_evas_rotation_get(const Ecore_Evas *ee); -/** - * @brief Raise an Ecore_Evas' window. - * - * @param ee The Ecore_Evas to raise. - * - * This functions raises the Ecore_Evas to the front. - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_lower() - * @see ecore_evas_layer_set() - */ -EAPI void ecore_evas_raise(Ecore_Evas *ee); -/** - * @brief Lower an Ecore_Evas' window. - * - * @param ee The Ecore_Evas to raise. - * - * This functions lowers the Ecore_Evas to the back. - * - * @warning Support for this depends on the underlying windowing system. - * - * @see ecore_evas_raise() - * @see ecore_evas_layer_set() - */ -EAPI void ecore_evas_lower(Ecore_Evas *ee); -/** - * @brief 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. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_title_set(Ecore_Evas *ee, const char *t); -/** - * @brief 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. - * - * @see ecore_evas_title_set() - */ -EAPI const char *ecore_evas_title_get(const Ecore_Evas *ee); -/** - * @brief 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. The - * meaning of @p name and @p class depends on the underlying windowing system. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI void ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c); -/** - * @brief Get the name and class of an Ecore_Evas' window - * - * This function gets the name of @p ee into @p n, and its class into - * @p c. - * - * @param ee The Ecore_Evas to query. - * @param n A pointer to a string to place the name in. - * @param c A pointer to a string to place the class in. - * @see ecore_evas_name_class_set() - */ -EAPI void ecore_evas_name_class_get(const Ecore_Evas *ee, const char **n, const char **c); -/** - * @brief Returns a pointer to the underlying window. - * - * @param ee The Ecore_Evas whose window is desired. - * @return A pointer to the underlying window. - * - * @warning Support for this depends on the underlying windowing system. - */ -EAPI Ecore_Window ecore_evas_window_get(const Ecore_Evas *ee); - - -/* 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, Eina_Bool on); -EAPI Eina_Bool 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_VSYNC 2 -#define ECORE_EVAS_GL_X11_OPT_SWAP_MODE 3 -#define ECORE_EVAS_GL_X11_OPT_LAST 4 - -#define ECORE_EVAS_GL_X11_SWAP_MODE_AUTO 0 -#define ECORE_EVAS_GL_X11_SWAP_MODE_FULL 1 -#define ECORE_EVAS_GL_X11_SWAP_MODE_COPY 2 -#define ECORE_EVAS_GL_X11_SWAP_MODE_DOUBLE 3 -#define ECORE_EVAS_GL_X11_SWAP_MODE_TRIPLE 4 - -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, Eina_Bool on); -EAPI Eina_Bool 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, Eina_Bool on); -EAPI Eina_Bool 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_8_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_8_window_get(const Ecore_Evas *ee); -EAPI Ecore_X_Window ecore_evas_software_x11_8_subwindow_get(const Ecore_Evas *ee); -EAPI void ecore_evas_software_x11_8_direct_resize_set(Ecore_Evas *ee, Eina_Bool on); -EAPI Eina_Bool ecore_evas_software_x11_8_direct_resize_get(const Ecore_Evas *ee); -EAPI void ecore_evas_software_x11_8_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, Eina_Bool on); -EAPI Eina_Bool 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_wayland_shm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame); -EAPI Ecore_Evas *ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame); -EAPI void ecore_evas_wayland_resize(Ecore_Evas *ee, int location); -EAPI void ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y); - -EAPI void ecore_evas_wayland_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y); -EAPI void ecore_evas_wayland_type_set(Ecore_Evas *ee, int type); -EAPI Ecore_Wl_Window *ecore_evas_wayland_window_get(const Ecore_Evas *ee); - -/** - * @brief Create a new @c Ecore_Evas canvas bound to the Evas - * @b buffer engine - * - * @param w The width of the canvas, in pixels - * @param h The height of the canvas, in pixels - * @return A new @c Ecore_Evas instance or @c NULL, on failure - * - * This creates a new buffer canvas wrapper, with image data array - * @b bound to the ARGB format, 8 bits per pixel. - * - * This function will allocate the needed pixels array with canonical - * @c malloc(). If you wish a custom function to allocate it, consider - * using ecore_evas_buffer_allocfunc_new(), instead. - * - * @note This function actually is a wrapper on - * ecore_evas_buffer_allocfunc_new(), using the same @a w and @a h - * arguments and canonical @c malloc() and @c free() to the memory - * allocation and freeing functions. See that function's documentation - * for more details. - */ -EAPI Ecore_Evas *ecore_evas_buffer_new(int w, int h); - -/** - * @brief Create a new @c Ecore_Evas canvas bound to the Evas - * @b buffer engine, giving custom allocation and freeing functions for - * the canvas memory region - * - * @param w The width of the canvas, in canvas units - * @param h The height of the canvas, in canvas units - * @param alloc_func Function to be called to allocate the memory - * needed for the new buffer canvas. @a data will be passed the same - * value as the @p data of this function, while @a size will be passed - * @p w times @p h times @c sizeof(int). - * @param free_func Function to be called to free the memory used by - * the new buffer canvas. @a data will be passed the same value as the - * @p data of this function, while @a pix will be passed the canvas - * memory pointer. - * @param data Custom data to be passed to the allocation and freeing - * functions - * @return A new @c Ecore_Evas instance or @c NULL, on failure - * - * This creates a new buffer canvas wrapper, with image data array - * @b bound to the ARGB format, 8 bits per pixel. - * - * This function is useful when one wants an @c Ecore_Evas buffer - * canvas with a custom allocation function, like one getting memory - * chunks from a memory pool, for example. - * - * On any resizing of this @c Ecore_Evas buffer canvas, its image data - * will be @b freed, to be allocated again with the new size. - * - * @note @p w and @p h sizes have to greater or equal to 1. Otherwise, - * they'll be interpreted as 1, exactly. - * - * @see ecore_evas_buffer_new() - */ -EAPI Ecore_Evas *ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data); - -/** - * @brief Grab a pointer to the actual pixels array of a given - * @c Ecore_Evas @b buffer canvas/window. - * - * @param ee An @c Ecore_Evas handle - * @return A pointer to the internal pixels array of @p ee - * - * Besides returning a pointer to the actual pixel array of the given - * canvas, this call will force a rendering update on @p ee, - * first. - * - * A common use case for this call is to create an image object, from - * @b another canvas, to have as data @p ee's contents, thus - * snapshoting the canvas. For that case, one can also use the - * ecore_evas_object_image_new() helper function. - */ -EAPI const void *ecore_evas_buffer_pixels_get(Ecore_Evas *ee); - -/** - * @brief Create a new @c Ecore_Evas canvas bound to the Evas - * @b ews (Ecore + Evas Single Process Windowing System) engine - * - * EWS is a simple single process windowing system. The backing store - * is also an @c Ecore_Evas that can be setup with - * ecore_evas_ews_setup() and retrieved with - * ecore_evas_ews_ecore_evas_get(). It will allow window management - * using events prefixed with @c ECORE_EVAS_EVENT_EWS_. - * - * The EWS windows (returned by this function or - * ecore_evas_new("ews"...)) will all be software buffer windows - * automatic rendered to the backing store. - * - * @param x horizontal position of window, in pixels - * @param y vertical position of window, in pixels - * @param w The width of the canvas, in pixels - * @param h The height of the canvas, in pixels - * @return A new @c Ecore_Evas instance or @c NULL, on failure - * - * @see ecore_evas_ews_setup() - * @see ecore_evas_ews_ecore_evas_get() - * - * @since 1.1 - */ -EAPI Ecore_Evas *ecore_evas_ews_new(int x, int y, int w, int h); - - -/** - * Returns the backing store image object that represents the given - * window in EWS. - * @return The evas object of EWS backing store. - * - * @note This should not be modified anyhow, but may be helpful to - * determine stacking and geometry of it for window managers - * that decorate windows. - * - * @param ee The Ecore_Evas from which to get the backing store. - * @see ecore_evas_ews_manager_set() - * @see ecore_evas_ews_evas_get() - * @since 1.1 - */ -EAPI Evas_Object *ecore_evas_ews_backing_store_get(const Ecore_Evas *ee); - -/** - * Calls the window to be deleted (freed), but can let user decide to - * forbid it by using ecore_evas_callback_delete_request_set() - * - * @param ee The Ecore_Evas for which window will be deleted. - * @since 1.1 - */ -EAPI void ecore_evas_ews_delete_request(Ecore_Evas *ee); - -/** - * @brief Create an Evas image object with image data bound to an - * own, internal @c Ecore_Evas canvas wrapper - * - * @param ee_target @c Ecore_Evas to have the canvas receiving the new - * image object - * @return A handle to the new image object - * - * This will create a @b special Evas image object. The image's pixel - * array will get bound to the same image data array of an @b internal - * @b buffer @c Ecore_Evas canvas. The user of this function is, then, - * supposed to grab that @c Ecore_Evas handle, with - * ecore_evas_object_ecore_evas_get(), and use its canvas to render - * whichever contents he/she wants, @b independently of the contents - * of the canvas owned by @p ee_target. Those contents will reflect on - * the canvas of @p ee, though, being exactly the image data of the - * object returned by this function. - * - * This is a helper function for the scenario of one wanting to grab a - * buffer canvas' contents (with ecore_evas_buffer_pixels_get()) to be - * used on another canvas, for whichever reason. The most common goal - * of this setup is to @b save an image file with a whole canvas as - * contents, which could not be achieved by using an image file within - * the target canvas. - * - * @warning Always resize the returned image and its underlying - * @c Ecore_Evas handle accordingly. They must be kept with same sizes - * for things to work as expected. Also, you @b must issue - * @c evas_object_image_size_set() on the image with that same size. If - * the image is to be shown in a canvas bound to an engine different - * than the buffer one, then you must also set this image's @b fill - * properties accordingly. - * - * @note The image returned will always be bound to the - * @c EVAS_COLORSPACE_ARGB8888 colorspace, always. - * - * @note Use ecore_evas_object_evas_get() to grab the image's internal - * own canvas directly. - * - * @note If snapshoting this image's internal canvas, remember to - * flush its internal @c Ecore_Evas firstly, with - * ecore_evas_manual_render(). - */ -EAPI Evas_Object *ecore_evas_object_image_new(Ecore_Evas *ee_target); - -/** - * @brief Retrieve the internal @c Ecore_Evas handle of an image - * object created via ecore_evas_object_image_new() - * - * @param obj A handle to an image object created via - * ecore_evas_object_image_new() - * @return The underlying @c Ecore_Evas handle in @p obj - */ -EAPI Ecore_Evas *ecore_evas_object_ecore_evas_get(Evas_Object *obj); - -/** - * @brief Retrieve the canvas bound to the internal @c Ecore_Evas - * handle of an image object created via ecore_evas_object_image_new() - * - * @param obj A handle to an image object created via - * ecore_evas_object_image_new() - * @return A handle to @p obj's underlying @c Ecore_Evas's canvas - */ -EAPI Evas *ecore_evas_object_evas_get(Evas_Object *obj); - -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(Ecore_Cocoa_Window *parent, - int x, - int y, - int w, - int h); - -EAPI Ecore_Evas *ecore_evas_psl1ght_new(const char* name, int w, int h); - - -/* generic manipulation calls */ -/** - * @brief Get the engine name used by this Ecore_Evas(window). - * - * @param ee Ecore_Evas whose engine's name is desired. - * @return A string that can(usually) be used in ecore_evas_new() - * - * @see ecore_evas_free() - */ -EAPI const char *ecore_evas_engine_name_get(const Ecore_Evas *ee); -/** - * @brief 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, or @c NULL if not held by one. - * - * @warning Only use on Evas' created with ecore evas! - */ -EAPI Ecore_Evas *ecore_evas_ecore_evas_get(const Evas *e); -/** - * @brief 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); -/** - * @brief 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 @c 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); -/** - * @brief 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_callback_pre_free_set() - * @see ecore_evas_free() - * @see ecore_evas_data_get() - */ -EAPI void ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data); -/** - * 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_show_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_hide_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_sticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_unsticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); -/** - * Set a callback for Ecore_Evas 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_pre_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_post_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. - * - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_pre_free_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); -/** - * Set a callback for Ecore_Evas state changes. - * @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 changes state. - * - * @since 1.2 - * @warning If and when this function is called depends on the underlying - * windowing system. - */ -EAPI void ecore_evas_callback_state_change_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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); - -/** - * 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); - -/** - * Set whether an Ecore_Evas is shaped or not. - * - * @param ee The Ecore_Evas to shape. - * @param shaped @c EINA_TRUE to shape, @c EINA_FALSE to not. - * - * This function allows one to make an Ecore_Evas shaped to the contents of the - * evas. If @p shaped is @c EINA_TRUE, @p ee will be transparent in parts of - * the evas that contain no objects. If @p shaped is @c EINA_FALSE, then @p ee - * will be rectangular, and parts with no data will show random framebuffer - * artifacting. For non-shaped Ecore_Evases, it is recommended to cover the - * entire evas with a background object. - */ -EAPI void ecore_evas_shaped_set(Ecore_Evas *ee, Eina_Bool shaped); - -/** - * Query whether an Ecore_Evas is shaped or not. - * - * @param ee The Ecore_Evas to query. - * @return @c EINA_TRUE if shaped, @c EINA_FALSE if not. - * - * This function returns @c EINA_TRUE if @p ee is shaped, and @c EINA_FALSE if not. - */ -EAPI Eina_Bool ecore_evas_shaped_get(const Ecore_Evas *ee); -/** - * @brief 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); -/** - * @brief Hide an Ecore_Evas' window - * - * @param ee The Ecore_Evas to hide. - * - * This function makes @p ee hidden(not visible). - */ -EAPI void ecore_evas_hide(Ecore_Evas *ee); - -/** - * 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); - - -/** - * Set the minimum size of a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas window's handle - * @param w The minimum width - * @param h The minimum height - * - * This function sets the minimum size of @p ee to be @p w x @p h. - * One won't be able to resize that window to dimensions smaller than - * the ones set. - * - * @note When base sizes are set, via ecore_evas_size_base_set(), - * they'll be used to calculate a window's minimum size, instead of - * those set by this function. - * - * @see ecore_evas_size_min_get() - */ -EAPI void ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h); - -/** - * Get the minimum size set for a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas window's handle - * @param w A pointer to an int to place the minimum width in. - * @param h A pointer to an int to place the minimum height in. - * - * @note Use @c NULL pointers on the size components you're not - * interested in: they'll be ignored by the function. - * - * @see ecore_evas_size_min_set() for more details - */ -EAPI void ecore_evas_size_min_get(const Ecore_Evas *ee, int *w, int *h); - -/** - * Set the maximum size of a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas window's handle - * @param w The maximum width - * @param h The maximum height - * - * This function sets the maximum size of @p ee to be @p w x @p h. - * One won't be able to resize that window to dimensions bigger than - * the ones set. - * - * @see ecore_evas_size_max_get() - */ -EAPI void ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h); - -/** - * Get the maximum size set for a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas window's handle - * @param w A pointer to an int to place the maximum width in. - * @param h A pointer to an int to place the maximum height in. - * - * @note Use @c NULL pointers on the size components you're not - * interested in: they'll be ignored by the function. - * - * @see ecore_evas_size_max_set() for more details - */ -EAPI void ecore_evas_size_max_get(const Ecore_Evas *ee, int *w, int *h); - -/** - * Set the base size for a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas window's handle - * @param w The base width - * @param h The base height - * - * This function sets the @b base size of @p ee to be @p w x @p h. - * When base sizes are set, they'll be used to calculate a window's - * @b minimum size, instead of those set by ecore_evas_size_min_get(). - * - * @see ecore_evas_size_base_get() - */ -EAPI void ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h); - -/** - * Get the base size set for a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas window's handle - * @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. - * - * @note Use @c NULL pointers on the size components you're not - * interested in: they'll be ignored by the function. - * - * @see ecore_evas_size_base_set() for more details - */ -EAPI void ecore_evas_size_base_get(const Ecore_Evas *ee, int *w, int *h); - -/** - * Set the "size step" for a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas window's handle - * @param w The step width - * @param h The step height - * - * This function sets the size steps of @p ee to be @p w x @p h. This - * limits the size of this @c Ecore_Evas window to be @b always an - * integer multiple of the step size, for each axis. - */ -EAPI void ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h); - -/** - * Get the "size step" set for a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas window's handle - * @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. - * - * @note Use @c NULL pointers on the size components you're not - * interested in: they'll be ignored by the function. - * - * @see ecore_evas_size_base_set() for more details - */ -EAPI void ecore_evas_size_step_get(const Ecore_Evas *ee, int *w, int *h); - -/** - * @brief 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 The layer in which the cursor will appear. - * @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. - * - * @note This function creates an object from the image and uses - * ecore_evas_object_cursor_set(). - * - * @see ecore_evas_object_cursor_set() - */ -EAPI void ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y); -/** - * @brief 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. - * - * @see ecore_evas_cursor_set() - * @see ecore_evas_object_cursor_set() - */ -EAPI void ecore_evas_cursor_get(const Ecore_Evas *ee, Evas_Object **obj, int *layer, int *hot_x, int *hot_y); -/** - * @brief Set the cursor of an Ecore_Evas - * - * @param ee The Ecore_Evas - * - * @param obj The Evas_Object which will be the cursor. - * @param layer The layer in which the cursor will appear. - * @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 object specified by - * @p obj. The actual point within the object 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 object. - * - * @see ecore_evas_cursor_set() - */ -EAPI void ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y); - -/** - * Tell the WM whether or not to ignore an Ecore_Evas' window - * - * @param ee The Ecore_Evas. - * @param on @c EINA_TRUE to ignore, @c EINA_FALSE to not. - * - * This function causes the window manager to ignore @p ee if @p on is - * @c EINA_TRUE, or not ignore @p ee if @p on is @c EINA_FALSE. - */ -EAPI void ecore_evas_override_set(Ecore_Evas *ee, Eina_Bool on); - -/** - * Query whether an Ecore_Evas' window is overridden or not - * - * @param ee The Ecore_Evas to set. - * @return @c EINA_TRUE if @p ee is overridden, @c EINA_FALSE if not. - */ -EAPI Eina_Bool ecore_evas_override_get(const Ecore_Evas *ee); - -/** - * Set whether or not an Ecore_Evas' window should avoid damage - * - * @param ee The Ecore_Evas - * @param on The type of the damage management - * - * This option causes updates of the Ecore_Evas to be done on a pixmap, and - * then copied to the window, or the pixmap used directly on the window, - * depending on the setting. Possible options are: - * - * @li @ref ECORE_EVAS_AVOID_DAMAGE_NONE - every expose event triggers a new - * damage and consequently render of the affected area. The rendering of things - * happens directly on the window; - * - * @li @ref ECORE_EVAS_AVOID_DAMAGE_EXPOSE - there's a pixmap where everything - * is rendered into, and then copied to the window. On expose events, there's - * no need to render things again, just to copy the exposed region to the - * window; - * - * @li @ref ECORE_EVAS_AVOID_DAMAGE_BUILT_IN - there's the same pixmap as the - * previous one, but it is set as a "background pixmap" of the window. The - * rendered things appear directly on the window, with no need to copy - * anything, but would stay stored on the pixmap, so there's no need to render - * things again on expose events. This option can be faster than the previous - * one, but may lead to artifacts during resize of the window. - */ -EAPI void ecore_evas_avoid_damage_set(Ecore_Evas *ee, Ecore_Evas_Avoid_Damage_Type on); - -/** - * Query whether an Ecore_Evas' window avoids damage or not - * @param ee The Ecore_Evas to set - * @return The type of the damage management - * - */ -EAPI Ecore_Evas_Avoid_Damage_Type ecore_evas_avoid_damage_get(const Ecore_Evas *ee); - -/** - * 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, Eina_Bool withdrawn); - -/** - * 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 Eina_Bool ecore_evas_withdrawn_get(const Ecore_Evas *ee); - -/** - * 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, Eina_Bool sticky); - -/** - * 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 Eina_Bool ecore_evas_sticky_get(const Ecore_Evas *ee); -EAPI void ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool manual_render); -EAPI Eina_Bool ecore_evas_manual_render_get(const Ecore_Evas *ee); - -/** - * @brief Registers an @c Ecore_Evas to receive events through ecore_input_evas. - * - * @param ee The @c Ecore_Evas handle. - * - * This function calls ecore_event_window_register() with the @p ee as its @c - * id argument, @c window argument, and uses its @c Evas too. It is useful when - * no @c window information is available on a given @c Ecore_Evas backend. - * - * @see ecore_evas_input_event_unregister() - * @since 1.1 - */ -EAPI void ecore_evas_input_event_register(Ecore_Evas *ee); -/** - * @brief Unregisters an @c Ecore_Evas receiving events through ecore_input_evas. - * - * @param ee The @c Ecore_Evas handle. - * - * @see ecore_evas_input_event_register() - * @since 1.1 - */ -EAPI void ecore_evas_input_event_unregister(Ecore_Evas *ee); - -/** - * @brief Force immediate rendering on a given @c Ecore_Evas window - * - * @param ee An @c Ecore_Evas handle - * - * Use this call to forcefully flush the @p ee's canvas rendering - * pipeline, thus bring its window to an up to date state. - */ -EAPI void ecore_evas_manual_render(Ecore_Evas *ee); -EAPI void ecore_evas_comp_sync_set(Ecore_Evas *ee, Eina_Bool do_sync); -EAPI Eina_Bool ecore_evas_comp_sync_get(const Ecore_Evas *ee); - -/** - * @brief Get geometry of screen associated with this Ecore_Evas. - * - * @param ee The Ecore_Evas whose window's to query container screen geometry. - * @param x where to return the horizontal offset value. May be @c NULL. - * @param y where to return the vertical offset value. May be @c NULL. - * @param w where to return the width value. May be @c NULL. - * @param h where to return the height value. May be @c NULL. - * - * @since 1.1 - */ -EAPI void ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); - -/** - * @brief Get the dpi of the screen the Ecore_Evas is primarily on. - * - * @param ee The Ecore_Evas whose window's to query. - * @param xdpi Pointer to integer to store horizontal DPI. May be @c NULL. - * @param ydpi Pointer to integer to store vertical DPI. May be @c NULL. - * - * @since 1.7 - */ -EAPI void ecore_evas_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi); - -EAPI void ecore_evas_draw_frame_set(Ecore_Evas *ee, Eina_Bool draw_frame); -EAPI Eina_Bool ecore_evas_draw_frame_get(const Ecore_Evas *ee); - -/** - * @brief Associate the given object to this ecore evas. - * - * @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 @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * 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: - * @li ECORE_EVAS_OBJECT_ASSOCIATE_BASE (or 0): to listen to basic events - * like delete, resize and move, but no stacking or layer are used. - * @li 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. - * @li 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(). - * @li 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. - */ -EAPI Eina_Bool ecore_evas_object_associate(Ecore_Evas *ee, Evas_Object *obj, Ecore_Evas_Object_Associate_Flags flags); -/** - * @brief 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 @c EINA_TRUE on success, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool ecore_evas_object_dissociate(Ecore_Evas *ee, Evas_Object *obj); -/** - * @brief Get the object associated with @p ee - * - * @param ee The Ecore_Evas to get the object from. - * @return The associated object, or @c NULL if there is no associated object. - */ -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); - -/** - * @brief Get a list of all the ecore_evases. - * - * @return A list of ecore_evases. - * - * The returned list of ecore evases is only valid until the canvases are - * destroyed (and should not be cached for instance). The list can be freed by - * just deleting the list. - */ -EAPI Eina_List *ecore_evas_ecore_evas_list_get(void); - -/* specific calls to an x11 environment ecore_evas */ -EAPI void ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win); -EAPI Ecore_X_Window ecore_evas_x11_leader_get(Ecore_Evas *ee); -EAPI void ecore_evas_x11_leader_default_set(Ecore_Evas *ee); -EAPI void ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h); -EAPI void ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas *ee, int x, int y, int w, int h); -EAPI void ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas *ee, int x, int y, int w, int h); -EAPI void ecore_evas_x11_shape_input_empty(Ecore_Evas *ee); -EAPI void ecore_evas_x11_shape_input_reset(Ecore_Evas *ee); -EAPI void ecore_evas_x11_shape_input_apply(Ecore_Evas *ee); - -/** - * @defgroup Ecore_Evas_Ews Ecore_Evas Single Process Windowing System. - * - * These are global scope functions to manage the EWS to be used by - * ecore_evas_ews_new(). - * - * @since 1.1 - * @{ - */ - -/** - * Sets the engine to be used by the backing store engine. - * - * @param engine The engine to be set. - * @param options The options of the engine to be set. - * @return @c EINA_TRUE on success, @c EINA_FALSE if ews is already in use. - * @since 1.1 - */ -EAPI Eina_Bool ecore_evas_ews_engine_set(const char *engine, const char *options); - -/** - * Reconfigure the backing store used. - * - * @param x The X coordinate to be used. - * @param y The Y coordinate to be used. - * @param w The width of the Ecore_Evas to setup. - * @param h The height of the Ecore_Evas to setup. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * @since 1.1 - */ -EAPI Eina_Bool ecore_evas_ews_setup(int x, int y, int w, int h); - -/** - * Return the internal backing store in use. - * - * @return The internal backing store in use. - * @note this will forced it to be created, making future calls to - * ecore_evas_ews_engine_set() void. - * - * @see ecore_evas_ews_evas_get() - * @since 1.1 - */ -EAPI Ecore_Evas *ecore_evas_ews_ecore_evas_get(void); - -/** - * Return the internal backing store in use. - * - * @return The internal backing store in use. - * @note this will forced it to be created, making future calls to - * ecore_evas_ews_engine_set() void. - * - * @see ecore_evas_ews_ecore_evas_get() - * @since 1.1 - */ -EAPI Evas *ecore_evas_ews_evas_get(void); - -/** - * Get the current background. - */ -EAPI Evas_Object *ecore_evas_ews_background_get(void); - -/** - * Set the current background, must be created at evas ecore_evas_ews_evas_get() - * - * It will be kept at lowest layer (EVAS_LAYER_MIN) and below - * everything else. You can set any object, default is a black - * rectangle. - * - * @note previous object will be deleted! - * @param o The Evas_Object for which to set the background. - */ -EAPI void ecore_evas_ews_background_set(Evas_Object *o); - -/** - * Return all Ecore_Evas* created by EWS. - * - * @return An eina list of Ecore_evases. - e @note Do not change the returned list or its contents. - * @since 1.1 - */ -EAPI const Eina_List *ecore_evas_ews_children_get(void); - -/** - * Set the identifier of the manager taking care of internal windows. - * - * The ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE event is issued. Consider - * handling it to know if you should stop handling events yourself - * (ie: another manager took over) - * - * @param manager any unique identifier address. - * - * @see ecore_evas_ews_manager_get() - * @since 1.1 - */ -EAPI void ecore_evas_ews_manager_set(const void *manager); - -/** - * Get the identifier of the manager taking care of internal windows. - * - * @return the value set by ecore_evas_ews_manager_set() - * @since 1.1 - */ -EAPI const void *ecore_evas_ews_manager_get(void); - -EAPI extern int ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE; /**< manager was changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_ADD; /**< window was created @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_DEL; /**< window was deleted, pointer is already invalid but may be used as reference for further cleanup work. @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_RESIZE; /**< window was resized @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_MOVE; /**< window was moved @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_SHOW; /**< window become visible @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_HIDE; /**< window become hidden @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_FOCUS; /**< window was focused @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_UNFOCUS; /**< window lost focus @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_RAISE; /**< window was raised @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_LOWER; /**< window was lowered @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_ACTIVATE; /**< window was activated @since 1.1 */ - -EAPI extern int ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE; /**< window minimized/iconified changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE; /**< window maximized changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_LAYER_CHANGE; /**< window layer changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE; /**< window fullscreen changed @since 1.1 */ -EAPI extern int ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE; /**< some other window property changed (title, name, class, alpha, transparent, shaped...) @since 1.1 */ - -/** - * @} - */ - -/** - * @defgroup Ecore_Evas_Extn External plug/socket infrastructure to remote canvases - * - * These functions allow 1 process to create a "socket" was pluged into which another - * process can create a "plug" remotely to plug into. - * Socket can provides content for several plugs. - * This is best for small sized objects (about the size range - * of a small icon up to a few large icons). Sine the plug is actually an - * image object, you can fetch the pixel data - * - * @since 1.2 - * @{ - */ - -EAPI extern int ECORE_EVAS_EXTN_CLIENT_ADD; /**< this event is received when a plug has connected to an extn socket @since 1.2 */ -EAPI extern int ECORE_EVAS_EXTN_CLIENT_DEL; /**< this event is received when a plug has disconnected from an extn socket @since 1.2 */ - -/** - * @brief Create a new Ecore_Evas canvas for the new external ecore evas socket - * - * @param w The width of the canvas, in pixels - * @param h The height of the canvas, in pixels - * @return A new @c Ecore_Evas instance or @c NULL, on failure - * - * This creates a new extn_socket canvas wrapper, with image data array - * @b bound to the ARGB format, 8 bits per pixel. - * - * If creation is successful, an Ecore_Evas handle is returned or @c NULL if - * creation fails. Also focus, show, hide etc. callbacks will also be called - * if the plug object is shown, or already visible on connect, or if it is - * hidden later, focused or unfocused. - * - * This function has to be flowed by ecore_evas_extn_socket_listen(), - * for starting ecore ipc service. - * - * @code - * Eina_Bool res = EINA_FALSE; - * Ecore_Evas *ee = ecore_evas_extn_socket_new(1, 1); - * - * res = ecore_evas_extn_socket_listen("svcname", 1, EINA_FALSE); - * if (!res) return; - * ecore_evas_resize(ee, 240, 400); - * @endcode - * - * or - * - * @code - * Eina_Bool res = EINA_FALSE; - * Ecore_Evas *ee = ecore_evas_extn_socket_new(240, 400); - * - * res = ecore_evas_extn_socket_listen("svcname", 1, EINA_FALSE); - * if (!res) return; - * @endcode - * - * When a client(plug) connects, you will get the ECORE_EVAS_EXTN_CLIENT_ADD event - * in the ecore event queue, with event_info being the image object pointer - * passed as a void pointer. When a client disconnects you will get the - * ECORE_EVAS_EXTN_CLIENT_DEL event. - * - * You can set up event handles for these events as follows: - * - * @code - * static void client_add_cb(void *data, int event, void *event_info) - * { - * Evas_Object *obj = event_info; - * printf("client added to image object %p\n", obj); - * evas_object_show(obj); - * } - * - * static void client_del_cb(void *data, int event, void *event_info) - * { - * Evas_Object *obj = event_info; - * printf("client deleted from image object %p\n", obj); - * evas_object_hide(obj); - * } - * - * void setup(void) - * { - * ecore_event_handler_add(ECORE_EVAS_EXTN_CLIENT_ADD, - * client_add_cb, NULL); - * ecore_event_handler_add(ECORE_EVAS_EXTN_CLIENT_DEL, - * client_del_cb, NULL); - * } - * @endcode - * - * Note that events come in later after the event happened. You may want to be - * careful as data structures you had associated with the image object - * may have been freed after deleting, but the object may still be around - * awating cleanup and thus still be valid.You can change the size with something like: - * - * @see ecore_evas_extn_socket_listen() - * @see ecore_evas_extn_plug_new() - * @see ecore_evas_extn_plug_object_data_lock() - * @see ecore_evas_extn_plug_object_data_unlock() - * - * @since 1.2 - */ -EAPI Ecore_Evas *ecore_evas_extn_socket_new(int w, int h); - -/** - * @brief Create a socket to provide the service for external ecore evas - * socket. - * - * @param ee The Ecore_Evas. - * @param svcname The name of the service to be advertised. ensure that it is - * unique (when combined with @p svcnum) otherwise creation may fail. - * @param svcnum A number (any value, @c 0 being the common default) to - * differentiate multiple instances of services with the same name. - * @param svcsys A boolean that if true, specifies to create a system-wide - * service all users can connect to, otherwise the service is private to the - * user ide that created the service. - * @return @c EINA_TRUE if creation is successful, @c EINA_FALSE if it does - * not. - * - * This creates socket specified by @p svcname, @p svcnum and @p svcsys. If - * creation is successful, @c EINA_TRUE is returned or @c EINA_FALSE if - * creation fails. - * - * @see ecore_evas_extn_socket_new() - * @see ecore_evas_extn_plug_new() - * @see ecore_evas_extn_plug_object_data_lock() - * @see ecore_evas_extn_plug_object_data_unlock() - * - * @since 1.2 - */ -EAPI Eina_Bool ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys); - -/** - * @brief Lock the pixel data so the socket cannot change it - * - * @param obj The image object returned by ecore_evas_extn_plug_new() to lock - * - * You may need to get the image pixel data with evas_object_image_data_get() - * from the image object, but need to ensure that it does not change while - * you are using the data. This function lets you set an advisory lock on the - * image data so the external plug process will not render to it or alter it. - * - * You should only hold the lock for just as long as you need to read out the - * image data or otherwise deal with it, and then unlock it with - * ecore_evas_extn_plug_object_data_unlock(). Keeping a lock over more than - * 1 iteration of the main ecore loop will be problematic, so avoid it. Also - * forgetting to unlock may cause the socket process to freeze and thus create - * odd behavior. - * - * @see ecore_evas_extn_plug_new() - * @see ecore_evas_extn_plug_object_data_unlock() - * - * @since 1.2 - */ -EAPI void ecore_evas_extn_plug_object_data_lock(Evas_Object *obj); - -/** - * @brief Unlock the pixel data so the socket can change it again. - * - * @param obj The image object returned by ecore_evas_extn_plug_new() to unlock - * - * This unlocks after an advisor lock has been taken by - * ecore_evas_extn_plug_object_data_lock(). - * - * @see ecore_evas_extn_plug_new() - * @see ecore_evas_extn_plug_object_data_lock() - * - * @since 1.2 - */ -EAPI void ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj); - -/** - * @brief Create a new external ecore evas plug - * - * @param ee_target The Ecore_Evas containing the canvas in which the new image object will live. - * @return An evas image object that will contain the image output of a socket. - * - * This creates an image object that will contain the output of another - * processes socket canvas when it connects. All input will be sent back to - * this process as well, effectively swallowing or placing the socket process - * in the canvas of the plug process in place of the image object. The image - * object by default is created to be filled (equivalent of - * evas_object_image_filled_add() on creation) so image content will scale - * to fill the image unless otherwise reconfigured. The Ecore_Evas size - * of the plug is the master size and determines size in pixels of the - * plug canvas. You can change the size with something like: - * - * @code - * Eina_Bool res = EINA_FALSE; - * Evas_Object *obj = ecore_evas_extn_plug_new(ee); - * - * res = ecore_evas_extn_plug_connect("svcname", 1, EINA_FALSE); - * if (!res) return; - * ecore_evas_resize(ee, 240, 400); - * @endcode - * - * @see ecore_evas_extn_socket_new() - * @see ecore_evas_extn_plug_connect() - * @since 1.2 - */ -EAPI Evas_Object *ecore_evas_extn_plug_new(Ecore_Evas *ee_target); - -/** - * @brief Connect an external ecore evas plug to service provided by external - * ecore evas socket. - * - * @param obj The Ecore_Evas containing the canvas in which the new image - * object will live. - * @param svcname The service name to connect to set up by the socket. - * @param svcnum The service number to connect to (set up by socket). - * @param svcsys Boolean to set if the service is a system one or not (set up - * by socket). - * @return @c EINA_TRUE if creation is successful, @c EINA_FALSE if it does - * not. - * - * @see ecore_evas_extn_plug_new() - * - * @since 1.2 - */ -EAPI Eina_Bool ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys); - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas.c deleted file mode 100644 index 3d841e7db6..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas.c +++ /dev/null @@ -1,2781 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#ifndef _MSC_VER -# include -#endif - -#ifdef HAVE_SYS_MMAN_H -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" -#include "Ecore_Input.h" - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - -Eina_Bool _ecore_evas_app_comp_sync = 1; -int _ecore_evas_log_dom = -1; -static int _ecore_evas_init_count = 0; -static Ecore_Fd_Handler *_ecore_evas_async_events_fd = NULL; -static Eina_Bool _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 Eina_Bool -_ecore_evas_idle_enter(void *data EINA_UNUSED) -{ - Ecore_Evas *ee; - double t1 = 0.0; - double t2 = 0.0; - int rend = 0; - - if (!ecore_evases) return ECORE_CALLBACK_RENEW; - 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 ECORE_CALLBACK_RENEW; -} - -/** - * Query if a particular rendering engine target has support - * @param engine The engine to check support for - * @return 1 if the particular 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 EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_SOFTWARE_XLIB: -#ifdef BUILD_ECORE_EVAS_SOFTWARE_XLIB - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_XRENDER_X11: - return EINA_FALSE; - case ECORE_EVAS_ENGINE_OPENGL_X11: -#ifdef BUILD_ECORE_EVAS_OPENGL_X11 - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_SOFTWARE_XCB: -#ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_XRENDER_XCB: - return EINA_FALSE; - case ECORE_EVAS_ENGINE_SOFTWARE_GDI: -#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_SOFTWARE_DDRAW: -#ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_DIRECT3D: -#ifdef BUILD_ECORE_EVAS_DIRECT3D - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_OPENGL_GLEW: -#ifdef BUILD_ECORE_EVAS_OPENGL_GLEW - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_SOFTWARE_SDL: -#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_OPENGL_SDL: -#ifdef BUILD_ECORE_EVAS_OPENGL_SDL - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_DIRECTFB: -#ifdef BUILD_ECORE_EVAS_DIRECTFB - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_SOFTWARE_FB: -#ifdef BUILD_ECORE_EVAS_FB - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - - case ECORE_EVAS_ENGINE_SOFTWARE_8_X11: -#ifdef BUILD_ECORE_EVAS_SOFTWARE_8_X11 - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - - case ECORE_EVAS_ENGINE_SOFTWARE_16_X11: - return EINA_FALSE; - case ECORE_EVAS_ENGINE_SOFTWARE_16_DDRAW: - return EINA_FALSE; - case ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE: - return EINA_FALSE; - - case ECORE_EVAS_ENGINE_OPENGL_COCOA: -#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_EWS: -#ifdef BUILD_ECORE_EVAS_EWS - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_PSL1GHT: -#ifdef BUILD_ECORE_EVAS_PSL1GHT - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_WAYLAND_SHM: -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - case ECORE_EVAS_ENGINE_WAYLAND_EGL: -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL - return EINA_TRUE; -#else - return EINA_FALSE; -#endif - default: - return EINA_FALSE; - }; -} - -static void -_ecore_evas_fork_cb(void *data EINA_UNUSED) -{ - int fd; - - if (_ecore_evas_async_events_fd) - ecore_main_fd_handler_del(_ecore_evas_async_events_fd); - 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); -} - -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; - } - - ecore_fork_reset_callback_add(_ecore_evas_fork_cb, NULL); - 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(); - -#ifdef BUILD_ECORE_EVAS_EWS - _ecore_evas_ews_events_init(); -#endif - - _ecore_evas_extn_init(); - - if (getenv("ECORE_EVAS_COMP_NOSYNC")) - _ecore_evas_app_comp_sync = 0; - return _ecore_evas_init_count; - - shutdown_ecore: - ecore_shutdown(); - shutdown_evas: - evas_shutdown(); - - return --_ecore_evas_init_count; -} - -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); - - _ecore_evas_extn_shutdown(); - - 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_EWS - while (_ecore_evas_ews_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 - - if (_ecore_evas_async_events_fd) - ecore_main_fd_handler_del(_ecore_evas_async_events_fd); - - ecore_fork_reset_callback_del(_ecore_evas_fork_cb, NULL); - - eina_log_domain_unregister(_ecore_evas_log_dom); - _ecore_evas_log_dom = -1; - ecore_shutdown(); - evas_shutdown(); - - return _ecore_evas_init_count; -} - -EAPI void -ecore_evas_app_comp_sync_set(Eina_Bool do_sync) -{ - _ecore_evas_app_comp_sync = do_sync; -} - -EAPI Eina_Bool -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_OPENGL_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(NULL, x, y, w, h); - free(name); - - if (ee) ecore_evas_move(ee, x, y); - 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_8_X11 -static Ecore_Evas * -_ecore_evas_constructor_software_8_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_8_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 EINA_UNUSED, int y EINA_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, "noframe=", &noframe); - _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; -} -#endif - -#ifdef BUILD_ECORE_EVAS_OPENGL_SDL -static Ecore_Evas * -_ecore_evas_constructor_opengl_sdl(int x EINA_UNUSED, int y EINA_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 EINA_UNUSED, int y EINA_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_PSL1GHT -static Ecore_Evas * -_ecore_evas_constructor_psl1ght(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options) -{ - Ecore_Evas *ee; - char *name = NULL; - - _ecore_evas_parse_extra_options_str(extra_options, "name=", &name); - ee = ecore_evas_psl1ght_new(name, w, h); - free(name); - - if (ee) ecore_evas_move(ee, x, y); - return ee; -} -#endif - -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM -static Ecore_Evas * -_ecore_evas_constructor_wayland_shm(int x, int y, int w, int h, const char *extra_options) -{ - char *disp_name = NULL; - unsigned int frame = 1, parent = 0; - Ecore_Evas *ee; - - _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name); - _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame); - _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent); - ee = ecore_evas_wayland_shm_new(disp_name, parent, x, y, w, h, frame); - free(disp_name); - - return ee; -} -#endif - -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL -static Ecore_Evas * -_ecore_evas_constructor_wayland_egl(int x, int y, int w, int h, const char *extra_options) -{ - char *disp_name = NULL; - unsigned int frame = 1, parent = 0; - Ecore_Evas *ee; - - _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name); - _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame); - _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent); - ee = ecore_evas_wayland_egl_new(disp_name, parent, x, y, w, h, frame); - 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_BUFFER -static Ecore_Evas * -_ecore_evas_constructor_buffer(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options EINA_UNUSED) -{ - return ecore_evas_buffer_new(w, h); -} -#endif - -#ifdef BUILD_ECORE_EVAS_EWS -static Ecore_Evas * -_ecore_evas_constructor_ews(int x, int y, int w, int h, const char *extra_options EINA_UNUSED) -{ - return ecore_evas_ews_new(x, y, 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_OPENGL_X11 - {"opengl_x11", _ecore_evas_constructor_opengl_x11}, -#endif -#ifdef BUILD_ECORE_EVAS_SOFTWARE_8_X11 - {"software_8_x11", _ecore_evas_constructor_software_8_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 - - /* Apple */ -#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA - {"opengl_cocoa", _ecore_evas_constructor_cocoa}, -#endif - - /* PS3 support */ -#ifdef BUILD_ECORE_EVAS_PSL1GHT - {"psl1ght", _ecore_evas_constructor_psl1ght}, -#endif - - /* Wayland */ -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM - {"wayland_shm", _ecore_evas_constructor_wayland_shm}, -#endif - -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL - {"wayland_egl", _ecore_evas_constructor_wayland_egl}, -#endif - - /* Last chance to have a window */ -#ifdef BUILD_ECORE_EVAS_OPENGL_SDL - {"opengl_sdl", _ecore_evas_constructor_opengl_sdl}, -#endif - -#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL - {"sdl", _ecore_evas_constructor_sdl}, -#endif - - /* independent */ -#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER - {"buffer", _ecore_evas_constructor_buffer}, -#endif - -#ifdef BUILD_ECORE_EVAS_EWS - {"ews", _ecore_evas_constructor_ews}, -#endif - {NULL, NULL} -}; - -EAPI Eina_List * -ecore_evas_engines_get(void) -{ - const struct ecore_evas_engine *itr; - Eina_List *lst = NULL; - - for (itr = _engines; itr->name; itr++) - lst = eina_list_append(lst, itr->name); - - return lst; -} - -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; 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; -} - -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; 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; -} - -EAPI const char * -ecore_evas_engine_name_get(const Ecore_Evas *ee) -{ - if (!ee) - return NULL; - return ee->driver; -} - -EAPI Ecore_Evas * -ecore_evas_ecore_evas_get(const Evas *e) -{ - Ecore_Evas *ee = evas_data_attach_get(e); - if (!ee) return NULL; - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_ecore_evas_get"); - return NULL; - } - return ee; -} - -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; -} - -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); -} - -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;} - -EAPI void -ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_show_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_hide_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_sticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_unsticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_pre_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_post_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_pre_free_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - 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; -} - -EAPI void -ecore_evas_callback_state_change_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_callback_state_change_set"); - return; - } - ee->func.fn_state_change = func; -} - -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; -} - -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; -} - -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; -} - -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; - } -} - -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; - } -} - -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; - } -} - -EAPI void -ecore_evas_request_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_request_geometry_get"); - return; - } - if ((ee->rotation == 90) || (ee->rotation == 270)) - { - if (x) *x = ee->req.x; - if (y) *y = ee->req.y; - if (w) *w = ee->req.h; - if (h) *h = ee->req.w; - } - else - { - if (x) *x = ee->req.x; - if (y) *y = ee->req.y; - if (w) *w = ee->req.w; - if (h) *h = ee->req.h; - } -} - -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; -} - -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; -} - -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; -} - -EAPI void -ecore_evas_shaped_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->shaped ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_alpha_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->alpha ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_transparent_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->transparent ? EINA_TRUE : 0; -} - -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; -} - -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; -} - - 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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; - } -} - -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; - } -} - -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; - } -} - -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; - } -} - -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; - } -} - -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; - } -} - -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; - } -} - -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; - } -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -EAPI void -ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->prop.focused ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_iconified_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->prop.iconified ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_borderless_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->prop.borderless ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_override_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->prop.override ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_maximized_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->prop.maximized ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->prop.fullscreen ? EINA_TRUE : EINA_FALSE; -} - -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; -} - -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 ECORE_EVAS_AVOID_DAMAGE_NONE; - } - return ee->prop.avoid_damage; -} - -EAPI void -ecore_evas_withdrawn_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->prop.withdrawn ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_sticky_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->prop.sticky ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_window_group_set(Ecore_Evas *ee, const Ecore_Evas *ee_group) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return; - } - - IFC(ee, fn_window_group_set) (ee, ee_group); - IFE; -} - -EAPI const Ecore_Evas * -ecore_evas_window_group_get(const Ecore_Evas *ee) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return EINA_FALSE; - } - return ee->prop.group_ee; -} - -EAPI void -ecore_evas_aspect_set(Ecore_Evas *ee, double aspect) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return; - } - - IFC(ee, fn_aspect_set) (ee, aspect); - IFE; -} - -EAPI double -ecore_evas_aspect_get(const Ecore_Evas *ee) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return EINA_FALSE; - } - return ee->prop.aspect; -} - -EAPI void -ecore_evas_urgent_set(Ecore_Evas *ee, Eina_Bool urgent) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return; - } - - IFC(ee, fn_urgent_set) (ee, urgent); - IFE; -} - -EAPI Eina_Bool -ecore_evas_urgent_get(const Ecore_Evas *ee) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return EINA_FALSE; - } - return ee->prop.urgent ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_modal_set(Ecore_Evas *ee, Eina_Bool modal) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return; - } - - IFC(ee, fn_modal_set) (ee, modal); - IFE; -} - -EAPI Eina_Bool -ecore_evas_modal_get(const Ecore_Evas *ee) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return EINA_FALSE; - } - return ee->prop.modal ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_demand_attention_set(Ecore_Evas *ee, Eina_Bool demand) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return; - } - - IFC(ee, fn_demands_attention_set) (ee, demand); - IFE; -} - -EAPI Eina_Bool -ecore_evas_demand_attention_get(const Ecore_Evas *ee) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return EINA_FALSE; - } - return ee->prop.demand_attention ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_focus_skip_set(Ecore_Evas *ee, Eina_Bool skip) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return; - } - - IFC(ee, fn_focus_skip_set) (ee, skip); - IFE; -} - -EAPI Eina_Bool -ecore_evas_focus_skip_get(const Ecore_Evas *ee) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "XXX"); - return EINA_FALSE; - } - return ee->prop.focus_skip ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_ignore_events_set(Ecore_Evas *ee, Eina_Bool 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - return ee->ignore_events ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool 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 Eina_Bool -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 EINA_FALSE; - } - return ee->manual_render ? EINA_TRUE : EINA_FALSE; -} - -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, Eina_Bool 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 Eina_Bool -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 EINA_FALSE; - } - 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; -} - -EAPI void -ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h) -{ - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = 0; - if (h) *h = 0; - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_screen_geometry_get"); - return; - } - - IFC(ee, fn_screen_geometry_get) (ee, x, y, w, h); - IFE; -} - -EAPI void -ecore_evas_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi) -{ - if (xdpi) *xdpi = 0; - if (ydpi) *ydpi = 0; - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_screen_geometry_get"); - return; - } - - IFC(ee, fn_screen_dpi_get) (ee, xdpi, ydpi); - IFE; -} - -EAPI void -ecore_evas_draw_frame_set(Ecore_Evas *ee, Eina_Bool draw_frame) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_draw_frame_set"); - return; - } - ee->prop.draw_frame = draw_frame; -} - -EAPI Eina_Bool -ecore_evas_draw_frame_get(const Ecore_Evas *ee) -{ - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_draw_frame_get"); - return EINA_FALSE; - } - return ee->prop.draw_frame; -} - -/* 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]; - const char *tmp; - - _ecore_evas_fps_debug_init_count++; - if (_ecore_evas_fps_debug_init_count > 1) return; - -#ifndef HAVE_EVIL - tmp = "/tmp"; -#else - tmp = evil_tmpdir_get (); -#endif /* HAVE_EVIL */ - snprintf(buf, sizeof(buf), "%s/.ecore_evas_fps_debug-%i", tmp, (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 *buf2 = (char *)&zero; - ssize_t todo = sizeof(unsigned int); - - while (todo > 0) - { - ssize_t r = write(_ecore_evas_fps_debug_fd, buf2, todo); - if (r > 0) - { - todo -= r; - buf2 += 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_ref(Ecore_Evas *ee) -{ - ee->refcount++; -} - -void -_ecore_evas_unref(Ecore_Evas *ee) -{ - ee->refcount--; - if (ee->refcount == 0) - { - if (ee->deleted) _ecore_evas_free(ee); - } - else if (ee->refcount < -1) - ERR("Ecore_Evas %p->refcount=%d < 0", ee, ee->refcount); -} - -void -_ecore_evas_free(Ecore_Evas *ee) -{ - ee->deleted = EINA_TRUE; - if (ee->refcount > 0) return; - - if (ee->func.fn_pre_free) ee->func.fn_pre_free(ee); - while (ee->sub_ecore_evas) - { - _ecore_evas_free(ee->sub_ecore_evas->data); - } - if (ee->data) eina_hash_free(ee->data); - ee->data = NULL; - if (ee->name) free(ee->name); - ee->name = NULL; - if (ee->prop.title) free(ee->prop.title); - ee->prop.title = NULL; - if (ee->prop.name) free(ee->prop.name); - ee->prop.name = NULL; - if (ee->prop.clas) free(ee->prop.clas); - ee->prop.clas = NULL; - if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); - ee->prop.cursor.object = NULL; - if (ee->evas) evas_free(ee->evas); - ee->evas = NULL; - ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE); - ee->driver = 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 Eina_Bool -_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 ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_ecore_evas_async_events_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - evas_async_events_process(); - - return ECORE_CALLBACK_RENEW; -} - -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) - { - int fx, fy; - evas_output_framespace_get(ee->evas, &fx, &fy, NULL, NULL); - evas_object_show(ee->prop.cursor.object); - if (ee->rotation == 0) - evas_object_move(ee->prop.cursor.object, - x - fx - ee->prop.cursor.hot.x, - y - fy - ee->prop.cursor.hot.y); - else if (ee->rotation == 90) - evas_object_move(ee->prop.cursor.object, - ee->h - y - fx - 1 - ee->prop.cursor.hot.x, - x - fy - ee->prop.cursor.hot.y); - else if (ee->rotation == 180) - evas_object_move(ee->prop.cursor.object, - ee->w - x - fx - 1 - ee->prop.cursor.hot.x, - ee->h - y - fy - 1 - ee->prop.cursor.hot.y); - else if (ee->rotation == 270) - evas_object_move(ee->prop.cursor.object, - y - fx - ee->prop.cursor.hot.x, - ee->w - x - fy - 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); -} - -void -_ecore_evas_mouse_multi_move_process(Ecore_Evas *ee, int device, - int x, int y, - double radius, - double radius_x, double radius_y, - double pressure, - double angle, - double mx, double my, - unsigned int timestamp) -{ - if (ee->rotation == 0) - evas_event_feed_multi_move(ee->evas, device, - x, y, - radius, - radius_x, radius_y, - pressure, - angle - ee->rotation, - mx, my, - timestamp, NULL); - else if (ee->rotation == 90) - evas_event_feed_multi_move(ee->evas, device, - ee->h - y - 1, x, - radius, - radius_y, radius_x, - pressure, - angle - ee->rotation, - ee->h - my - 1, mx, - timestamp, NULL); - else if (ee->rotation == 180) - evas_event_feed_multi_move(ee->evas, device, - ee->w - x - 1, ee->h - y - 1, - radius, - radius_x, radius_y, - pressure, - angle - ee->rotation, - ee->w - mx - 1, ee->h - my - 1, - timestamp, NULL); - else if (ee->rotation == 270) - evas_event_feed_multi_move(ee->evas, device, - y, ee->w - x - 1, - radius, - radius_y, radius_x, - pressure, - angle - ee->rotation, - my, ee->w - mx - 1, - timestamp, NULL); -} - -void -_ecore_evas_mouse_multi_down_process(Ecore_Evas *ee, int device, - int x, int y, - double radius, - double radius_x, double radius_y, - double pressure, - double angle, - double mx, double my, - Evas_Button_Flags flags, - unsigned int timestamp) -{ - if (ee->rotation == 0) - evas_event_feed_multi_down(ee->evas, device, - x, y, - radius, - radius_x, radius_y, - pressure, - angle - ee->rotation, - mx, my, - flags, timestamp, NULL); - else if (ee->rotation == 90) - evas_event_feed_multi_down(ee->evas, device, - ee->h - y - 1, x, - radius, - radius_y, radius_x, - pressure, - angle - ee->rotation, - ee->h - my - 1, mx, - flags, timestamp, NULL); - else if (ee->rotation == 180) - evas_event_feed_multi_down(ee->evas, device, - ee->w - x - 1, ee->h - y - 1, - radius, - radius_x, radius_y, - pressure, - angle - ee->rotation, - ee->w - mx - 1, ee->h - my - 1, - flags, timestamp, NULL); - else if (ee->rotation == 270) - evas_event_feed_multi_down(ee->evas, device, - y, ee->w - x - 1, - radius, - radius_y, radius_x, - pressure, - angle - ee->rotation, - my, ee->w - mx - 1, - flags, timestamp, NULL); -} - -void -_ecore_evas_mouse_multi_up_process(Ecore_Evas *ee, int device, - int x, int y, - double radius, - double radius_x, double radius_y, - double pressure, - double angle, - double mx, double my, - Evas_Button_Flags flags, - unsigned int timestamp) -{ - if (ee->rotation == 0) - evas_event_feed_multi_up(ee->evas, device, - x, y, - radius, - radius_x, radius_y, - pressure, - angle - ee->rotation, - mx, my, - flags, timestamp, NULL); - else if (ee->rotation == 90) - evas_event_feed_multi_up(ee->evas, device, - ee->h - y - 1, x, - radius, - radius_y, radius_x, - pressure, - angle - ee->rotation, - ee->h - my - 1, mx, - flags, timestamp, NULL); - else if (ee->rotation == 180) - evas_event_feed_multi_up(ee->evas, device, - ee->w - x - 1, ee->h - y - 1, - radius, - radius_x, radius_y, - pressure, - angle - ee->rotation, - ee->w - mx - 1, ee->h - my - 1, - flags, timestamp, NULL); - else if (ee->rotation == 270) - evas_event_feed_multi_up(ee->evas, device, - y, ee->w - x - 1, - radius, - radius_y, radius_x, - pressure, - angle - ee->rotation, - my, ee->w - mx - 1, - flags, timestamp, NULL); -} - -EAPI Eina_List * -ecore_evas_ecore_evas_list_get(void) -{ - Ecore_Evas *ee; - Eina_List *l = NULL; - - EINA_INLIST_FOREACH(ecore_evases, ee) - { - l = eina_list_append(l, ee); - } - - return l; -} - -EAPI void -ecore_evas_input_event_register(Ecore_Evas *ee) -{ - ecore_event_window_register((Ecore_Window)ee, ee, ee->evas, - (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); -} - -EAPI void -ecore_evas_input_event_unregister(Ecore_Evas *ee) -{ - ecore_event_window_unregister((Ecore_Window)ee); -} - -#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined (BUILD_ECORE_EVAS_WAYLAND_EGL) -EAPI void -ecore_evas_wayland_resize(Ecore_Evas *ee, int location) -{ - if (!ee) return; - if (!strcmp(ee->driver, "wayland_shm")) - { -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM - _ecore_evas_wayland_shm_resize(ee, location); -#endif - } - else if (!strcmp(ee->driver, "wayland_egl")) - { -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL - _ecore_evas_wayland_egl_resize(ee, location); -#endif - } -} - -EAPI void -ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y) -{ - if (!ee) return; - if (!strncmp(ee->driver, "wayland", 7)) - { - if (ee->engine.wl.win) - { - ee->engine.wl.win->moving = EINA_TRUE; - ecore_wl_window_move(ee->engine.wl.win, x, y); - } - } -} - -EAPI void -ecore_evas_wayland_type_set(Ecore_Evas *ee, int type) -{ - if (!ee) return; - ecore_wl_window_type_set(ee->engine.wl.win, type); -} - -EAPI Ecore_Wl_Window * -ecore_evas_wayland_window_get(const Ecore_Evas *ee) -{ - if (!(!strncmp(ee->driver, "wayland", 7))) - return NULL; - - return ee->engine.wl.win; -} - -EAPI void -ecore_evas_wayland_pointer_set(Ecore_Evas *ee EINA_UNUSED, int hot_x EINA_UNUSED, int hot_y EINA_UNUSED) -{ - -} - -#else -EAPI void -ecore_evas_wayland_resize(Ecore_Evas *ee EINA_UNUSED, int location EINA_UNUSED) -{ - -} - -EAPI void -ecore_evas_wayland_move(Ecore_Evas *ee EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED) -{ - -} - -EAPI void -ecore_evas_wayland_type_set(Ecore_Evas *ee EINA_UNUSED, int type EINA_UNUSED) -{ - -} - -EAPI Ecore_Wl_Window * -ecore_evas_wayland_window_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return NULL; -} - -EAPI void -ecore_evas_wayland_pointer_set(Ecore_Evas *ee EINA_UNUSED, int hot_x EINA_UNUSED, int hot_y EINA_UNUSED) -{ - -} - -#endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_buffer.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_buffer.c deleted file mode 100644 index 26f48ce336..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_buffer.c +++ /dev/null @@ -1,836 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! -#include - -#include -#include "ecore_private.h" -#include - -#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++; - 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 - { - ee->engine.buffer.free_func(ee->engine.buffer.data, - 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; - int stride = 0; - - if (w < 1) w = 1; - if (h < 1) h = 1; - ee->req.w = w; - ee->req.h = 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->engine.buffer.image) - { - ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1); - stride = evas_object_image_stride_get(ee->engine.buffer.image); - } - else - { - if (ee->engine.buffer.pixels) - ee->engine.buffer.free_func(ee->engine.buffer.data, - ee->engine.buffer.pixels); - ee->engine.buffer.pixels = - ee->engine.buffer.alloc_func(ee->engine.buffer.data, - ee->w * ee->h * sizeof(int)); - stride = ee->w * sizeof(int); - } - - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) - { - if (ee->alpha) - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - else - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.dest_buffer = ee->engine.buffer.pixels; - einfo->info.dest_buffer_row_bytes = stride; - 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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - } - if (ee->engine.buffer.image) - evas_object_image_data_set(ee->engine.buffer.image, ee->engine.buffer.pixels); - if (ee->func.fn_resize) ee->func.fn_resize(ee); -} - -static void -_ecore_evas_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h) -{ - _ecore_evas_resize(ee, w, h); -} - -int -_ecore_evas_buffer_shutdown(void) -{ - _ecore_evas_init_count--; - if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; - return _ecore_evas_init_count; -} - -static void -_ecore_evas_show(Ecore_Evas *ee) -{ - if (ee->engine.buffer.image) return; - if (ee->prop.focused) return; - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); -} - -int -_ecore_evas_buffer_render(Ecore_Evas *ee) -{ - Eina_List *updates = NULL, *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); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_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); - ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1); - } - if (ee->engine.buffer.pixels) - { - updates = evas_render_updates(ee->evas); - } - if (ee->engine.buffer.image) - { - Eina_Rectangle *r; - - evas_object_image_data_set(ee->engine.buffer.image, ee->engine.buffer.pixels); - EINA_LIST_FOREACH(updates, l, r) - 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; -} - -// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! -static void -_ecore_evas_buffer_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y) -{ - Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh; - - evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, &ww, &hh); - evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh); - - if (fw < 1) fw = 1; - if (fh < 1) fh = 1; - - if (evas_object_map_get(ee->engine.buffer.image) && - evas_object_map_enable_get(ee->engine.buffer.image)) - { - fx = 0; fy = 0; - fw = ee->w; fh = ee->h; - ww = ee->w; hh = ee->h; - } - - if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh)) - { - *x = (ee->w * (*x - xx)) / fw; - *y = (ee->h * (*y - yy)) / fh; - } - else - { - xx = (*x - xx) - fx; - while (xx < 0) xx += fw; - while (xx > fw) xx -= fw; - *x = (ee->w * xx) / fw; - - yy = (*y - yy) - fy; - while (yy < 0) yy += fh; - while (yy > fh) yy -= fh; - *y = (ee->h * yy) / fh; - } -} - -static void -_ecore_evas_buffer_transfer_modifiers_locks(Evas *e, Evas *e2) -{ - const char *mods[] = - { "Shift", "Control", "Alt", "Meta", "Hyper", "Super", NULL }; - const char *locks[] = - { "Scroll_Lock", "Num_Lock", "Caps_Lock", NULL }; - int i; - - for (i = 0; mods[i]; i++) - { - if (evas_key_modifier_is_set(evas_key_modifier_get(e), mods[i])) - evas_key_modifier_on(e2, mods[i]); - else - evas_key_modifier_off(e2, mods[i]); - } - for (i = 0; locks[i]; i++) - { - if (evas_key_lock_is_set(evas_key_lock_get(e), locks[i])) - evas_key_lock_on(e2, locks[i]); - else - evas_key_lock_off(e2, locks[i]); - } -} - -static void -_ecore_evas_buffer_cb_mouse_in(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - Evas_Event_Mouse_In *ev; - - ee = data; - ev = event_info; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); -} - -static void -_ecore_evas_buffer_cb_mouse_out(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - Evas_Event_Mouse_Out *ev; - - ee = data; - ev = event_info; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); -} - -static void -_ecore_evas_buffer_cb_mouse_down(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee; - Evas_Event_Mouse_Down *ev; - - ee = data; - ev = event_info; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - 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, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee; - Evas_Event_Mouse_Up *ev; - - ee = data; - ev = event_info; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - 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, Evas_Object *obj EINA_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_buffer_transfer_modifiers_locks(e, ee->evas); - _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); -} - -static void -_ecore_evas_buffer_cb_mouse_wheel(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee; - Evas_Event_Mouse_Wheel *ev; - - ee = data; - ev = event_info; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - 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, Evas_Object *obj EINA_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; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - 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, Evas_Object *obj EINA_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; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - 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, Evas_Object *obj EINA_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; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - 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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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 EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee; - Evas_Event_Key_Down *ev; - - ee = data; - ev = event_info; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - 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 EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee; - Evas_Event_Key_Up *ev; - - ee = data; - ev = event_info; - _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); - 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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - - ee = data; - ee->visible = 0; - if (ee->func.fn_hide) ee->func.fn_hide(ee); -} - -static void -_ecore_evas_buffer_alpha_set(Ecore_Evas *ee, int alpha) -{ - if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha))) return; - ee->alpha = alpha; - if (ee->engine.buffer.image) - evas_object_image_alpha_set(ee->engine.buffer.image, ee->alpha); - else - { - Evas_Engine_Info_Buffer *einfo; - - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) - { - if (ee->alpha) - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - else - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - } - } -} - -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, - _ecore_evas_move_resize, - NULL, - NULL, - _ecore_evas_show, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - _ecore_evas_buffer_alpha_set, - NULL, //transparent - NULL, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - _ecore_evas_buffer_render, - NULL, // screen_geometry_get - NULL // screen_dpi_get -}; -#endif - -static void * -_ecore_evas_buffer_pix_alloc(void *data EINA_UNUSED, int size) -{ - return malloc(size); -} - -static void -_ecore_evas_buffer_pix_free(void *data EINA_UNUSED, void *pix) -{ - free(pix); -} - -EAPI Ecore_Evas * -ecore_evas_buffer_new(int w, int h) -{ - return ecore_evas_buffer_allocfunc_new - (w, h, _ecore_evas_buffer_pix_alloc, _ecore_evas_buffer_pix_free, NULL); -} - -EAPI Ecore_Evas * -ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data) -{ -// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! -#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER - Evas_Engine_Info_Buffer *einfo; - Ecore_Evas *ee; - int rmethod; - - if ((!alloc_func) || (!free_func)) return NULL; - 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->engine.buffer.alloc_func = alloc_func; - ee->engine.buffer.free_func = free_func; - ee->engine.buffer.data = (void *)data; - - 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->req.w = ee->w; - ee->req.h = ee->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 = - ee->engine.buffer.alloc_func - (ee->engine.buffer.data, 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_RGB32; - 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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - 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); - - _ecore_evas_register(ee); - - evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); - - return ee; -#else - return NULL; -#endif -} - -EAPI const void * -ecore_evas_buffer_pixels_get(Ecore_Evas *ee) -{ -#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER - if (!ee) - { - CRIT("Ecore_Evas is missing"); - return NULL; - } - _ecore_evas_buffer_render(ee); - return ee->engine.buffer.pixels; -#else - return NULL; -#endif -} - -EAPI Evas * -ecore_evas_object_evas_get(Evas_Object *obj) -{ - Ecore_Evas *ee; - - ee = evas_object_data_get(obj, "Ecore_Evas"); - if (!ee) return NULL; - - return ecore_evas_get(ee); -} - -EAPI Ecore_Evas * -ecore_evas_object_ecore_evas_get(Evas_Object *obj) -{ - return evas_object_data_get(obj, "Ecore_Evas"); -} - -EAPI Evas_Object * -ecore_evas_object_image_new(Ecore_Evas *ee_target) -{ -// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! -#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER - Evas_Object *o; - Evas_Engine_Info_Buffer *einfo; - Ecore_Evas *ee; - int rmethod; - int w = 1, h = 1; - - if (!ee_target) return NULL; - - 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); - evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); - evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888); - evas_object_image_alpha_set(o, 0); - evas_object_image_size_set(o, w, h); - - 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"; - - ee->rotation = 0; - ee->visible = 0; - ee->w = w; - ee->h = h; - ee->req.w = ee->w; - ee->req.h = ee->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_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) - { - ee->engine.buffer.pixels = evas_object_image_data_get(o, 1); - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - einfo->info.dest_buffer = ee->engine.buffer.pixels; - einfo->info.dest_buffer_row_bytes = evas_object_image_stride_get(o); - 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_object_image_data_set(o, ee->engine.buffer.pixels); - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - 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); - - return o; -#else - return NULL; -#endif -} diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_cocoa.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_cocoa.c deleted file mode 100644 index bf88e5e33f..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_cocoa.c +++ /dev/null @@ -1,584 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "Ecore.h" -#include "ecore_private.h" -#include "Ecore_Input.h" -#include "Ecore_Input_Evas.h" - -#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA -#include -#include -#endif - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - - -#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA - -// 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"; - - -static int -_ecore_evas_cocoa_render(Ecore_Evas *ee) -{ - int rend = 0; - Eina_List *updates = NULL; - Eina_List *ll; - Ecore_Evas *ee2; - - DBG("Render"); - - EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) - { - if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); - updates = evas_render_updates(ee->evas); - 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); - - 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 Ecore_Evas * -_ecore_evas_cocoa_match(void) -{ - DBG("Match"); - return ecore_evases; -} - -static int -_ecore_evas_cocoa_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - - DBG("Got Focus"); - - ee = _ecore_evas_cocoa_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - - return ECORE_CALLBACK_PASS_ON; -} - -static int -_ecore_evas_cocoa_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - - DBG("Lost Focus"); - - ee = _ecore_evas_cocoa_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - evas_focus_out(ee->evas); - ee->prop.focused = 0; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - - return ECORE_CALLBACK_PASS_ON; -} - -static int -_ecore_evas_cocoa_event_video_resize(void *data EINA_UNUSED, int type EINA_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;*/ - - DBG("Video Resize"); - return ECORE_CALLBACK_PASS_ON; -} - -static int -_ecore_evas_cocoa_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Evas *ee; - int w; - int h; - - DBG("Video Expose"); - - ee = _ecore_evas_cocoa_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - evas_output_size_get(ee->evas, &w, &h); - evas_damage_rectangle_add(ee->evas, 0, 0, w, h); - - return ECORE_CALLBACK_PASS_ON; -} - -static int -_ecore_evas_idle_enter(void *data EINA_UNUSED) -{ - Ecore_Evas *ee; - double t1 = 0.; - double t2 = 0.; - - DBG("Idle enter"); - - EINA_INLIST_FOREACH(ecore_evases, ee) - { - if (ee->visible) - evas_render(ee->evas); - else - evas_norender(ee->evas); - } - - return EINA_TRUE; -} - -static int -_ecore_evas_cocoa_event(void *data) -{ - // ecore_cocoa_feed_events(); - - DBG("Cocoa Event"); - - return 1; -} - -static int -_ecore_evas_cocoa_init(void) -{ - DBG("Cocoa Init"); - _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_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); - - ecore_event_evas_init(); - return _ecore_evas_init_count; -} - -static int -_ecore_evas_cocoa_shutdown(void) -{ - DBG("Cocoa SHutodwn"); - _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) -{ - DBG("Cocoa Free"); - 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) -{ - DBG("Resize"); - if ((w == ee->w) && (h == ee->h)) return; - ee->w = w; - ee->h = h; - - printf("Ecore_Evas Resize %d %d\n", w, h); - - ecore_cocoa_window_resize(ee->prop.window, w, 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, int y, int w, int h) -{ - DBG("Move Resize"); - if ((w == ee->w) && (h == ee->h)) return; - ee->w = w; - ee->h = h; - - ecore_cocoa_window_move_resize(ee->prop.window, x, y, w, 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_show(Ecore_Evas *ee, int x, int y, int w, int h) -{ - DBG("Show"); - ee->should_be_visible = 1; - if (ee->prop.avoid_damage) - _ecore_evas_cocoa_render(ee); - - ecore_cocoa_window_show(ee->prop.window); - evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); -} - - -static void -_ecore_evas_hide(Ecore_Evas *ee, int x, int y, int w, int h) -{ - DBG("Hide"); - - ecore_cocoa_window_hide(ee->prop.window); - ee->should_be_visible = 0; -} - -static void -_ecore_evas_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_cocoa_window_title_set(ee->prop.window, - ee->prop.title); -} - -static void -_ecore_evas_object_cursor_del(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - Ecore_Evas *ee; - - DBG("Cursor DEL"); - - 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; - DBG("Cursor Set"); - 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 int -_ecore_evas_engine_cocoa_init(Ecore_Evas *ee) -{ - Evas_Engine_Info_GL_Cocoa *einfo; - const char *driver; - int rmethod; - - DBG("Cocoa Init"); - - driver = "gl_cocoa"; - - 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_Cocoa *)evas_engine_info_get(ee->evas); - if (einfo) - { - /* FIXME: REDRAW_DEBUG missing for now */ - einfo->window = ee->prop.window; - //einfo->info.depth = ecore_win32_screen_depth_get(); - //einfo->info.rotation = 0; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - return 0; - } - ecore_cocoa_window_view_set(einfo->window, einfo->view); - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - return 0; - } - - return 1; -} - -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, //move - NULL, - _ecore_evas_resize, - _ecore_evas_move_resize, - NULL, //rotation - NULL, //shaped - _ecore_evas_show, - _ecore_evas_hide, - NULL, //raise - NULL, //lower - NULL, //activate - _ecore_evas_title_set, - 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, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - NULL, // render - NULL, - NULL // screen_dpi_get - }; -#endif - -EAPI Ecore_Evas * -ecore_evas_cocoa_new(Ecore_Cocoa_Window *parent, int x, int y, int w, int h) -{ -#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA - Evas_Engine_Info_GL_Cocoa *einfo; - Ecore_Evas *ee; - int rmethod; - - DBG("Cocoa new"); - - if (!ecore_cocoa_init()) - 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(); - - ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_cocoa_engine_func; - - if (w < 1) w = 1; - if (h < 1) h = 1; - ee->visible = 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->semi_sync = 1; - - - ee->prop.max.w = 32767; - ee->prop.max.h = 32767; - ee->prop.layer = 4; - ee->prop.request_pos = 0; - ee->prop.sticky = 0; - ee->prop.window = 0; - - printf("Create New Evas\n"); - - ee->evas = evas_new(); - - if (!ee->evas) - goto free_name; - - 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); - - printf("Create New Cocoa Window\n"); - ee->prop.window = (Ecore_Cocoa_Window*)ecore_cocoa_window_new(x, y, w, h); - printf("Window Created %p\n", ee->prop.window); - if (!ee->prop.window) - { - _ecore_evas_cocoa_shutdown(); - free(ee); - return NULL; - } - - printf("Init Evas engine cocoa\n"); - if (!_ecore_evas_engine_cocoa_init(ee)) - { - _ecore_evas_cocoa_shutdown(); - free(ee); - return NULL; - } - - - ee->engine.func->fn_render = _ecore_evas_cocoa_render; - _ecore_evas_register(ee); - ecore_event_window_register(0, ee, ee->evas, NULL, NULL, NULL, NULL); - - evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); - printf("Ecore Evas returned : %p\n", ee); - 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("Cocoa support in ecore-evas not enabled"); - return NULL; - (void) parent; - (void) x; (void) y; (void) w; (void) h; -#endif -} diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_directfb.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_directfb.c deleted file mode 100644 index f3567341b1..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_directfb.c +++ /dev/null @@ -1,606 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include -#include "ecore_private.h" -#ifdef BUILD_ECORE_EVAS_DIRECTFB -#include -#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; - - EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) - { - if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - 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 Eina_Bool -_ecore_evas_directfb_event_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Key_Down *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* pass on event */ - evas_event_feed_key_down(ee->evas, e->name, e->name, e->string, - e->key_compose, e->time, NULL); - return EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Key_Up *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* pass on event */ - evas_event_feed_key_up(ee->evas, e->name, e->name, e->string, - e->key_compose, e->time, NULL); - return EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_motion(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Motion *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* pass on event */ - _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time); - return EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_button_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Button_Down *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* 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 EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_button_up(void *data EINA_UNUSED, int type EINA_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 EINA_TRUE; /* 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 EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_enter(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Enter *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* 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 EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_leave(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Leave *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* 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 EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Wheel *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* pass on event */ - evas_event_feed_mouse_wheel(ee->evas, e->direction, e->z, e->time, NULL); - return EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Got_Focus *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* pass on event */ - ee->prop.focused = 1; - return EINA_TRUE; -} - -static Eina_Bool -_ecore_evas_directfb_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_DirectFB_Event_Lost_Focus *e; - - e = event; - ee = _ecore_evas_directfb_match(e->win); - - if (!ee) return EINA_TRUE; /* pass on event */ - ee->prop.focused = 0; - return EINA_TRUE; -} - -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) -{ - ee->req.w = w; - ee->req.h = 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 EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) - { - 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; - 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); - } - } - einfo = (Evas_Engine_Info_DirectFB *)evas_engine_info_get(ee->evas); - if (einfo) - { - einfo->info.surface = ee->engine.directfb.window->surface; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - } - 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, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - NULL, // render - NULL, // screen_geometry_get - NULL // screen_dpi_get -}; -#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->req.x = ee->x; - ee->req.y = ee->y; - ee->req.w = ee->w; - ee->req.h = ee->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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - - 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 EINA_UNUSED, int windowed EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ - return NULL; -} -#endif - -#ifdef BUILD_ECORE_EVAS_DIRECTFB -EAPI Ecore_DirectFB_Window * -ecore_evas_directfb_window_get(const Ecore_Evas *ee) -{ - if (!(!strcmp(ee->driver, "directfb"))) return 0; - return (Ecore_DirectFB_Window *) _ecore_evas_directfb_window_get(ee); -} -#else -EAPI Ecore_DirectFB_Window * -ecore_evas_directfb_window_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return NULL; -} -#endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_ews.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_ews.c deleted file mode 100644 index ceffd663e6..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_ews.c +++ /dev/null @@ -1,1469 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#include -#include -#include "ecore_private.h" -#include - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - -EAPI int ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_ADD = 0; -EAPI int ECORE_EVAS_EWS_EVENT_DEL = 0; -EAPI int ECORE_EVAS_EWS_EVENT_RESIZE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_MOVE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_SHOW = 0; -EAPI int ECORE_EVAS_EWS_EVENT_HIDE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_FOCUS = 0; -EAPI int ECORE_EVAS_EWS_EVENT_UNFOCUS = 0; -EAPI int ECORE_EVAS_EWS_EVENT_RAISE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_LOWER = 0; -EAPI int ECORE_EVAS_EWS_EVENT_ACTIVATE = 0; - -EAPI int ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_LAYER_CHANGE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE = 0; -EAPI int ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE = 0; - -#ifdef BUILD_ECORE_EVAS_EWS -static int _ecore_evas_init_count = 0; - -static Ecore_Evas *_ews_ee = NULL; -static Evas_Object *_ews_bg = NULL; -static Eina_List *_ews_children = NULL; -static const void *_ews_manager = NULL; -static char *_ews_engine = NULL; -static char *_ews_options = NULL; -static int _ews_x = 0; -static int _ews_y = 0; -static int _ews_w = 1024; -static int _ews_h = 768; -static Eina_Bool _ews_defaults_engine = EINA_TRUE; -static Eina_Bool _ews_defaults_geo = EINA_TRUE; - -static const char EWS_ENGINE_NAME[] = "ews"; - -static void -_ecore_evas_ews_pre_free(Ecore_Evas *ee EINA_UNUSED) -{ - DBG("EWS backing store free'd"); - _ews_children = eina_list_free(_ews_children); - _ews_ee = NULL; - _ews_bg = NULL; -} - -static void -_ecore_evas_ews_del_request(Ecore_Evas *ee EINA_UNUSED) -{ - INF("EWS backing store deletion is forbidden!"); -} - -static Ecore_Evas * -_ecore_evas_ews_ee_new(void) -{ - Ecore_Evas *ee = ecore_evas_new(_ews_engine, _ews_x, _ews_y, _ews_w, _ews_h, - _ews_options); - if (!ee) - ERR("Failed: ecore_evas_new(%s, %d, %d, %d, %d, %s)", - _ews_engine, _ews_x, _ews_y, _ews_w, _ews_h, _ews_options); - else - { - ecore_evas_size_min_set(ee, _ews_w, _ews_h); - ecore_evas_size_max_set(ee, _ews_w, _ews_h); - ecore_evas_callback_pre_free_set(ee, _ecore_evas_ews_pre_free); - ecore_evas_callback_delete_request_set(ee, _ecore_evas_ews_del_request); - ecore_evas_name_class_set(ee, "ecore_evas_ews", "ews"); - ecore_evas_title_set - (ee, "EWS: Ecore + Evas Single Process Windowing System"); - ecore_evas_show(ee); - } - - return ee; -} - -static void -_ecore_evas_ews_env_setup(void) -{ - const char *env = getenv("ECORE_EVAS_EWS"); - char *p, *n, *tmp; - - if (_ews_defaults_engine) - { - free(_ews_engine); - _ews_engine = NULL; - free(_ews_options); - _ews_options = NULL; - } - if (_ews_defaults_geo) - { - _ews_x = 0; - _ews_y = 0; - _ews_w = 1024; - _ews_h = 768; - } - - if ((!env) || (!*env)) return; - - p = tmp = strdup(env); - if (!tmp) return; - - n = strchr(p, ':'); - if (n) *n = '\0'; - if (_ews_defaults_engine) _ews_engine = strdup(p); - if (!n) goto end; - - p = n + 1; - n = strchr(p, ':'); - if (!n) goto end; - *n = '\0'; - if (_ews_defaults_geo) _ews_x = atoi(p); - - p = n + 1; - n = strchr(p, ':'); - if (!n) goto end; - *n = '\0'; - if (_ews_defaults_geo) _ews_y = atoi(p); - - p = n + 1; - n = strchr(p, ':'); - if (!n) goto end; - *n = '\0'; - if (_ews_defaults_geo) _ews_w = atoi(p); - - p = n + 1; - n = strchr(p, ':'); - if (n) *n = '\0'; - if (_ews_defaults_geo) _ews_h = atoi(p); - if (!n) goto end; - - p = n + 1; - if (_ews_defaults_engine) _ews_options = strdup(p); - - end: - free(tmp); -} - -static void -_ecore_evas_ews_event_free(void *data EINA_UNUSED, void *ev) -{ - Ecore_Evas *ee = ev; - _ecore_evas_unref(ee); -} - -static void -_ecore_evas_ews_event(Ecore_Evas *ee, int event) -{ - _ecore_evas_ref(ee); - ecore_event_add(event, ee, _ecore_evas_ews_event_free, NULL); -} - -static void -_ecore_evas_ews_event_free_del(void *data EINA_UNUSED, void *ev EINA_UNUSED) -{ - _ecore_evas_ews_shutdown(); -} - -static void -_ecore_evas_ews_free(Ecore_Evas *ee) -{ - evas_object_del(ee->engine.ews.image); - _ews_ee->sub_ecore_evas = eina_list_remove(_ews_ee->sub_ecore_evas, ee); - - ecore_event_add(ECORE_EVAS_EWS_EVENT_DEL, ee, _ecore_evas_ews_event_free_del, NULL); -} - -static void -_ecore_evas_ews_move(Ecore_Evas *ee, int x, int y) -{ - ee->req.x = x; - ee->req.y = y; - - if ((x == ee->x) && (y == ee->y)) return; - ee->x = x; - ee->y = y; - evas_object_move(ee->engine.ews.image, x, y); - if (ee->func.fn_move) ee->func.fn_move(ee); - - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MOVE); -} - -static void -_ecore_evas_ews_managed_move(Ecore_Evas *ee, int x, int y) -{ - ee->req.x = x; - ee->req.y = y; - - if ((x == ee->x) && (y == ee->y)) return; - ee->x = x; - ee->y = y; - if (ee->func.fn_move) ee->func.fn_move(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MOVE); -} - -static void -_ecore_evas_ews_resize_internal(Ecore_Evas *ee, int w, int h) -{ - Evas_Engine_Info_Buffer *einfo; - void *pixels; - int stride; - - evas_output_size_set(ee->evas, w, h); - evas_output_viewport_set(ee->evas, 0, 0, w, h); - evas_damage_rectangle_add(ee->evas, 0, 0, w, h); - - evas_object_image_size_set(ee->engine.ews.image, w, h); - evas_object_image_fill_set(ee->engine.ews.image, 0, 0, w, h); - evas_object_resize(ee->engine.ews.image, w, h); - - pixels = evas_object_image_data_get(ee->engine.ews.image, 1); - evas_object_image_data_set(ee->engine.ews.image, pixels); // refcount - stride = evas_object_image_stride_get(ee->engine.ews.image); - - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - EINA_SAFETY_ON_NULL_RETURN(einfo); - - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - einfo->info.dest_buffer = pixels; - einfo->info.dest_buffer_row_bytes = stride; - 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_object_image_data_set(ee->engine.ews.image, pixels); - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } -} - -static void -_ecore_evas_ews_resize(Ecore_Evas *ee, int w, int h) -{ - if (w < 1) w = 1; - if (h < 1) h = 1; - - ee->req.w = w; - ee->req.h = h; - - if ((w == ee->w) && (h == ee->h)) return; - ee->w = w; - ee->h = h; - _ecore_evas_ews_resize_internal(ee, w, h); - if (ee->func.fn_resize) ee->func.fn_resize(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_RESIZE); -} - -static void -_ecore_evas_ews_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) -{ - _ecore_evas_ews_move(ee, x, y); - _ecore_evas_ews_resize(ee, w, h); -} - -static void -_ecore_evas_ews_rotation_set(Ecore_Evas *ee, int rot, int resize EINA_UNUSED) -{ - if (ee->rotation == rot) return; - ee->rotation = rot; - - ERR("TODO: rot=%d, resize=%d", rot, resize); - - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_shaped_set(Ecore_Evas *ee, int val) -{ - if (ee->shaped == val) return; - ee->shaped = val; - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_show(Ecore_Evas *ee) -{ - ee->should_be_visible = EINA_TRUE; - evas_object_show(ee->engine.ews.image); - if (ee->prop.fullscreen) - evas_object_focus_set(ee->engine.ews.image, EINA_TRUE); - - if (ee->func.fn_show) ee->func.fn_show(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_SHOW); -} - -static void -_ecore_evas_ews_hide(Ecore_Evas *ee) -{ - ee->should_be_visible = EINA_FALSE; - evas_object_hide(ee->engine.ews.image); - - if (ee->func.fn_hide) ee->func.fn_hide(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_HIDE); -} - -static void -_ecore_evas_ews_raise(Ecore_Evas *ee) -{ - evas_object_raise(ee->engine.ews.image); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_RAISE); -} - -static void -_ecore_evas_ews_lower(Ecore_Evas *ee) -{ - evas_object_lower(ee->engine.ews.image); - evas_object_lower(_ews_bg); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_LOWER); -} - -static void -_ecore_evas_ews_activate(Ecore_Evas *ee) -{ - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ACTIVATE); -} - -static void -_ecore_evas_ews_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_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_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_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_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; - evas_object_size_hint_min_set(ee->engine.ews.image, w, h); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_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; - evas_object_size_hint_max_set(ee->engine.ews.image, w, h); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_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; - evas_object_size_hint_request_set(ee->engine.ews.image, w, h); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_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_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - ee->prop.cursor.object = NULL; -} - -static void -_ecore_evas_ews_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) - { - 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_ews_object_cursor_del, ee); - - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_layer_set(Ecore_Evas *ee, int layer) -{ - if (layer < EVAS_LAYER_MIN + 1) - layer = EVAS_LAYER_MIN + 1; - else if (layer > EVAS_LAYER_MAX) - layer = EVAS_LAYER_MAX; - - if (ee->prop.layer == layer) return; - ee->prop.layer = layer; - evas_object_layer_set(ee->engine.ews.image, layer); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_LAYER_CHANGE); -} - -static void -_ecore_evas_ews_focus_set(Ecore_Evas *ee, int val) -{ - evas_object_focus_set(ee->engine.ews.image, val); - ee->prop.focused = val; - if (val) - { - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_FOCUS); - } - else - { - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_UNFOCUS); - } -} - -static void -_ecore_evas_ews_iconified_set(Ecore_Evas *ee, int val) -{ - if (ee->prop.iconified == val) return; - ee->prop.iconified = val; - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE); -} - -static void -_ecore_evas_ews_borderless_set(Ecore_Evas *ee, int val) -{ - if (ee->prop.borderless == val) return; - ee->prop.borderless = val; - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_override_set(Ecore_Evas *ee, int val) -{ - if (ee->prop.override == val) return; - if (ee->visible) evas_object_show(ee->engine.ews.image); - if (ee->prop.focused) evas_object_focus_set(ee->engine.ews.image, EINA_TRUE); - ee->prop.override = val; - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_maximized_set(Ecore_Evas *ee, int val) -{ - if (ee->prop.maximized == val) return; - ee->prop.maximized = val; - if (val) evas_object_show(ee->engine.ews.image); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE); -} - -static void -_ecore_evas_ews_fullscreen_set(Ecore_Evas *ee, int val) -{ - if (ee->prop.fullscreen == val) return; - ee->prop.fullscreen = val; - - if (!val) - { - evas_object_move(ee->engine.ews.image, ee->x, ee->y); - evas_object_resize(ee->engine.ews.image, ee->w, ee->h); - } - else - { - Evas_Coord w, h; - ecore_evas_geometry_get(_ews_ee, NULL, NULL, &w, &h); - evas_object_move(ee->engine.ews.image, 0, 0); - evas_object_resize(ee->engine.ews.image, w, h); - evas_object_focus_set(ee->engine.ews.image, EINA_TRUE); - } - - if (ee->should_be_visible) - evas_object_show(ee->engine.ews.image); - else - evas_object_hide(ee->engine.ews.image); - - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE); -} - -static void -_ecore_evas_ews_avoid_damage_set(Ecore_Evas *ee, int val) -{ - if (ee->prop.avoid_damage == val) return; - ee->prop.avoid_damage = val; - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_withdrawn_set(Ecore_Evas *ee, int val) -{ - if (ee->prop.withdrawn == val) return; - ee->prop.withdrawn = val; - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_sticky_set(Ecore_Evas *ee, int val) -{ - if (ee->prop.sticky == val) return; - ee->prop.sticky = val; - if ((val) && (ee->func.fn_sticky)) ee->func.fn_sticky(ee); - else if ((!val) && (ee->func.fn_unsticky)) ee->func.fn_unsticky(ee); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_ignore_events_set(Ecore_Evas *ee, int val) -{ - if (ee->ignore_events == val) return; - ee->ignore_events = val; - evas_object_pass_events_set(ee->engine.ews.image, val); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_alpha_set(Ecore_Evas *ee, int val) -{ - if (ee->alpha == val) return; - ee->alpha = val; - evas_object_image_alpha_set(ee->engine.ews.image, val); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static void -_ecore_evas_ews_transparent_set(Ecore_Evas *ee, int val) -{ - if (ee->transparent == val) return; - ee->transparent = val; - evas_object_image_alpha_set(ee->engine.ews.image, val); - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); -} - -static int -_ecore_evas_ews_render(Ecore_Evas *ee) -{ - Eina_List *updates = NULL, *l, *ll; - Ecore_Evas *ee2; - Eina_Rectangle *r; - int w, h, rend = 0; - void *pixels; - - EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) - { - if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); - rend |= _ecore_evas_ews_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - evas_object_image_size_get(ee->engine.ews.image, &w, &h); - if ((w != ee->w) || (h != ee->h)) - ecore_evas_resize(ee, w, h); - - pixels = evas_object_image_data_get(ee->engine.ews.image, 1); - if (pixels) - { - updates = evas_render_updates(ee->evas); - } - evas_object_image_data_set(ee->engine.ews.image, pixels); - - EINA_LIST_FOREACH(updates, l, r) - evas_object_image_data_update_add(ee->engine.ews.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_ews_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) -{ - ecore_evas_geometry_get(_ews_ee, x, y, w, h); -} - -static const Ecore_Evas_Engine_Func _ecore_ews_engine_func = -{ - _ecore_evas_ews_free, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - _ecore_evas_ews_move, - _ecore_evas_ews_managed_move, - _ecore_evas_ews_resize, - _ecore_evas_ews_move_resize, - _ecore_evas_ews_rotation_set, - _ecore_evas_ews_shaped_set, - _ecore_evas_ews_show, - _ecore_evas_ews_hide, - _ecore_evas_ews_raise, - _ecore_evas_ews_lower, - _ecore_evas_ews_activate, - _ecore_evas_ews_title_set, - _ecore_evas_ews_name_class_set, - _ecore_evas_ews_size_min_set, - _ecore_evas_ews_size_max_set, - _ecore_evas_ews_size_base_set, - _ecore_evas_ews_size_step_set, - _ecore_evas_ews_object_cursor_set, - _ecore_evas_ews_layer_set, - _ecore_evas_ews_focus_set, - _ecore_evas_ews_iconified_set, - _ecore_evas_ews_borderless_set, - _ecore_evas_ews_override_set, - _ecore_evas_ews_maximized_set, - _ecore_evas_ews_fullscreen_set, - _ecore_evas_ews_avoid_damage_set, - _ecore_evas_ews_withdrawn_set, - _ecore_evas_ews_sticky_set, - _ecore_evas_ews_ignore_events_set, - _ecore_evas_ews_alpha_set, - _ecore_evas_ews_transparent_set, - NULL, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - _ecore_evas_ews_render, - _ecore_evas_ews_screen_geometry_get, - NULL // screen_dpi_get -}; - -void -_ecore_evas_ews_events_init(void) -{ - if (ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE != 0) return; - ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_ADD = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_DEL = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_RESIZE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_MOVE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_SHOW = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_HIDE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_FOCUS = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_UNFOCUS = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_RAISE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_LOWER = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_ACTIVATE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_LAYER_CHANGE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE = ecore_event_type_new(); - ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE = ecore_event_type_new(); -} - -static int -_ecore_evas_ews_init(void) -{ - _ecore_evas_init_count++; - if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; - - _ecore_evas_ews_env_setup(); - - return _ecore_evas_init_count; -} - -int -_ecore_evas_ews_shutdown(void) -{ - _ecore_evas_init_count--; - if (_ecore_evas_init_count == 0) - { - if (_ews_ee) - { - ecore_evas_free(_ews_ee); - _ews_ee = NULL; - } - if (_ews_children) - { - eina_list_free(_ews_children); - _ews_children = NULL; - } - - free(_ews_engine); - _ews_engine = NULL; - free(_ews_options); - _ews_options = NULL; - _ews_defaults_engine = EINA_TRUE; - _ews_defaults_geo = EINA_TRUE; - - } - if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; - return _ecore_evas_init_count; -} - -static void -_ecore_evas_ews_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y) -{ - Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh; - - evas_object_geometry_get(ee->engine.ews.image, &xx, &yy, &ww, &hh); - evas_object_image_fill_get(ee->engine.ews.image, &fx, &fy, &fw, &fh); - - if (fw < 1) fw = 1; - if (fh < 1) fh = 1; - - if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh)) - { - *x = (ee->w * (*x - xx)) / fw; - *y = (ee->h * (*y - yy)) / fh; - } - else - { - xx = (*x - xx) - fx; - while (xx < 0) xx += fw; - while (xx > fw) xx -= fw; - *x = (ee->w * xx) / fw; - - yy = (*y - yy) - fy; - while (yy < 0) yy += fh; - while (yy > fh) yy -= fh; - *y = (ee->h * yy) / fh; - } -} - -static void -_ecore_evas_ews_modifiers_apply(Ecore_Evas *ee, const Evas_Modifier *modifier) -{ - Evas *e = ee->evas; - - if (evas_key_modifier_is_set(modifier, "Shift")) - evas_key_modifier_on(e, "Shift"); - else evas_key_modifier_off(e, "Shift"); - - if (evas_key_modifier_is_set(modifier, "Control")) - evas_key_modifier_on(e, "Control"); - else evas_key_modifier_off(e, "Control"); - - if (evas_key_modifier_is_set(modifier, "Alt")) - evas_key_modifier_on(e, "Alt"); - else evas_key_modifier_off(e, "Alt"); - - if (evas_key_modifier_is_set(modifier, "Super")) - evas_key_modifier_on(e, "Super"); - else evas_key_modifier_off(e, "Super"); - - if (evas_key_modifier_is_set(modifier, "Hyper")) - evas_key_modifier_on(e, "Hyper"); - else evas_key_modifier_off(e, "Hyper"); - - if (evas_key_modifier_is_set(modifier, "Scroll_Lock")) - evas_key_lock_on(e, "Scroll_Lock"); - else evas_key_lock_off(e, "Scroll_Lock"); - - if (evas_key_modifier_is_set(modifier, "Num_Lock")) - evas_key_lock_on(e, "Num_Lock"); - else evas_key_lock_off(e, "Num_Lock"); - - if (evas_key_modifier_is_set(modifier, "Caps_Lock")) - evas_key_lock_on(e, "Caps_Lock"); - else evas_key_lock_off(e, "Caps_Lock"); - - if (evas_key_modifier_is_set(modifier, "Shift_Lock")) - evas_key_lock_on(e, "Shift_Lock"); - else evas_key_lock_off(e, "Shift_Lock"); -} - -static void -_ecore_evas_ews_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_In *ev = event_info; - Evas_Coord x = ev->canvas.x; - Evas_Coord y = ev->canvas.y; - _ecore_evas_ews_coord_translate(ee, &x, &y); - if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); - _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); -} - -static void -_ecore_evas_ews_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Out *ev = event_info; - Evas_Coord x = ev->canvas.x; - Evas_Coord y = ev->canvas.y; - // TODO: consider grab mode in EWS - _ecore_evas_ews_coord_translate(ee, &x, &y); - if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); - if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); - _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); -} - -static void -_ecore_evas_ews_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Down *ev = event_info; - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - evas_event_feed_mouse_down(ee->evas, ev->button, ev->flags, ev->timestamp, NULL); -} - -static void -_ecore_evas_ews_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Up *ev = event_info; - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - evas_event_feed_mouse_up(ee->evas, ev->button, ev->flags, ev->timestamp, NULL); -} - -static void -_ecore_evas_ews_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Move *ev = event_info; - Evas_Coord x = ev->cur.canvas.x; - Evas_Coord y = ev->cur.canvas.y; - _ecore_evas_ews_coord_translate(ee, &x, &y); - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); -} - -static void -_ecore_evas_ews_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Wheel *ev = event_info; - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, ev->timestamp, NULL); -} - -static void -_ecore_evas_ews_cb_multi_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Multi_Down *ev = event_info; - Evas_Coord x, y, xx, yy; - double xf, yf; - - x = ev->canvas.x; - y = ev->canvas.y; - xx = x; - yy = y; - _ecore_evas_ews_coord_translate(ee, &x, &y); - xf = (ev->canvas.xsub - (double)xx) + (double)x; - yf = (ev->canvas.ysub - (double)yy) + (double)y; - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - 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_ews_cb_multi_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Multi_Up *ev = event_info; - Evas_Coord x, y, xx, yy; - double xf, yf; - - x = ev->canvas.x; - y = ev->canvas.y; - xx = x; - yy = y; - _ecore_evas_ews_coord_translate(ee, &x, &y); - xf = (ev->canvas.xsub - (double)xx) + (double)x; - yf = (ev->canvas.ysub - (double)yy) + (double)y; - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - 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_ews_cb_multi_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Multi_Move *ev = event_info; - Evas_Coord x, y, xx, yy; - double xf, yf; - - x = ev->cur.canvas.x; - y = ev->cur.canvas.y; - xx = x; - yy = y; - _ecore_evas_ews_coord_translate(ee, &x, &y); - xf = (ev->cur.canvas.xsub - (double)xx) + (double)x; - yf = (ev->cur.canvas.ysub - (double)yy) + (double)y; - _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); - 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_ews_cb_free(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - if (ee->driver) _ecore_evas_free(ee); -} - -static void -_ecore_evas_ews_cb_key_down(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Key_Down *ev = event_info; - - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift")) - evas_key_modifier_on(ee->evas, "Shift"); - else - evas_key_modifier_off(ee->evas, "Shift"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control")) - evas_key_modifier_on(ee->evas, "Control"); - else - evas_key_modifier_off(ee->evas, "Control"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt")) - evas_key_modifier_on(ee->evas, "Alt"); - else - evas_key_modifier_off(ee->evas, "Alt"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta")) - evas_key_modifier_on(ee->evas, "Meta"); - else - evas_key_modifier_off(ee->evas, "Meta"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper")) - evas_key_modifier_on(ee->evas, "Hyper"); - else - evas_key_modifier_off(ee->evas, "Hyper"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super")) - evas_key_modifier_on(ee->evas, "Super"); - else - evas_key_modifier_off(ee->evas, "Super"); - if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock")) - evas_key_lock_on(ee->evas, "Scroll_Lock"); - else - evas_key_lock_off(ee->evas, "Scroll_Lock"); - if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock")) - evas_key_lock_on(ee->evas, "Num_Lock"); - else - evas_key_lock_off(ee->evas, "Num_Lock"); - if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock")) - evas_key_lock_on(ee->evas, "Caps_Lock"); - else - evas_key_lock_off(ee->evas, "Caps_Lock"); - evas_event_feed_key_down(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL); -} - -static void -_ecore_evas_ews_cb_key_up(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Key_Up *ev = event_info; - - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift")) - evas_key_modifier_on(ee->evas, "Shift"); - else - evas_key_modifier_off(ee->evas, "Shift"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control")) - evas_key_modifier_on(ee->evas, "Control"); - else - evas_key_modifier_off(ee->evas, "Control"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt")) - evas_key_modifier_on(ee->evas, "Alt"); - else - evas_key_modifier_off(ee->evas, "Alt"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta")) - evas_key_modifier_on(ee->evas, "Meta"); - else - evas_key_modifier_off(ee->evas, "Meta"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper")) - evas_key_modifier_on(ee->evas, "Hyper"); - else - evas_key_modifier_off(ee->evas, "Hyper"); - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super")) - evas_key_modifier_on(ee->evas, "Super"); - else - evas_key_modifier_off(ee->evas, "Super"); - if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock")) - evas_key_lock_on(ee->evas, "Scroll_Lock"); - else - evas_key_lock_off(ee->evas, "Scroll_Lock"); - if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock")) - evas_key_lock_on(ee->evas, "Num_Lock"); - else - evas_key_lock_off(ee->evas, "Num_Lock"); - if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock")) - evas_key_lock_on(ee->evas, "Caps_Lock"); - else - evas_key_lock_off(ee->evas, "Caps_Lock"); - evas_event_feed_key_up(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL); -} - -static void -_ecore_evas_ews_cb_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - ecore_evas_focus_set(ee, EINA_TRUE); -} - -static void -_ecore_evas_ews_cb_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - if (ee->deleted) return; - ecore_evas_focus_set(ee, EINA_FALSE); -} - -static void -_ecore_evas_ews_cb_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - ecore_evas_show(ee); -} - -static void -_ecore_evas_ews_cb_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - if (ee->deleted) return; - ecore_evas_hide(ee); -} -#endif - -EAPI Ecore_Evas * -ecore_evas_ews_new(int x, int y, int w, int h) -{ -// basically a copy of ecore_evas_buffer_new() keep in sync... -#ifdef BUILD_ECORE_EVAS_EWS - Evas_Object *o; - Evas_Engine_Info_Buffer *einfo; - Ecore_Evas *ee; - int rmethod; - - if (_ecore_evas_ews_init() < 1) return NULL; - - if (!_ews_ee) _ews_ee = _ecore_evas_ews_ee_new(); - if (!_ews_ee) - { - ERR("Could not create EWS backing store"); - _ecore_evas_ews_shutdown(); - return NULL; - } - - rmethod = evas_render_method_lookup("buffer"); - if (!rmethod) return NULL; - ee = calloc(1, sizeof(Ecore_Evas)); - if (!ee) return NULL; - - if (w < 1) w = 1; - if (h < 1) h = 1; - - o = evas_object_image_add(_ews_ee->evas); - evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); - evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888); - evas_object_image_size_set(o, w, h); - evas_object_image_alpha_set(o, 1); - - ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); - - ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_ews_engine_func; - - ee->driver = EWS_ENGINE_NAME; - - ee->x = 0; - ee->y = 0; - 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; - - /* 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); - - evas_object_move(o, x, y); - evas_object_resize(o, w, h); - evas_object_image_fill_set(o, 0, 0, w, h); - - ee->engine.ews.image = o; - evas_object_data_set(ee->engine.ews.image, "Ecore_Evas", ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MOUSE_IN, - _ecore_evas_ews_cb_mouse_in, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MOUSE_OUT, - _ecore_evas_ews_cb_mouse_out, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MOUSE_DOWN, - _ecore_evas_ews_cb_mouse_down, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MOUSE_UP, - _ecore_evas_ews_cb_mouse_up, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MOUSE_MOVE, - _ecore_evas_ews_cb_mouse_move, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MOUSE_WHEEL, - _ecore_evas_ews_cb_mouse_wheel, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MULTI_DOWN, - _ecore_evas_ews_cb_multi_down, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MULTI_UP, - _ecore_evas_ews_cb_multi_up, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_MULTI_MOVE, - _ecore_evas_ews_cb_multi_move, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_FREE, - _ecore_evas_ews_cb_free, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_KEY_DOWN, - _ecore_evas_ews_cb_key_down, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_KEY_UP, - _ecore_evas_ews_cb_key_up, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_FOCUS_IN, - _ecore_evas_ews_cb_focus_in, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_FOCUS_OUT, - _ecore_evas_ews_cb_focus_out, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_SHOW, - _ecore_evas_ews_cb_show, ee); - evas_object_event_callback_add(ee->engine.ews.image, - EVAS_CALLBACK_HIDE, - _ecore_evas_ews_cb_hide, ee); - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) - { - void *pixels = evas_object_image_data_get(o, 1); - evas_object_image_data_set(o, pixels); // refcount - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - einfo->info.dest_buffer = pixels; - einfo->info.dest_buffer_row_bytes = evas_object_image_stride_get(o); - 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_object_image_data_set(o, pixels); - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - 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"); - - _ews_ee->sub_ecore_evas = eina_list_append(_ews_ee->sub_ecore_evas, ee); - _ews_children = eina_list_append(_ews_children, ee); - - _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ADD); - - return ee; -#else - return NULL; - (void)x; - (void)y; - (void)w; - (void)h; -#endif -} - -EAPI Evas_Object * -ecore_evas_ews_backing_store_get(const Ecore_Evas *ee) -{ -#ifdef BUILD_ECORE_EVAS_EWS - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_ews_backing_store_get"); - return NULL; - } - return ee->engine.ews.image; -#else - return NULL; - (void)ee; -#endif -} - -EAPI void -ecore_evas_ews_delete_request(Ecore_Evas *ee) -{ -#ifdef BUILD_ECORE_EVAS_EWS - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_ews_delete_request"); - return; - } - if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee); - else ecore_evas_free(ee); -#else - (void)ee; -#endif -} - - -EAPI Eina_Bool -ecore_evas_ews_engine_set(const char *engine, const char *options) -{ -#ifdef BUILD_ECORE_EVAS_EWS - if (_ews_ee) return EINA_FALSE; - - free(_ews_engine); - free(_ews_options); - - _ews_engine = engine ? strdup(engine) : NULL; - _ews_options = options ? strdup(options) : NULL; - - if ((engine) && (!_ews_engine)) return EINA_FALSE; - if ((options) && (!_ews_options)) return EINA_FALSE; - - _ews_defaults_engine = EINA_FALSE; - return EINA_TRUE; -#else - return EINA_FALSE; - (void)engine; - (void)options; -#endif -} - -EAPI Eina_Bool -ecore_evas_ews_setup(int x, int y, int w, int h) -{ -#ifdef BUILD_ECORE_EVAS_EWS - Eina_Bool ret = EINA_TRUE; - - _ews_defaults_geo = EINA_FALSE; - _ews_x = x; - _ews_y = y; - _ews_w = w; - _ews_h = h; - - if (!_ews_ee) return EINA_TRUE; - - /* move-resize is not as implemented as move + resize */ - ecore_evas_move(_ews_ee, x, y); - ecore_evas_size_min_set(_ews_ee, w, h); - ecore_evas_size_max_set(_ews_ee, w, h); - ecore_evas_resize(_ews_ee, w, h); - - ecore_evas_geometry_get(_ews_ee, &x, &y, &w, &h); - -#define TST(n) if ((n != _ews_##n)) \ - { \ - WRN("Asked %d, got %d for "#n, _ews_##n, n); \ - ret = EINA_FALSE; \ - } - TST(x); - TST(y); - TST(w); - TST(h); -#undef TST - return ret; -#else - return EINA_FALSE; - (void)x; - (void)y; - (void)w; - (void)h; -#endif -} - -EAPI Ecore_Evas * -ecore_evas_ews_ecore_evas_get(void) -{ -#ifdef BUILD_ECORE_EVAS_EWS - if (!_ews_ee) _ews_ee = _ecore_evas_ews_ee_new(); - return _ews_ee; -#else - return NULL; -#endif -} - -EAPI Evas * -ecore_evas_ews_evas_get(void) -{ -#ifdef BUILD_ECORE_EVAS_EWS - return ecore_evas_get(ecore_evas_ews_ecore_evas_get()); -#else - return NULL; -#endif -} - -EAPI Evas_Object * -ecore_evas_ews_background_get(void) -{ -#ifdef BUILD_ECORE_EVAS_EWS - return _ews_bg; -#else - return NULL; -#endif -} - -#ifdef BUILD_ECORE_EVAS_EWS -static void -_ecore_evas_ews_background_free(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED) -{ - _ews_bg = NULL; - ecore_evas_ews_background_set(NULL); -} -#endif - -EAPI void -ecore_evas_ews_background_set(Evas_Object *o) -{ -#ifdef BUILD_ECORE_EVAS_EWS - if ((o) && (o == _ews_bg)) return; - - if (_ews_bg) - { - evas_object_del(_ews_bg); - _ews_bg = NULL; - } - - if ((!o) && (_ews_ee)) - { - o = evas_object_rectangle_add(ecore_evas_get(_ews_ee)); - evas_object_color_set(o, 0, 0, 0, 255); - } - - if (_ews_ee) - { - Evas_Coord w, h; - Evas *e = ecore_evas_get(_ews_ee); - - if (e != evas_object_evas_get(o)) - { - ERR("background not in ecore_evas_ews_evas_get() canvas!"); - return; - } - - evas_output_viewport_get(e, NULL, NULL, &w, &h); - evas_object_move(o, 0, 0); - evas_object_resize(o, w, h); - evas_object_layer_set(o, EVAS_LAYER_MIN); - evas_object_lower(o); - evas_object_show(o); - - evas_object_event_callback_add - (o, EVAS_CALLBACK_FREE, _ecore_evas_ews_background_free, NULL); - } - - _ews_bg = o; -#else - return; - (void)o; -#endif -} - - -EAPI const Eina_List * -ecore_evas_ews_children_get(void) -{ -#ifdef BUILD_ECORE_EVAS_EWS - return _ews_children; -#else - return NULL; -#endif -} - -EAPI void -ecore_evas_ews_manager_set(const void *manager) -{ -#ifdef BUILD_ECORE_EVAS_EWS - if (_ews_manager == manager) return; - _ews_manager = manager; - ecore_event_add(ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE, NULL, NULL, NULL); -#else - (void)manager; -#endif -} - -EAPI const void * -ecore_evas_ews_manager_get(void) -{ -#ifdef BUILD_ECORE_EVAS_EWS - return _ews_manager; -#else - return NULL; -#endif -} diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_extn.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_extn.c deleted file mode 100644 index 2e1dac5cf8..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_extn.c +++ /dev/null @@ -1,2266 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_MMAN_H -# include -#endif -#include -#include -#include -#include -#include - -#include -#include "ecore_private.h" -#include - -#ifdef BUILD_ECORE_EVAS_EXTN - -#include - -#endif - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - - -#ifdef BUILD_ECORE_EVAS_EXTN - - -typedef struct _Shmfile Shmfile; - -struct _Shmfile -{ - int fd; - int size; - void *addr; - const char *file; -}; - -static int blank = 0x00000000; - -static Shmfile * -shmfile_new(const char *base, int id, int size, Eina_Bool sys) -{ - Shmfile *sf; - char file[PATH_MAX]; - - sf = calloc(1, sizeof(Shmfile)); - do - { - mode_t mode; - - snprintf(file, sizeof(file), "/%s-%i-%i.%i.%i", - base, id, (int)time(NULL), (int)getpid(), (int)rand()); - mode = S_IRUSR | S_IWUSR; - if (sys) mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - sf->fd = shm_open(file, O_RDWR | O_CREAT | O_EXCL, mode); - } - while (sf->fd < 0); - - sf->file = eina_stringshare_add(file); - if (!sf->file) - { - close(sf->fd); - shm_unlink(sf->file); - eina_stringshare_del(sf->file); - free(sf); - return NULL; - } - sf->size = size; - if (ftruncate(sf->fd, size) < 0) - { - close(sf->fd); - shm_unlink(sf->file); - eina_stringshare_del(sf->file); - free(sf); - return NULL; - } - sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0); - if (sf->addr == MAP_FAILED) - { - close(sf->fd); - shm_unlink(sf->file); - eina_stringshare_del(sf->file); - free(sf); - return NULL; - } - return sf; -} - -void -shmfile_free(Shmfile *sf) -{ - munmap(sf->addr, sf->size); - close(sf->fd); - shm_unlink(sf->file); - eina_stringshare_del(sf->file); - free(sf); -} - -static Shmfile * -shmfile_open(const char *ref, int size, Eina_Bool sys) -{ - Shmfile *sf; - mode_t mode; - - sf = calloc(1, sizeof(Shmfile)); - mode = S_IRUSR | S_IWUSR; - if (sys) mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - sf->fd = shm_open(ref, O_RDWR, mode); - if (sf->fd < 0) - { - free(sf); - return NULL; - } - sf->file = eina_stringshare_add(ref); - if (!sf->file) - { - close(sf->fd); - eina_stringshare_del(sf->file); - free(sf); - return NULL; - } - sf->size = size; - sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0); - if (sf->addr == MAP_FAILED) - { - close(sf->fd); - eina_stringshare_del(sf->file); - free(sf); - return NULL; - } - return sf; -} - -void -shmfile_close(Shmfile *sf) -{ - munmap(sf->addr, sf->size); - close(sf->fd); - eina_stringshare_del(sf->file); - free(sf); -} - -// procotol version - change this as needed -#define MAJOR 0x1011 - -enum // opcodes -{ - OP_RESIZE, - OP_SHOW, - OP_HIDE, - OP_FOCUS, - OP_UNFOCUS, - OP_UPDATE, - OP_UPDATE_DONE, - OP_LOCK_FILE, - OP_SHM_REF, - OP_EV_MOUSE_IN, - OP_EV_MOUSE_OUT, - OP_EV_MOUSE_UP, - OP_EV_MOUSE_DOWN, - OP_EV_MOUSE_MOVE, - OP_EV_MOUSE_WHEEL, - OP_EV_MULTI_UP, - OP_EV_MULTI_DOWN, - OP_EV_MULTI_MOVE, - OP_EV_KEY_UP, - OP_EV_KEY_DOWN, - OP_EV_HOLD -}; - -enum -{ - MOD_SHIFT = (1 << 0), - MOD_CTRL = (1 << 1), - MOD_ALT = (1 << 2), - MOD_META = (1 << 3), - MOD_HYPER = (1 << 4), - MOD_SUPER = (1 << 5), - MOD_CAPS = (1 << 6), - MOD_NUM = (1 << 7), - MOD_SCROLL = (1 << 8), -}; - -typedef struct _Ipc_Data_Resize Ipc_Data_Resize; -typedef struct _Ipc_Data_Update Ipc_Data_Update; -typedef struct _Ipc_Data_Ev_Mouse_In Ipc_Data_Ev_Mouse_In; -typedef struct _Ipc_Data_Ev_Mouse_Out Ipc_Data_Ev_Mouse_Out; -typedef struct _Ipc_Data_Ev_Mouse_Up Ipc_Data_Ev_Mouse_Up; -typedef struct _Ipc_Data_Ev_Mouse_Down Ipc_Data_Ev_Mouse_Down; -typedef struct _Ipc_Data_Ev_Mouse_Move Ipc_Data_Ev_Mouse_Move; -typedef struct _Ipc_Data_Ev_Mouse_Wheel Ipc_Data_Ev_Mouse_Wheel; -typedef struct _Ipc_Data_Ev_Hold Ipc_Data_Ev_Hold; -typedef struct _Ipc_Data_Ev_Multi_Up Ipc_Data_Ev_Multi_Up; -typedef struct _Ipc_Data_Ev_Multi_Down Ipc_Data_Ev_Multi_Down; -typedef struct _Ipc_Data_Ev_Multi_Move Ipc_Data_Ev_Multi_Move; -typedef struct _Ipc_Data_Ev_Key_Up Ipc_Data_Ev_Key_Up; -typedef struct _Ipc_Data_Ev_Key_Down Ipc_Data_Ev_Key_Down; - -struct _Ipc_Data_Resize -{ - int w, h; -}; - -struct _Ipc_Data_Update -{ - int x, w, y, h; -}; - -struct _Ipc_Data_Ev_Mouse_In -{ - unsigned int timestamp; - int mask; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Mouse_Out -{ - unsigned int timestamp; - int mask; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Mouse_Up -{ - int b; - Evas_Button_Flags flags; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Mouse_Down -{ - int b; - Evas_Button_Flags flags; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Mouse_Move -{ - int x, y; - Evas_Button_Flags flags; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Mouse_Wheel -{ - int direction, z; - Evas_Button_Flags flags; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Hold -{ - int hold; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Multi_Up -{ - Evas_Button_Flags flags; - int d, x, y; - double rad, radx, rady, pres, ang, fx, fy; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Multi_Down -{ - Evas_Button_Flags flags; - int d, x, y; - double rad, radx, rady, pres, ang, fx, fy; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Multi_Move -{ - int d, x, y; - double rad, radx, rady, pres, ang, fx, fy; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Key_Up -{ - const char *keyname, *key, *string, *compose; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -struct _Ipc_Data_Ev_Key_Down -{ - const char *keyname, *key, *string, *compose; - int mask; - unsigned int timestamp; - Evas_Event_Flags event_flags; -}; - -typedef struct _Extn Extn; - -struct _Extn -{ - struct { - Ecore_Ipc_Server *server; - Eina_List *clients; - Eina_List *handlers; - Eina_Bool am_server : 1; - } ipc; - struct { - const char *name; - int num; - Eina_Bool sys : 1; - } svc; - struct { - const char *lock; - int lockfd; - const char *shm; - int w, h; - Shmfile *shmfile; - Eina_List *updates; - Eina_Bool have_lock : 1; - Eina_Bool have_real_lock : 1; - } file; -}; - -static Eina_List *extn_ee_list = NULL; - -EAPI int ECORE_EVAS_EXTN_CLIENT_ADD = 0; -EAPI int ECORE_EVAS_EXTN_CLIENT_DEL = 0; - -void -_ecore_evas_extn_init(void) -{ - if (ECORE_EVAS_EXTN_CLIENT_ADD) return; - ECORE_EVAS_EXTN_CLIENT_ADD = ecore_event_type_new(); - ECORE_EVAS_EXTN_CLIENT_DEL = ecore_event_type_new(); -} - -void -_ecore_evas_extn_shutdown(void) -{ -} - -static void -_ecore_evas_extn_event_free(void *data, void *ev EINA_UNUSED) -{ - Ecore_Evas *ee = data; - if (ee->engine.buffer.image) - evas_object_unref(ee->engine.buffer.image); - _ecore_evas_unref(ee); -} - -static void -_ecore_evas_extn_event(Ecore_Evas *ee, int event) -{ - _ecore_evas_ref(ee); - if (ee->engine.buffer.image) - evas_object_ref(ee->engine.buffer.image); - ecore_event_add(event, ee->engine.buffer.image, - _ecore_evas_extn_event_free, ee); -} - -static Eina_Bool -_ecore_evas_lock_other_have(Ecore_Evas *ee) -{ - Eina_List *l; - Ecore_Evas *ee2; - Extn *extn, *extn2; - - extn = ee->engine.buffer.data; - if (!extn) return EINA_FALSE; - // brute force - i know. i expect extn_ee_list to be fairly short. could - // be improved with a hash of lockfiles - EINA_LIST_FOREACH(extn_ee_list, l, ee2) - { - if (ee == ee2) continue; - extn2 = ee2->engine.buffer.data; - if (!extn2) continue; - if ((extn->file.lock) && (extn2->file.lock) && - (!strcmp(extn->file.lock, extn2->file.lock)) && - (extn2->file.have_real_lock)) - return EINA_TRUE; - } - return EINA_FALSE; -} - -static void -_ecore_evas_socket_lock(Ecore_Evas *ee) -{ - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->file.lockfd < 0) return; - if (extn->file.have_lock) return; - extn->file.have_lock = EINA_TRUE; - if (_ecore_evas_lock_other_have(ee)) return; - flock(extn->file.lockfd, LOCK_EX); - extn->file.have_real_lock = EINA_TRUE; -} - -static void -_ecore_evas_socket_unlock(Ecore_Evas *ee) -{ - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->file.lockfd < 0) return; - if (!extn->file.have_lock) return; - extn->file.have_lock = EINA_FALSE; - if (!extn->file.have_real_lock) return; - flock(extn->file.lockfd, LOCK_UN); -} - -static void -_ecore_evas_extn_plug_targer_render_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - if (ee) _ecore_evas_socket_lock(ee); -} - -static void -_ecore_evas_extn_plug_targer_render_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - if (ee) _ecore_evas_socket_unlock(ee); -} - -static void -_ecore_evas_extn_plug_image_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - if (ee) ecore_evas_free(ee); -} - -static void -_ecore_evas_extn_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y) -{ - Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh; - - evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, &ww, &hh); - evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh); - - if (fw < 1) fw = 1; - if (fh < 1) fh = 1; - - if (evas_object_map_get(ee->engine.buffer.image) && - evas_object_map_enable_get(ee->engine.buffer.image)) - { - fx = 0; fy = 0; - fw = ee->w; fh = ee->h; - ww = ee->w; hh = ee->h; - } - - if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh)) - { - *x = (ee->w * (*x - xx)) / fw; - *y = (ee->h * (*y - yy)) / fh; - } - else - { - xx = (*x - xx) - fx; - while (xx < 0) xx += fw; - while (xx > fw) xx -= fw; - *x = (ee->w * xx) / fw; - - yy = (*y - yy) - fy; - while (yy < 0) yy += fh; - while (yy > fh) yy -= fh; - *y = (ee->h * yy) / fh; - } -} - -static void -_ecore_evas_extn_free(Ecore_Evas *ee) -{ - Extn *extn; - Ecore_Ipc_Client *client; - - extn = ee->engine.buffer.data; - if (extn) - { - Ecore_Event_Handler *hdl; - - if (extn->file.have_lock) - _ecore_evas_socket_unlock(ee); - if (extn->file.lockfd) - { - close(extn->file.lockfd); - if (extn->ipc.am_server) - { - if (extn->file.lock) unlink(extn->file.lock); - } - } - if (extn->svc.name) eina_stringshare_del(extn->svc.name); - if (extn->ipc.clients) - { - EINA_LIST_FREE(extn->ipc.clients, client) - ecore_ipc_client_del(client); - } - if (extn->ipc.server) ecore_ipc_server_del(extn->ipc.server); - if (extn->file.lock) eina_stringshare_del(extn->file.lock); - if (extn->file.shm) eina_stringshare_del(extn->file.shm); - if (extn->file.shmfile) - { - if (extn->ipc.am_server) - shmfile_free(extn->file.shmfile); - else - shmfile_close(extn->file.shmfile); - } - - EINA_LIST_FREE(extn->ipc.handlers, hdl) - ecore_event_handler_del(hdl); - free(extn); - ecore_ipc_shutdown(); - ee->engine.buffer.data = NULL; - } - if (ee->engine.buffer.image) - { - Ecore_Evas *ee2; - - evas_object_event_callback_del_full(ee->engine.buffer.image, - EVAS_CALLBACK_DEL, - _ecore_evas_extn_plug_image_obj_del, - ee); - evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image), - EVAS_CALLBACK_RENDER_PRE, - _ecore_evas_extn_plug_targer_render_pre, - ee); - evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image), - EVAS_CALLBACK_RENDER_POST, - _ecore_evas_extn_plug_targer_render_post, - ee); - evas_object_del(ee->engine.buffer.image); - ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent"); - if (ee2) - { - ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee); - } - } - extn_ee_list = eina_list_remove(extn_ee_list, ee); -} - -static void -_ecore_evas_resize(Ecore_Evas *ee, int w, int h) -{ - if (w < 1) w = 1; - if (h < 1) h = 1; - ee->req.w = w; - ee->req.h = h; - if ((w == ee->w) && (h == ee->h)) return; - ee->w = w; - ee->h = h; - - /* - * No need for it if not used later. - Extn *extn; - - extn = ee->engine.buffer.data; - */ - if (ee->engine.buffer.image) - evas_object_image_size_set(ee->engine.buffer.image, ee->w, ee->h); - /* Server can have many plugs, so I block resize comand from client to server * - if ((extn) && (extn->ipc.server)) - { - Ipc_Data_Resize ipc; - - ipc.w = ee->w; - ipc.h = ee->h; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_RESIZE, 0, 0, 0, &ipc, sizeof(ipc)); - }*/ - if (ee->func.fn_resize) ee->func.fn_resize(ee); -} - -static void -_ecore_evas_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h) -{ - _ecore_evas_resize(ee, w, h); -} - -static int -_ecore_evas_modifiers_locks_mask_get(Evas *e) -{ - int mask = 0; - - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift")) - mask |= MOD_SHIFT; - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control")) - mask |= MOD_CTRL; - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt")) - mask |= MOD_ALT; - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta")) - mask |= MOD_META; - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper")) - mask |= MOD_HYPER; - if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super")) - mask |= MOD_SUPER; - if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock")) - mask |= MOD_SCROLL; - if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock")) - mask |= MOD_NUM; - if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock")) - mask |= MOD_CAPS; - return mask; -} - -static void -_ecore_evas_modifiers_locks_mask_set(Evas *e, int mask) -{ - if (mask & MOD_SHIFT) evas_key_modifier_on (e, "Shift"); - else evas_key_modifier_off(e, "Shift"); - if (mask & MOD_CTRL) evas_key_modifier_on (e, "Control"); - else evas_key_modifier_off(e, "Control"); - if (mask & MOD_ALT) evas_key_modifier_on (e, "Alt"); - else evas_key_modifier_off(e, "Alt"); - if (mask & MOD_META) evas_key_modifier_on (e, "Meta"); - else evas_key_modifier_off(e, "Meta"); - if (mask & MOD_HYPER) evas_key_modifier_on (e, "Hyper"); - else evas_key_modifier_off(e, "Hyper"); - if (mask & MOD_SUPER) evas_key_modifier_on (e, "Super"); - else evas_key_modifier_off(e, "Super"); - if (mask & MOD_SCROLL) evas_key_lock_on (e, "Scroll_Lock"); - else evas_key_lock_off(e, "Scroll_Lock"); - if (mask & MOD_NUM) evas_key_lock_on (e, "Num_Lock"); - else evas_key_lock_off(e, "Num_Lock"); - if (mask & MOD_CAPS) evas_key_lock_on (e, "Caps_Lock"); - else evas_key_lock_off(e, "Caps_Lock"); -} - -static void -_ecore_evas_extn_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_In *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Mouse_In ipc; - memset(&ipc, 0, sizeof(ipc)); - - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_IN, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - -static void -_ecore_evas_extn_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Out *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Mouse_Out ipc; - memset(&ipc, 0, sizeof(ipc)); - - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_OUT, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - -static void -_ecore_evas_extn_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Down *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - /* We have send mouse move event before mouse down event */ - { - Ipc_Data_Ev_Mouse_Move ipc_move; - memset(&ipc_move, 0, sizeof(ipc_move)); - Evas_Coord x, y; - - x = ev->canvas.x; - y = ev->canvas.y; - _ecore_evas_extn_coord_translate(ee, &x, &y); - ipc_move.x = x; - ipc_move.y = y; - ipc_move.timestamp = ev->timestamp; - ipc_move.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc_move.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc_move, sizeof(ipc_move)); - } - { - Ipc_Data_Ev_Mouse_Down ipc; - memset(&ipc, 0, sizeof(ipc)); - ipc.b = ev->button; - ipc.flags = ev->flags; - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_DOWN, 0, 0, 0, &ipc, sizeof(ipc)); - } - } -} - -static void -_ecore_evas_extn_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Up *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Mouse_Up ipc; - memset(&ipc, 0, sizeof(ipc)); - - ipc.b = ev->button; - ipc.flags = ev->flags; - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_UP, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - -static void -_ecore_evas_extn_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Move *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Mouse_Move ipc; - memset(&ipc, 0, sizeof(ipc)); - Evas_Coord x, y; - - x = ev->cur.canvas.x; - y = ev->cur.canvas.y; - _ecore_evas_extn_coord_translate(ee, &x, &y); - ipc.x = x; - ipc.y = y; - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - -static void -_ecore_evas_extn_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Mouse_Wheel *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Mouse_Wheel ipc; - memset(&ipc, 0, sizeof(ipc)); - - ipc.direction = ev->direction; - ipc.z = ev->z; - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_WHEEL, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - -static void -_ecore_evas_extn_cb_multi_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Multi_Down *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Multi_Down ipc; - memset(&ipc, 0, sizeof(ipc)); - Evas_Coord x, y; - - ipc.d = ev->device; - x = ev->canvas.x; - y = ev->canvas.y; - _ecore_evas_extn_coord_translate(ee, &x, &y); - ipc.x = x; - ipc.y = y; - ipc.rad = ev->radius; - ipc.radx = ev->radius_x; - ipc.rady = ev->radius_y; - ipc.pres = ev->pressure; - ipc.ang = ev->angle; - ipc.fx = ev->canvas.xsub; - ipc.fy = ev->canvas.ysub; - ipc.flags = ev->flags; - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_DOWN, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - - -static void -_ecore_evas_extn_cb_multi_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Multi_Up *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Multi_Up ipc; - memset(&ipc, 0, sizeof(ipc)); - Evas_Coord x, y; - - ipc.d = ev->device; - x = ev->canvas.x; - y = ev->canvas.y; - _ecore_evas_extn_coord_translate(ee, &x, &y); - ipc.x = x; - ipc.y = y; - ipc.rad = ev->radius; - ipc.radx = ev->radius_x; - ipc.rady = ev->radius_y; - ipc.pres = ev->pressure; - ipc.ang = ev->angle; - ipc.fx = ev->canvas.xsub; - ipc.fy = ev->canvas.ysub; - ipc.flags = ev->flags; - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_UP, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - -static void -_ecore_evas_extn_cb_multi_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Multi_Move *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Multi_Move ipc; - memset(&ipc, 0, sizeof(ipc)); - Evas_Coord x, y; - - ipc.d = ev->device; - x = ev->cur.canvas.x; - y = ev->cur.canvas.y; - _ecore_evas_extn_coord_translate(ee, &x, &y); - ipc.x = x; - ipc.y = y; - ipc.rad = ev->radius; - ipc.radx = ev->radius_x; - ipc.rady = ev->radius_y; - ipc.pres = ev->pressure; - ipc.ang = ev->angle; - ipc.fx = ev->cur.canvas.xsub; - ipc.fy = ev->cur.canvas.ysub; - ipc.timestamp = ev->timestamp; - ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_MOVE, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - -static void -_ecore_evas_extn_cb_free(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - - ee = data; - if (ee->driver) _ecore_evas_free(ee); -} - -static void -_ecore_evas_extn_cb_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Key_Down *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Key_Down *ipc; - char *st, *p; - int len = 0; - - len = sizeof(Ipc_Data_Ev_Key_Down); - if (ev->key) len += strlen(ev->key) + 1; - if (ev->keyname) len += strlen(ev->keyname) + 1; - if (ev->string) len += strlen(ev->string) + 1; - if (ev->compose) len += strlen(ev->compose) + 1; - len += 1; - st = alloca(len); - ipc = (Ipc_Data_Ev_Key_Down *)st; - memset(st, 0, len); - p = st + sizeof(Ipc_Data_Ev_Key_Down); - if (ev->key) - { - strcpy(p, ev->key); - ipc->key = p - (long)st; - p += strlen(p) + 1; - } - if (ev->keyname) - { - strcpy(p, ev->keyname); - ipc->keyname = p - (long)st; - p += strlen(p) + 1; - } - if (ev->string) - { - strcpy(p, ev->string); - ipc->string = p - (long)st; - p += strlen(p) + 1; - } - if (ev->compose) - { - strcpy(p, ev->compose); - ipc->compose = p - (long)st; - p += strlen(p) + 1; - } - ipc->timestamp = ev->timestamp; - ipc->mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc->event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_KEY_DOWN, 0, 0, 0, ipc, len); - } -} - -static void -_ecore_evas_extn_cb_key_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Key_Up *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Key_Up *ipc; - char *st, *p; - int len = 0; - - len = sizeof(Ipc_Data_Ev_Key_Up); - if (ev->key) len += strlen(ev->key) + 1; - if (ev->keyname) len += strlen(ev->keyname) + 1; - if (ev->string) len += strlen(ev->string) + 1; - if (ev->compose) len += strlen(ev->compose) + 1; - len += 1; - st = alloca(len); - ipc = (Ipc_Data_Ev_Key_Up *)st; - memset(st, 0, len); - p = st + sizeof(Ipc_Data_Ev_Key_Down); - if (ev->key) - { - strcpy(p, ev->key); - ipc->key = p - (long)st; - p += strlen(p) + 1; - } - if (ev->keyname) - { - strcpy(p, ev->keyname); - ipc->keyname = p - (long)st; - p += strlen(p) + 1; - } - if (ev->string) - { - strcpy(p, ev->string); - ipc->string = p - (long)st; - p += strlen(p) + 1; - } - if (ev->compose) - { - strcpy(p, ev->compose); - ipc->compose = p - (long)st; - p += strlen(p) + 1; - } - ipc->timestamp = ev->timestamp; - ipc->mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); - ipc->event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_KEY_UP, 0, 0, 0, ipc, len); - } -} - -static void -_ecore_evas_extn_cb_hold(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Evas *ee = data; - Evas_Event_Hold *ev = event_info; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return; - if (extn->ipc.server) - { - Ipc_Data_Ev_Hold ipc; - memset(&ipc, 0, sizeof(ipc)); - - ipc.hold = ev->hold; - ipc.timestamp = ev->timestamp; - ipc.event_flags = ev->event_flags; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_HOLD, 0, 0, 0, &ipc, sizeof(ipc)); - } -} - -static void -_ecore_evas_extn_cb_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - Extn *extn; - - ee = data; - ee->prop.focused = 1; - extn = ee->engine.buffer.data; - if (!extn) return; - if (!extn->ipc.server) return; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_FOCUS, 0, 0, 0, NULL, 0); -} - -static void -_ecore_evas_extn_cb_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - Extn *extn; - - ee = data; - ee->prop.focused = 0; - extn = ee->engine.buffer.data; - if (!extn) return; - if (!extn->ipc.server) return; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_UNFOCUS, 0, 0, 0, NULL, 0); -} - -static void -_ecore_evas_extn_cb_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - Extn *extn; - - ee = data; - ee->visible = 1; - extn = ee->engine.buffer.data; - if (!extn) return; - if (!extn->ipc.server) return; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_SHOW, 0, 0, 0, NULL, 0); -} - -static void -_ecore_evas_extn_cb_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - Extn *extn; - - ee = data; - ee->visible = 0; - extn = ee->engine.buffer.data; - if (!extn) return; - if (!extn->ipc.server) return; - ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_HIDE, 0, 0, 0, NULL, 0); -} - -static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func = -{ - _ecore_evas_extn_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, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, //transparent - NULL, // profiles_set - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - NULL, // render - NULL, // screen_geometry_get - NULL // screen_dpi_get -}; - -static Eina_Bool -_ipc_server_add(void *data, int type EINA_UNUSED, void *event) -{ - Ecore_Ipc_Event_Server_Add *e = event; - Ecore_Evas *ee = data; - Extn *extn; - - if (ee != ecore_ipc_server_data_get(e->server)) - return ECORE_CALLBACK_PASS_ON; - if (!eina_list_data_find(extn_ee_list, ee)) - return ECORE_CALLBACK_PASS_ON; - extn = ee->engine.buffer.data; - if (!extn) return ECORE_CALLBACK_PASS_ON; - //FIXME: find a way to let app know server there - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ipc_server_del(void *data, int type EINA_UNUSED, void *event) -{ - Ecore_Ipc_Event_Server_Del *e = event; - Ecore_Evas *ee = data; - Extn *extn; - - extn = ee->engine.buffer.data; - if (!extn) return ECORE_CALLBACK_PASS_ON; - if (extn->ipc.server != e->server) return ECORE_CALLBACK_PASS_ON; - evas_object_image_data_set(ee->engine.buffer.image, NULL); - ee->engine.buffer.pixels = NULL; - if (extn->file.shmfile) - { - shmfile_close(extn->file.shmfile); - extn->file.shmfile = NULL; - } - if (extn->file.shm) - { - eina_stringshare_del(extn->file.shm); - extn->file.shm = NULL; - } - extn->ipc.server = NULL; - if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ipc_server_data(void *data, int type EINA_UNUSED, void *event) -{ - Ecore_Ipc_Event_Server_Data *e = event; - Ecore_Evas *ee = data; - Extn *extn; - - if (ee != ecore_ipc_server_data_get(e->server)) - return ECORE_CALLBACK_PASS_ON; - if (!eina_list_data_find(extn_ee_list, ee)) - return ECORE_CALLBACK_PASS_ON; - extn = ee->engine.buffer.data; - if (!extn) return ECORE_CALLBACK_PASS_ON; - if (e->major != MAJOR) - return ECORE_CALLBACK_PASS_ON; - switch (e->minor) - { - case OP_UPDATE: - // add rect to update list - if (e->size >= (int)sizeof(Ipc_Data_Update)) - { - Ipc_Data_Update *ipc = malloc(sizeof(Ipc_Data_Update)); - if (ipc) - { - memcpy(ipc, e->data, sizeof(Ipc_Data_Update)); - extn->file.updates = eina_list_append(extn->file.updates, ipc); - } - } - break; - case OP_UPDATE_DONE: - // updates finished being sent - done now. frame ready - { - Ipc_Data_Update *ipc; - - EINA_LIST_FREE(extn->file.updates, ipc) - { - if (ee->engine.buffer.image) - evas_object_image_data_update_add(ee->engine.buffer.image, - ipc->x, ipc->y, - ipc->w, ipc->h); - } - } - break; - case OP_LOCK_FILE: - if ((e->data) && (e->size > 0) && - (((unsigned char *)e->data)[e->size - 1] == 0)) - { - if (extn->file.have_lock) _ecore_evas_socket_unlock(ee); - if (extn->file.lockfd) close(extn->file.lockfd); - if (extn->file.lock) eina_stringshare_del(extn->file.lock); - extn->file.lock = eina_stringshare_add(e->data); - extn->file.lockfd = open(extn->file.lock, O_RDONLY); - } - break; - case OP_SHM_REF: - // e->ref == w - // e->ref_to == h - // e->response == alpha - // e->data = shm ref string + nul byte - if ((e->data) && ((unsigned char *)e->data)[e->size - 1] == 0) - { - ee->engine.buffer.pixels = NULL; - if (extn->file.shmfile) - { - shmfile_close(extn->file.shmfile); - extn->file.shmfile = NULL; - } - if (extn->file.shm) - { - eina_stringshare_del(extn->file.shm); - extn->file.shm = NULL; - } - if ((e->ref > 0) && (e->ref_to > 0)) - { - extn->file.w = e->ref; - extn->file.h = e->ref_to; - extn->file.shm = eina_stringshare_add(e->data); - extn->file.shmfile = shmfile_open(extn->file.shm, - extn->file.w * - extn->file.h * 4, - EINA_TRUE); - if (extn->file.shmfile) - { - ee->engine.buffer.pixels = extn->file.shmfile->addr; - if (ee->engine.buffer.image) - { - if (e->response) - evas_object_image_alpha_set(ee->engine.buffer.image, - EINA_TRUE); - else - evas_object_image_alpha_set(ee->engine.buffer.image, - EINA_FALSE); - evas_object_image_size_set(ee->engine.buffer.image, - extn->file.w, - extn->file.h); - evas_object_image_data_set(ee->engine.buffer.image, - ee->engine.buffer.pixels); - evas_object_image_data_update_add(ee->engine.buffer.image, - 0, 0, - extn->file.w, - extn->file.h); - _ecore_evas_resize(ee, - extn->file.w, - extn->file.h); - } - else - evas_object_image_data_set(ee->engine.buffer.image, NULL); - } - else - evas_object_image_data_set(ee->engine.buffer.image, NULL); - } - else - evas_object_image_data_set(ee->engine.buffer.image, NULL); - } - break; - case OP_RESIZE: - if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize))) - { - Ipc_Data_Resize *ipc = e->data; - _ecore_evas_resize(ee, ipc->w, ipc->h); - } - break; - default: - break; - } - return ECORE_CALLBACK_PASS_ON; -} -#else -void -_ecore_evas_extn_init(void) -{ -} - -void -_ecore_evas_extn_shutdown(void) -{ -} - -#endif /* BUILD_ECORE_EVAS_EXTN */ - -EAPI Evas_Object * -ecore_evas_extn_plug_new(Ecore_Evas *ee_target) -{ -#ifdef BUILD_ECORE_EVAS_EXTN - Evas_Object *o; - Ecore_Evas *ee; - int w = 1, h = 1; - - if (!ee_target) return NULL; - - ee = calloc(1, sizeof(Ecore_Evas)); - if (!ee) return NULL; - - o = evas_object_image_filled_add(ee_target->evas); - /* this make problem in gl engine, so I'll block this until solve problem - evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);*/ - evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888); - evas_object_image_alpha_set(o, 1); - evas_object_image_size_set(o, 1, 1); - evas_object_image_data_set(o, &blank); - - ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); - - ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_plug_engine_func; - - ee->driver = "extn_plug"; - - ee->rotation = 0; - ee->visible = 0; - ee->w = w; - ee->h = h; - ee->req.w = ee->w; - ee->req.h = ee->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; - - 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_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MOUSE_IN, - _ecore_evas_extn_cb_mouse_in, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MOUSE_OUT, - _ecore_evas_extn_cb_mouse_out, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MOUSE_DOWN, - _ecore_evas_extn_cb_mouse_down, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MOUSE_UP, - _ecore_evas_extn_cb_mouse_up, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MOUSE_MOVE, - _ecore_evas_extn_cb_mouse_move, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MOUSE_WHEEL, - _ecore_evas_extn_cb_mouse_wheel, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MULTI_DOWN, - _ecore_evas_extn_cb_multi_down, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MULTI_UP, - _ecore_evas_extn_cb_multi_up, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_MULTI_MOVE, - _ecore_evas_extn_cb_multi_move, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_FREE, - _ecore_evas_extn_cb_free, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_KEY_DOWN, - _ecore_evas_extn_cb_key_down, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_KEY_UP, - _ecore_evas_extn_cb_key_up, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_HOLD, - _ecore_evas_extn_cb_hold, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_FOCUS_IN, - _ecore_evas_extn_cb_focus_in, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_FOCUS_OUT, - _ecore_evas_extn_cb_focus_out, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_SHOW, - _ecore_evas_extn_cb_show, ee); - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_HIDE, - _ecore_evas_extn_cb_hide, ee); - - evas_object_event_callback_add(ee->engine.buffer.image, - EVAS_CALLBACK_DEL, - _ecore_evas_extn_plug_image_obj_del, ee); - - - extn_ee_list = eina_list_append(extn_ee_list, ee); - ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee); - - evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_PRE, - _ecore_evas_extn_plug_targer_render_pre, ee); - evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_POST, - _ecore_evas_extn_plug_targer_render_post, ee); - return o; -#else - return NULL; -#endif -} - -EAPI Eina_Bool -ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys) -{ -#ifdef BUILD_ECORE_EVAS_EXTN - Extn *extn; - Ecore_Evas *ee = NULL; - - if (!obj) return EINA_FALSE; - - ee = evas_object_data_get(obj, "Ecore_Evas"); - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) return EINA_FALSE; - - if (!svcname) - { - ee->engine.buffer.data = NULL; - return EINA_FALSE; - } - - extn = calloc(1, sizeof(Extn)); - if (!extn) return EINA_FALSE; - - Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER; - - ecore_ipc_init(); - extn->svc.name = eina_stringshare_add(svcname); - extn->svc.num = svcnum; - extn->svc.sys = svcsys; - - if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM; - extn->ipc.server = ecore_ipc_server_connect(ipctype, (char *)extn->svc.name, - extn->svc.num, ee); - if (!extn->ipc.server) - { - ee->engine.buffer.data = NULL; - eina_stringshare_del(extn->svc.name); - free(extn); - ecore_ipc_shutdown(); - return EINA_FALSE; - } - ee->engine.buffer.data = extn; - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, - _ipc_server_add, ee)); - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, - _ipc_server_del, ee)); - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, - _ipc_server_data, ee)); - return EINA_TRUE; -#else - return EINA_FALSE; -#endif -} - -EAPI void -ecore_evas_extn_plug_object_data_lock(Evas_Object *obj) -{ -#ifdef BUILD_ECORE_EVAS_EXTN - Ecore_Evas *ee; - - ee = ecore_evas_object_ecore_evas_get(obj); - if (!ee) return; - _ecore_evas_socket_lock(ee); -#endif -} - -EAPI void -ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj) -{ -#ifdef BUILD_ECORE_EVAS_EXTN - Ecore_Evas *ee; - - ee = ecore_evas_object_ecore_evas_get(obj); - if (!ee) return; - _ecore_evas_socket_unlock(ee); -#endif -} - -#ifdef BUILD_ECORE_EVAS_EXTN -static void -_ecore_evas_socket_resize(Ecore_Evas *ee, int w, int h) -{ - Extn *extn; - Evas_Engine_Info_Buffer *einfo; - int stride = 0; - - if (w < 1) w = 1; - if (h < 1) h = 1; - ee->req.w = w; - ee->req.h = 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); - extn = ee->engine.buffer.data; - if (extn) - { - if (extn->file.shmfile) - shmfile_free(extn->file.shmfile); - ee->engine.buffer.pixels = NULL; - extn->file.shmfile = shmfile_new(extn->svc.name, extn->svc.num, - ee->w * ee->h * 4, extn->svc.sys); - if (extn->file.shmfile) - ee->engine.buffer.pixels = extn->file.shmfile->addr; - - stride = ee->w * 4; - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) - { - if (ee->alpha) - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - else - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.dest_buffer = ee->engine.buffer.pixels; - einfo->info.dest_buffer_row_bytes = stride; - 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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - } - - if (extn->ipc.clients && extn->file.shmfile) - { - Ipc_Data_Resize ipc; - Eina_List *l; - Ecore_Ipc_Client *client; - - EINA_LIST_FOREACH(extn->ipc.clients, l, client) - ecore_ipc_client_send(client, MAJOR, OP_SHM_REF, - ee->w, ee->h, ee->alpha, - extn->file.shmfile->file, - strlen(extn->file.shmfile->file) + 1); - ipc.w = ee->w; - ipc.h = ee->h; - EINA_LIST_FOREACH(extn->ipc.clients, l, client) - ecore_ipc_client_send(client, MAJOR, OP_RESIZE, - 0, 0, 0, &ipc, sizeof(ipc)); - } - } - if (ee->func.fn_resize) ee->func.fn_resize(ee); -} - -static void -_ecore_evas_socket_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h) -{ - _ecore_evas_socket_resize(ee, w, h); -} - -int -_ecore_evas_extn_socket_render(Ecore_Evas *ee) -{ - Eina_List *updates = NULL, *l, *ll; - Ecore_Evas *ee2; - int rend = 0; - Eina_Rectangle *r; - Extn *extn; - Ecore_Ipc_Client *client; - - extn = ee->engine.buffer.data; - if (!extn) return rend; - EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) - { - if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); - - if (ee->engine.buffer.pixels) - { - _ecore_evas_socket_lock(ee); - updates = evas_render_updates(ee->evas); - _ecore_evas_socket_unlock(ee); - } - EINA_LIST_FOREACH(updates, l, r) - { - Ipc_Data_Update ipc; - - - ipc.x = r->x; - ipc.y = r->y; - ipc.w = r->w; - ipc.h = r->h; - EINA_LIST_FOREACH(extn->ipc.clients, ll, client) - ecore_ipc_client_send(client, MAJOR, OP_UPDATE, 0, 0, 0, &ipc, sizeof(ipc)); - } - if (updates) - { - evas_render_updates_free(updates); - _ecore_evas_idle_timeout_update(ee); - EINA_LIST_FOREACH(extn->ipc.clients, ll, client) - ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0); - } - - if (ee->func.fn_post_render) ee->func.fn_post_render(ee); - return updates ? 1 : rend; -} - -static Eina_Bool -_ipc_client_add(void *data, int type EINA_UNUSED, void *event) -{ - Ecore_Ipc_Event_Client_Add *e = event; - Ecore_Evas *ee = data; - Extn *extn; - - if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client))) - return ECORE_CALLBACK_PASS_ON; - if (!eina_list_data_find(extn_ee_list, ee)) - return ECORE_CALLBACK_PASS_ON; - extn = ee->engine.buffer.data; - if (!extn) return ECORE_CALLBACK_PASS_ON; - - extn->ipc.clients = eina_list_append(extn->ipc.clients, e->client); - ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE, 0, 0, 0, extn->file.lock, strlen(extn->file.lock) + 1); - - if (extn->file.shmfile) - { - Ipc_Data_Resize ipc; - - ecore_ipc_client_send(e->client, MAJOR, OP_SHM_REF, - ee->w, ee->h, ee->alpha, - extn->file.shmfile->file, - strlen(extn->file.shmfile->file) + 1); - ipc.w = ee->w; - ipc.h = ee->h; - - ecore_ipc_client_send(e->client, MAJOR, OP_RESIZE, - 0, 0, 0, &ipc, sizeof(ipc)); - } - _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_ADD); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ipc_client_del(void *data, int type EINA_UNUSED, void *event) -{ - Ecore_Ipc_Event_Client_Del *e = event; - Ecore_Evas *ee = data; - Extn *extn; - extn = ee->engine.buffer.data; - if (!extn) return ECORE_CALLBACK_PASS_ON; - if (!eina_list_data_find(extn->ipc.clients, e->client)) return ECORE_CALLBACK_PASS_ON; - - extn->ipc.clients = eina_list_remove(extn->ipc.clients, e->client); - - _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_DEL); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ipc_client_data(void *data, int type EINA_UNUSED, void *event) -{ - Ecore_Ipc_Event_Client_Data *e = event; - Ecore_Evas *ee = data; - Extn *extn; - - if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client))) - return ECORE_CALLBACK_PASS_ON; - if (!eina_list_data_find(extn_ee_list, ee)) - return ECORE_CALLBACK_PASS_ON; - extn = ee->engine.buffer.data; - if (!extn) return ECORE_CALLBACK_PASS_ON; - if (e->major != MAJOR) - return ECORE_CALLBACK_PASS_ON; - switch (e->minor) - { - case OP_RESIZE: - if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize))) - { - - Ipc_Data_Resize *ipc = e->data; - /* create callbacke data size changed */ - _ecore_evas_socket_resize(ee, ipc->w, ipc->h); - } - break; - case OP_SHOW: - if (!ee->visible) - { - ee->visible = 1; - if (ee->func.fn_show) ee->func.fn_show(ee); - } - break; - case OP_HIDE: - if (ee->visible) - { - ee->visible = 0; - if (ee->func.fn_hide) ee->func.fn_hide(ee); - } - break; - case OP_FOCUS: - if (!ee->prop.focused) - { - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - } - break; - case OP_UNFOCUS: - if (ee->prop.focused) - { - ee->prop.focused = 0; - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - } - break; - case OP_EV_MOUSE_IN: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_In)) - { - Ipc_Data_Ev_Mouse_In *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_mouse_in(ee->evas, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - case OP_EV_MOUSE_OUT: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Out)) - { - Ipc_Data_Ev_Mouse_Out *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_mouse_out(ee->evas, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - case OP_EV_MOUSE_UP: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Up)) - { - Ipc_Data_Ev_Mouse_Up *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_mouse_up(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - case OP_EV_MOUSE_DOWN: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Down)) - { - Ipc_Data_Ev_Mouse_Up *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_mouse_down(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - case OP_EV_MOUSE_MOVE: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Move)) - { - Ipc_Data_Ev_Mouse_Move *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_mouse_move(ee->evas, ipc->x, ipc->y, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - case OP_EV_MOUSE_WHEEL: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Wheel)) - { - Ipc_Data_Ev_Mouse_Wheel *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_mouse_wheel(ee->evas, ipc->direction, ipc->z, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - case OP_EV_MULTI_UP: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Up)) - { - Ipc_Data_Ev_Multi_Up *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_multi_up(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->flags, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - case OP_EV_MULTI_DOWN: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Down)) - { - Ipc_Data_Ev_Multi_Down *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_multi_down(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->flags, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - case OP_EV_MULTI_MOVE: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Move)) - { - Ipc_Data_Ev_Multi_Move *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_multi_move(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - -#define STRGET(val) \ - do { \ - if ((ipc->val) && (ipc->val < (char *)(long)(e->size - 1))) \ - ipc->val = ((char *)ipc) + (long)ipc->val; \ - else \ - ipc->val = NULL; \ - } while (0) - - case OP_EV_KEY_UP: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Up)) - { - if ((e->data) && (e->size > 0) && - (((unsigned char *)e->data)[e->size - 1] == 0)) - { - Ipc_Data_Ev_Key_Up *ipc = e->data; - Evas_Event_Flags flags; - - STRGET(keyname); - STRGET(key); - STRGET(string); - STRGET(compose); - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_key_up(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - } - break; - case OP_EV_KEY_DOWN: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Down)) - { - if ((e->data) && (e->size > 0) && - (((unsigned char *)e->data)[e->size - 1] == 0)) - { - Ipc_Data_Ev_Key_Down *ipc = e->data; - Evas_Event_Flags flags; - - STRGET(keyname); - STRGET(key); - STRGET(string); - STRGET(compose); - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); - evas_event_feed_key_down(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - } - break; - case OP_EV_HOLD: - if (e->size >= (int)sizeof(Ipc_Data_Ev_Hold)) - { - Ipc_Data_Ev_Hold *ipc = e->data; - Evas_Event_Flags flags; - - flags = evas_event_default_flags_get(ee->evas); - evas_event_default_flags_set(ee->evas, ipc->event_flags); - evas_event_feed_hold(ee->evas, ipc->hold, ipc->timestamp, NULL); - evas_event_default_flags_set(ee->evas, flags); - } - break; - default: - break; - } - return ECORE_CALLBACK_PASS_ON; -} - -static void -_ecore_evas_extn_socket_alpha_set(Ecore_Evas *ee, int alpha) -{ - Extn *extn; - Eina_List *l; - Ecore_Ipc_Client *client; - - if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha))) return; - ee->alpha = alpha; - - extn = ee->engine.buffer.data; - if (extn) - { - Evas_Engine_Info_Buffer *einfo; - - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) - { - if (ee->alpha) - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - else - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); - } - EINA_LIST_FOREACH(extn->ipc.clients, l, client) - ecore_ipc_client_send(client, MAJOR, OP_SHM_REF, - ee->w, ee->h, ee->alpha, - extn->file.shmfile->file, - strlen(extn->file.shmfile->file) + 1); - } -} - -static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func = -{ - _ecore_evas_extn_free, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - _ecore_evas_socket_resize, - _ecore_evas_socket_move_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, - _ecore_evas_extn_socket_alpha_set, - NULL, //transparent - NULL, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - _ecore_evas_extn_socket_render, // render - NULL, // screen_geometry_get - NULL, // screen_dpi_get -}; - -#endif - -EAPI Ecore_Evas * -ecore_evas_extn_socket_new(int w, int h) -{ -#ifdef BUILD_ECORE_EVAS_EXTN - 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); - - ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func; - - ee->driver = "extn_socket"; - - ee->rotation = 0; - ee->visible = 0; - ee->w = w; - ee->h = h; - ee->req.w = ee->w; - ee->req.h = ee->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); - - einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); - if (einfo) - { - if (ee->alpha) - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; - else - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.dest_buffer = NULL; - einfo->info.dest_buffer_row_bytes = 0; - 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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - 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"); - - extn_ee_list = eina_list_append(extn_ee_list, ee); - - _ecore_evas_register(ee); - - return ee; -#else - return NULL; -#endif -} - -EAPI Eina_Bool -ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys) -{ -#ifdef BUILD_ECORE_EVAS_EXTN - Extn *extn; - - extn = calloc(1, sizeof(Extn)); - if (!extn) - { - return EINA_FALSE; - } - else - { - Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER; - char buf[PATH_MAX]; - - ecore_ipc_init(); - extn->svc.name = eina_stringshare_add(svcname); - extn->svc.num = svcnum; - extn->svc.sys = svcsys; - - snprintf(buf, sizeof(buf), "/tmp/ee-lock-XXXXXX"); - extn->file.lockfd = mkstemp(buf); - if (extn->file.lockfd >= 0) - extn->file.lock = eina_stringshare_add(buf); - if ((extn->file.lockfd < 0) || (!extn->file.lock)) - { - if (extn->file.lockfd) - { - close(extn->file.lockfd); - unlink(buf); - } - eina_stringshare_del(extn->svc.name); - if (extn->file.lock) eina_stringshare_del(extn->file.lock); - free(extn); - ecore_ipc_shutdown(); - return EINA_FALSE; - } - - if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM; - extn->ipc.am_server = EINA_TRUE; - extn->ipc.server = ecore_ipc_server_add(ipctype, - (char *)extn->svc.name, - extn->svc.num, ee); - if (!extn->ipc.server) - { - if (extn->file.lockfd) - { - close(extn->file.lockfd); - if (extn->file.lock) unlink(extn->file.lock); - } - eina_stringshare_del(extn->svc.name); - eina_stringshare_del(extn->file.lock); - free(extn); - ecore_ipc_shutdown(); - return EINA_FALSE; - } - ee->engine.buffer.data = extn; - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, - _ipc_client_add, ee)); - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, - _ipc_client_del, ee)); - extn->ipc.handlers = eina_list_append - (extn->ipc.handlers, - ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, - _ipc_client_data, ee)); - } - return EINA_TRUE; -#else - return EINA_FALSE; -#endif -} diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c deleted file mode 100644 index 0f98e62d06..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c +++ /dev/null @@ -1,678 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#include -#include "ecore_private.h" -#ifdef BUILD_ECORE_EVAS_FB -#include -#include -#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[4] = {NULL, NULL, NULL, NULL}; - -static void -_ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y) -{ - 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); - } -} - -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 EINA_UNUSED) -{ - 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 EINA_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 Eina_Bool -_ecore_evas_event_mouse_button_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Event_Mouse_Button *e; - - e = event; - ee = _ecore_evas_fb_match(); - if (!ee) return ECORE_CALLBACK_PASS_ON; - _ecore_evas_mouse_move_process_fb(ee, e->x, e->y); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_event_mouse_button_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Event_Mouse_Button *e; - - e = event; - ee = _ecore_evas_fb_match(); - if (!ee) return ECORE_CALLBACK_PASS_ON; - _ecore_evas_mouse_move_process_fb(ee, e->x, e->y); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_event_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Event_Mouse_Move *e; - - e = event; - ee = _ecore_evas_fb_match(); - if (!ee) return ECORE_CALLBACK_PASS_ON; - _ecore_evas_mouse_move_process_fb(ee, e->x, e->y); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_event_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Event_Mouse_Wheel *e; - - e = event; - ee = _ecore_evas_fb_match(); - if (!ee) return ECORE_CALLBACK_PASS_ON; - _ecore_evas_mouse_move_process_fb(ee, e->x, e->y); - return ECORE_CALLBACK_PASS_ON; -} - -static int -_ecore_evas_fb_render(Ecore_Evas *ee) -{ - int rend = 0; - - if (ee->visible) - { - Eina_List *updates; - Eina_List *ll; - Ecore_Evas *ee2; - - if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); - - EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) - { - if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - 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(Ecore_Evas *ee, int w, int h) -{ - Eina_File_Direct_Info *info; - Eina_Iterator *ls; - Ecore_Fb_Input_Device *device; - Ecore_Fb_Input_Device_Cap caps; - int mouse_handled = 0; - - _ecore_evas_init_count++; - if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; - - ecore_event_evas_init(); - - /* register all input devices */ - ls = eina_file_direct_ls("/dev/input/"); - - EINA_ITERATOR_FOREACH(ls, info) - { - if (strncmp(info->path + info->name_start, "event", 5) != 0) - continue; - - if (!(device = ecore_fb_input_device_open(info->path))) - continue; - ecore_fb_input_device_window_set(device, ee); - - 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[0] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL); - ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL); - ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL); - ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_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); - } - } - eina_iterator_free(ls); - - if (!mouse_handled) - { - if (ecore_fb_ts_init()) - { - ecore_fb_ts_event_window_set(ee); - ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL); - ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL); - ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_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) -{ - ecore_evas_input_event_unregister(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) -{ - ee->req.w = w; - ee->req.h = 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 EINA_UNUSED, int y EINA_UNUSED, int w, int h) -{ - ee->req.w = w; - ee->req.h = 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 EINA_UNUSED) -{ - 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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - if (!ee->prop.fullscreen) - { - int tmp; - - tmp = ee->w; - ee->w = ee->h; - ee->h = tmp; - ee->req.w = ee->w; - ee->req.h = ee->h; - } - 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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - 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); - if (ee->func.fn_resize) ee->func.fn_resize(ee); -} - -static void -_ecore_evas_show(Ecore_Evas *ee) -{ - if (ee->prop.focused) return; - 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_hide(Ecore_Evas *ee) -{ - if (ee->prop.focused) - { - 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_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) - { - 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; - ee->req.w = ee->w; - ee->req.h = ee->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; - ee->req.w = ee->w; - ee->req.h = ee->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 < 4; i++) - { - if (ecore_evas_event_handlers[i]) - ecore_event_handler_del(ecore_evas_event_handlers[i]); - } - ecore_fb_ts_shutdown(); - 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_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, - _ecore_evas_show, - _ecore_evas_hide, - 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, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - NULL, // render - NULL, // screen_geometry_get - NULL // screen_dpi_get -}; -#endif - -/** - * @brief Create Ecore_Evas using fb backend. - * @param disp_name The name of the display to be used. - * @param rotation The rotation to be used. - * @param w The width of the Ecore_Evas to be created. - * @param h The height of the Ecore_Evas to be created. - * @return The new Ecore_Evas. - */ -#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(ee, 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->req.w = ee->w; - ee->req.h = ee->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 = 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 && disp_name) - { - einfo->info.virtual_terminal = 0; - einfo->info.device_number = strtol(disp_name, NULL, 10); - einfo->info.refresh = 0; - einfo->info.rotation = ee->rotation; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - - ecore_evas_input_event_register(ee); - - ee->engine.func->fn_render = _ecore_evas_fb_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); - return ee; -} -#else -EAPI Ecore_Evas * -ecore_evas_fb_new(const char *disp_name EINA_UNUSED, int rotation EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ - return NULL; -} -#endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h b/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h deleted file mode 100644 index 0c7b03043d..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h +++ /dev/null @@ -1,490 +0,0 @@ -#ifndef _ECORE_EVAS_PRIVATE_H -#define _ECORE_EVAS_PRIVATE_H - -#include -#include -#include -#include -#include - -#define ECORE_MAGIC_EVAS 0x76543211 - -#ifdef BUILD_ECORE_EVAS_X11 -# include -# include -# ifdef HAVE_ECORE_X_XCB -# include -# endif -# ifdef HAVE_ECORE_X_XLIB -# include -# include -# endif -#endif - -#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 -# include -#endif - -#ifdef BUILD_ECORE_EVAS_OPENGL_X11 -# include -#endif - -#ifdef BUILD_ECORE_EVAS_FB -# include -#endif - -#ifdef BUILD_ECORE_EVAS_DIRECTFB -# include -# include "Ecore_DirectFB.h" -#endif - -#if defined(BUILD_ECORE_EVAS_SOFTWARE_BUFFER) || defined(BUILD_ECORE_EVAS_EWS) -# include -#endif - -#ifdef BUILD_ECORE_EVAS_WIN32 -# include "Ecore_Win32.h" -# ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI -# include -# endif -# ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW -# include -# endif -# ifdef BUILD_ECORE_EVAS_DIRECT3D -# include -# endif -# ifdef BUILD_ECORE_EVAS_OPENGL_GLEW -# include -# endif -#endif - -#ifdef BUILD_ECORE_EVAS_GL_COCOA -# include "Ecore_Cocoa.h" -# include -#endif - -#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) -# include "Ecore_Wayland.h" -#endif - -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM -# include -#endif - -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL -# include -#endif - -/** Log domain macros and variables **/ - -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; -typedef void (*Ecore_Evas_Event_Cb) (Ecore_Evas *ee); -#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, Ecore_Evas_Event_Cb func); - void (*fn_callback_move_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_show_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_hide_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_delete_request_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_destroy_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_focus_in_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_focus_out_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_mouse_in_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_mouse_out_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_sticky_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_unsticky_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_pre_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - void (*fn_callback_post_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); - 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); - void (*fn_profiles_set) (Ecore_Evas *ee, const char **profiles, int num_profiles); - - void (*fn_window_group_set) (Ecore_Evas *ee, const Ecore_Evas *ee_group); - void (*fn_aspect_set) (Ecore_Evas *ee, double aspect); - void (*fn_urgent_set) (Ecore_Evas *ee, int urgent); - void (*fn_modal_set) (Ecore_Evas *ee, int modal); - void (*fn_demands_attention_set) (Ecore_Evas *ee, int demand); - void (*fn_focus_skip_set) (Ecore_Evas *ee, int skip); - - int (*fn_render) (Ecore_Evas *ee); - void (*fn_screen_geometry_get) (const Ecore_Evas *ee, int *x, int *y, int *w, int *h); - void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi); -}; - -struct _Ecore_Evas_Engine -{ - Ecore_Evas_Engine_Func *func; - -/* TODO: UGLY! This should be an union or inheritance! */ -#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; - Ecore_X_Window leader; - Ecore_X_Sync_Counter netwm_sync_counter; - int netwm_sync_val_hi; - unsigned int netwm_sync_val_lo; - 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; - unsigned char netwm_sync_set : 1; - unsigned char configure_coming : 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; - Ecore_X_Window win_shaped_input; - } 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; - void (*free_func) (void *data, void *pix); - void *(*alloc_func) (void *data, int size); - void *data; - } 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 region : 1; - unsigned char fullscreen : 1; - } state; - } win32; -#endif -#ifdef BUILD_ECORE_EVAS_EWS - struct { - Evas_Object *image; - } ews; -#endif - -#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) - struct - { - Ecore_Wl_Window *parent, *win; - Evas_Object *frame; - -# if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) - struct wl_shm_pool *pool; - size_t pool_size; - void *pool_data; - struct wl_buffer *buffer; -# endif - - } wl; -#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_Bool in : 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; - char *profile; - 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; - Ecore_Evas *group_ee; - Ecore_Window group_ee_win; - double aspect; - 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; - char draw_frame : 1; - char hwsurface : 1; - char urgent : 1; - char modal : 1; - char demand_attention : 1; - char focus_skip : 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); - void (*fn_state_change) (Ecore_Evas *ee); - } func; - - Ecore_Evas_Engine engine; - Eina_List *sub_ecore_evas; - - int refcount; - - unsigned char ignore_events : 1; - unsigned char manual_render : 1; - unsigned char registered : 1; - unsigned char no_comp_sync : 1; - unsigned char semi_sync : 1; - unsigned char deleted : 1; - int gl_sync_draw_done; // added by gl77.lee -}; - -void _ecore_evas_ref(Ecore_Evas *ee); -void _ecore_evas_unref(Ecore_Evas *ee); - -#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_EWS -void _ecore_evas_ews_events_init(void); -int _ecore_evas_ews_shutdown(void); -#endif - -#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) -int _ecore_evas_wl_common_init(void); -int _ecore_evas_wl_common_shutdown(void); -void _ecore_evas_wl_common_pre_free(Ecore_Evas *ee); -void _ecore_evas_wl_common_free(Ecore_Evas *ee); -void _ecore_evas_wl_common_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -void _ecore_evas_wl_common_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -void _ecore_evas_wl_common_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -void _ecore_evas_wl_common_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -void _ecore_evas_wl_common_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -void _ecore_evas_wl_common_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -void _ecore_evas_wl_common_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); -void _ecore_evas_wl_common_move(Ecore_Evas *ee, int x, int y); -void _ecore_evas_wl_common_raise(Ecore_Evas *ee); -void _ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title); -void _ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *c); -void _ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h); -void _ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h); -void _ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h); -void _ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h); -void _ecore_evas_wl_common_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y); -void _ecore_evas_wl_common_layer_set(Ecore_Evas *ee, int layer); -void _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, int iconify); -void _ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, int max); -void _ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, int full); -void _ecore_evas_wl_common_ignore_events_set(Ecore_Evas *ee, int ignore); -int _ecore_evas_wl_common_pre_render(Ecore_Evas *ee); -int _ecore_evas_wl_common_render_updates(Ecore_Evas *ee); -void _ecore_evas_wl_common_post_render(Ecore_Evas *ee); -int _ecore_evas_wl_common_render(Ecore_Evas *ee); -void _ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); -void _ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi); - -Evas_Object * _ecore_evas_wl_common_frame_add(Evas *evas); - -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM -void _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location); -#endif - -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL -void _ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location); -#endif -#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); -void _ecore_evas_mouse_multi_move_process(Ecore_Evas *ee, int device, - int x, int y, - double radius, - double radius_x, double radius_y, - double pressure, - double angle, - double mx, double my, - unsigned int timestamp); -void _ecore_evas_mouse_multi_down_process(Ecore_Evas *ee, int device, - int x, int y, - double radius, - double radius_x, double radius_y, - double pressure, - double angle, - double mx, double my, - Evas_Button_Flags flags, - unsigned int timestamp); -void _ecore_evas_mouse_multi_up_process(Ecore_Evas *ee, int device, - int x, int y, - double radius, - double radius_x, double radius_y, - double pressure, - double angle, - double mx, double my, - Evas_Button_Flags flags, - unsigned int timestamp); - -extern Eina_Bool _ecore_evas_app_comp_sync; - -void _ecore_evas_extn_init(void); -void _ecore_evas_extn_shutdown(void); - -#endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_psl1ght.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_psl1ght.c deleted file mode 100644 index 35252a3703..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_psl1ght.c +++ /dev/null @@ -1,515 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - -#ifdef BUILD_ECORE_EVAS_PSL1GHT -#include -#include - -static int _ecore_evas_init_count = 0; - -static Ecore_Evas *psl1ght_ee = NULL; -static Ecore_Event_Handler *ecore_evas_event_handlers[5] = { - NULL, NULL, NULL, NULL -}; - -static const char *ecore_evas_psl1ght_default = "EFL PSL1GHT"; -static int _ecore_evas_fps_debug = 0; -static Ecore_Poller *ecore_evas_event; - -static unsigned int -_ecore_evas_time_get() -{ - return (unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff; -} - -static Ecore_Evas * -_ecore_evas_psl1ght_match(void) -{ - return psl1ght_ee; -} - -static Eina_Bool -_ecore_evas_psl1ght_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Evas *ee; - - ee = _ecore_evas_psl1ght_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - /* pass on event */ - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_psl1ght_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Evas *ee; - - ee = _ecore_evas_psl1ght_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - /* pass on event */ - evas_focus_out(ee->evas); - ee->prop.focused = 0; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_psl1ght_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Evas *ee; - int w; - int h; - - ee = _ecore_evas_psl1ght_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - evas_output_size_get(ee->evas, &w, &h); - evas_damage_rectangle_add(ee->evas, 0, 0, w, h); - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_psl1ght_event_key_modifiers(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Psl1ght_Event_Key_Modifiers *e = event; - - ee = _ecore_evas_psl1ght_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - ecore_event_evas_modifier_lock_update(ee->evas, e->modifiers); - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_psl1ght_event_quit (void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Evas *ee; - - ee = _ecore_evas_psl1ght_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (ee->func.fn_delete_request) - ee->func.fn_delete_request(ee); - return ECORE_CALLBACK_PASS_ON; -} - -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_psl1ght_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 Eina_Bool -_ecore_evas_psl1ght_event(void *data EINA_UNUSED) -{ - ecore_psl1ght_poll_events(); - return ECORE_CALLBACK_RENEW; -} - -static int -_ecore_evas_psl1ght_init(int w EINA_UNUSED, int h EINA_UNUSED) -{ - _ecore_evas_init_count++; - if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; - - _ecore_evas_fps_debug = 1; - - // 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_psl1ght_event, NULL); - ecore_poller_poll_interval_set(ECORE_POLLER_CORE, 0.006); - - if (_ecore_evas_fps_debug) - _ecore_evas_fps_debug_init(); - - ecore_event_evas_init(); - - ecore_evas_event_handlers[0] = - ecore_event_handler_add(ECORE_PSL1GHT_EVENT_GOT_FOCUS, - _ecore_evas_psl1ght_event_got_focus, NULL); - ecore_evas_event_handlers[1] = - ecore_event_handler_add(ECORE_PSL1GHT_EVENT_LOST_FOCUS, - _ecore_evas_psl1ght_event_lost_focus, NULL); - ecore_evas_event_handlers[2] = - ecore_event_handler_add(ECORE_PSL1GHT_EVENT_EXPOSE, - _ecore_evas_psl1ght_event_video_expose, NULL); - ecore_evas_event_handlers[3] = - ecore_event_handler_add(ECORE_PSL1GHT_EVENT_KEY_MODIFIERS, - _ecore_evas_psl1ght_event_key_modifiers, NULL); - ecore_evas_event_handlers[4] = - ecore_event_handler_add(ECORE_PSL1GHT_EVENT_QUIT, - _ecore_evas_psl1ght_event_quit, NULL); - - return _ecore_evas_init_count; -} - -static int -_ecore_evas_psl1ght_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++) - ecore_event_handler_del(ecore_evas_event_handlers[i]); - ecore_event_evas_shutdown(); - ecore_poller_del(ecore_evas_event); - ecore_evas_event = NULL; - if (_ecore_evas_fps_debug) - _ecore_evas_fps_debug_shutdown(); - } - if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; - return _ecore_evas_init_count; -} - -static void -_ecore_evas_psl1ght_free(Ecore_Evas *ee) -{ - if (psl1ght_ee == ee) psl1ght_ee = NULL; - - ecore_event_window_unregister(0); - _ecore_evas_psl1ght_shutdown(); - ecore_psl1ght_shutdown(); -} - -static void -_ecore_evas_psl1ght_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) -{ - ee->func.fn_delete_request = func; -} - -static void -_ecore_evas_screen_resized(Ecore_Evas *ee) -{ - int w, h; - - /* Do not resize if the window is not fullscreen */ - if (ee->prop.fullscreen == 0) return; - - ecore_psl1ght_screen_resolution_get (&w, &h); - - if (w != ee->w || h != ee->h) - { - ee->req.w = ee->w = w; - ee->req.h = 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_psl1ght_resolution_set (w, h); - evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); - - _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, - _ecore_evas_time_get()); - if (ee->func.fn_resize) ee->func.fn_resize(ee); - } -} - -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); - - ecore_psl1ght_resolution_set (w, h); - - if (ee->func.fn_resize) ee->func.fn_resize(ee); - - _ecore_evas_screen_resized (ee); -} - -static void -_ecore_evas_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h) -{ - _ecore_evas_resize (ee, w, h); -} - -static void -_ecore_evas_show(Ecore_Evas *ee) -{ - if (ee->prop.focused) return; - 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_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) -{ - if (x) *x = 0; - if (y) *y = 0; - ecore_psl1ght_screen_resolution_get (w, h); -} - -static void -_ecore_evas_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) - { - 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_psl1ght_engine_func = -{ - _ecore_evas_psl1ght_free, - NULL, - NULL, - NULL, - NULL, - _ecore_evas_psl1ght_callback_delete_request_set, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - _ecore_evas_resize, - _ecore_evas_move_resize, - NULL, - NULL, - _ecore_evas_show, - 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, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - NULL, // render - _ecore_evas_screen_geometry_get, // screen_geometry_get - NULL // screen_dpi_get -}; - -EAPI Ecore_Evas * -ecore_evas_psl1ght_new(const char *name, int w, int h) -{ - void *einfo; - Ecore_Evas *ee; - - if (!name) - name = ecore_evas_psl1ght_default; - - 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_psl1ght_engine_func; - - ee->driver = "psl1ght"; - 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 = 0; - 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, evas_render_method_lookup("psl1ght")); - - evas_output_size_set(ee->evas, w, h); - evas_output_viewport_set(ee->evas, 0, 0, w, h); - - einfo = evas_engine_info_get(ee->evas); - if (einfo) - { - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - - if (!ecore_psl1ght_init(name)) - { - evas_free(ee->evas); - if (ee->name) free(ee->name); - free(ee); - return NULL; - } - ecore_psl1ght_resolution_set (w, h); - - _ecore_evas_psl1ght_init(w, h); - - ecore_event_window_register(0, ee, ee->evas, - (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); - - ee->engine.func->fn_render = _ecore_evas_psl1ght_render; - _ecore_evas_register(ee); - - psl1ght_ee = ee; - - _ecore_evas_screen_resized (ee); - - if (getenv("ECORE_EVAS_PSL1GHT_CURSOR_PATH")) - ecore_evas_cursor_set(ee, getenv("ECORE_EVAS_PSL1GHT_CURSOR_PATH"), EVAS_LAYER_MAX, 0, 0); - - evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); - - return ee; -} - -#else /* BUILD_ECORE_EVAS_PSL1GHT */ - -EAPI Ecore_Evas * -ecore_evas_psl1ght_new(const char *name EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ - ERR("OUTCH !"); - return NULL; -} - -#endif /* BUILD_ECORE_EVAS_PSL1GHT */ diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_sdl.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_sdl.c deleted file mode 100644 index 90b348ef2c..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_sdl.c +++ /dev/null @@ -1,665 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#if defined(BUILD_ECORE_EVAS_SOFTWARE_SDL) || defined(BUILD_ECORE_EVAS_OPENGL_SDL) -# include -# ifdef BUILD_ECORE_EVAS_OPENGL_SDL -# include -# endif -#endif - -#include -#include - -#if defined(BUILD_ECORE_EVAS_SOFTWARE_SDL) || defined(BUILD_ECORE_EVAS_OPENGL_SDL) -#include -#endif - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - -/* - * SDL only handle one window at a time. That's by definition, there is nothing wrong here. - * - */ -#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_evas_sdl_match(void) -{ - return sdl_ee; -} - -static void * -_ecore_evas_sdl_switch_buffer(void *data, void *dest EINA_UNUSED) -{ - SDL_Flip(data); - return ((SDL_Surface*)data)->pixels; -} - -static Eina_Bool -_ecore_evas_sdl_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Evas *ee; - - ee = _ecore_evas_sdl_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - /* pass on event */ - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_sdl_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Evas *ee; - - ee = _ecore_evas_sdl_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - /* pass on event */ - ee->prop.focused = 0; - evas_focus_out(ee->evas); - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_sdl_event_video_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Sdl_Event_Video_Resize *e; - Ecore_Evas *ee; - int rmethod; - - e = event; - ee = _ecore_evas_sdl_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - - rmethod = evas_output_method_get(ee->evas); - if (rmethod == evas_render_method_lookup("buffer")) - { - Evas_Engine_Info_Buffer *einfo; - - einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); - if (einfo) - { - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.switch_data = SDL_SetVideoMode(e->w, e->h, 32, - (ee->prop.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) - | (ee->prop.fullscreen ? SDL_FULLSCREEN : 0) - | (ee->alpha ? SDL_SRCALPHA : 0) - | SDL_DOUBLEBUF); - if (!einfo->info.switch_data) - { - return EINA_FALSE; - } - - SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); - SDL_FillRect(einfo->info.switch_data, NULL, 0); - - einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; - einfo->info.dest_buffer_row_bytes = e->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; - einfo->info.func.switch_buffer = _ecore_evas_sdl_switch_buffer; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *) einfo)) - { - return EINA_FALSE; - } - } - } - - ee->w = e->w; - ee->h = e->h; - ee->req.w = e->w; - ee->req.h = e->h; - - evas_output_size_set(ee->evas, e->w, e->h); - evas_output_viewport_set(ee->evas, 0, 0, e->w, e->h); - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_sdl_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - Ecore_Evas *ee; - int w; - int h; - - ee = _ecore_evas_sdl_match(); - - if (!ee) return ECORE_CALLBACK_PASS_ON; - evas_output_size_get(ee->evas, &w, &h); - evas_damage_rectangle_add(ee->evas, 0, 0, w, h); - - return ECORE_CALLBACK_PASS_ON; -} - -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; - 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); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - 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 Eina_Bool -_ecore_evas_sdl_event(void *data EINA_UNUSED) -{ - ecore_sdl_feed_events(); - return ECORE_CALLBACK_RENEW; -} - -static int -_ecore_evas_sdl_init(int w EINA_UNUSED, int h EINA_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) - { - unsigned 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) -{ - int rmethod; - - if ((w == ee->w) && (h == ee->h)) return; - ee->req.w = w; - ee->req.h = h; - ee->w = w; - ee->h = h; - - rmethod = evas_output_method_get(ee->evas); - if (rmethod == evas_render_method_lookup("buffer")) - { - Evas_Engine_Info_Buffer *einfo; - - einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); - if (einfo) - { - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.switch_data = SDL_SetVideoMode(w, h, 32, - (ee->prop.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) - | (ee->prop.fullscreen ? SDL_FULLSCREEN : 0) - | (ee->alpha ? SDL_SRCALPHA : 0) - | SDL_DOUBLEBUF); - if (!einfo->info.switch_data) - { - return ; - } - - SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); - SDL_FillRect(einfo->info.switch_data, NULL, 0); - - einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; - einfo->info.dest_buffer_row_bytes = 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; - einfo->info.func.switch_buffer = _ecore_evas_sdl_switch_buffer; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *) einfo)) - { - return ; - } - } - } - - 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 EINA_UNUSED, int y EINA_UNUSED, int w, int h) -{ - if ((w == ee->w) && (h == ee->h)) return; - ee->req.w = w; - ee->req.h = 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); - 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_show(Ecore_Evas *ee) -{ - if (ee->prop.focused) return; - ee->prop.focused = 1; - evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); -} - -static void -_ecore_evas_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) - { - 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, - _ecore_evas_show, - 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, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - NULL, // render - NULL, // screen_geometry_get - NULL // screen_dpi_get -}; - -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) -{ - Ecore_Evas *ee; - - if (!name) - name = ecore_evas_sdl_default; - - 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->req.w = w; - ee->req.h = h; - 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; - ee->alpha = alpha; - ee->prop.hwsurface = hwsurface; - - /* 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("buffer")) - { - Evas_Engine_Info_Buffer *einfo; - - einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); - if (einfo) - { - SDL_Init(SDL_INIT_NOPARACHUTE); - - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) - { - ERR("SDL_Init failed with %s", SDL_GetError()); - SDL_Quit(); - return NULL; - } - - einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.switch_data = SDL_SetVideoMode(w, h, 32, - (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) - | (fullscreen ? SDL_FULLSCREEN : 0) - | (noframe ? SDL_NOFRAME : 0) - | (alpha ? SDL_SRCALPHA : 0) - | SDL_DOUBLEBUF); - if (!einfo->info.switch_data) - { - ERR("SDL_SetVideoMode failed !"); - ecore_evas_free(ee); - return NULL; - } - - SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); - SDL_FillRect(einfo->info.switch_data, NULL, 0); - - einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; - einfo->info.dest_buffer_row_bytes = 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; - einfo->info.func.switch_buffer = _ecore_evas_sdl_switch_buffer; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *) einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else if (rmethod == evas_render_method_lookup("gl_sdl")) - { -#ifdef BUILD_ECORE_EVAS_OPENGL_SDL - Evas_Engine_Info_GL_SDL *einfo; - - einfo = (Evas_Engine_Info_GL_SDL *) evas_engine_info_get(ee->evas); - if (einfo) - { - einfo->flags.fullscreen = fullscreen; - einfo->flags.noframe = noframe; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } -#endif - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - - 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, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); - - SDL_ShowCursor(SDL_ENABLE); - - ee->engine.func->fn_render = _ecore_evas_sdl_render; - _ecore_evas_register(ee); - - sdl_ee = ee; - 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("buffer"); - if (!rmethod) return NULL; - - ee = _ecore_evas_internal_sdl_new(rmethod, name, w, h, fullscreen, hwsurface, noframe, alpha); - return ee; -} -#else -EAPI Ecore_Evas* -ecore_evas_sdl_new(const char* name EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, int fullscreen EINA_UNUSED, int hwsurface EINA_UNUSED, int noframe EINA_UNUSED, int alpha EINA_UNUSED) -{ - ERR("OUTCH !"); - return NULL; -} -#endif - -EAPI Ecore_Evas* -ecore_evas_sdl16_new(const char* name EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, int fullscreen EINA_UNUSED, int hwsurface EINA_UNUSED, int noframe EINA_UNUSED, int alpha EINA_UNUSED) -{ - ERR("OUTCH !"); - return NULL; -} - -#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); - if (ee) ee->driver = "gl_sdl"; - return ee; -} -#else -EAPI Ecore_Evas* -ecore_evas_gl_sdl_new(const char* name EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, int fullscreen EINA_UNUSED, int noframe EINA_UNUSED) -{ - ERR("OUTCH !"); - return NULL; -} -#endif - diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_util.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_util.c deleted file mode 100644 index 85ff2bd37f..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_util.c +++ /dev/null @@ -1,451 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include -#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, Evas_Coord x, Evas_Coord y) -{ - Ecore_Evas *ee = data; - // FIXME: account for frame - ecore_evas_move(ee, x, y); - if (ecore_evas_override_get(ee)) evas_object_move(obj, x, y); -} - -static void -_ecore_evas_obj_intercept_raise(void *data, Evas_Object *obj EINA_UNUSED) -{ - Ecore_Evas *ee = data; - ecore_evas_raise(ee); -} - -static void -_ecore_evas_obj_intercept_lower(void *data, Evas_Object *obj EINA_UNUSED) -{ - Ecore_Evas *ee = data; - ecore_evas_lower(ee); -} - -static void -_ecore_evas_obj_intercept_stack_above(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *above EINA_UNUSED) -{ - INF("TODO: %s", __FUNCTION__); -} - -static void -_ecore_evas_obj_intercept_stack_below(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *below EINA_UNUSED) -{ - INF("TODO: %s", __FUNCTION__); -} - -static void -_ecore_evas_obj_intercept_layer_set(void *data, Evas_Object *obj EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - ecore_evas_show(ee); -} - -static void -_ecore_evas_obj_callback_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - ecore_evas_hide(ee); -} - -static void -_ecore_evas_obj_callback_resize(void *data, Evas *e, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - Evas_Coord ow, oh, fw, fh; - - evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); - evas_output_framespace_get(e, NULL, NULL, &fw, &fh); - ow += fw; - oh += fh; - ecore_evas_resize(ee, ow, oh); -} - -static void -_ecore_evas_obj_callback_changed_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj, void *event_info EINA_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 EINA_UNUSED, 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; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - - CHECK_PARAM_POINTER_RETURN("obj", obj, EINA_FALSE); - if (!_ecore_evas_object_evas_check(__FUNCTION__, ee, obj)) - return EINA_FALSE; - - 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 EINA_TRUE; -} - -EAPI Eina_Bool -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 EINA_FALSE; - } - - CHECK_PARAM_POINTER_RETURN("obj", obj, EINA_FALSE); - 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 EINA_FALSE; - } - - 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 EINA_FALSE; - } - - _ecore_evas_object_dissociate(ee, obj); - - return EINA_TRUE; -} - -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. - * @param parser This parameter isn't in use. - * @param desc This parameter isn't in use. - * @param str This parameter isn't in use. - * @param data The data to be used. - * @param storage The storage to be used. - * @return The function always return 1. - */ -unsigned char -ecore_getopt_callback_ecore_evas_list_engines(const Ecore_Getopt *parser EINA_UNUSED, const Ecore_Getopt_Desc *desc EINA_UNUSED, const char *str EINA_UNUSED, void *data, Ecore_Getopt_Value *storage) -{ - Eina_List *lst, *n; - const char *engine; - - if (!storage) - { - ERR("Storage is missing"); - return 0; - } - - 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; -} diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_common.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_common.c deleted file mode 100644 index 5e83175932..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_common.c +++ /dev/null @@ -1,783 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -//#define LOGFNS 1 - -#ifdef LOGFNS -# include -# define LOGFN(fl, ln, fn) \ - printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn); -#else -# define LOGFN(fl, ln, fn) -#endif - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - -/* local structures */ -typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data; -struct _EE_Wl_Smart_Data -{ - Evas_Object *frame; - Evas_Object *text; - Evas_Coord x, y, w, h; -}; - -static Evas_Smart *_ecore_evas_wl_common_smart = NULL; - -/* local variables */ - -static int _ecore_evas_wl_init_count = 0; -static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[5]; - -static Eina_Bool -_ecore_evas_wl_common_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Mouse_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->window); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); - ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); - evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); - _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); - ee->in = EINA_TRUE; - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_common_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Mouse_Out *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->window); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->in) - { - ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); - evas_event_feed_mouse_out(ee->evas, ev->timestamp, 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); - ee->in = EINA_FALSE; - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_common_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Focus_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Focus_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - evas_focus_out(ee->evas); - ee->prop.focused = 0; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Wl_Event_Window_Configure *ev; - int nw = 0, nh = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = event; - ee = ecore_event_window_match(ev->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; - if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - - if (ee->prop.fullscreen) - { - _ecore_evas_wl_common_move(ee, ev->x, ev->y); - ee->engine.func->fn_resize(ee, ev->w, ev->h); - - return ECORE_CALLBACK_PASS_ON; - } - - if ((ee->x != ev->x) || (ee->y != ev->y)) - { - ee->req.x = ee->x; - ee->req.y = ee->y; - if (ee->func.fn_move) ee->func.fn_move(ee); - } - - nw = ev->w; - nh = ev->h; - - if ((ee->prop.maximized) || (!ee->prop.fullscreen)) - { - int fw = 0, fh = 0; - - evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - nw = ev->w - fw; - nh = ev->h - fh; - } - - if (ee->prop.min.w > nw) nw = ee->prop.min.w; - else if (nw > ee->prop.max.w) nw = ee->prop.max.w; - if (ee->prop.min.h > nh) nh = ee->prop.min.h; - else if (nh > ee->prop.max.h) nh = ee->prop.max.h; - - if ((ee->w != nw) || (ee->h != nh)) - { - ee->req.w = nw; - ee->req.h = nh; - if (ee->func.fn_resize) ee->func.fn_resize(ee); - } - - return ECORE_CALLBACK_PASS_ON; -} - -int -_ecore_evas_wl_common_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (++_ecore_evas_wl_init_count != 1) - return _ecore_evas_wl_init_count; - - _ecore_evas_wl_event_hdls[0] = - ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, - _ecore_evas_wl_common_cb_mouse_in, NULL); - _ecore_evas_wl_event_hdls[1] = - ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, - _ecore_evas_wl_common_cb_mouse_out, NULL); - _ecore_evas_wl_event_hdls[2] = - ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, - _ecore_evas_wl_common_cb_focus_in, NULL); - _ecore_evas_wl_event_hdls[3] = - ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, - _ecore_evas_wl_common_cb_focus_out, NULL); - _ecore_evas_wl_event_hdls[4] = - ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, - _ecore_evas_wl_common_cb_window_configure, NULL); - - ecore_event_evas_init(); - - return _ecore_evas_wl_init_count; -} - -int -_ecore_evas_wl_common_shutdown(void) -{ - unsigned int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (--_ecore_evas_wl_init_count != 0) - return _ecore_evas_wl_init_count; - - for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++) - { - if (_ecore_evas_wl_event_hdls[i]) - ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]); - } - - ecore_event_evas_shutdown(); - - return _ecore_evas_wl_init_count; -} - -void -_ecore_evas_wl_common_pre_free(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame); -} - -void -_ecore_evas_wl_common_free(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win); - ee->engine.wl.win = NULL; - - ecore_event_window_unregister(ee->prop.window); - ecore_evas_input_event_unregister(ee); - - _ecore_evas_wl_common_shutdown(); - ecore_wl_shutdown(); -} - -void -_ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (w < 1) w = 1; - if (h < 1) h = 1; - - ee->req.w = w; - ee->req.h = h; - - if (!ee->prop.fullscreen) - { - int fw = 0, fh = 0; - - if (ee->prop.min.w > w) w = ee->prop.min.w; - else if (w > ee->prop.max.w) w = ee->prop.max.w; - if (ee->prop.min.h > h) h = ee->prop.min.h; - else if (h > ee->prop.max.h) h = ee->prop.max.h; - - evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - w += fw; - h += fh; - } - - if ((ee->w != w) || (ee->h != h)) - { - ee->w = w; - ee->h = h; - - if ((ee->rotation == 90) || (ee->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); - } - - if (ee->prop.avoid_damage) - { - int pdam = 0; - - pdam = ecore_evas_avoid_damage_get(ee); - ecore_evas_avoid_damage_set(ee, 0); - ecore_evas_avoid_damage_set(ee, pdam); - } - - if (ee->engine.wl.frame) - evas_object_resize(ee->engine.wl.frame, w, h); - } -} - -void -_ecore_evas_wl_common_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - if (!ee) return; - ee->func.fn_resize = func; -} - -void -_ecore_evas_wl_common_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - if (!ee) return; - ee->func.fn_move = func; -} - -void -_ecore_evas_wl_common_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - if (!ee) return; - ee->func.fn_delete_request = func; -} - -void -_ecore_evas_wl_common_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - if (!ee) return; - ee->func.fn_focus_in = func; -} - -void -_ecore_evas_wl_common_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - if (!ee) return; - ee->func.fn_focus_out = func; -} - -void -_ecore_evas_wl_common_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - if (!ee) return; - ee->func.fn_mouse_in = func; -} - -void -_ecore_evas_wl_common_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) -{ - if (!ee) return; - ee->func.fn_mouse_out = func; -} - -void -_ecore_evas_wl_common_move(Ecore_Evas *ee, int x, int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - - ee->req.x = x; - ee->req.y = y; - - if ((ee->x != x) || (ee->y != y)) - { - ee->x = x; - ee->y = y; - if (ee->engine.wl.win) - ecore_wl_window_update_location(ee->engine.wl.win, x, y); - if (ee->func.fn_move) ee->func.fn_move(ee); - } -} - -static void -_ecore_evas_wl_common_smart_add(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - Evas *evas; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return; - - evas = evas_object_evas_get(obj); - - sd->x = 0; - sd->y = 0; - sd->w = 1; - sd->h = 1; - - sd->frame = evas_object_rectangle_add(evas); - evas_object_color_set(sd->frame, 249, 249, 249, 255); - evas_object_smart_member_add(sd->frame, obj); - - sd->text = evas_object_text_add(evas); - evas_object_color_set(sd->text, 0, 0, 0, 255); - evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN); - evas_object_text_font_set(sd->text, "Sans", 10); - evas_object_text_text_set(sd->text, "Smart Test"); - evas_object_smart_member_add(sd->text, obj); - - evas_object_smart_data_set(obj, sd); -} - -static void -_ecore_evas_wl_common_smart_del(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_del(sd->text); - evas_object_del(sd->frame); - free(sd); -} - -static void -_ecore_evas_wl_common_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - if ((sd->w == w) && (sd->h == h)) return; - sd->w = w; - sd->h = h; - evas_object_resize(sd->frame, w, h); -} - -static void -_ecore_evas_wl_common_smart_show(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_show(sd->frame); - evas_object_show(sd->text); -} - -static void -_ecore_evas_wl_common_smart_hide(Evas_Object *obj) -{ - EE_Wl_Smart_Data *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sd = evas_object_smart_data_get(obj))) return; - evas_object_hide(sd->text); - evas_object_hide(sd->frame); -} - -static void -_ecore_evas_wl_common_smart_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (_ecore_evas_wl_common_smart) return; - { - static const Evas_Smart_Class sc = - { - "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION, - _ecore_evas_wl_common_smart_add, - _ecore_evas_wl_common_smart_del, - NULL, - _ecore_evas_wl_common_smart_resize, - _ecore_evas_wl_common_smart_show, - _ecore_evas_wl_common_smart_hide, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - }; - _ecore_evas_wl_common_smart = evas_smart_class_new(&sc); - } -} - -Evas_Object * -_ecore_evas_wl_common_frame_add(Evas *evas) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_evas_wl_common_smart_init(); - return evas_object_smart_add(evas, _ecore_evas_wl_common_smart); -} - -void -_ecore_evas_wl_common_raise(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (!ee->visible)) return; - ecore_wl_window_raise(ee->engine.wl.win); -} - -void -_ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.title) free(ee->prop.title); - ee->prop.title = NULL; - if (title) ee->prop.title = strdup(title); - if ((ee->prop.draw_frame) && (ee->engine.wl.frame)) - { - EE_Wl_Smart_Data *sd; - - if ((sd = evas_object_smart_data_get(ee->engine.wl.frame))) - evas_object_text_text_set(sd->text, ee->prop.title); - } - - if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, - ee->prop.title); -} - -void -_ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *c) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - 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); - - if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, - ee->prop.clas); -} - -void -_ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - 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; -} - -void -_ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - 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; -} - -void -_ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - 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; -} - -void -_ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 0) w = 0; - if (h < 0) h = 0; - if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return; - ee->prop.step.w = w; - ee->prop.step.h = h; -} - -static void -_ecore_evas_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee; - - ee = data; - if (ee) ee->prop.cursor.object = NULL; -} - -void -_ecore_evas_wl_common_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y) -{ - int x, y, fx, fy; - - if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); - - if (!obj) - { - ee->prop.cursor.object = NULL; - ee->prop.cursor.layer = 0; - ee->prop.cursor.hot.x = 0; - ee->prop.cursor.hot.y = 0; - ecore_wl_window_cursor_default_restore(ee->engine.wl.win); - 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_wl_window_pointer_set(ee->engine.wl.win, NULL, 0, 0); - - evas_pointer_output_xy_get(ee->evas, &x, &y); - evas_output_framespace_get(ee->evas, &fx, &fy, NULL, NULL); - evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer); - evas_object_move(ee->prop.cursor.object, - x - fx - ee->prop.cursor.hot.x, - y - fy - 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); -} - -void -_ecore_evas_wl_common_layer_set(Ecore_Evas *ee, int layer) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.layer == layer) return; - if (layer < 1) layer = 1; - else if (layer > 255) layer = 255; - ee->prop.layer = layer; -} - -void -_ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, int iconify) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.iconified == iconify) return; - ee->prop.iconified = iconify; - /* FIXME: Implement this in Wayland someshow */ -} - -void -_ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, int max) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.maximized == max) return; - ee->prop.maximized = max; - ecore_wl_window_maximized_set(ee->engine.wl.win, max); -} - -void -_ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, int full) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->prop.fullscreen == full) return; - ee->prop.fullscreen = full; - ecore_wl_window_fullscreen_set(ee->engine.wl.win, full); -} - -void -_ecore_evas_wl_common_ignore_events_set(Ecore_Evas *ee, int ignore) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - ee->ignore_events = ignore; - /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */ -} - -int -_ecore_evas_wl_common_pre_render(Ecore_Evas *ee) -{ - int rend = 0; - Eina_List *ll = NULL; - Ecore_Evas *ee2 = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); - - EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) - { - if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - return rend; -} - -int -_ecore_evas_wl_common_render_updates(Ecore_Evas *ee) -{ - int rend = 0; - Eina_List *updates = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((updates = evas_render_updates(ee->evas))) - { - Eina_List *l = NULL; - Eina_Rectangle *r; - - EINA_LIST_FOREACH(updates, l, r) - ecore_wl_window_damage(ee->engine.wl.win, - r->x, r->y, r->w, r->h); - - ecore_wl_flush(); - - evas_render_updates_free(updates); - rend = 1; - } - - return rend; -} - -void -_ecore_evas_wl_common_post_render(Ecore_Evas *ee) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_evas_idle_timeout_update(ee); - if (ee->func.fn_post_render) ee->func.fn_post_render(ee); -} - -int -_ecore_evas_wl_common_render(Ecore_Evas *ee) -{ - int rend = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return 0; - if (!ee->visible) - { - evas_norender(ee->evas); - return 0; - } - - rend = _ecore_evas_wl_common_pre_render(ee); - rend |= _ecore_evas_wl_common_render_updates(ee); - _ecore_evas_wl_common_post_render(ee); - - return rend; -} - -void -_ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (x) *x = 0; - if (y) *y = 0; - ecore_wl_screen_size_get(w, h); -} - -void -_ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee EINA_UNUSED, int *xdpi, int *ydpi) -{ - int dpi = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (xdpi) *xdpi = 0; - if (ydpi) *ydpi = 0; - /* FIXME: Ideally this needs to get the DPI from a specific screen */ - dpi = ecore_wl_dpi_get(); - if (xdpi) *xdpi = dpi; - if (ydpi) *ydpi = dpi; -} diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c deleted file mode 100644 index ed176e8b6e..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c +++ /dev/null @@ -1,434 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -//#define LOGFNS 1 - -#ifdef LOGFNS -# include -# define LOGFN(fl, ln, fn) \ - printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn); -#else -# define LOGFN(fl, ln, fn) -#endif - -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL -# include -# include -# include -# include -# include -#endif - -#include - -#include "Ecore_Evas.h" - -#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL -# include "ecore_evas_private.h" -# include -# include - -/* local function prototypes */ -static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_show(Ecore_Evas *ee); -static void _ecore_evas_wl_hide(Ecore_Evas *ee); -static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha); -static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent); - -static Ecore_Evas_Engine_Func _ecore_wl_engine_func = -{ - _ecore_evas_wl_common_free, - _ecore_evas_wl_common_callback_resize_set, - _ecore_evas_wl_common_callback_move_set, - NULL, - NULL, - _ecore_evas_wl_common_callback_delete_request_set, - NULL, - _ecore_evas_wl_common_callback_focus_in_set, - _ecore_evas_wl_common_callback_focus_out_set, - _ecore_evas_wl_common_callback_mouse_in_set, - _ecore_evas_wl_common_callback_mouse_out_set, - NULL, // sticky_set - NULL, // unsticky_set - NULL, // pre_render_set - NULL, // post_render_set - _ecore_evas_wl_common_move, - NULL, // managed_move - _ecore_evas_wl_resize, - NULL, // move_resize - NULL, // rotation_set - NULL, // shaped_set - _ecore_evas_wl_show, - _ecore_evas_wl_hide, - _ecore_evas_wl_common_raise, - NULL, // lower - NULL, // activate - _ecore_evas_wl_common_title_set, - _ecore_evas_wl_common_name_class_set, - _ecore_evas_wl_common_size_min_set, - _ecore_evas_wl_common_size_max_set, - _ecore_evas_wl_common_size_base_set, - _ecore_evas_wl_common_size_step_set, - _ecore_evas_wl_common_object_cursor_set, - _ecore_evas_wl_common_layer_set, - NULL, // focus set - _ecore_evas_wl_common_iconified_set, - NULL, // borderless set - NULL, // override set - _ecore_evas_wl_common_maximized_set, - _ecore_evas_wl_common_fullscreen_set, - NULL, // func avoid_damage set - NULL, // func withdrawn set - NULL, // func sticky set - _ecore_evas_wl_common_ignore_events_set, - _ecore_evas_wl_alpha_set, - _ecore_evas_wl_transparent_set, - NULL, // func profiles set - NULL, // window group set - NULL, // aspect set - NULL, // urgent set - NULL, // modal set - NULL, // demand attention set - NULL, // focus skip set - _ecore_evas_wl_common_render, - _ecore_evas_wl_common_screen_geometry_get, - _ecore_evas_wl_common_screen_dpi_get -}; - -/* external variables */ - -/* external functions */ -EAPI Ecore_Evas * -ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame) -{ - Ecore_Wl_Window *p = NULL; - Evas_Engine_Info_Wayland_Egl *einfo; - Ecore_Evas *ee; - int method = 0, count = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(method = evas_render_method_lookup("wayland_egl"))) - { - ERR("Render method lookup failed for Wayland_Egl"); - return NULL; - } - - count = ecore_wl_init(disp_name); - if (!count) - { - ERR("Failed to initialize Ecore_Wayland"); - return NULL; - } - else if (count == 1) - ecore_wl_display_iterate(); - - if (!(ee = calloc(1, sizeof(Ecore_Evas)))) - { - ERR("Failed to allocate Ecore_Evas"); - goto ee_err; - } - - ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); - - _ecore_evas_wl_common_init(); - - ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func; - - ee->driver = "wayland_egl"; - 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->rotation = 0; - ee->prop.max.w = 32767; - ee->prop.max.h = 32767; - ee->prop.layer = 4; - ee->prop.request_pos = 0; - ee->prop.sticky = 0; - ee->prop.draw_frame = frame; - ee->alpha = EINA_FALSE; - - ee->evas = evas_new(); - evas_data_attach_set(ee->evas, ee); - evas_output_method_set(ee->evas, method); - evas_output_size_set(ee->evas, ee->w, ee->h); - evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); - - /* FIXME: This needs to be set based on theme & scale */ - if (ee->prop.draw_frame) - evas_output_framespace_set(ee->evas, 4, 18, 8, 22); - - if (parent) - p = ecore_wl_window_find(parent); - - /* FIXME: Get if parent is alpha, and set */ - - ee->engine.wl.parent = p; - ee->engine.wl.win = - ecore_wl_window_new(p, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW); - ee->prop.window = ee->engine.wl.win->id; - - if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) - { - einfo->info.display = ecore_wl_display_get(); - einfo->info.destination_alpha = ee->alpha; - einfo->info.rotation = ee->rotation; - einfo->info.depth = 32; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("Failed to set Evas Engine Info for '%s'", ee->driver); - goto err; - } - } - else - { - ERR("Failed to get Evas Engine Info for '%s'", ee->driver); - goto err; - } - - ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free); - - if (ee->prop.draw_frame) - { - ee->engine.wl.frame = _ecore_evas_wl_common_frame_add(ee->evas); - evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE); - evas_object_move(ee->engine.wl.frame, 0, 0); - } - - _ecore_evas_register(ee); - ecore_evas_input_event_register(ee); - - ecore_event_window_register(ee->prop.window, ee, ee->evas, - (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); - - return ee; - - err: - ecore_evas_free(ee); - _ecore_evas_wl_common_shutdown(); - - ee_err: - ecore_wl_shutdown(); - return NULL; -} - -static void -_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 1) w = 1; - if (h < 1) h = 1; - - ee->req.w = w; - ee->req.h = h; - - if (!ee->prop.fullscreen) - { - int fw = 0, fh = 0; - - if (ee->prop.min.w > w) w = ee->prop.min.w; - else if (w > ee->prop.max.w) w = ee->prop.max.w; - if (ee->prop.min.h > h) h = ee->prop.min.h; - else if (h > ee->prop.max.h) h = ee->prop.max.h; - - evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - w += fw; - h += fh; - } - - if ((ee->w != w) || (ee->h != h)) - { - ee->w = w; - ee->h = h; - - if ((ee->rotation == 90) || (ee->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); - } - - if (ee->prop.avoid_damage) - { - int pdam = 0; - - pdam = ecore_evas_avoid_damage_get(ee); - ecore_evas_avoid_damage_set(ee, 0); - ecore_evas_avoid_damage_set(ee, pdam); - } - - if (ee->engine.wl.frame) - evas_object_resize(ee->engine.wl.frame, w, h); - - - if (ee->engine.wl.win) - { - ecore_wl_window_update_size(ee->engine.wl.win, w, h); - ecore_wl_window_buffer_attach(ee->engine.wl.win, NULL, 0, 0); - } - - if (ee->func.fn_resize) ee->func.fn_resize(ee); - } -} - -static void -_ecore_evas_wl_show(Ecore_Evas *ee) -{ - Evas_Engine_Info_Wayland_Egl *einfo; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (ee->visible)) return; - - if (ee->engine.wl.win) - { - ecore_wl_window_show(ee->engine.wl.win); - ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); - ecore_wl_window_buffer_attach(ee->engine.wl.win, NULL, 0, 0); - - if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, - ee->prop.clas); - if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, - ee->prop.title); - } - - if (ee->engine.wl.frame) - { - evas_object_show(ee->engine.wl.frame); - evas_object_resize(ee->engine.wl.frame, ee->w, ee->h); - } - - if (ee->engine.wl.win) - { - einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas); - if (!einfo) - { - ERR("Failed to get Evas Engine Info for '%s'", ee->driver); - return; - } - - einfo->info.surface = ecore_wl_window_surface_get(ee->engine.wl.win); - /* if (einfo->info.surface) */ - evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - /* else */ - /* printf("Failed to get a Surface from Ecore_Wl\n"); */ - } - - ee->visible = 1; - if (ee->func.fn_show) ee->func.fn_show(ee); -} - -static void -_ecore_evas_wl_hide(Ecore_Evas *ee) -{ - Evas_Engine_Info_Wayland_Egl *einfo; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (!ee->visible)) return; - - einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas); - if (einfo) - { - einfo->info.surface = NULL; - evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - } - - if (ee->engine.wl.win) - ecore_wl_window_hide(ee->engine.wl.win); - - ee->visible = 0; - ee->should_be_visible = 0; - - if (ee->func.fn_hide) ee->func.fn_hide(ee); -} - -static void -_ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha) -{ - Evas_Engine_Info_Wayland_Egl *einfo; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if ((ee->alpha == alpha)) return; - ee->alpha = alpha; - if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) - { - einfo->info.destination_alpha = alpha; - 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); - } -} - -static void -_ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent) -{ - Evas_Engine_Info_Wayland_Egl *einfo; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if ((ee->transparent == transparent)) return; - ee->transparent = transparent; - if (!ee->visible) return; - if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) - { - 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); - } -} - -void -_ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->engine.wl.win) - { - Evas_Engine_Info_Wayland_Egl *einfo; - - if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) - { - einfo->info.edges = location; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - - ee->engine.wl.win->resizing = EINA_TRUE; - ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location); - } -} -#else -EAPI Ecore_Evas * -ecore_evas_wayland_egl_new(const char *disp_name EINA_UNUSED, unsigned int parent EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, Eina_Bool frame EINA_UNUSED) -{ - return NULL; -} -#endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_shm.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_shm.c deleted file mode 100644 index 24e349534a..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_shm.c +++ /dev/null @@ -1,656 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -//#define LOGFNS 1 - -#ifdef LOGFNS -# include -# define LOGFN(fl, ln, fn) \ - printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn); -#else -# define LOGFN(fl, ln, fn) -#endif - -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM -# include -# include -# include -# include -# include -#endif - -#include - -#include "Ecore_Evas.h" - -#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM -# include "ecore_evas_private.h" -# include -# include - -/* local function prototypes */ -static void _ecore_evas_wl_free(Ecore_Evas *ee); -static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h); -static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); -static void _ecore_evas_wl_show(Ecore_Evas *ee); -static void _ecore_evas_wl_hide(Ecore_Evas *ee); -static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha); -static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent); -static int _ecore_evas_wl_render(Ecore_Evas *ee); - -/* SHM Only */ -static void _ecore_evas_wl_shm_pool_free(Ecore_Evas *ee); -static void _ecore_evas_wl_shm_pool_create(Ecore_Evas *ee, size_t size); -static void _ecore_evas_wl_buffer_free(Ecore_Evas *ee); -static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, int w, int h); - -/* Frame listener */ -static void _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t time); -static const struct wl_callback_listener frame_listener = -{ - _ecore_evas_wl_frame_complete, -}; - -static Ecore_Evas_Engine_Func _ecore_wl_engine_func = -{ - _ecore_evas_wl_free, - _ecore_evas_wl_common_callback_resize_set, - _ecore_evas_wl_common_callback_move_set, - NULL, - NULL, - _ecore_evas_wl_common_callback_delete_request_set, - NULL, - _ecore_evas_wl_common_callback_focus_in_set, - _ecore_evas_wl_common_callback_focus_out_set, - _ecore_evas_wl_common_callback_mouse_in_set, - _ecore_evas_wl_common_callback_mouse_out_set, - NULL, // sticky_set - NULL, // unsticky_set - NULL, // pre_render_set - NULL, // post_render_set - _ecore_evas_wl_common_move, - NULL, // managed_move - _ecore_evas_wl_resize, - _ecore_evas_wl_move_resize, - NULL, // rotation_set - NULL, // shaped_set - _ecore_evas_wl_show, - _ecore_evas_wl_hide, - _ecore_evas_wl_common_raise, - NULL, // lower - NULL, // activate - _ecore_evas_wl_common_title_set, - _ecore_evas_wl_common_name_class_set, - _ecore_evas_wl_common_size_min_set, - _ecore_evas_wl_common_size_max_set, - _ecore_evas_wl_common_size_base_set, - _ecore_evas_wl_common_size_step_set, - _ecore_evas_wl_common_object_cursor_set, - _ecore_evas_wl_common_layer_set, - NULL, // focus set - _ecore_evas_wl_common_iconified_set, - NULL, // borderless set - NULL, // override set - _ecore_evas_wl_common_maximized_set, - _ecore_evas_wl_common_fullscreen_set, - NULL, // func avoid_damage set - NULL, // func withdrawn set - NULL, // func sticky set - _ecore_evas_wl_common_ignore_events_set, - _ecore_evas_wl_alpha_set, - _ecore_evas_wl_transparent_set, - NULL, // func profiles set - NULL, // window group set - NULL, // aspect set - NULL, // urgent set - NULL, // modal set - NULL, // demand attention set - NULL, // focus skip set - _ecore_evas_wl_render, - _ecore_evas_wl_common_screen_geometry_get, - _ecore_evas_wl_common_screen_dpi_get -}; - -/* external variables */ - -/* external functions */ -EAPI Ecore_Evas * -ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame) -{ - Ecore_Wl_Window *p = NULL; - Evas_Engine_Info_Wayland_Shm *einfo; - Ecore_Evas *ee; - int method = 0, count = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(method = evas_render_method_lookup("wayland_shm"))) - { - ERR("Render method lookup failed for Wayland_Shm"); - return NULL; - } - - count = ecore_wl_init(disp_name); - if (!count) - { - ERR("Failed to initialize Ecore_Wayland"); - return NULL; - } - else if (count == 1) - ecore_wl_display_iterate(); - - if (!(ee = calloc(1, sizeof(Ecore_Evas)))) - { - ERR("Failed to allocate Ecore_Evas"); - goto ee_err; - } - - ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); - - _ecore_evas_wl_common_init(); - - ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func; - - ee->driver = "wayland_shm"; - 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->rotation = 0; - ee->prop.max.w = 32767; - ee->prop.max.h = 32767; - ee->prop.layer = 4; - ee->prop.request_pos = 0; - ee->prop.sticky = 0; - ee->prop.draw_frame = frame; - ee->alpha = EINA_FALSE; - - ee->evas = evas_new(); - evas_data_attach_set(ee->evas, ee); - evas_output_method_set(ee->evas, method); - evas_output_size_set(ee->evas, ee->w, ee->h); - evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); - - /* FIXME: This needs to be set based on theme & scale */ - if (ee->prop.draw_frame) - evas_output_framespace_set(ee->evas, 4, 18, 8, 22); - - if (parent) - p = ecore_wl_window_find(parent); - - /* FIXME: Get if parent is alpha, and set */ - - ee->engine.wl.parent = p; - ee->engine.wl.win = - ecore_wl_window_new(p, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_SHM); - ee->prop.window = ee->engine.wl.win->id; - - if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) - { - einfo->info.destination_alpha = ee->alpha; - einfo->info.rotation = ee->rotation; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("Failed to set Evas Engine Info for '%s'", ee->driver); - goto err; - } - } - else - { - ERR("Failed to get Evas Engine Info for '%s'", ee->driver); - goto err; - } - - ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free); - - if (ee->prop.draw_frame) - { - ee->engine.wl.frame = _ecore_evas_wl_common_frame_add(ee->evas); - evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE); - evas_object_move(ee->engine.wl.frame, 0, 0); - } - - _ecore_evas_register(ee); - ecore_evas_input_event_register(ee); - - ecore_event_window_register(ee->prop.window, ee, ee->evas, - (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); - - return ee; - - err: - ecore_evas_free(ee); - _ecore_evas_wl_common_shutdown(); - - ee_err: - ecore_wl_shutdown(); - return NULL; -} - -static void -_ecore_evas_wl_free(Ecore_Evas *ee) -{ - _ecore_evas_wl_buffer_free(ee); - _ecore_evas_wl_shm_pool_free(ee); - _ecore_evas_wl_common_free(ee); -} - -static void -_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) -{ - Evas_Engine_Info_Wayland_Shm *einfo; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (w < 1) w = 1; - if (h < 1) h = 1; - - ee->req.w = w; - ee->req.h = h; - - if (!ee->prop.fullscreen) - { - int fw = 0, fh = 0; - - if (ee->prop.min.w > w) w = ee->prop.min.w; - else if (w > ee->prop.max.w) w = ee->prop.max.w; - if (ee->prop.min.h > h) h = ee->prop.min.h; - else if (h > ee->prop.max.h) h = ee->prop.max.h; - - evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); - w += fw; - h += fh; - } - - if ((ee->w != w) || (ee->h != h)) - { - ee->w = w; - ee->h = h; - - if ((ee->rotation == 90) || (ee->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); - } - - if (ee->prop.avoid_damage) - { - int pdam = 0; - - pdam = ecore_evas_avoid_damage_get(ee); - ecore_evas_avoid_damage_set(ee, 0); - ecore_evas_avoid_damage_set(ee, pdam); - } - - if (ee->engine.wl.frame) - evas_object_resize(ee->engine.wl.frame, w, h); - - _ecore_evas_wl_buffer_new(ee, w, h); - - einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); - if (!einfo) - { - ERR("Failed to get Evas Engine Info for '%s'", ee->driver); - return; - } - - einfo->info.dest = ee->engine.wl.pool_data; - evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - - if (ee->engine.wl.win) - { - ecore_wl_window_update_size(ee->engine.wl.win, w, h); - ecore_wl_window_buffer_attach(ee->engine.wl.win, - ee->engine.wl.buffer, 0, 0); - } - - if (ee->func.fn_resize) ee->func.fn_resize(ee); - } -} - -static void -_ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if ((ee->x != x) || (ee->y != y)) - _ecore_evas_wl_common_move(ee, x, y); - if ((ee->w != w) || (ee->h != h)) - _ecore_evas_wl_resize(ee, w, h); -} - -static void -_ecore_evas_wl_show(Ecore_Evas *ee) -{ - Evas_Engine_Info_Wayland_Shm *einfo; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (ee->visible)) return; - - _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); - - einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); - if (!einfo) - { - ERR("Failed to get Evas Engine Info for '%s'", ee->driver); - return; - } - - einfo->info.dest = ee->engine.wl.pool_data; - evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - - if (ee->engine.wl.win) - { - ecore_wl_window_show(ee->engine.wl.win); - ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); - ecore_wl_window_buffer_attach(ee->engine.wl.win, - ee->engine.wl.buffer, 0, 0); - - if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, - ee->prop.clas); - if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) - wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, - ee->prop.title); - } - - if (ee->engine.wl.frame) - { - evas_object_show(ee->engine.wl.frame); - evas_object_resize(ee->engine.wl.frame, ee->w, ee->h); - } - - ee->visible = 1; - if (ee->func.fn_show) ee->func.fn_show(ee); -} - -static void -_ecore_evas_wl_hide(Ecore_Evas *ee) -{ - Evas_Engine_Info_Wayland_Shm *einfo; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!ee) || (!ee->visible)) return; - - _ecore_evas_wl_buffer_free(ee); - - munmap(ee->engine.wl.pool_data, ee->engine.wl.pool_size); - - einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); - if ((einfo) && (einfo->info.dest)) - { - einfo->info.dest = NULL; - evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); - } - - if (ee->engine.wl.win) - ecore_wl_window_hide(ee->engine.wl.win); - - ee->visible = 0; - ee->should_be_visible = 0; - - if (ee->func.fn_hide) ee->func.fn_hide(ee); -} - -static void -_ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha) -{ - Evas_Engine_Info_Wayland_Shm *einfo; - Ecore_Wl_Window *win = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if ((ee->alpha == alpha)) return; - ee->alpha = alpha; - - /* FIXME: NB: We should really add a ecore_wl_window_alpha_set function - * but we are in API freeze, so just hack it in for now and fix when - * freeze is over */ - if ((win = ee->engine.wl.win)) - win->alpha = alpha; - - /* if (ee->engine.wl.win) */ - /* ecore_wl_window_transparent_set(ee->engine.wl.win, alpha); */ - - _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); - - if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) - { - einfo->info.destination_alpha = alpha; - einfo->info.dest = ee->engine.wl.pool_data; - 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); - } - - if (win) - { - ecore_wl_window_update_size(win, ee->w, ee->h); - ecore_wl_window_buffer_attach(win, ee->engine.wl.buffer, 0, 0); - } -} - -static void -_ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent) -{ - Evas_Engine_Info_Wayland_Shm *einfo; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if ((ee->transparent == transparent)) return; - ee->transparent = transparent; - - if (ee->engine.wl.win) - ecore_wl_window_transparent_set(ee->engine.wl.win, transparent); - - _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); - - if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) - { - einfo->info.destination_alpha = transparent; - einfo->info.dest = ee->engine.wl.pool_data; - 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); - } - - if (ee->engine.wl.win) - { - ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); - ecore_wl_window_buffer_attach(ee->engine.wl.win, - ee->engine.wl.buffer, 0, 0); - } -} - -static void -_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t time EINA_UNUSED) -{ - Ecore_Evas *ee = data; - Ecore_Wl_Window *win = NULL; - - if (!ee) return; - if (!(win = ee->engine.wl.win)) return; - - win->frame_callback = NULL; - win->frame_pending = EINA_FALSE; - wl_callback_destroy(callback); - - if (win->surface) - { - win->frame_callback = wl_surface_frame(win->surface); - wl_callback_add_listener(win->frame_callback, &frame_listener, ee); - } -} - -static int -_ecore_evas_wl_render(Ecore_Evas *ee) -{ - int rend = 0; - Ecore_Wl_Window *win = NULL; - - if (!ee) return 0; - if (!ee->visible) - { - evas_norender(ee->evas); - return 0; - } - - if (!(win = ee->engine.wl.win)) return 0; - - rend = _ecore_evas_wl_common_pre_render(ee); - if (!(win->frame_pending)) - { - /* FIXME - ideally have an evas_changed_get to return the value - * of evas->changed to avoid creating this callback and - * destroying it again - */ - - if (!win->frame_callback) - { - win->frame_callback = wl_surface_frame(win->surface); - wl_callback_add_listener(win->frame_callback, &frame_listener, ee); - } - - rend |= _ecore_evas_wl_common_render_updates(ee); - if (rend) - win->frame_pending = EINA_TRUE; - } - _ecore_evas_wl_common_post_render(ee); - return rend; -} - -static void -_ecore_evas_wl_shm_pool_free(Ecore_Evas *ee) -{ - if (!ee->engine.wl.pool) return; - - wl_shm_pool_destroy(ee->engine.wl.pool); - ee->engine.wl.pool = NULL; - ee->engine.wl.pool_size = 0; - ee->engine.wl.pool_data = NULL; -} - -static void -_ecore_evas_wl_shm_pool_create(Ecore_Evas *ee, size_t size) -{ - struct wl_shm *shm; - void *data; - char tmp[PATH_MAX]; - int fd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (size <= ee->engine.wl.pool_size) - return; - - size *= 1.5; - _ecore_evas_wl_shm_pool_free(ee); - - if (!(shm = ecore_wl_shm_get())) - { - ERR("ecore_wl_shm_get returned NULL"); - return; - } - - strcpy(tmp, "/tmp/ecore-evas-wayland_shm-XXXXXX"); - if ((fd = mkstemp(tmp)) < 0) - { - ERR("Could not create temporary file."); - return; - } - - if (ftruncate(fd, size) < 0) - { - ERR("Could not truncate temporary file."); - goto end; - } - - data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0); - unlink(tmp); - - if (data == MAP_FAILED) - { - ERR("mmap of temporary file failed."); - goto end; - } - - ee->engine.wl.pool_size = size; - ee->engine.wl.pool_data = data; - ee->engine.wl.pool = wl_shm_create_pool(shm, fd, size); - - end: - close(fd); -} - -static void -_ecore_evas_wl_buffer_free(Ecore_Evas *ee) -{ - if (!ee->engine.wl.buffer) return; - - wl_buffer_destroy(ee->engine.wl.buffer); - ee->engine.wl.buffer = NULL; -} - -static void -_ecore_evas_wl_buffer_new(Ecore_Evas *ee, int w, int h) -{ - unsigned int format; - int stride = 0; - - stride = (w * sizeof(int)); - - _ecore_evas_wl_shm_pool_create(ee, stride * h); - - if ((ee->alpha) || (ee->transparent)) - format = WL_SHM_FORMAT_ARGB8888; - else - format = WL_SHM_FORMAT_XRGB8888; - - _ecore_evas_wl_buffer_free(ee); - ee->engine.wl.buffer = - wl_shm_pool_create_buffer(ee->engine.wl.pool, 0, w, h, stride, format); -} - -void -_ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ee) return; - if (ee->engine.wl.win) - { - ee->engine.wl.win->resizing = EINA_TRUE; - ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location); - } -} -#else -EAPI Ecore_Evas * -ecore_evas_wayland_shm_new(const char *disp_name EINA_UNUSED, unsigned int parent EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, Eina_Bool frame EINA_UNUSED) -{ - return NULL; -} -#endif diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c deleted file mode 100644 index 32ecc46de4..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c +++ /dev/null @@ -1,1524 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include /* for NULL */ - -#include -#include "ecore_private.h" -#ifdef BUILD_ECORE_EVAS_WIN32 -# define WIN32_LEAN_AND_MEAN -# include -# undef WIN32_LEAN_AND_MEAN -# include -# include -#endif /* BUILD_ECORE_EVAS_WIN32 */ - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - -#ifdef BUILD_ECORE_EVAS_WIN32 - -#define ECORE_EVAS_EVENT_COUNT 10 - -static int _ecore_evas_init_count = 0; - -static Ecore_Event_Handler *ecore_evas_event_handlers[ECORE_EVAS_EVENT_COUNT]; - -static Eina_Bool _ecore_evas_win32_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_window_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_window_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_window_damage(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_window_destroy(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_window_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_window_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -static Eina_Bool _ecore_evas_win32_event_window_delete_request(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); - -/* Private functions */ - -static int -_ecore_evas_win32_render(Ecore_Evas *ee) -{ - int rend = 0; - Eina_List *updates = NULL; - 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); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - 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_FOCUS_IN, _ecore_evas_win32_event_window_focus_in, NULL); - ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT, _ecore_evas_win32_event_window_focus_out, NULL); - ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_DAMAGE, _ecore_evas_win32_event_window_damage, NULL); - ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_DESTROY, _ecore_evas_win32_event_window_destroy, NULL); - ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_SHOW, _ecore_evas_win32_event_window_show, NULL); - ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_HIDE, _ecore_evas_win32_event_window_hide, NULL); - ecore_evas_event_handlers[8] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_CONFIGURE, _ecore_evas_win32_event_window_configure, NULL); - ecore_evas_event_handlers[9] = 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 Eina_Bool -_ecore_evas_win32_event_mouse_in(void *data EINA_UNUSED, int type EINA_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->timestamp, NULL); - evas_focus_in(ee->evas); - _ecore_evas_mouse_move_process(ee, e->x, e->y, e->timestamp); - - return 1; -} - -static Eina_Bool -_ecore_evas_win32_event_mouse_out(void *data EINA_UNUSED, int type EINA_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->timestamp); - - evas_event_feed_mouse_out(ee->evas, e->timestamp, 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 Eina_Bool -_ecore_evas_win32_event_window_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Win32_Event_Window_Focus_In *e; - - e = event; - ee = ecore_event_window_match((Ecore_Window)e->window); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if ((Ecore_Window)e->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_win32_event_window_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_Win32_Event_Window_Focus_Out *e; - - e = event; - ee = ecore_event_window_match((Ecore_Window)e->window); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; - if ((Ecore_Window)e->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - - evas_focus_out(ee->evas); - ee->prop.focused = 0; - if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_win32_event_window_damage(void *data EINA_UNUSED, int type EINA_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 Eina_Bool -_ecore_evas_win32_event_window_destroy(void *data EINA_UNUSED, int type EINA_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 Eina_Bool -_ecore_evas_win32_event_window_show(void *data EINA_UNUSED, int type EINA_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 Eina_Bool -_ecore_evas_win32_event_window_hide(void *data EINA_UNUSED, int type EINA_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 Eina_Bool -_ecore_evas_win32_event_window_configure(void *data EINA_UNUSED, int type EINA_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->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->width) || (ee->h != e->height)) - { - ee->w = e->width; - ee->h = e->height; - 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) */ -/* _ecore_evas_win32_region_border_resize(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 Eina_Bool -_ecore_evas_win32_event_window_delete_request(void *data EINA_UNUSED, int type EINA_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, - Ecore_Evas_Event_Cb func) -{ - 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); - ee->req.x = x; - ee->req.y = 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); - ee->req.w = width; - ee->req.h = 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); - } - 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_win32_region_border_resize(ee); */ - 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); - ee->req.x = x; - ee->req.y = y; - ee->req.w = width; - ee->req.h = 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); - } - 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_win32_region_border_resize(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); - } - } -} - -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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - _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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - _ecore_evas_win32_rotation_set_internal(ee, rotation); - } -#endif /* BUILD_ECORE_EVAS_SOFTWARE_DDRAW */ -} - -static void -_ecore_evas_win32_shaped_set(Ecore_Evas *ee, int shaped) -{ - if (((ee->shaped) && (shaped)) || ((!ee->shaped) && (!shaped))) - return; - - if (!strcmp(ee->driver, "software_ddraw")) 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); - ee->shaped = shaped; - if (einfo) - { - ee->engine.win32.state.region = ee->shaped; - einfo->info.region = ee->engine.win32.state.region; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - if (ee->shaped) - evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); - } -#endif /* BUILD_ECORE_EVAS_SOFTWARE_GDI */ - } -} - -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((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 EINA_UNUSED) -{ - ecore_win32_window_focus((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); - -#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) - { - einfo->info.borderless = ee->prop.borderless; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - } - if (ee->prop.borderless) - evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); - } - } -#endif /* BUILD_ECORE_EVAS_SOFTWARE_GDI */ -} - -static void -_ecore_evas_win32_override_set(Ecore_Evas *ee, int on) -{ - struct _Ecore_Win32_Window *window; - - INF("ecore evas override set"); - - window = (struct _Ecore_Win32_Window *)ee->prop.window; - - if (ee->prop.override == on) return; - if (ee->should_be_visible) ecore_win32_window_hide(window); - /* FIXME: use borderless_set for now */ - ecore_win32_window_borderless_set(window, on); - if (ee->should_be_visible) ecore_win32_window_show(window); - if (ee->prop.focused) ecore_win32_window_focus(window); - ee->prop.override = on; -} - -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_fullscreen_set(window, on); - } - else - { - ecore_win32_window_fullscreen_set(window, on); - } - - /* 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) - { - einfo->info.fullscreen = !!on; -/* einfo->info.layered = window->shape.layered; */ - 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_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) - { - einfo->info.fullscreen = !!on; - einfo->info.layered = window->shape.layered; - 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_DIRECT3D */ -} -static void -_ecore_evas_win32_alpha_set(Ecore_Evas *ee, int alpha) -{ - alpha = !!alpha; - if ((ee->alpha == alpha)) return; - - if (!strcmp(ee->driver, "software_gdi")) - { -#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI - Evas_Engine_Info_Software_Gdi *einfo; - - einfo = (Evas_Engine_Info_Software_Gdi *)evas_engine_info_get(ee->evas); - if (!einfo) return; - - ee->shaped = 0; - ee->alpha = alpha; - /* ecore_win32_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_win32_window_override_new(ee->engine.win32.win_root, */ - /* ee->req.x, */ - /* ee->req.y, */ - /* ee->req.w, */ - /* ee->req.h); */ - /* else */ - /* ee->prop.window = ecore_win32_window_new(ee->engine.win32.win_root, */ - /* ee->req.x, */ - /* ee->req.y, */ - /* ee->req.w, */ - /* ee->req.h); */ - /* if (ee->engine.win32.mask) ecore_x_pixmap_free(ee->engine.x.mask); */ - /* ee->engine.win32.mask = 0; */ - /* ecore_win32_window_shape_input_mask_set(ee->prop.window, 0); */ - /* } */ - - /* einfo->info.destination_alpha = alpha; */ - einfo->info.region = alpha; - -// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask); -// ee->engine.x.mask = 0; - /* einfo->info.mask = ee->engine.win32.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_win32_window_shape_mask_set(ee->prop.window, 0); */ - /* ecore_event_window_register(ee->prop.window, ee, ee->evas, */ - /* (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, */ - /* (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, */ - /* (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, */ - /* (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); */ - if (ee->prop.borderless) - ecore_win32_window_borderless_set((struct _Ecore_Win32_Window *)ee->prop.window, ee->prop.borderless); - if (ee->visible) ecore_win32_window_show((struct _Ecore_Win32_Window *)ee->prop.window); - if (ee->prop.focused) ecore_win32_window_focus((struct _Ecore_Win32_Window *)ee->prop.window); - if (ee->prop.title) - { - ecore_win32_window_title_set((struct _Ecore_Win32_Window *)ee->prop.window, ee->prop.title); - /* ecore_win32_name_set(ee->prop.window, ee->prop.title); */ - } - ecore_win32_window_type_set((struct _Ecore_Win32_Window *)ee->prop.window, ECORE_WIN32_WINDOW_TYPE_NORMAL); -#endif /* BUILD_ECORE_EVAS_SOFTWARE_GDI */ - } -} - -static void -_ecore_evas_win32_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi) -{ - HDC dc; - - dc = GetDC(NULL); - if (!dc) - { - if (xdpi) *xdpi = 0; - if (ydpi) *ydpi = 0; - return; - } - - if (xdpi) *xdpi = GetDeviceCaps(dc, LOGPIXELSX); - if (ydpi) *ydpi = GetDeviceCaps(dc, LOGPIXELSY); - - /* - * Alternative (to test) - int width_mm; - int height_mm; - int width_px; - int height_px; - - width_mm = GetDeviceCaps(dc, HORZSIZE); - height_mm = GetDeviceCaps(dc, VERTSIZE); - width_px = GetDeviceCaps(dc, HORZRES); - height_px = GetDeviceCaps(dc, VERTRES); - - *xdpi = (width_px * 254) / (width_mm * 10); - *ydpi = (height_px * 254) / (height_mm * 10); - - code with LOGPIXELS gives 96x96 - code with the computation gives 101x77 - - */ - - ReleaseDC(NULL, dc); -} - -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, - _ecore_evas_win32_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, - _ecore_evas_win32_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 */ - _ecore_evas_win32_alpha_set, - NULL, //transparent - NULL, // profiles_set - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - - NULL, // render - NULL, // screen_geometry_get - _ecore_evas_win32_screen_dpi_get -}; - -#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.depth = ecore_win32_screen_depth_get(); - einfo->info.rotation = 0; - einfo->info.borderless = 0; - einfo->info.fullscreen = 0; - einfo->info.region = 0; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - return 0; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - return 0; - } - - 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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - return 0; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - return 0; - } - - 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; - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - return 0; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - return 0; - } - - 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(); - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - return 0; - } - } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - return 0; - } - - return 1; -} -#endif /* BUILD_ECORE_EVAS_OPENGL_GLEW */ - -#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->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; - /* 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_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_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 EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_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 EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_UNUSED) -{ - return NULL; -} - -#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_DDRAW */ - - -EAPI Ecore_Evas * -ecore_evas_software_16_ddraw_new(Ecore_Win32_Window *parent EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_UNUSED) -{ - return NULL; -} - -#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 EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_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 EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_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 EINA_UNUSED) -{ - return NULL; -} - -#endif /* BUILD_ECORE_EVAS_WIN32 */ diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_wince.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_wince.c deleted file mode 100644 index 142a85059c..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_wince.c +++ /dev/null @@ -1,67 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include /* for NULL */ - -#include -#include "ecore_private.h" - -#include "ecore_evas_private.h" -#include "Ecore_Evas.h" - -EAPI Ecore_Evas * -ecore_evas_software_wince_new(Ecore_WinCE_Window *parent EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_UNUSED) -{ - return NULL; -} - -EAPI Ecore_Evas * -ecore_evas_software_wince_fb_new(Ecore_WinCE_Window *parent EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_UNUSED) -{ - return NULL; -} - -EAPI Ecore_Evas * -ecore_evas_software_wince_gapi_new(Ecore_WinCE_Window *parent EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_UNUSED) -{ - return NULL; -} - -EAPI Ecore_Evas * -ecore_evas_software_wince_ddraw_new(Ecore_WinCE_Window *parent EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_UNUSED) -{ - return NULL; -} - -EAPI Ecore_Evas * -ecore_evas_software_wince_gdi_new(Ecore_WinCE_Window *parent EINA_UNUSED, - int x EINA_UNUSED, - int y EINA_UNUSED, - int width EINA_UNUSED, - int height EINA_UNUSED) -{ - return NULL; -} - -EAPI Ecore_WinCE_Window * -ecore_evas_software_wince_window_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return NULL; -} diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_x.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_x.c deleted file mode 100644 index d94f055319..0000000000 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_x.c +++ /dev/null @@ -1,3663 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include -#include - -#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 int leader_ref = 0; -static Ecore_X_Window leader_win = 0; - -static void -_ecore_evas_x_hints_update(Ecore_Evas *ee) -{ - ecore_x_icccm_hints_set - (ee->prop.window, - !ee->prop.focus_skip /* accepts_focus */, - ee->prop.iconified ? ECORE_X_WINDOW_STATE_HINT_ICONIC : - ee->prop.withdrawn ? ECORE_X_WINDOW_STATE_HINT_WITHDRAWN : - ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */, - 0 /* icon_pixmap */, - 0 /* icon_mask */, - 0 /* icon_window */, - ee->prop.group_ee_win /* window_group */, - ee->prop.urgent /* is_urgent */); -} - -static void -_ecore_evas_x_group_leader_set(Ecore_Evas *ee) -{ - leader_ref++; - if (leader_ref == 1) - { - char *id = NULL; - - leader_win = - ecore_x_window_override_new(ee->engine.x.win_root, 1234, 5678, 1, 2); - ecore_x_window_defaults_set(leader_win); - if ((id = getenv("DESKTOP_STARTUP_ID"))) - ecore_x_netwm_startup_id_set(leader_win,id); - ecore_x_icccm_client_leader_set(leader_win, leader_win); - } - ee->engine.x.leader = leader_win; - ecore_x_icccm_client_leader_set(ee->prop.window, leader_win); -} - -static void -_ecore_evas_x_group_leader_unset(Ecore_Evas *ee) -{ - ecore_x_window_prop_property_del(ee->prop.window, - ECORE_X_ATOM_WM_CLIENT_LEADER); - if (ee->engine.x.leader == leader_win) - { - leader_ref--; - if (leader_ref <= 0) - { - ecore_x_window_free(leader_win); - leader_win = 0; - } - ee->engine.x.leader = 0; - } -} - -static void -_ecore_evas_x_group_leader_update(Ecore_Evas *ee) -{ - if (ee->engine.x.leader) - ecore_x_icccm_client_leader_set(ee->prop.window, ee->engine.x.leader); -} - -static void -_ecore_evas_x_protocols_set(Ecore_Evas *ee) -{ - Ecore_X_Atom protos[3]; - unsigned int num = 0, tmp = 0; - - if (ee->func.fn_delete_request) - protos[num++] = ECORE_X_ATOM_WM_DELETE_WINDOW; - protos[num++] = ECORE_X_ATOM_NET_WM_PING; - protos[num++] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; - ecore_x_icccm_protocol_atoms_set(ee->prop.window, protos, num); - - if (!ee->engine.x.netwm_sync_counter) - ee->engine.x.netwm_sync_counter = ecore_x_sync_counter_new(0); - - tmp = ee->engine.x.netwm_sync_counter; - ecore_x_window_prop_card32_set(ee->prop.window, - ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, - &tmp, 1); -} - -static void -_ecore_evas_x_sync_set(Ecore_Evas *ee) -{ - Ecore_X_Sync_Counter sync_counter = ee->engine.x.sync_counter; - - if (((ee->should_be_visible) || (ee->visible)) && - ((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_val = 0; - } - ee->engine.x.sync_counter = 0; - } - if (sync_counter != ee->engine.x.sync_counter) - 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_val = 0; - ee->engine.x.sync_counter = 0; -} - -# ifdef BUILD_ECORE_EVAS_OPENGL_X11 -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) - { - 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]; - } - else if (opt[op] == ECORE_EVAS_GL_X11_OPT_VSYNC) - { - op++; - einfo->vsync = opt[op]; - } -#ifdef EVAS_ENGINE_GL_X11_SWAP_MODE_EXISTS - else if (opt[op] == ECORE_EVAS_GL_X11_OPT_SWAP_MODE) - { - op++; - if ((evas_version->major >= 1) && - (evas_version->minor >= 7) && - (evas_version->micro >= 99)) - einfo->swap_mode = opt[op]; - } -#endif - } - } - - /* FIXME: this is inefficient as its 1 or more round trips */ - screen = ecore_x_screen_index_get(ecore_x_default_screen_get()); - if (ecore_x_screen_count_get() > 1) - { - Ecore_X_Window *roots; - int num, i; - - num = 0; - roots = ecore_x_window_root_list(&num); - if (roots) - { - Ecore_X_Window root; - - root = ecore_x_window_root_get(parent); - for (i = 0; i < num; i++) - { - if (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); - if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - return 0; - } - } - - if (argb) - { - if (override) - win = ecore_x_window_override_argb_new(parent, x, y, w, h); - else - win = ecore_x_window_argb_new(parent, x, y, w, h); - } - else - { - if (override) - win = ecore_x_window_override_new(parent, x, y, w, h); - else - win = ecore_x_window_new(parent, x, y, w, h); - } - - ecore_x_window_pixel_gravity_set(win, ECORE_X_GRAVITY_FORGET); - - /* 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)) - { - ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); - ecore_x_window_free(win); - return 0; - } - } - else - win = 0; - - return win; -} -#endif - -static int -_ecore_evas_x_render(Ecore_Evas *ee) -{ - int rend = 0; - Eina_List *updates = NULL; - 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); - if (ee2->engine.func->fn_render) - rend |= ee2->engine.func->fn_render(ee2); - if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); - } - - if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); - updates = evas_render_updates(ee->evas); - if (ee->prop.avoid_damage) - { - if (ee->engine.x.using_bg_pixmap) - { - if (updates) - { - Eina_List *l = NULL; - Eina_Rectangle *r; - - 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) - { - 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); - } - _ecore_evas_idle_timeout_update(ee); - rend = 1; - } - } - else - { - if (updates) - { - Eina_List *l = NULL; - Eina_Rectangle *r; - - 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 (ee->shaped) - { - - /* if we have a damage pixmap - we can avoid exposures by - * disabling them just for setting the mask */ - ecore_x_event_mask_unset(ee->prop.window, ECORE_X_EVENT_MASK_WINDOW_DAMAGE); - 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_WINDOW_DAMAGE); - } - ecore_x_xregion_set(ee->engine.x.damages, ee->engine.x.gc); - 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; - } - _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))) - { - 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); - } - _ecore_evas_idle_timeout_update(ee); - rend = 1; - } - } - else - evas_norender(ee->evas); - evas_render_updates_free(updates); - - 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 */ - } -} - -/* TODO: we need to make this work for all the states, not just sticky */ -static Eina_Bool -_ecore_evas_x_event_property_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_X_Event_Window_Property *e; - int state_change = 0; - - e = event; - ee = ecore_event_window_match(e->win); - if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (e->atom == ECORE_X_ATOM_NET_WM_STATE) - { - unsigned int i, num; - Ecore_X_Window_State *state; - struct { - 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; - } x; - struct { - char modal : 1; - char maximized : 1; - char sticky : 1; - char fullscreen : 1; - char focus_skip : 1; - } prop; - } prev; - - prev.x.modal = ee->engine.x.state.modal; - prev.x.sticky = ee->engine.x.state.sticky; - prev.x.maximized_v = ee->engine.x.state.maximized_v; - prev.x.maximized_h = ee->engine.x.state.maximized_h; - prev.x.shaded = ee->engine.x.state.shaded; - prev.x.skip_taskbar = ee->engine.x.state.skip_taskbar; - prev.x.skip_pager = ee->engine.x.state.skip_pager; - prev.x.fullscreen = ee->engine.x.state.fullscreen; - prev.x.above = ee->engine.x.state.above; - prev.x.below = ee->engine.x.state.below; - - prev.prop.modal = ee->prop.modal; - prev.prop.maximized = ee->prop.maximized; - prev.prop.sticky = ee->prop.sticky; - prev.prop.fullscreen = ee->prop.fullscreen; - prev.prop.focus_skip = ee->prop.focus_skip; - - ee->engine.x.state.modal = 0; - ee->engine.x.state.sticky = 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->engine.x.state.fullscreen = 0; - ee->engine.x.state.above = 0; - ee->engine.x.state.below = 0; - - ee->prop.modal = 0; - ee->prop.maximized = 0; - ee->prop.sticky = 0; - ee->prop.fullscreen = 0; - ee->prop.focus_skip = 0; - - 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; - ee->prop.modal = 1; - break; - case ECORE_X_WINDOW_STATE_STICKY: - ee->prop.sticky = 1; - ee->engine.x.state.sticky = 1; - break; - case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT: - ee->engine.x.state.maximized_v = 1; - ee->prop.maximized = 1; - break; - case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ: - ee->engine.x.state.maximized_h = 1; - ee->prop.maximized = 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; - ee->prop.focus_skip = 1; - break; - case ECORE_X_WINDOW_STATE_SKIP_PAGER: - ee->engine.x.state.skip_pager = 1; - ee->prop.focus_skip = 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); - } - if ( -// (prev.x.modal != ee->engine.x.state.modal) || - (prev.x.sticky != ee->engine.x.state.sticky) || - (prev.x.maximized_v != ee->engine.x.state.maximized_v) || - (prev.x.maximized_h != ee->engine.x.state.maximized_h) || -// (prev.x.shaded != ee->engine.x.state.shaded) || -// (prev.x.skip_taskbar != ee->engine.x.state.skip_taskbar) || -// (prev.x.skip_pager != ee->engine.x.state.skip_pager) || - (prev.x.fullscreen != ee->engine.x.state.fullscreen) || -// (prev.x.above != ee->engine.x.state.above) || -// (prev.x.below != ee->engine.x.state.below) || -// (prev.prop.modal != ee->prop.modal) || - (prev.prop.maximized != ee->prop.maximized) || - (prev.prop.sticky != ee->prop.sticky) || - (prev.prop.fullscreen != ee->prop.fullscreen) || - (prev.prop.focus_skip != ee->prop.focus_skip)) - state_change = 1; - } - else if (e->atom == ECORE_X_ATOM_WM_STATE) - { - Ecore_X_Window_State_Hint state; - - // handle WM_STATE changes - state = ecore_x_icccm_state_get(e->win); - switch (state) - { - case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN: - if ((!ee->prop.withdrawn) || (ee->prop.iconified)) - { - state_change = 1; - ee->prop.withdrawn = 1; - ee->prop.iconified = 0; - } - break; - case ECORE_X_WINDOW_STATE_HINT_ICONIC: - if ((!ee->prop.iconified) || (ee->prop.withdrawn)) - { - state_change = 1; - ee->prop.iconified = 1; - ee->prop.withdrawn = 0; - } - break; - case ECORE_X_WINDOW_STATE_HINT_NORMAL: - if ((ee->prop.iconified) || (ee->prop.withdrawn)) - { - state_change = 1; - ee->prop.iconified = 0; - ee->prop.withdrawn = 0; - } - break; - default: - break; - } - } - else if (e->atom == ECORE_X_ATOM_E_PROFILE) - { - char *p = ecore_x_e_window_profile_get(e->win); - if ((p) && (ee->prop.profile)) - { - if (strcmp(p, ee->prop.profile) != 0) - { - free(ee->prop.profile); - ee->prop.profile = strdup(p); - state_change = 1; - } - } - else if ((!p) && (ee->prop.profile)) - { - free(ee->prop.profile); - ee->prop.profile = NULL; - state_change = 1; - } - else if ((p) && (!ee->prop.profile)) - { - ee->prop.profile = strdup(p); - state_change = 1; - } - - if (p) - free(p); - } - - if (state_change) - { - if (ee->func.fn_state_change) ee->func.fn_state_change(ee); - } - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_visibility_change(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; -// 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 ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_client_message(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_X_Event_Client_Message *e; - - e = event; - if (e->format != 32) return ECORE_CALLBACK_PASS_ON; - if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_BEGIN) - { - ee = ecore_event_window_match(e->data.l[0]); - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->data.l[0] != (long)ee->prop.window) - return ECORE_CALLBACK_PASS_ON; - if (!ee->engine.x.sync_began) - { - // qeue a damage + draw. work around an event re-ordering thing. - evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); - } - 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 ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->data.l[0] != (long)ee->prop.window) - return ECORE_CALLBACK_PASS_ON; - 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 ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->data.l[0] != (long)ee->prop.window) - return ECORE_CALLBACK_PASS_ON; - ee->engine.x.sync_began = 0; - ee->engine.x.sync_cancel = 1; - } - else if ((e->message_type == ECORE_X_ATOM_WM_PROTOCOLS) && - (e->data.l[0] == (int)ECORE_X_ATOM_NET_WM_SYNC_REQUEST)) - { - ee = ecore_event_window_match(e->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - ee->engine.x.netwm_sync_val_lo = (unsigned int)e->data.l[2]; - ee->engine.x.netwm_sync_val_hi = (int)e->data.l[3]; - ee->engine.x.netwm_sync_set = 1; - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_mouse_in(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; -/* { */ -/* 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 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; */ - if (!ee->in) - { - 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); - ee->in = EINA_TRUE; - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_mouse_out(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; - /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; -/* { */ -/* 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; */ -// printf("OUT: ee->in=%i, e->mode=%i, e->detail=%i, dount_count=%i\n", -// ee->in, e->mode, e->detail, evas_event_down_count_get(ee->evas)); - if (ee->in) - { - if ((evas_event_down_count_get(ee->evas) > 0) && - (!((e->mode == ECORE_X_EVENT_MODE_GRAB) && - (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))) - return ECORE_CALLBACK_PASS_ON; - 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); - ee->in = EINA_FALSE; - } - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_window_focus_in(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; -//xx// filtering with these doesnt help -//xx// if (e->mode == ECORE_X_EVENT_MODE_UNGRAB) return ECORE_CALLBACK_PASS_ON; - ee->prop.focused = 1; - evas_focus_in(ee->evas); - if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_window_focus_out(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; -//xx// filtering with these doesnt help -//xx// if (e->mode == ECORE_X_EVENT_MODE_GRAB) return ECORE_CALLBACK_PASS_ON; - -// 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 ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_window_damage(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_X_Event_Window_Damage *e; - - e = event; - ee = ecore_event_window_match(e->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->engine.x.using_bg_pixmap) return ECORE_CALLBACK_PASS_ON; -// 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 ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_window_destroy(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_X_Event_Window_Destroy *e; - - e = event; - ee = ecore_event_window_match(e->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->func.fn_destroy) ee->func.fn_destroy(ee); - _ecore_evas_x_sync_clear(ee); - ecore_evas_free(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_X_Event_Window_Configure *e; - - e = event; - ee = ecore_event_window_match(e->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->engine.x.direct_resize) return ECORE_CALLBACK_PASS_ON; - - ee->engine.x.configure_coming = 0; - 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 ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_window_delete_request(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_window_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_X_Event_Window_Show *e; - static int first_map_bug = -1; - - e = event; - ee = ecore_event_window_match(e->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - /* some GL drivers are doing buffer copy in a separate thread. - * we need to check whether GL driver sends SYNC_DRAW_DONE msg afger copying - * that are required in order to exactly render. - added by gl77.lee - */ - if (ee->gl_sync_draw_done < 0) - { - if (getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE")) - ee->gl_sync_draw_done = atoi(getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE")); - else - ee->gl_sync_draw_done = 0; - } - if (first_map_bug < 0) - { - char *bug = NULL; - - if ((bug = getenv("ECORE_EVAS_GL_FIRST_MAP_BUG"))) - first_map_bug = atoi(bug); - else - first_map_bug = 0; - } - if ((first_map_bug) && (!strcmp(ee->driver, "opengl_x11"))) - evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); - if (ee->visible) return ECORE_CALLBACK_PASS_ON; -// if (ee->visible) return ECORE_CALLBACK_DONE; -// printf("SHOW EVENT %p\n", ee); - ee->visible = 1; - if (ee->func.fn_show) ee->func.fn_show(ee); - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_ecore_evas_x_event_window_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Evas *ee; - Ecore_X_Event_Window_Hide *e; - - e = event; - ee = ecore_event_window_match(e->win); - if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ - if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; - if (ee->in) - { - 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); - ee->in = EINA_FALSE; - } - if (!ee->visible) return ECORE_CALLBACK_PASS_ON; -// if (!ee->visible) return ECORE_CALLBACK_DONE; -// printf("HIDE EVENT %p\n", ee); - ee->visible = 0; - if (ee->func.fn_hide) ee->func.fn_hide(ee); - return ECORE_CALLBACK_PASS_ON; -} - -/* FIXME, should be in idler */ -/* FIXME, round trip */ -static void -_ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee) -{ - 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 */, - ee->prop.aspect /* min_aspect */, - ee->prop.aspect /* max_aspect */); -} - -/* FIXME, should be in idler */ -static void -_ecore_evas_x_state_update(Ecore_Evas *ee) -{ - Ecore_X_Window_State state[10]; - int num = 0; - - if (ee->prop.modal) - state[num++] = ECORE_X_WINDOW_STATE_MODAL; - if (ee->prop.sticky) - state[num++] = ECORE_X_WINDOW_STATE_STICKY; - if (ee->prop.maximized) - state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_VERT; - if (ee->prop.maximized) - state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ; -// if (bd->client.netwm.state.shaded) -// state[num++] = ECORE_X_WINDOW_STATE_SHADED; - if (ee->prop.focus_skip) - state[num++] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR; - if (ee->prop.focus_skip) - 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; - if (ee->prop.demand_attention) - state[num++] = ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION; - - 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_group_leader_unset(ee); - _ecore_evas_x_sync_set(ee); - if (ee->engine.x.win_shaped_input) - ecore_x_window_free(ee->engine.x.win_shaped_input); - 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, Ecore_Evas_Event_Cb func) -{ - 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 - { - if (((ee->x != x) || (ee->y != y)) || - (ee->engine.x.configure_coming)) - { - ee->engine.x.configure_coming = 1; - if (!ee->engine.x.managed) - { - 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); - } - } -} - -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)) - { - ee->w = w; - ee->h = h; - ecore_x_window_resize(ee->prop.window, w, 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 if (((ee->w != w) || (ee->h != h)) || - (ee->engine.x.configure_coming)) - { - ee->engine.x.configure_coming = 1; - 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 if (((ee->w != w) || (ee->h != h) || (ee->x != x) || (ee->y != y)) || - (ee->engine.x.configure_coming)) - { - ee->engine.x.configure_coming = 1; - 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) - { - ee->engine.x.configure_coming = 1; - 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; - 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); - } - 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); - } -} - -#define _USE_WIN_ROT_EFFECT 1 - -#if _USE_WIN_ROT_EFFECT -static void _ecore_evas_x_flush_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED); - -typedef struct _Ecore_Evas_X_Rotation_Effect Ecore_Evas_X_Rotation_Effect; -struct _Ecore_Evas_X_Rotation_Effect -{ - Eina_Bool wait_for_comp_reply; -}; - -static Ecore_Evas_X_Rotation_Effect _rot_effect = -{ - EINA_FALSE -}; - -static void -_ecore_evas_x_rotation_effect_setup(void) -{ - _rot_effect.wait_for_comp_reply = EINA_TRUE; -} -#endif /* end of _USE_WIN_ROT_EFFECT */ - -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 _USE_WIN_ROT_EFFECT - int angles[2]; - angles[0] = rotation; - angles[1] = ee->rotation; -#endif /* end of _USE_WIN_ROT_EFFECT */ - - 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); -# if _USE_WIN_ROT_EFFECT - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &angles, 2); -# else - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &rotation, 1); -# endif -#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); -# if _USE_WIN_ROT_EFFECT - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &angles, 2); -# else - ecore_x_window_prop_property_set(ee->prop.window, - ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, - ECORE_X_ATOM_CARDINAL, 32, &rotation, 1); -# endif -#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */ - } - -#if _USE_WIN_ROT_EFFECT - if ((ee->visible) && - ((ecore_x_e_comp_sync_supported_get(ee->engine.x.win_root)) && - (!ee->no_comp_sync) && (_ecore_evas_app_comp_sync)) && - (ee->engine.x.sync_counter) && - (ee->engine.x.sync_val > 0)) - { - _ecore_evas_x_rotation_effect_setup(); - _ecore_evas_x_flush_pre(ee, NULL, NULL); - } -#endif /* end of _USE_WIN_ROT_EFFECT */ -} - -static void -_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped) -{ - if ((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; - 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_SOFTWARE_X11 */ - } -} - -/* FIXME, round trip */ -static void -_ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) -{ - Ecore_X_Window_Attributes att; - char *id = NULL; - - if ((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; - - ecore_x_window_attributes_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, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_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); - } - if (ee->prop.name) - ecore_x_icccm_name_class_set(ee->prop.window, - ee->prop.name, ee->prop.clas); - _ecore_evas_x_hints_update(ee); - _ecore_evas_x_group_leader_update(ee); - ecore_x_window_defaults_set(ee->prop.window); - _ecore_evas_x_protocols_set(ee); - _ecore_evas_x_sync_set(ee); - _ecore_evas_x_size_pos_hints_update(ee); -#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */ - if ((id = getenv("DESKTOP_STARTUP_ID"))) - { - ecore_x_netwm_startup_id_set(ee->prop.window, 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); - } - */ - - ecore_x_window_attributes_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, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_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); - } - if (ee->prop.name) - ecore_x_icccm_name_class_set(ee->prop.window, - ee->prop.name, ee->prop.clas); - _ecore_evas_x_hints_update(ee); - _ecore_evas_x_group_leader_update(ee); - ecore_x_window_defaults_set(ee->prop.window); - _ecore_evas_x_protocols_set(ee); - _ecore_evas_x_sync_set(ee); - _ecore_evas_x_size_pos_hints_update(ee); -#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */ - if ((id = getenv("DESKTOP_STARTUP_ID"))) - { - ecore_x_netwm_startup_id_set(ee->prop.window, 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)) 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 - } -} - -static void -_ecore_evas_x_window_group_set(Ecore_Evas *ee, const Ecore_Evas *group_ee) -{ - if (ee->prop.group_ee == group_ee) return; - - ee->prop.group_ee = (Ecore_Evas *)group_ee; - if (ee->prop.group_ee) - ee->prop.group_ee_win = group_ee->prop.window; - else - ee->prop.group_ee_win = 0; - _ecore_evas_x_hints_update(ee); -} - -static void -_ecore_evas_x_aspect_set(Ecore_Evas *ee, double aspect) -{ - if (ee->prop.aspect == aspect) return; - - ee->prop.aspect = aspect; - _ecore_evas_x_size_pos_hints_update(ee); -// netwm state -// 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_urgent_set(Ecore_Evas *ee, int urgent) -{ - if (ee->prop.urgent == urgent) return; - - ee->prop.urgent = urgent; - _ecore_evas_x_hints_update(ee); -} - -static void -_ecore_evas_x_modal_set(Ecore_Evas *ee, int modal) -{ - if (ee->prop.modal == modal) return; - - ee->prop.modal = modal; - if (ee->should_be_visible) - ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, - ECORE_X_WINDOW_STATE_MODAL, -1, modal); - else - _ecore_evas_x_state_update(ee); -} - -static void -_ecore_evas_x_demand_attention_set(Ecore_Evas *ee, int demand) -{ - if (ee->prop.demand_attention == demand) return; - - ee->prop.demand_attention = demand; - if (ee->should_be_visible) - ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, - ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION, -1, demand); - else - _ecore_evas_x_state_update(ee); -} - -static void -_ecore_evas_x_focus_skip_set(Ecore_Evas *ee, int skip) -{ - if (ee->prop.focus_skip == skip) return; - - ee->prop.focus_skip = skip; - if (ee->should_be_visible) - { - ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, - ECORE_X_WINDOW_STATE_SKIP_TASKBAR, -1, skip); - ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, - ECORE_X_WINDOW_STATE_SKIP_PAGER, -1, skip); - } - else - _ecore_evas_x_state_update(ee); - _ecore_evas_x_hints_update(ee); -} - -#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_evas_x_sync_set(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; - _ecore_evas_x_sync_set(ee); -} - -static void -_ecore_evas_x_raise(Ecore_Evas *ee) -{ - ecore_x_window_raise(ee->prop.window); -} - -static void -_ecore_evas_x_lower(Ecore_Evas *ee) -{ - 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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) - { - 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 EINA_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) return; - ee->prop.iconified = on; - _ecore_evas_x_hints_update(ee); - if (on) - ecore_x_icccm_iconic_request_send(ee->prop.window, ee->engine.x.win_root); - else - ecore_evas_show(ee); -} - -static void -_ecore_evas_x_borderless_set(Ecore_Evas *ee, int on) -{ - if (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) -{ - if (ee->prop.withdrawn == withdrawn) return; - ee->prop.withdrawn = withdrawn; - _ecore_evas_x_hints_update(ee); -} - -static void -_ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky) -{ - if (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) return; - - ee->ignore_events = ignore; - if (ee->prop.window) - ecore_x_window_ignore_set(ee->prop.window, ignore); -} - -/* -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, "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) return; - if (ee->should_be_visible) ecore_x_window_hide(ee->prop.window); - ecore_x_window_override_set(ee->prop.window, on); - if (ee->should_be_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_maximized_set(Ecore_Evas *ee, int on) -{ - if (ee->prop.maximized == on) return; - ee->engine.x.state.maximized_h = 1; - ee->engine.x.state.maximized_v = 1; - ee->prop.maximized = on; - if (ee->should_be_visible) - { - ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, - ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, -1, on); - ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, - ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, -1, on); - } - else - _ecore_evas_x_state_update(ee); -} - -static void -_ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on) -{ - if (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_profiles_set(Ecore_Evas *ee, const char **plist, int n) -{ - /* Ecore_Evas's profile will be updated when WM sets the E_PROFILE. */ - ecore_x_e_window_profile_list_set(ee->prop.window, plist, n); -} - -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, "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 */ - } -} - -static void -_ecore_evas_x_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) -{ - int outnum = 0; - int px = 0, py = 0, pw = 0, ph = 0; - Ecore_X_Window root; - Ecore_X_Randr_Output *out = NULL; - Ecore_X_Randr_Crtc crtc; - unsigned int val[4] = { 0 }; - - if (ecore_x_window_prop_card32_get - (ee->prop.window, ecore_x_atom_get("E_ZONE_GEOMETRY"), val, 4) == 4) - { - if (x) *x = (int)val[0]; - if (y) *y = (int)val[1]; - if (w) *w = (int)val[2]; - if (h) *h = (int)val[3]; - return; - } - - root = ecore_x_window_root_get(ee->prop.window); - out = ecore_x_randr_window_outputs_get(ee->prop.window, &outnum); - if (!out) - { -norandr: - if (out) free(out); - if (x) *x = 0; - if (y) *y = 0; - ecore_x_window_size_get(root, w, h); - return; - } - crtc = ecore_x_randr_output_crtc_get(root, out[0]); - if (!crtc) goto norandr; - ecore_x_randr_crtc_geometry_get(root, crtc, &px, &py, &pw, &ph); - if ((pw == 0) || (ph == 0)) goto norandr; - if (x) *x = px; - if (y) *y = py; - if (w) *w = pw; - if (h) *h = ph; - free(out); -} - -static void -_ecore_evas_x_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi) -{ - int scdpi, xmm = 0, ymm = 0, outnum = 0, w = 0, h = 0; - int px = 0, py = 0; - Ecore_X_Window root; - Ecore_X_Randr_Output *out = NULL; - Ecore_X_Randr_Crtc crtc; - - root = ecore_x_window_root_get(ee->prop.window); - out = ecore_x_randr_window_outputs_get(ee->prop.window, &outnum); - if (!out) - { -norandr: - if (out) free(out); - scdpi = ecore_x_dpi_get(); - if (xdpi) *xdpi = scdpi; - if (ydpi) *ydpi = scdpi; - return; - } - crtc = ecore_x_randr_output_crtc_get(root, out[0]); - if (!crtc) goto norandr; - ecore_x_randr_crtc_geometry_get(root, crtc, &px, &py, &w, &h); - if ((w == 0) || (h == 0)) goto norandr; - ecore_x_randr_output_size_mm_get(root, out[0], &xmm, &ymm); - if ((xmm == 0) || (ymm == 0)) goto norandr; - if (xdpi) *xdpi = (w * 254) / (xmm * 10); // 25.4mm / inch - if (ydpi) *ydpi = (h * 254) / (ymm * 10); // 25.4mm / inch - free(out); -} - -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, - _ecore_evas_x_maximized_set, - _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, - _ecore_evas_x_profiles_set, - - _ecore_evas_x_window_group_set, - _ecore_evas_x_aspect_set, - _ecore_evas_x_urgent_set, - _ecore_evas_x_modal_set, - _ecore_evas_x_demand_attention_set, - _ecore_evas_x_focus_skip_set, - - NULL, // render - _ecore_evas_x_screen_geometry_get, - _ecore_evas_x_screen_dpi_get -}; -#endif /* BUILD_ECORE_EVAS_X11 */ - -/* - * FIXME: there are some round trips. Especially, we can split - * ecore_x_init in 2 functions and suppress some round trips. - */ - -#if defined (BUILD_ECORE_EVAS_SOFTWARE_X11) || defined (BUILD_ECORE_EVAS_OPENGL_X11) -static void -_ecore_evas_x_flush_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_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) - { - if (!ee->semi_sync) - 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 EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Ecore_Evas *ee = data; - - if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) && - (!ee->gl_sync_draw_done)) // added by gl77.lee - { - if (ee->engine.x.sync_counter) - { - if (ee->engine.x.sync_began) - { - if (!ee->engine.x.sync_cancel) - { - ecore_x_e_comp_sync_draw_size_done_send - (ee->engine.x.win_root, ee->prop.window, ee->w, ee->h); - } - } - } - } - if (ee->engine.x.netwm_sync_set) - { - ecore_x_sync_counter_2_set(ee->engine.x.netwm_sync_counter, - ee->engine.x.netwm_sync_val_hi, - ee->engine.x.netwm_sync_val_lo); - ee->engine.x.netwm_sync_set = 0; - } -} -#endif - -/** - * @brief Create Ecore_Evas using software x11. - * @note If ecore is not compiled with support to x11 then nothing is done and NULL is returned. - * @param disp_name The name of the Ecore_Evas to be created. - * @param parent The parent of the Ecore_Evas to be created. - * @param x The X coordinate to be used. - * @param y The Y coordinate to be used. - * @param w The width of the Ecore_Evas to be created. - * @param h The height of the Ecore_Evas to be created. - * @return A handle to the created Ecore_Evas. - */ -#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, rmethod; - static int redraw_debug = -1; - char *id = NULL; - - 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 ((id = getenv("DESKTOP_STARTUP_ID"))) - { - ecore_x_netwm_startup_id_set(ee->prop.window, 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) - { - Ecore_X_Screen *screen; - - /* FIXME: this is inefficient as its 1 or more round trips */ - screen = ecore_x_default_screen_get(); - if (ecore_x_screen_count_get() > 1) - { - Ecore_X_Window *roots; - int num, i; - - num = 0; - roots = ecore_x_window_root_list(&num); - if (roots) - { - Ecore_X_Window root; - - root = ecore_x_window_root_get(parent); - for (i = 0; i < num; i++) - { - if (root == roots[i]) - { - screen = ecore_x_screen_get(i); - break; - } - } - free(roots); - } - } - - einfo->info.destination_alpha = argb; - - 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 - einfo->info.drawable = ee->prop.window; - - if (argb) - { - Ecore_X_Window_Attributes at; - - ecore_x_window_attributes_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; - } - else - { - einfo->info.visual = - ecore_x_default_visual_get(einfo->info.connection, screen); - einfo->info.colormap = - ecore_x_default_colormap_get(einfo->info.connection, screen); - einfo->info.depth = - ecore_x_default_depth_get(einfo->info.connection, screen); - 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)) - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - } - - _ecore_evas_x_hints_update(ee); - _ecore_evas_x_group_leader_set(ee); - ecore_x_window_defaults_set(ee->prop.window); - _ecore_evas_x_protocols_set(ee); - _ecore_evas_x_sync_set(ee); - - 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, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); - return ee; -} -#else -EAPI Ecore_Evas * -ecore_evas_software_x11_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, - int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ - return NULL; -} -#endif - -/** - * @brief Get the window from Ecore_Evas using software x11. - * @note If ecore is not compiled with support for x11 or if @p ee was not - * created with ecore_evas_software_x11_new() then nothing is done and - * 0 is returned. - * @param ee The Ecore_Evas from which to get the window. - * @return The window of type Ecore_X_Window. - */ -#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 -EAPI Ecore_X_Window -ecore_evas_software_x11_window_get(const Ecore_Evas *ee) -{ - if (!(!strcmp(ee->driver, "software_x11"))) return 0; - return (Ecore_X_Window) ecore_evas_window_get(ee); -} -#else -EAPI Ecore_X_Window -ecore_evas_software_x11_window_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} -#endif - -/** - * @brief Set the direct_resize of Ecore_Evas using software x11. - * @note If ecore is not compiled with support to x11 then nothing is done. - * @param ee The Ecore_Evas in which to set direct resize. - * @param on Enables the resize of Ecore_Evas if equals EINA_TRUE, disables if equals EINA_FALSE. - */ -#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 -EAPI void -ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool 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 EINA_UNUSED, Eina_Bool on EINA_UNUSED) -{ -} -#endif - -/** - * @brief Gets if the Ecore_Evas is being directly resized using software x11. - * @note If ecore is not compiled with support to x11 then nothing is done and EINA_FALSE is returned. - * @param ee The Ecore_Evas from which to get direct resize. - * @return EINA_TRUE if the resize was managed directly, otherwise return EINA_FALSE. - */ -#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 -EAPI Eina_Bool -ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee) -{ - return ee->engine.x.direct_resize; -} -#else -EAPI Eina_Bool -ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} -#endif - -/** - * @brief Add extra window on Ecore_Evas using software x11. - * @note If ecore is not compiled with support to x11 then nothing is done. - * @param ee The Ecore_Evas on which to add the window. - * @param win The window to be added at the Ecore_Evas. - */ -#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, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); - } -} -#else -EAPI void -ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) -{ -} -#endif - -/** - * @brief Create Ecore_Evas using opengl x11. - * @note If ecore is not compiled with support to x11 then nothing is done and NULL is returned. - * @param disp_name The name of the display of the Ecore_Evas to be created. - * @param parent The parent of the Ecore_Evas to be created. - * @param x The X coordinate to be used. - * @param y The Y coordinate to be used. - * @param w The width of the Ecore_Evas to be created. - * @param h The height of the Ecore_Evas to be created. - * @return The new Ecore_Evas. - */ -#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) -{ - Ecore_Evas *ee; - int rmethod; - char *id = NULL; - - 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); - - ee->gl_sync_draw_done = -1; // added by gl77.lee - - _ecore_evas_x_init(); - - ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func; - - ee->driver = "opengl_x11"; -#if 1 - ee->semi_sync = 0; // gl engine doesn't need to sync - its whole swaps -#else - if (!getenv("ECORE_EVAS_COMP_NOSEMISYNC")) - ee->semi_sync = 1; // gl engine doesn't need to sync - its whole swaps -// ee->no_comp_sync = 1; // gl engine doesn't need to sync - its whole swaps -#endif - 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) - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - if ((id = getenv("DESKTOP_STARTUP_ID"))) - { - ecore_x_netwm_startup_id_set(ee->prop.window, 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_evas_x_hints_update(ee); - _ecore_evas_x_group_leader_set(ee); - ecore_x_window_defaults_set(ee->prop.window); - _ecore_evas_x_protocols_set(ee); - _ecore_evas_x_sync_set(ee); - - 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, - (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, - (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, - (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); - - return ee; -} -#else -EAPI Ecore_Evas * -ecore_evas_gl_x11_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, - int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ - return NULL; -} -EAPI Ecore_Evas * -ecore_evas_gl_x11_options_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, - int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, const int *opt EINA_UNUSED) -{ - return NULL; -} -#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ - -/** - * @brief Get the window from Ecore_Evas using opengl x11. - * @note If ecore is not compiled with support for x11 or if @p ee was not - * created with ecore_evas_gl_x11_new() then nothing is done and - * 0 is returned. - * @param ee The Ecore_Evas from which to get the window. - * @return The window of type Ecore_X_Window of Ecore_Evas. - */ -#ifdef BUILD_ECORE_EVAS_OPENGL_X11 -EAPI Ecore_X_Window -ecore_evas_gl_x11_window_get(const Ecore_Evas *ee) -{ - if (!(!strcmp(ee->driver, "opengl_x11"))) return 0; - return (Ecore_X_Window) ecore_evas_window_get(ee); -} -#else -EAPI Ecore_X_Window -ecore_evas_gl_x11_window_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} -#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ - -/** - * @brief Set direct_resize for Ecore_Evas using opengl x11. - * @note If ecore is not compiled with support to x11 then nothing is done. - * @param ee The Ecore_Evas in which to set direct resize. - * @param on Enables the resize of Ecore_Evas if equals EINA_TRUE, disables if equals EINA_FALSE. - */ -#ifdef BUILD_ECORE_EVAS_OPENGL_X11 -EAPI void -ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on) -{ - ee->engine.x.direct_resize = on; -} -#else -EAPI void -ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool on EINA_UNUSED) -{ -} -#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ - -/** - * @brief Gets if the Ecore_Evas is being directly resized using opengl x11. - * @note If ecore is not compiled with support to x11 then nothing is done and EINA_FALSE is returned. - * @param ee The Ecore_Evas from which to get direct resize. - * @return EINA_TRUE if the resize was managed directly, otherwise return EINA_FALSE. - */ -#ifdef BUILD_ECORE_EVAS_OPENGL_X11 -EAPI Eina_Bool -ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee) -{ - return ee->engine.x.direct_resize; -} -#else -EAPI Eina_Bool -ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} -#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ - -/** - * @brief Add extra window on Ecore_Evas using opengl x11. - * @note If ecore is not compiled with support to x11 then nothing is done. - * @param ee The Ecore_Evas for which to add the window. - * @param win The window to be added at the Ecore_Evas. - */ -#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 EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) -{ -} -#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ - -/** - * @brief Set the functions to be used before and after the swap callback. - * @note If ecore is not compiled with support to x11 then nothing is done and the function is returned. - * @param ee The Ecore_Evas for which to set the swap callback. - * @param data The data for which to set the swap callback. - * @param pre_cb The function to be called before the callback. - * @param post_cb The function to be called after the callback. - */ -#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.post_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 EINA_UNUSED, void *data EINA_UNUSED, void (*pre_cb) (void *data, Evas *e) EINA_UNUSED, void (*post_cb) (void *data, Evas *e) EINA_UNUSED) -{ - return; -} -#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ - -EAPI Ecore_Evas * -ecore_evas_xrender_x11_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, - int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ - return NULL; -} - -EAPI Ecore_X_Window -ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} - -EAPI void -ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool on EINA_UNUSED) -{ -} - -EAPI Eina_Bool -ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} - -EAPI void -ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) -{ -} - -EAPI Ecore_Evas * -ecore_evas_software_x11_16_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, - int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ - return NULL; -} - -EAPI Ecore_X_Window -ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} - -EAPI void -ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool on EINA_UNUSED) -{ -} - -EAPI Eina_Bool -ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} - -EAPI void -ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) -{ -} - -EAPI Ecore_Evas * -ecore_evas_software_x11_8_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ - return NULL; -} - -EAPI Ecore_X_Window -ecore_evas_software_x11_8_window_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} - -EAPI Ecore_X_Window -ecore_evas_software_x11_8_subwindow_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} - -EAPI void -ecore_evas_software_x11_8_direct_resize_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool on EINA_UNUSED) -{ -} - -EAPI Eina_Bool -ecore_evas_software_x11_8_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) -{ - return 0; -} - -EAPI void -ecore_evas_software_x11_8_extra_event_window_add(Ecore_Evas *ee EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) -{ - return; -} - -EAPI void -ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win) -{ -#ifdef BUILD_ECORE_EVAS_X11 - _ecore_evas_x_group_leader_unset(ee); - ee->engine.x.leader = win; - _ecore_evas_x_group_leader_update(ee); -#else - return; - ee = NULL; - win = 0; -#endif -} - -EAPI Ecore_X_Window -ecore_evas_x11_leader_get(Ecore_Evas *ee) -{ -#ifdef BUILD_ECORE_EVAS_X11 - return ee->engine.x.leader; -#else - return 0; - ee = NULL; -#endif -} - -EAPI void -ecore_evas_x11_leader_default_set(Ecore_Evas *ee) -{ -#ifdef BUILD_ECORE_EVAS_X11 - _ecore_evas_x_group_leader_unset(ee); - _ecore_evas_x_group_leader_set(ee); -#else - return; - ee = NULL; -#endif -} - -#ifdef BUILD_ECORE_EVAS_X11 -static Eina_Bool -_ecore_evas_x11_convert_rectangle_with_angle(Ecore_Evas *ee, Ecore_X_Rectangle *dst_rect, Ecore_X_Rectangle *src_rect) -{ - if ((!src_rect) || (!dst_rect)) return 0; - - if (ee->rotation == 0) - { - dst_rect->x = src_rect->x; - dst_rect->y = src_rect->y; - dst_rect->width = src_rect->width; - dst_rect->height = src_rect->height; - } - else if (ee->rotation == 90) - { - dst_rect->x = src_rect->y; - dst_rect->y = ee->req.h - src_rect->x - src_rect->width; - dst_rect->width = src_rect->height; - dst_rect->height = src_rect->width; - } - else if (ee->rotation == 180) - { - dst_rect->x = ee->req.w - src_rect->x - src_rect->width; - dst_rect->y = ee->req.h - src_rect->y - src_rect->height; - dst_rect->width = src_rect->width; - dst_rect->height = src_rect->height; - } - else if (ee->rotation == 270) - { - dst_rect->x = ee->req.w - src_rect->y - src_rect->height; - dst_rect->y = src_rect->x; - dst_rect->width = src_rect->height; - dst_rect->height = src_rect->width; - } - else - { - return 0; - } - - return 1; -} -#endif - -EAPI void -ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h) -{ -#ifdef BUILD_ECORE_EVAS_X11 - Eina_Bool ret; - Ecore_X_Rectangle src_rect; - Ecore_X_Rectangle dst_rect; - - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_x11_shape_input_rectangle_set"); - return; - } - - src_rect.x = x; - src_rect.y = y; - src_rect.width = w; - src_rect.height = h; - - dst_rect.x = 0; - dst_rect.y = 0; - dst_rect.width = 0; - dst_rect.height = 0; - - ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect); - - if (!ee->engine.x.win_shaped_input) - ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, - 0, 0, 1, 1); - - if (ret) - ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, - dst_rect.x, dst_rect.y, - dst_rect.width, dst_rect.height); -#else - return; - ee = NULL; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas *ee, int x, int y, int w, int h) -{ -#ifdef BUILD_ECORE_EVAS_X11 - Eina_Bool ret; - Ecore_X_Rectangle src_rect; - Ecore_X_Rectangle dst_rect; - - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_x11_shape_input_rectangle_add"); - return; - } - - src_rect.x = x; - src_rect.y = y; - src_rect.width = w; - src_rect.height = h; - - dst_rect.x = 0; - dst_rect.y = 0; - dst_rect.width = 0; - dst_rect.height = 0; - - ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect); - - if (!ee->engine.x.win_shaped_input) - ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, - 0, 0, 1, 1); - - if (ret) - ecore_x_window_shape_input_rectangle_add(ee->engine.x.win_shaped_input, - dst_rect.x, dst_rect.y, - dst_rect.width, dst_rect.height); -#else - return; - ee = NULL; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas *ee, int x, int y, int w, int h) -{ -#ifdef BUILD_ECORE_EVAS_X11 - Eina_Bool ret; - Ecore_X_Rectangle src_rect; - Ecore_X_Rectangle dst_rect; - - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_x11_shape_input_rectangle_subtract"); - return; - } - - src_rect.x = x; - src_rect.y = y; - src_rect.width = w; - src_rect.height = h; - - dst_rect.x = 0; - dst_rect.y = 0; - dst_rect.width = 0; - dst_rect.height = 0; - - ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect); - - if (!ee->engine.x.win_shaped_input) - ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, - 0, 0, 1, 1); - - if (ret) - ecore_x_window_shape_input_rectangle_subtract(ee->engine.x.win_shaped_input, - dst_rect.x, dst_rect.y, - dst_rect.width, dst_rect.height); -#else - return; - ee = NULL; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_evas_x11_shape_input_empty(Ecore_Evas *ee) -{ -#ifdef BUILD_ECORE_EVAS_X11 - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_x11_shape_input_empty"); - return; - } - - if (!ee->engine.x.win_shaped_input) - ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1); - - ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, 0, 0, 0, 0); -#else - return; - ee = NULL; -#endif -} - -EAPI void -ecore_evas_x11_shape_input_reset(Ecore_Evas *ee) -{ -#ifdef BUILD_ECORE_EVAS_X11 - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_x11_shape_input_reset"); - return; - } - - if (!ee->engine.x.win_shaped_input) - ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1); - - ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, 0, 0, 65535, 65535); -#else - return; - ee = NULL; -#endif -} - -EAPI void -ecore_evas_x11_shape_input_apply(Ecore_Evas *ee) -{ -#ifdef BUILD_ECORE_EVAS_X11 - if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) - { - ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, - "ecore_evas_x11_shape_input_apply"); - return; - } - - if (!ee->engine.x.win_shaped_input) return; - - ecore_x_window_shape_input_window_set(ee->prop.window, ee->engine.x.win_shaped_input); -#else - return; - ee = NULL; -#endif -} diff --git a/legacy/ecore/src/lib/ecore_fb/Ecore_Fb.h b/legacy/ecore/src/lib/ecore_fb/Ecore_Fb.h deleted file mode 100644 index 069cccdff9..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/Ecore_Fb.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef _ECORE_FB_H -#define _ECORE_FB_H - -#include - -#ifdef EAPI -# undef EAPI -#endif - -#ifdef __GNUC__ -# if __GNUC__ >= 4 -# define EAPI __attribute__ ((visibility("default"))) -# else -# define EAPI -# endif -#else -# define EAPI -#endif - -/* FIXME: - * maybe a new module? - * - code to get battery info - * - code to get thermal info - * ecore evas fb isn't 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 - -/** - * @defgroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. - * - * Functions used to set up and shut down the Ecore_Framebuffer functions. - * - * @{ - */ - -/** - * @typedef Ecore_Fb_Input_Device - * Input device handler. - */ -typedef struct _Ecore_Fb_Input_Device Ecore_Fb_Input_Device; - -/** - * @enum _Ecore_Fb_Input_Device_Cap - * 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 Ecore_Fb_Input_Device_Cap - * Device capabilities. - */ -typedef enum _Ecore_Fb_Input_Device_Cap Ecore_Fb_Input_Device_Cap; - -/* 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, Eina_Bool 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); -EAPI void ecore_fb_input_device_window_set(Ecore_Fb_Input_Device *dev, void *window); - -/* 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 diff --git a/legacy/ecore/src/lib/ecore_fb/ecore_fb.c b/legacy/ecore/src/lib/ecore_fb/ecore_fb.c deleted file mode 100644 index ff96ac8a77..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/ecore_fb.c +++ /dev/null @@ -1,129 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "Ecore_Fb.h" -#include "ecore_fb_private.h" - -static void _ecore_fb_size_get(int *w, int *h); - -static int _ecore_fb_init_count = 0; -static int _ecore_fb_console_w = 0; -static int _ecore_fb_console_h = 0; - -/** - * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. - * - * @{ - */ - -static sighandler_t oldhand = NULL; - -static void -nosigint(int val EINA_UNUSED) -{ -} - -/** - * @brief Initialize the Ecore_Fb library. - * - * @param name Device target name. - * @return 1 or greater on success, 0 on error. - * - * This function sets up all the Ecore_Fb library. It returns 0 on - * failure, otherwise it returns the number of times it has already - * been called. - * - * When Ecore_Fb is not used anymore, call ecore_fb_shutdown() to shut down - * the Ecore_Fb library. - */ -EAPI int -ecore_fb_init(const char *name EINA_UNUSED) -{ - if (++_ecore_fb_init_count != 1) - return _ecore_fb_init_count; - - if (!ecore_fb_vt_init()) - return --_ecore_fb_init_count; - - if (!oldhand) - { - oldhand = signal(SIGINT, nosigint); - } - - _ecore_fb_size_get(&_ecore_fb_console_w, &_ecore_fb_console_h); - - return _ecore_fb_init_count; -} - -/** - * @brief Shut down the Ecore_Fb library. - * - * @return 0 when the library is completely shut down, 1 or - * greater otherwise. - * - * This function shuts down the Ecore_Fb library. It returns 0 when it has - * been called the same number of times than ecore_fb_init(). - */ -EAPI int -ecore_fb_shutdown(void) -{ - if (--_ecore_fb_init_count != 0) - return _ecore_fb_init_count; - - if (oldhand) - { - signal(SIGINT, oldhand); - oldhand = NULL; - } - - ecore_fb_vt_shutdown(); - - return _ecore_fb_init_count; -} - - -/** - * @brief Retrieve 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. - * - * This function retrieves the size of the current frame buffer in - * pixels. @p w and @p h can be buffers that will be filled with the - * corresponding values. If one of them is @c NULL, nothing will be - * done for that parameter. - */ -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) - goto exit; - - if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) - goto err_ioctl; - - *w = fb_var.xres; - *h = fb_var.yres; - -err_ioctl: - close(fb); -exit: - return; -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_fb/ecore_fb_kbd.c b/legacy/ecore/src/lib/ecore_fb/ecore_fb_kbd.c deleted file mode 100644 index fd111db04d..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/ecore_fb_kbd.c +++ /dev/null @@ -1,326 +0,0 @@ -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 * 7] = -{ -#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 = -1; -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 Eina_Bool _ecore_fb_kbd_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); - -static void -_ecore_fb_event_free_key_down(void *data EINA_UNUSED, void *ev) -{ - Ecore_Fb_Event_Key_Down *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 EINA_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 Eina_Bool -_ecore_fb_kbd_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - int v = 0; - - do - { - unsigned char buf; - - v = read(_ecore_fb_kbd_fd, &buf, 1); - if (v < 0) return EINA_TRUE; - if (v < 1) return EINA_TRUE; - 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) * 7]); - e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + add]); - e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + 3 + add]); - } - else - e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]); - if (!e->keyname) - { - free(e); - goto retry; - } - e->window = 1; - e->event_window = e->window; - e->root_window = e->window; - e->same_screen = 1; - e->timestamp = ecore_loop_time_get() * 1000.0; - 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 ((_ecore_fb_kbd_fd == _ecore_fb_tty_fd) && - (_ecore_fb_ctrl)) - { - const char *ts = _ecore_fb_kbd_syms[(buf & 0x7f) + 3 + 3]; - - if (ts) - { - if (e->key_compose) free(e->key_compose); - e->key_compose = strdup(ts); - } - } - if ((vt_switch >= 0) && - (_ecore_fb_ctrl) && - (_ecore_fb_alt)) - _ecore_fb_vt_switch(vt_switch); - ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, e, _ecore_fb_event_free_key_down, NULL); - } - 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) * 7]); - e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + add]); - e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + 3 + add]); - } - else - e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]); - if (!e->keyname) - { - free(e); - goto retry; - } - e->window = 1; - e->event_window = e->window; - e->root_window = e->window; - e->same_screen = 1; - e->timestamp = ecore_loop_time_get() * 1000.0; - 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 EINA_TRUE; -} - -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_handler_handle) - ecore_main_fd_handler_del(_ecore_fb_kbd_fd_handler_handle); - if (_ecore_fb_kbd_fd >= 0) close(_ecore_fb_kbd_fd); - _ecore_fb_kbd_fd = -1; - _ecore_fb_kbd_fd_handler_handle = NULL; - _ecore_fb_ctrl = 0; - _ecore_fb_lock = 0; - _ecore_fb_shift = 0; - _ecore_fb_alt = 0; -} diff --git a/legacy/ecore/src/lib/ecore_fb/ecore_fb_keytable.h b/legacy/ecore/src/lib/ecore_fb/ecore_fb_keytable.h deleted file mode 100644 index 70bf6b9689..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/ecore_fb_keytable.h +++ /dev/null @@ -1,129 +0,0 @@ -/* this table was taken from ecore_fb, is the default en layout */ - "0x00", "0x00", "0x00", /**/"", "", "", NULL,/***/ - "Escape", "Escape", "Escape", /**/"", "", "", "\x1b",/***/ - "1", "exclam", "1", /**/"1", "!", "1", NULL,/***/ - "2", "at", "2", /**/"2", "@", "2", "",/***/ - "3", "numbersign", "3", /**/"3", "#", "3", "\x1b",/***/ - "4", "dollar", "4", /**/"4", "$", "4", "\x1c",/***/ - "5", "percent", "5", /**/"5", "%", "5", "\x1d",/***/ - "6", "asciicircumm", "6", /**/"6", "^", "6", "\x1e",/***/ - "7", "ampersand", "7", /**/"7", "&", "7", "\x1f",/***/ - "8", "asterisk", "8", /**/"8", "*", "8", "\x7f",/***/ - "9", "parenleft", "9", /**/"9", "(", "9", NULL,/***/ - "0", "parenright", "0", /**/"0", ")", "0", NULL,/***/ - "minus", "underscore", "minus", /**/"-", "_", "-", NULL,/***/ - "equal", "plus", "equal", /**/"=", "+", "=", NULL,/***/ - "BackSpace", "BackSpace", "BackSpace", /**/"\010","\010","\010", NULL,/***/ - "Tab", "ISO_Left_Tab", "Tab", /**/"\011","", "\011", NULL,/***/ - "q", "Q", "Q", /**/"q", "Q", "Q", "\x11",/***/ - "w", "W", "W", /**/"w", "W", "W", "\x17",/***/ - "e", "E", "E", /**/"e", "E", "E", "\x05",/***/ - "r", "R", "R", /**/"r", "R", "R", "\x12",/***/ - "t", "T", "T", /**/"t", "T", "T", "\x14",/***/ - "y", "Y", "Y", /**/"y", "Y", "Y", "\x19",/***/ - "u", "U", "U", /**/"u", "U", "U", "\x15",/***/ - "i", "I", "I", /**/"i", "I", "I", "\x09",/***/ - "o", "O", "O", /**/"o", "O", "O", "\x0f",/***/ - "p", "P", "P", /**/"p", "P", "P", "\x10",/***/ - "bracketleft", "braceleft", "bracketleft", /**/"[", "{", "[", "\x1b",/***/ - "bracketright", "braceright", "bracketright", /**/"]", "}", "]", "\x1d",/***/ - "Return", "Return", "Return", /**/"\015","\015","\015", NULL,/***/ - "Control_L", "Control_L", "Control_L", /**/"", "", "", NULL,/***/ - "a", "A", "A", /**/"a", "A", "A", "\x01",/***/ - "s", "S", "S", /**/"s", "S", "S", "\x13",/***/ - "d", "D", "D", /**/"d", "D", "D", "\x04",/***/ - "f", "F", "F", /**/"f", "F", "F", "\x06",/***/ - "g", "G", "G", /**/"g", "G", "G", "\x07",/***/ - "h", "h", "H", /**/"h", "H", "H", "\x08",/***/ - "j", "J", "J", /**/"j", "J", "J", "\x0a",/***/ - "k", "K", "K", /**/"k", "K", "K", "\x0b",/***/ - "l", "L", "L", /**/"l", "L", "L", "\x0c",/***/ - "semicolon", "colon", "semicolon", /**/";", ":", ";", NULL,/***/ - "apostrophe", "quotedbl", "apostrophe", /**/"'", "\"", "'", NULL,/***/ - "grave", "asciitilde", "grave", /**/"`", "~", "`", "",/***/ - "Shift_L", "Shift_L", "Shift_L", /**/"", "", "", NULL,/***/ - "backslash", "bar", "backslash", /**/"\\", "|", "\\", "\x1c",/***/ - "z", "Z", "Z", /**/"z", "Z", "Z", "\x1a",/***/ - "x", "X", "X", /**/"x", "X", "X", "\x18",/***/ - "c", "C", "C", /**/"c", "C", "C", "\x03",/***/ - "v", "V", "V", /**/"v", "V", "V", "\x16",/***/ - "b", "B", "B", /**/"b", "B", "B", "\x02",/***/ - "n", "N", "N", /**/"n", "N", "N", "\x0e",/***/ - "m", "M", "M", /**/"m", "M", "M", "\x0d",/***/ - "comma", "less", "comma", /**/",", "<", ",", NULL,/***/ - "period", "greater", "period", /**/".", ">", ".", NULL,/***/ - "slash", "question", "slash", /**/"/", "?", "/", "",/***/ - "Shift_R", "Shift_R", "Shift_R", /**/"", "", "", NULL,/***/ - "KP_Multiply", "KP_Multiply", "KP_Multiply", /**/"", "*", "", NULL,/***/ - "Alt_L", "Alt_L", "Alt_L", /**/"", "", "", NULL,/***/ - "space", "space", "space", /**/" ", " ", " ", "",/***/ - "Caps_Lock", "Caps_Lock", "Caps_Lock", /**/"", "", "", NULL,/***/ - "F1", "F1", "F1", /**/"", "", "", NULL,/***/ - "F2", "F2", "F2", /**/"", "", "", NULL,/***/ - "F3", "F3", "F3", /**/"", "", "", NULL,/***/ - "F4", "F4", "F4", /**/"", "", "", NULL,/***/ - "F5", "F5", "F5", /**/"", "", "", NULL,/***/ - "F6", "F6", "F6", /**/"", "", "", NULL,/***/ - "F7", "F7", "F7", /**/"", "", "", NULL,/***/ - "F8", "F8", "F8", /**/"", "", "", NULL,/***/ - "F9", "F9", "F9", /**/"", "", "", NULL,/***/ - "F10", "F10", "F10", /**/"", "", "", NULL,/***/ - "Num_Lock", "Num_Lock", "Num_Lock", /**/"", "", "", NULL,/***/ - "Scroll_Lock", "Scroll_Lock", "Scroll_Lock", /**/"", "", "", NULL,/***/ - "KP_Home", "KP_7", "KP_Home", /**/"", "7", "", NULL,/***/ - "KP_Up", "KP_8", "KP_Up", /**/"", "8", "", NULL,/***/ - "KP_Prior", "KP_9", "KP_Prior", /**/"", "9", "", NULL,/***/ - "KP_Subtract", "KP_Subtract", "KP_Subtract", /**/"", "", "", NULL,/***/ - "KP_Left", "KP_4", "KP_Left", /**/"", "4", "", NULL,/***/ - "KP_Begin", "KP_5", "KP_Begin", /**/"", "5", "", NULL,/***/ - "KP_Right", "KP_6", "KP_Right", /**/"", "6", "", NULL,/***/ - "KP_Add", "KP_Add", "KP_Add", /**/"", "", "", NULL,/***/ - "KP_End", "KP_1", "KP_End", /**/"", "1", "", NULL,/***/ - "KP_Down", "KP_2", "KP_Down", /**/"", "2", "", NULL,/***/ - "KP_Next", "KP_3", "KP_Next", /**/"", "3", "", NULL,/***/ - "KP_Insert", "KP_0", "KP_Insert", /**/"", "0", "", NULL,/***/ - "KP_Delete", "KP_Decimal", "KP_Delete", /**/"", ".", "", NULL,/***/ - "0x54", "0x54", "0x54", /**/"", "", "", NULL,/***/ - "0x55", "0x55", "0x55", /**/"", "", "", NULL,/***/ - "0x56", "0x56", "0x56", /**/"", "", "", NULL,/***/ - "F11", "F11", "F11", /**/"", "", "", NULL,/***/ - "F12", "F12", "F12", /**/"", "", "", NULL,/***/ - "0x59", "0x59", "0x59", /**/"", "", "", NULL,/***/ - "0x5a", "0x5a", "0x5a", /**/"", "", "", NULL,/***/ - "0x5b", "0x5b", "0x5b", /**/"", "", "", NULL,/***/ - "0x5c", "0x5c", "0x5c", /**/"", "", "", NULL,/***/ - "0x5d", "0x5d", "0x5d", /**/"", "", "", NULL,/***/ - "0x5e", "0x5e", "0x5e", /**/"", "", "", NULL,/***/ - "0x5f", "0x5f", "0x5f", /**/"", "", "", NULL,/***/ - "KP_Enter", "KP_Enter", "KP_Enter", /**/"\015", "\015", "\015", NULL,/***/ - "Control_R", "Control_R", "Control_R", /**/"", "", "", NULL,/***/ - "KP_Divide", "KP_Divide", "KP_Divide", /**/"", "", "", NULL,/***/ - "Print", "Print", "Print", /**/"", "", "", NULL,/***/ - "Alt_R", "Alt_R", "Alt_R", /**/"", "", "", NULL,/***/ - "0x65", "0x65", "0x65", /**/"", "", "", NULL,/***/ - "Home", "Home", "Home", /**/"", "", "", NULL,/***/ - "Up", "Up", "Up", /**/"", "", "", NULL,/***/ - "Prior", "Prior", "Prior", /**/"", "", "", NULL,/***/ - "Left", "Left", "Left", /**/"", "", "", NULL,/***/ - "Right", "Right", "Right", /**/"", "", "", NULL,/***/ - "End", "End", "End", /**/"", "", "", NULL,/***/ - "Down", "Down", "Down", /**/"", "", "", NULL,/***/ - "Next", "Next", "Next", /**/"", "", "", NULL,/***/ - "Insert", "Insert", "Insert", /**/"", "", "", NULL,/***/ - "Delete", "Delete", "Delete", /**/"\177","\177","\177", NULL,/***/ - "0x70", "0x70", "0x70", /**/"", "", "", NULL,/***/ - "0x71", "0x71", "0x71", /**/"", "", "", NULL,/***/ - "0x72", "0x72", "0x72", /**/"", "", "", NULL,/***/ - "0x73", "0x73", "0x73", /**/"", "", "", NULL,/***/ - "0x74", "0x74", "0x74", /**/"", "", "", NULL,/***/ - "0x75", "0x75", "0x75", /**/"", "", "", NULL,/***/ - "0x76", "0x76", "0x76", /**/"", "", "", NULL,/***/ - "Pause", "Pause", "Pause", /**/"", "", "", NULL,/***/ - "0x78", "0x78", "0x78", /**/"", "", "", NULL,/***/ - "0x79", "0x79", "0x79", /**/"", "", "", NULL,/***/ - "0x7a", "0x7a", "0x7a", /**/"", "", "", NULL,/***/ - "0x7b", "0x7b", "0x7b", /**/"", "", "", NULL,/***/ - "0x7c", "0x7c", "0x7c", /**/"", "", "", NULL,/***/ - "Super_L", "Super_L", "Super_L", /**/"", "", "", NULL,/***/ - "Super_R", "Super_R", "Super_R", /**/"", "", "", NULL,/***/ - "0x7f", "0x7f", "0x7f", /**/"", "", "", NULL, /***/ diff --git a/legacy/ecore/src/lib/ecore_fb/ecore_fb_li.c b/legacy/ecore/src/lib/ecore_fb/ecore_fb_li.c deleted file mode 100644 index 0ea0549f92..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/ecore_fb_li.c +++ /dev/null @@ -1,721 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#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 * 7] = -{ -#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_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)) - { - int offset = 0; - const char *keyname = _ecore_fb_li_kbd_syms[iev->code * 7]; - - /* check the key table */ - if (iev->value) - { - /* its a repeated key, dont increment */ - if (iev->value != 2) - { - if (!strcmp(keyname, "Control_L")) - dev->keyboard.ctrl++; - else if (!strcmp(keyname, "Control_R")) - dev->keyboard.ctrl++; - else if (!strcmp(keyname, "Alt_L")) - dev->keyboard.alt++; - else if (!strcmp(keyname, "Alt_R")) - dev->keyboard.alt++; - else if (!strcmp(keyname, "Shift_L")) - dev->keyboard.shift++; - else if (!strcmp(keyname, "Shift_R")) - dev->keyboard.shift++; - else if (!strcmp(keyname, "Caps_Lock")) - dev->keyboard.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 - { - if (!strcmp(keyname, "Control_L")) - dev->keyboard.ctrl--; - else if (!strcmp(keyname, "Control_R")) - dev->keyboard.ctrl--; - else if (!strcmp(keyname, "Alt_L")) - dev->keyboard.alt--; - else if (!strcmp(keyname, "Alt_R")) - dev->keyboard.alt--; - else if (!strcmp(keyname, "Shift_L")) - dev->keyboard.shift--; - else if (!strcmp(keyname, "Shift_R")) - dev->keyboard.shift--; - 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; - } - - /* sending ecore_input_evas events */ - Ecore_Event_Key *e; - - if (dev->keyboard.shift) offset = 1; - else if (dev->keyboard.lock) offset = 2; - - const char *key = _ecore_fb_li_kbd_syms[(iev->code * 7) + offset]; - const char *compose = _ecore_fb_li_kbd_syms[(iev->code * 7) + 3 + offset]; - - if (dev->keyboard.ctrl) - { - const char *ts = _ecore_fb_li_kbd_syms[(iev->code * 7) + 3 + 3]; - - if (ts) compose = ts; - } - - e = calloc(1, sizeof(Ecore_Event_Key) + strlen(key) + - strlen(keyname) + (compose ? strlen(compose) : 0) + 3); - 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 = 0; - if (dev->keyboard.shift) - e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL; - if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS; - - e->timestamp = ecore_loop_time_get() * 1000.0; - e->window = (Ecore_Window)dev->window; - e->event_window = (Ecore_Window)dev->window; - e->root_window = (Ecore_Window)dev->window; - e->same_screen = 1; - - if (iev->value) - ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); - else - ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); - } - /* check for mouse button events */ - else if ((iev->code >= BTN_MOUSE) && (iev->code < BTN_JOYSTICK)) - { - int button; - Ecore_Event_Mouse_Button *e; - double current = ecore_loop_time_get(); - - button = ((iev->code & 0x00F) + 1); - // swap 2 and 3 to make middle and right butotn work right. - if (button == 3) button = 2; - else if (button == 2) button = 3; - if (iev->value) - { - dev->mouse.did_double = EINA_FALSE; - dev->mouse.did_triple = EINA_FALSE; - - if (((current - dev->mouse.prev) <= dev->mouse.threshold) && - (button == dev->mouse.prev_button)) - { - dev->mouse.did_double = EINA_TRUE; - if (((current - dev->mouse.last) <= (2 * dev->mouse.threshold)) && - (button == dev->mouse.last_button)) - { - dev->mouse.did_triple = EINA_TRUE; - /* reset */ - dev->mouse.prev = 0; - dev->mouse.last = 0; - current = 0; - } - } - dev->mouse.last = dev->mouse.prev; - dev->mouse.prev = current; - dev->mouse.last_button = dev->mouse.prev_button; - dev->mouse.prev_button = button; - } - - e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); - if (!e) - return; - - e->timestamp = current * 1000.0; - e->window = (Ecore_Window)dev->window; - e->event_window = (Ecore_Window)dev->window; - e->root_window = (Ecore_Window)dev->window; - e->same_screen = 1; - - e->modifiers = 0; - if (dev->keyboard.shift) - e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL; - if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS; - - e->x = dev->mouse.x; - e->y = dev->mouse.y; - e->root.x = e->x; - e->root.y = e->y; - e->buttons = button; - - if (dev->mouse.did_double) - e->double_click = 1; - if (dev->mouse.did_triple) - e->triple_click = 1; - - if (iev->value) - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); - else - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, 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_Event_Mouse_Move *e; - 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; - } - - e = calloc(1, sizeof(Ecore_Event_Mouse_Move)); - if (!e) - return; - - e->window = (Ecore_Window)dev->window; - e->event_window = (Ecore_Window)dev->window; - e->root_window = (Ecore_Window)dev->window; - e->same_screen = 1; - - e->modifiers = 0; - if (dev->keyboard.shift) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL; - if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS; - - e->x = dev->mouse.x; - e->y = dev->mouse.y; - e->root.x = e->x; - e->root.y = e->y; - - e->timestamp = ecore_loop_time_get() * 1000.0; - - ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); - - break; - } - case REL_WHEEL: - case REL_HWHEEL: - { - Ecore_Event_Mouse_Wheel *e; - - e = calloc(1, sizeof(Ecore_Event_Mouse_Wheel)); - if (!e) - return; - - e->x = dev->mouse.x; - e->y = dev->mouse.y; - if (iev->code == REL_HWHEEL) e->direction = 1; - e->z = iev->value; - e->root.x = dev->mouse.x; - e->root.y = dev->mouse.y; - - e->window = (Ecore_Window)dev->window; - e->event_window = (Ecore_Window)dev->window; - e->root_window = (Ecore_Window)dev->window; - e->same_screen = 1; - - e->modifiers = 0; - if (dev->keyboard.shift) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL; - if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS; - - e->timestamp = ecore_loop_time_get() * 1000.0; - - ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, 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_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_EVENT_MOUSE_MOVE; - } - break; - - case ABS_PRESSURE: - pressure = iev->value; - if ((pressure) && (!prev_pressure)) - { - /* DOWN: mouse is down, but was not before */ - dev->mouse.event = ECORE_EVENT_MOUSE_BUTTON_DOWN; - } - else if ((!pressure) && (prev_pressure)) - { - /* UP: mouse was down, but is not now */ - dev->mouse.event = ECORE_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 EINA_UNUSED) -{ - if (!dev->listen) return; - - if (dev->mouse.event == ECORE_EVENT_MOUSE_MOVE) - { - Ecore_Event_Mouse_Move *ev; - ev = calloc(1,sizeof(Ecore_Event_Mouse_Move)); - ev->x = dev->mouse.x; - ev->y = dev->mouse.y; - ev->root.x = ev->x; - ev->root.y = ev->y; - ev->timestamp = ecore_loop_time_get() * 1000.0; - } - else if (dev->mouse.event == ECORE_EVENT_MOUSE_BUTTON_DOWN) - { - Ecore_Event_Mouse_Button *ev; - ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)); - ev->x = dev->mouse.x; - ev->y = dev->mouse.y; - ev->root.x = ev->x; - ev->root.y = ev->y; - ev->buttons = 1; - ev->timestamp = ecore_loop_time_get() * 1000.0; - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); - } - else if (dev->mouse.event == ECORE_EVENT_MOUSE_BUTTON_UP) - { - Ecore_Event_Mouse_Button *ev; - ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)); - ev->x = dev->mouse.x; - ev->y = dev->mouse.y; - ev->root.x = ev->x; - ev->root.y = ev->y; - ev->buttons = 1; - ev->timestamp = ecore_loop_time_get() * 1000.0; - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); - } -} - -static Eina_Bool -_ecore_fb_li_device_fd_callback(void *data, Ecore_Fd_Handler *fdh EINA_UNUSED) -{ - 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)); - for(i = 0; i < (int)(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 EINA_TRUE; -} - -/** - * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. - * - * @{ - */ - -/** - * @brief Set the listen mode for an input device . - * - * @param dev The device to set the mode of. - * @param listen @c EINA_FALSE to disable listening mode, @c EINA_TRUE to - * enable it. - * - * This function enables or disables listening on the input device @p dev. - * If @p listen is @c EINA_FALSE, listening mode is disabled, if it is - * @c EINA_TRUE, it is enabled. - */ -EAPI void -ecore_fb_input_device_listen(Ecore_Fb_Input_Device *dev, Eina_Bool 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 - -/** - * @brief Associates an input device with the given @ref Ecore_Evas_Group. - * - * @param dev The input being associated with an @ref Ecore_Evas_Group (not @c NULL). - * @param window The window which this input is being associated to. - * @c NULL will remove any previous association. - * - * Events generated by this device will have a pointer to @p window. If this @p - * window is registered with ecore_event_window_register() or - * ecore_evas_input_event_register(), respective evas events will be delivered - * by the ecore_input_evas system. An example can be seen in the following code: - * - * @code - * Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 800, 600, NULL); - * - * ecore_evas_input_event_register(ee); - * - * device = ecore_fb_input_device_open(device_path); - * if (device) - * ecore_fb_input_device_window_set(device, ee); - * - * @endcode - * - * On the previous code, all input captured on the mentioned device will be - * delivered to the @c Ecore_Evas @c ee. - * - * @since 1.1 - */ -EAPI void -ecore_fb_input_device_window_set(Ecore_Fb_Input_Device *dev, void *window) -{ - if (!dev) return; - - dev->window = window; -} - -/** - * @brief Open an input device. - * - * @param dev The device to open. - * @return The @ref Ecore_Fb_Input_Device object that has been opened. - * - * This function opens the input device named @p dev and returns the - * object for it, or returns @c NULL on failure. - */ -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; -} - -/** - * @brief Close the given device. - * - * @param dev The device to close - * - * This function closes the device @p dev. If @p dev is @c NULL, this - * function does nothing. - */ -EAPI void -ecore_fb_input_device_close(Ecore_Fb_Input_Device *dev) -{ - if (!dev || dev->fd < 0) return; - /* 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); -} - - -/** - * @brief Set the axis size of the given device. - * - * @param dev The device to set the axis size to. - * @param w The width of the axis. - * @param h The height of the axis. - * - * This function sets set the width @p w and height @p h of the axis - * of device @p dev. If @p dev is a relative input device, a width and - * height must set 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; -} - -/** - * @brief Retrieve the name of the given device. - * - * @param dev The device to get the name from. - * @return The name of the device. - * - * This function returns the name of the device @p dev. If @p dev is - * @c NULL, this function returns @c NULL. - */ -EAPI const char * -ecore_fb_input_device_name_get(Ecore_Fb_Input_Device *dev) -{ - if (!dev) return NULL; - return dev->info.name; -} - -/** - * @brief Retrieve the capability of the given device. - * - * @param dev The device to get the name from. - * @return The capability of the device. - * - * This function returns the capability of the device @p dev. If @p dev is - * @c NULL, this function returns ECORE_FB_INPUT_DEVICE_CAP_NONE. - */ -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; -} - -/** - * @brief Set the threshold of mouse clicks of the given device. - * - * @param dev The device to set the threshodl mouse click to. - * @param threshold The threshold value. - * - * This function sets the threshold of mouse clicks of the device - * @p dev to @p threshold. If @p dev is @c NULL, this function does - * nothing. - */ -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; -} - -/** - * @brief Get the threshold of mouse clicks of the given device. - * - * @param dev The device to set the threshodl mouse click from. - * @return The threshold value. - * - * This function returns the threshold of mouse clicks of the device - * @p dev. If @p dev is @c NULL, this function returns 0.0. - */ -EAPI double -ecore_fb_input_device_threshold_click_get(Ecore_Fb_Input_Device *dev) -{ - if (!dev) return 0; - return dev->mouse.threshold; -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_fb/ecore_fb_private.h b/legacy/ecore/src/lib/ecore_fb/ecore_fb_private.h deleted file mode 100644 index 797f86305f..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/ecore_fb_private.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _ECORE_FB_PRIVATE_H -#define _ECORE_FB_PRIVATE_H - -#include "Ecore.h" -#include "ecore_private.h" -#include "Ecore_Input.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 - #undef kernel_ulong_t - #undef BITS_PER_LONG -#else - #include -#endif - -#include -#include -#include - -#include - -/* 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; - Eina_Bool did_double; - Eina_Bool did_triple; - /* absolute axis */ - int min_w, min_h; - double rel_w, rel_h; - int event; - int prev_button; - int last_button; - } mouse; - struct - { - int shift; - int ctrl; - int alt; - int lock; - } keyboard; - void *window; -}; - -/* ecore_fb_ts.c */ -EAPI int ecore_fb_ts_init(void); -EAPI void ecore_fb_ts_shutdown(void); -EAPI void ecore_fb_ts_events_window_set(void *window); -EAPI void *ecore_fb_ts_events_window_get(void); -EAPI void ecore_fb_ts_event_window_set(void *window); - -/* ecore_fb_vt.c */ -int ecore_fb_vt_init(void); -void ecore_fb_vt_shutdown(void); - -/* hacks to stop people NEEDING #include */ -#ifndef TS_SET_CAL -#define TS_SET_CAL 0x4014660b -#endif -#ifndef TS_GET_CAL -#define TS_GET_CAL 0x8014660a -#endif - -#endif diff --git a/legacy/ecore/src/lib/ecore_fb/ecore_fb_ps2.c b/legacy/ecore/src/lib/ecore_fb/ecore_fb_ps2.c deleted file mode 100644 index 53aa302fef..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/ecore_fb_ps2.c +++ /dev/null @@ -1,223 +0,0 @@ -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 Eina_Bool _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 Eina_Bool -_ecore_fb_ps2_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_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; - static int did_double = 0; - static 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 EINA_TRUE; - _ecore_fb_ps2_event_byte_count += v; - if (v < num) return EINA_TRUE; - t = ecore_loop_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_Event_Mouse_Move *e; - - e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move)); - if (!e) goto retry; - e->x = x; - e->y = y; - e->root.x = e->x; - e->root.y = e->y; - e->window = 1; - e->event_window = e->window; - e->root_window = e->window; - e->same_screen = 1; - e->timestamp = ecore_loop_time_get() * 1000.0; - ecore_event_add(ECORE_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_Event_Mouse_Button *e; - - e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); - if (!e) goto retry; - e->x = x; - e->y = y; - e->root.x = e->x; - e->root.y = e->y; - e->button = i; - e->window = 1; - e->event_window = e->window; - e->root_window = e->window; - e->same_screen = 1; - if ((t - last_time) <= _ecore_fb_double_click_time) - { - e->double_click = 1; - did_double = 1; - } - else - { - did_double = 0; - did_triple = 0; - } - if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time)) - { - did_triple = 1; - e->triple_click = 1; - } - else - { - did_triple = 0; - } - e->timestamp = ecore_loop_time_get() * 1000.0; - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); - } - else if ((!(button & mask)) && ((prev_button & mask))) - { - /* UP: mouse was down, but is not now */ - Ecore_Event_Mouse_Button *e; - - e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); - if (!e) goto retry; - e->x = x; - e->y = y; - e->root.x = e->x; - e->root.y = e->y; - e->button = i; - e->window = 1; - e->event_window = e->window; - e->root_window = e->window; - e->same_screen = 1; - if (did_double) - e->double_click = 1; - if (did_triple) - e->triple_click = 1; - e->timestamp = ecore_loop_time_get() * 1000.0; - ecore_event_add(ECORE_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 EINA_TRUE; -} -/** - * @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; -} - diff --git a/legacy/ecore/src/lib/ecore_fb/ecore_fb_ts.c b/legacy/ecore/src/lib/ecore_fb/ecore_fb_ts.c deleted file mode 100644 index ce9c733c3e..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/ecore_fb_ts.c +++ /dev/null @@ -1,362 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_TSLIB -# include -# include -#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 Eina_Bool _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; -static void *_ecore_fb_ts_event_window = NULL; - -EAPI int -ecore_fb_ts_init(void) -{ -#ifdef HAVE_TSLIB - char *tslib_tsdevice = NULL; - if ( (tslib_tsdevice = getenv("TSLIB_TSDEVICE")) ) - { - 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_handler_handle) - ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle); - if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd); - _ecore_fb_ts_fd = -1; - _ecore_fb_ts_fd_handler_handle = NULL; - _ecore_fb_ts_event_window = NULL; -} - -EAPI void -ecore_fb_ts_event_window_set(void *window) -{ - _ecore_fb_ts_event_window = window; -} - -EAPI void * -ecore_fb_ts_event_window_get(void) -{ - return _ecore_fb_ts_event_window; -} - -/** - * @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 Eina_Bool -_ecore_fb_ts_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_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 = 0.0; - static int did_double = 0; - static 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 */ -#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 - t = ecore_loop_time_get(); - /* add event to queue */ - /* always add a move event */ - if ((pressure) || (prev_pressure)) - { - /* MOVE: mouse is down and was */ - Ecore_Event_Mouse_Move *e; - - e = calloc(1, sizeof(Ecore_Event_Mouse_Move)); - if (!e) goto retry; - e->x = x; - e->y = y; - e->root.x = e->x; - e->root.y = e->y; - e->window = 1; - e->event_window = e->window; - e->root_window = e->window; - e->same_screen = 1; - e->timestamp = ecore_loop_time_get() * 1000.0; - ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); - } - if ((pressure) && (!prev_pressure)) - { - /* DOWN: mouse is down, but was not now */ - Ecore_Event_Mouse_Button *e; - - e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); - if (!e) goto retry; - e->x = x; - e->y = y; - e->root.x = e->x; - e->root.y = e->y; - e->buttons = 1; - if ((t - last_time) <= _ecore_fb_double_click_time) - { - e->double_click = 1; - did_double = 1; - } - else - { - did_double = 0; - did_triple = 0; - } - if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time)) - { - did_triple = 1; - e->triple_click = 1; - } - else - { - did_triple = 0; - } - e->window = 1; - e->event_window = e->window; - e->root_window = e->window; - e->same_screen = 1; - e->timestamp = ecore_loop_time_get() * 1000.0; - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); - } - else if ((!pressure) && (prev_pressure)) - { - /* UP: mouse was down, but is not now */ - Ecore_Event_Mouse_Button *e; - - e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); - if (!e) goto retry; - e->x = prev_x; - e->y = prev_y; - e->root.x = e->x; - e->root.y = e->y; - e->buttons = 1; - if (did_double) - e->double_click = 1; - if (did_triple) - e->triple_click = 1; - e->window = 1; - e->event_window = e->window; - e->root_window = e->window; - e->same_screen = 1; - e->timestamp = ecore_loop_time_get() * 1000.0; - ecore_event_add(ECORE_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; -} - diff --git a/legacy/ecore/src/lib/ecore_fb/ecore_fb_vt.c b/legacy/ecore/src/lib/ecore_fb/ecore_fb_vt.c deleted file mode 100644 index c92c087336..0000000000 --- a/legacy/ecore/src/lib/ecore_fb/ecore_fb_vt.c +++ /dev/null @@ -1,322 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#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 = -1; -static int _ecore_fb_vt_tty_fd = -1; -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 Eina_Bool _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; - -/* prototypes */ -/* XXX: unused -static void _ecore_fb_vt_switch(int vt); -static void *_ecore_fb_event_filter_start(void *data); -static Eina_Bool _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); -*/ - -static Eina_Bool -_ecore_fb_signal_usr_handler(void *data EINA_UNUSED, int type EINA_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; -} - -/* XXX: unused -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]; -// XXX: unused -// 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] can't open tty %d\n", _ecore_fb_vt_current_vt); - return 0; - } - close(_ecore_fb_vt_tty0_fd); - _ecore_fb_vt_tty0_fd = -1; - /* 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] can't set the mode to KD_GRAPHICS"); - close(_ecore_fb_vt_tty_fd); - _ecore_fb_vt_tty_fd = -1; - 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] can't set the tty mode"); - close(_ecore_fb_vt_tty_fd); - _ecore_fb_vt_tty_fd = -1; - 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 do? */ - /* - _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); - _ecore_fb_vt_tty_fd = -1; - 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); - _ecore_fb_vt_tty_fd = -1; - return 0; - } - /* FIXME assign the fb to the tty in case isn't 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] can't 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] can't 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] can't 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] can't 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 != -1) - { - 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 = -1; - } - - 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; -} - -/** - * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. - * - * @{ - */ - -/** - * @brief Set a callback called when a virtual terminal is gained. - * - * @param func The callback called when vt is gained. - * @param data The data to pass to the callback. - * - * This function sets the callback @p func which will be called when a - * virtual terminal is gained (for example you press Ctrl-Alt-F1 to go - * to vt1 and your app was using vt1). @p data will be pass to @p func if - * the callback is called. - */ -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; -} - -/** - * @brief Set a callback called when a virtual terminal is lost. - * - * @param func The callback called when vt is lost. - * @param data The data to pass to the callback. - * - * This function sets the callback @p func which will be called when a - * virtual terminal is lost (someone wants the tv from you and you - * want to give up that vt). @p data will be pass to @p func if the - * callback is called. - */ -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; - -} - -/** - * @} - */ - -/* - * This filter should take into account that the MOUSE_MOVE event can be - * triggered by a mouse, not just a touchscreen device, so you can't discard - * them (only those generated by a device that sends events with absolute - * coordinates). - -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 EINA_UNUSED) -{ - Ecore_Fb_Filter_Data *filter_data; - - filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data)); - return filter_data; -} - -static Eina_Bool -_ecore_fb_event_filter_filter(void *data EINA_UNUSED, void *loop_data,int type, void *event EINA_UNUSED) -{ - Ecore_Fb_Filter_Data *filter_data; - - filter_data = loop_data; - if (!filter_data) return EINA_TRUE; - if (type == ECORE_EVENT_MOUSE_MOVE) - { - if ((filter_data->last_event_type) == ECORE_EVENT_MOUSE_MOVE) - { - filter_data->last_event_type = type; - return EINA_FALSE; - } - } - filter_data->last_event_type = type; - return EINA_TRUE; -} - -static void -_ecore_fb_event_filter_end(void *data EINA_UNUSED, void *loop_data) -{ - Ecore_Fb_Filter_Data *filter_data; - - filter_data = loop_data; - if (filter_data) free(filter_data); -} -*/ diff --git a/legacy/ecore/src/lib/ecore_file/Ecore_File.h b/legacy/ecore/src/lib/ecore_file/Ecore_File.h deleted file mode 100644 index 30f3bd7d9e..0000000000 --- a/legacy/ecore/src/lib/ecore_file/Ecore_File.h +++ /dev/null @@ -1,190 +0,0 @@ -#ifndef ECORE_FILE_H -#define ECORE_FILE_H - -/* - * TODO: - * - More events, move/rename of directory file - */ - -#include - -#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 - -/** - * @defgroup Ecore_File_Group Ecore_File - Files and directories convenience functions - * - * @{ - */ - -/** - * @typedef Ecore_File_Monitor - * Abstract type used when monitoring a directory. - */ -typedef struct _Ecore_File_Monitor Ecore_File_Monitor; - -/** - * @typedef Ecore_File_Download_Job - * Abstract type used when aborting a download. - */ -typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job; - -/** - * @typedef _Ecore_File_Event - * The event type returned when a file or directory is monitored. - */ -typedef enum _Ecore_File_Event -{ - ECORE_FILE_EVENT_NONE, /**< No event. */ - ECORE_FILE_EVENT_CREATED_FILE, /**< Created file event. */ - ECORE_FILE_EVENT_CREATED_DIRECTORY, /**< Created directory event. */ - ECORE_FILE_EVENT_DELETED_FILE, /**< Deleted file event. */ - ECORE_FILE_EVENT_DELETED_DIRECTORY, /**< Deleted directory event. */ - ECORE_FILE_EVENT_DELETED_SELF, /**< Deleted monitored directory event. */ - ECORE_FILE_EVENT_MODIFIED, /**< Modified file or directory event. */ - ECORE_FILE_EVENT_CLOSED /**< Closed file event */ -} Ecore_File_Event; - -/** - * @typedef Ecore_File_Monitor_Cb - * Callback type used when a monitored directory has changes. - */ -typedef void (*Ecore_File_Monitor_Cb)(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path); - -/** - * @typedef Ecore_File_Download_Completion_Cb - * Callback type used when a download is finished. - */ -typedef void (*Ecore_File_Download_Completion_Cb)(void *data, const char *file, int status); - -/** - * @typedef _Ecore_File_Progress_Return - * What to do with the download as a return from the - * Ecore_File_Download_Progress_Cb function, if provided. - */ -typedef enum _Ecore_File_Progress_Return -{ - ECORE_FILE_PROGRESS_CONTINUE = 0, /**< Continue the download. */ - ECORE_FILE_PROGRESS_ABORT = 1 /**< Abort the download. */ -} Ecore_File_Progress_Return; - -/** - * @typedef Ecore_File_Download_Progress_Cb - * Callback type used while a download is in progress. - */ -typedef int (*Ecore_File_Download_Progress_Cb)(void *data, - const char *file, - long int dltotal, - long int dlnow, - long int ultotal, - long int ulnow); - -/* File operations */ - -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 Eina_Bool ecore_file_exists (const char *file); -EAPI Eina_Bool ecore_file_is_dir (const char *file); -EAPI Eina_Bool 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 Eina_Bool ecore_file_rmdir (const char *dir); -EAPI Eina_Bool ecore_file_recursive_rm (const char *dir); -EAPI Eina_Bool ecore_file_mkpath (const char *path); -EAPI int ecore_file_mkpaths (const char **paths); -EAPI Eina_Bool ecore_file_cp (const char *src, const char *dst); -EAPI Eina_Bool ecore_file_mv (const char *src, const char *dst); -EAPI Eina_Bool ecore_file_symlink (const char *src, const char *dest); -EAPI char *ecore_file_realpath (const char *file); -EAPI Eina_Bool ecore_file_unlink (const char *file); -EAPI Eina_Bool 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 Eina_Bool ecore_file_can_read (const char *file); -EAPI Eina_Bool ecore_file_can_write (const char *file); -EAPI Eina_Bool 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 Eina_Iterator *ecore_file_ls_iterator (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); - -/* Monitoring */ - -EAPI Ecore_File_Monitor *ecore_file_monitor_add(const char *path, - Ecore_File_Monitor_Cb func, - 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); - -/* Path */ - -EAPI Eina_Bool ecore_file_path_dir_exists(const char *in_dir); -EAPI Eina_Bool ecore_file_app_installed(const char *exe); -EAPI Eina_List *ecore_file_app_list(void); - -/* Download */ - -EAPI Eina_Bool ecore_file_download(const char *url, - const char *dst, - Ecore_File_Download_Completion_Cb completion_cb, - Ecore_File_Download_Progress_Cb progress_cb, - void *data, - Ecore_File_Download_Job **job_ret); -EAPI Eina_Bool ecore_file_download_full(const char *url, - const char *dst, - Ecore_File_Download_Completion_Cb completion_cb, - Ecore_File_Download_Progress_Cb progress_cb, - void *data, - Ecore_File_Download_Job **job_ret, - Eina_Hash *headers); - -EAPI void ecore_file_download_abort_all(void); -EAPI void ecore_file_download_abort(Ecore_File_Download_Job *job); -EAPI Eina_Bool ecore_file_download_protocol_available(const char *protocol); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file.c b/legacy/ecore/src/lib/ecore_file/ecore_file.c deleted file mode 100644 index 6876511fc6..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file.c +++ /dev/null @@ -1,1137 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#ifndef _MSC_VER -# include -# include -#endif - -#ifdef _WIN32 -# include -#endif - -#ifdef HAVE_FEATURES_H -# include -#endif -#include -#include - -#ifdef HAVE_ATFILE_SOURCE -# include -#endif - -#include "ecore_file_private.h" - -int _ecore_file_log_dom = -1; -static int _ecore_file_init_count = 0; - -/* externally accessible functions */ - -/** - * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions - * - * @{ - */ - -/** - * @brief Initialize the Ecore_File library. - * - * @return 1 or greater on success, 0 on error. - * - * This function sets up Ecore_File and the services it will use - * (monitoring, downloading, PATH related feature). It returns 0 on - * failure, otherwise it returns the number of times it has already - * been called. - * - * When Ecore_File is not used anymore, call ecore_file_shutdown() - * to shut down the Ecore_File library. - */ -EAPI int -ecore_file_init() -{ - if (++_ecore_file_init_count != 1) - return _ecore_file_init_count; - - if (!ecore_init()) - return --_ecore_file_init_count; - - _ecore_file_log_dom = eina_log_domain_register - ("ecore_file", 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; - */ -} - -/** - * @brief Shut down the Ecore_File library. - * - * @return 0 when the library is completely shut down, 1 or - * greater otherwise. - * - * This function shuts down the Ecore_File library. It returns 0 when it has - * been called the same number of times than ecore_file_init(). In that case - * it shuts down all the services it uses. - */ -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; - - ecore_shutdown(); - - return _ecore_file_init_count; -} - -/** - * @brief Get the time of the last modification to the given file. - * - * @param file The name of the file. - * @return Return the time of the last data modification, or 0 on - * failure. - * - * This function returns the time of the last modification of - * @p file. On failure, it returns 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; -} - -/** - * @brief Get the size of the given file. - * - * @param file The name of the file. - * @return Return the size of the file in bytes, or 0 on failure. - * - * This function returns the size of @p file in bytes. On failure, it - * returns 0. - */ -EAPI long long -ecore_file_size(const char *file) -{ - struct stat st; - - if (stat(file, &st) < 0) return 0; - return st.st_size; -} - -/** - * @brief Check if the given file exists. - * - * @param file The name of the file. - * @return @c EINA_TRUE if the @p file exists, @c EINA_FALSE otherwise. - * - * This function returns @c EINA_TRUE if @p file exists on local filesystem, - * @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_exists(const char *file) -{ - struct stat st; - if (!file) return EINA_FALSE; - - /*Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor*/ - if (stat(file, &st) < 0 && strcmp(file, "/")) return EINA_FALSE; - return EINA_TRUE; -} - -/** - * @brief Check if the given file is a directory. - * - * @param file The name of the file. - * @return @c EINA_TRUE if the file exists and is a directory, @c EINA_FALSE - * otherwise. - * - * This function returns @c EINA_TRUE if @p file exists exists and is a - * directory on local filesystem, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_is_dir(const char *file) -{ - struct stat st; - - if (stat(file, &st) < 0) return EINA_FALSE; - if (S_ISDIR(st.st_mode)) return EINA_TRUE; - return EINA_FALSE; -} - -static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - -/** - * @brief Create a new directory. - * - * @param dir The name of the directory to create - * @return @c EINA_TRUE on successful creation, @c EINA_FALSE otherwise. - * - * This function creates the directory @p dir with the mode S_IRUSR | - * S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH. On - * success, it returns @c EINA_TRUE, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_mkdir(const char *dir) -{ - if (mkdir(dir, default_mode) < 0) return EINA_FALSE; - return EINA_TRUE; -} - -/** - * @brief Create complete directory in a batch. - * - * @param dirs The list of directories, null terminated. - * @return The number of successful directories created, -1 if dirs is - * @c NULL. - * - * This function creates all the directories that are in the null - * terminated array @p dirs. The function loops over the directories - * and call ecore_file_mkdir(). This function returns -1 if @p dirs is - * @c NULL, otherwise if returns the number of suceesfully created - * directories. - */ -EAPI int -ecore_file_mkdirs(const char **dirs) -{ - int i = 0; - - if (!dirs) return -1; - - for (; *dirs; dirs++) - if (ecore_file_mkdir(*dirs)) - i++; - return i; -} - -/** - * @brief Create complete list of sub-directories in a batch (optimized). - * - * @param base The base directory to act on. - * @param subdirs The list of directories, null terminated. - * @return number of successful directories created, -1 on failure. - * - * This function creates all the directories that are in the null - * terminated array @p dirs in the @p base directory. If @p base does - * not exist, it will be created. The function loops over the directories - * and call ecore_file_mkdir(). The whole path of the directories must - * exist. So if base/a/b/c wants to be created, @p subdirs must - * contain "a", "a/b" and "a/b/c", in that order. This function - * returns -1 if @p dirs or @p base are @c NULL, or if @p base is - * empty ("\0"). It returns 0 is @p base is not a directory or - * invalid, or if it can't be created. Otherwise if returns the number - * of suceesfully created directories. - */ -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; 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; -} - -/** - * @brief Delete the given directory. - * - * @param dir The name of the directory to delete. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function deletes @p dir. It returns @c EINA_TRUE on success, - * @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_rmdir(const char *dir) -{ - if (rmdir(dir) < 0) return EINA_FALSE; - return EINA_TRUE; -} - -/** - * @brief Delete the given file. - * - * @param file The name of the file to delete. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function deletes @p file. It returns @c EINA_TRUE on success, - * @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_unlink(const char *file) -{ - if (unlink(file) < 0) return EINA_FALSE; - return EINA_TRUE; -} - -/** - * @brief Remove the given file or directory. - * - * @param file The name of the file or directory to delete. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function removes @p file. It returns @c EINA_TRUE on success, - * @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_remove(const char *file) -{ - if (remove(file) < 0) return EINA_FALSE; - return EINA_TRUE; -} - -/** - * @brief Delete the given directory and all its contents. - * - * @param dir The name of the directory to delete. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function delete @p dir and all its contents. If @p dir is a - * link only the link is removed. It returns @c EINA_TRUE on success, - * @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_recursive_rm(const char *dir) -{ - struct stat st; - -#ifdef _WIN32 - char buf[PATH_MAX]; - - if (readlink(dir, buf, sizeof(buf) - 1) > 0) - return ecore_file_unlink(dir); - if (stat(dir, &st) == -1) - return EINA_FALSE; -#else - if (lstat(dir, &st) == -1) - return EINA_FALSE; -#endif - - if (S_ISDIR(st.st_mode)) - { - Eina_File_Direct_Info *info; - Eina_Iterator *it; - int ret; - - ret = 1; - it = eina_file_direct_ls(dir); - EINA_ITERATOR_FOREACH(it, info) - { - if (!ecore_file_recursive_rm(info->path)) - ret = 0; - } - eina_iterator_free(it); - - if (!ecore_file_rmdir(dir)) ret = 0; - if (ret) - return EINA_TRUE; - else - return EINA_FALSE; - } - else - { - return ecore_file_unlink(dir); - } -} - -static inline Eina_Bool -_ecore_file_mkpath_if_not_exists(const char *path) -{ - struct stat st; - - /* Windows: path like C: or D: etc are valid, but stat() returns an error */ -#ifdef _WIN32 - if ((strlen(path) == 2) && - ((path[0] >= 'a' && path[0] <= 'z') || - (path[0] >= 'A' && path[0] <= 'Z')) && - (path[1] == ':')) - return EINA_TRUE; -#endif - - if (stat(path, &st) < 0) - return ecore_file_mkdir(path); - else if (!S_ISDIR(st.st_mode)) - return EINA_FALSE; - else - return EINA_TRUE; -} - -/** - * @brief Create a complete path. - * - * @param path The path to create - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function creates @p path and all the subdirectories it - * contains. The separator is '/' or '\'. If @p path exists, this - * function returns @c EINA_TRUE immediately. It returns @c EINA_TRUE on - * success, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_mkpath(const char *path) -{ - char ss[PATH_MAX]; - unsigned int i; - - if (ecore_file_is_dir(path)) - return EINA_TRUE; - - for (i = 0; path[i] != '\0'; ss[i] = path[i], i++) - { - if (i == sizeof(ss) - 1) return EINA_FALSE; - if (((path[i] == '/') || (path[i] == '\\')) && (i > 0)) - { - ss[i] = '\0'; - if (!_ecore_file_mkpath_if_not_exists(ss)) - return EINA_FALSE; - } - } - ss[i] = '\0'; - return _ecore_file_mkpath_if_not_exists(ss); -} - -/** - * @brief Create complete paths in a batch. - * - * @param paths list of paths, null terminated. - * @return number of successful paths created, -1 if paths is NULL. - * - * This function creates all the directories that are in the null - * terminated array @p paths. The function loops over the directories - * and call ecore_file_mkpath(), hence on Windows, '\' must be - * replaced by '/' before calling that function. This function - * returns -1 if @p paths is @c NULL. Otherwise if returns the number - * of suceesfully created directories. - */ -EAPI int -ecore_file_mkpaths(const char **paths) -{ - int i = 0; - - if (!paths) return -1; - - for (; *paths; paths++) - if (ecore_file_mkpath(*paths)) - i++; - return i; -} - -/** - * @brief Copy the given file to the given destination. - * - * @param src The name of the source file. - * @param dst The name of the destination file. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function copies @p src to @p dst. If the absolute path name of - * @p src and @p dst can not be computed, or if they are equal, or if - * the copy fails, the function returns @c EINA_FALSE, otherwise it - * returns @c EINA_TRUE. - */ -EAPI Eina_Bool -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; - Eina_Bool ret = EINA_TRUE; - - if (!realpath(src, realpath1)) return EINA_FALSE; - if (realpath(dst, realpath2) && !strcmp(realpath1, realpath2)) return EINA_FALSE; - - f1 = fopen(src, "rb"); - if (!f1) return EINA_FALSE; - f2 = fopen(dst, "wb"); - if (!f2) - { - fclose(f1); - return EINA_FALSE; - } - while ((num = fread(buf, 1, sizeof(buf), f1)) > 0) - { - if (fwrite(buf, 1, num, f2) != num) ret = EINA_FALSE; - } - fclose(f1); - fclose(f2); - return ret; -} - -/** - * @brief Move the given file to the given destination. - * - * @param src The name of the source file. - * @param dst The name of the destination file. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function moves @p src to @p dst. It returns @c EINA_TRUE on - * success, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -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) 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 EINA_TRUE; - -FAIL: - return EINA_FALSE; -} - -/** - * @brief Create a symbolic link. - * - * @param src The name of the file to link. - * @param dest The name of link. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function create the symbolic link @p dest of @p src. This - * function does not work on Windows. It returns @c EINA_TRUE on success, - * @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_symlink(const char *src, const char *dest) -{ - if (!symlink(src, dest)) return EINA_TRUE; - - return EINA_FALSE; -} - -/** - * @brief Get the canonicalized absolute path name. - * - * @param file The file path. - * @return The canonicalized absolute pathname or an empty string on - * failure. - * - * This function returns the absolute path name of @p file as a newly - * allocated string. If @p file is @c NULL, or on error, this function - * returns an empty string. Otherwise, it returns the absolute path - * name. When not needed anymore, the returned value must be freed. - */ -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 given path. - * - * @param path The complete path. - * @return The file name. - * - * This function returns the file name of @p path. If @p path is - * @c NULL, the functions returns @c NULL. - */ -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; -} - -/** - * @brief Get the directory where the given file resides. - * - * @param file The name of the file. - * @return The directory name. - * - * This function returns the directory where @p file resides as anewly - * allocated string. If @p file is @c NULL or on error, this function - * returns @c NULL. When not needed anymore, the returned value must - * be freed. - */ -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); -} - -/** - * @brief Check if the given file can be read. - * - * @param file The name of the file. - * @return @c EINA_TRUE if the @p file is readable, @c EINA_FALSE otherwise. - * - * This function returns @c EINA_TRUE if @p file can be read, @c EINA_FALSE - * otherwise. - */ -EAPI Eina_Bool -ecore_file_can_read(const char *file) -{ - if (!file) return EINA_FALSE; - if (!access(file, R_OK)) return EINA_TRUE; - return EINA_FALSE; -} - -/** - * @brief Check if the given file can be written. - * - * @param file The name of the file. - * @return @c EINA_TRUE if the @p file is writable, @c EINA_FALSE otherwise. - * - * This function returns @c EINA_TRUE if @p file can be written, @c EINA_FALSE - * otherwise. - */ -EAPI Eina_Bool -ecore_file_can_write(const char *file) -{ - if (!file) return EINA_FALSE; - if (!access(file, W_OK)) return EINA_TRUE; - return EINA_FALSE; -} - -/** - * @brief Check if the given file can be executed. - * - * @param file The name of the file. - * @return @c EINA_TRUE if the @p file can be executed, @c EINA_FALSE - * otherwise. - * - * This function returns @c EINA_TRUE if @p file can be executed, @c EINA_FALSE - * otherwise. - */ -EAPI Eina_Bool -ecore_file_can_exec(const char *file) -{ - if (!file) return EINA_FALSE; - if (!access(file, X_OK)) return EINA_TRUE; - return EINA_FALSE; -} - -/** - * @brief Get the path pointed by the given link. - * - * @param lnk The name of the link. - * @return The path pointed by link or NULL. - * - * This function returns the path pointed by @p link as a newly - * allocated string. This function does not work on Windows. On - * failure, the function returns @c NULL. When not needed anymore, the - * returned value must be freed. - */ -EAPI char * -ecore_file_readlink(const char *lnk) -{ - char buf[PATH_MAX]; - int count; - - if ((count = readlink(lnk, buf, sizeof(buf) - 1)) < 0) return NULL; - buf[count] = 0; - return strdup(buf); -} - -/** - * @brief Get the list of the files and directories in the given - * directory. - * - * @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. - * - * This function returns a list of allocated strings of all the files - * and directories contained in @p dir. 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 '..'. On failure, @c NULL is returned. When not needed - * anymore, the list elements must be freed. - */ -EAPI Eina_List * -ecore_file_ls(const char *dir) -{ - Eina_File_Direct_Info *info; - Eina_Iterator *ls; - Eina_List *list = NULL; - - ls = eina_file_direct_ls(dir); - if (!ls) return NULL; - - EINA_ITERATOR_FOREACH(ls, info) - { - char *f; - - f = strdup(info->path + info->name_start); - list = eina_list_append(list, f); - } - eina_iterator_free(ls); - - list = eina_list_sort(list, eina_list_count(list), EINA_COMPARE_CB(strcoll)); - - return list; -} - -/** - * @brief Return the executable from the given command. - * - * @param app The application command, with parameters. - * @return The executable from @p app as a newly allocated string. Arguments - * are removed and escape characters are handled. If @p app is @c NULL, or - * on failure, the function returns @c NULL. When not needed anymore, the - * returned value must be freed. - */ -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((unsigned char)*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((unsigned char)*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 - { - /* technically 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((unsigned char)*p)) - { - if (restart) - goto restart; - else - break; - } - else - { - *pp = *p; - pp++; - } - } - p++; - } - *pp = 0; - return exe; -} - -/** - * @brief Add the escape sequence ('\\') to the given file name. - * - * @param filename The file name. - * @return The file name with special characters escaped. - * - * This function adds the escape sequence ('\\') to the given file - * name and returns the result as a newly allocated string. If the - * length of the returned string is longer than PATH_MAX, or on - * failure, @c NULL is returned. When not needed anymore, the returned - * value must be freed. - */ -EAPI char * -ecore_file_escape_name(const char *filename) -{ - const char *p; - char *q; - char buf[PATH_MAX]; - - EINA_SAFETY_ON_NULL_RETURN_VAL(filename, NULL); - - p = filename; - q = buf; - while (*p) - { - if ((q - buf) > (PATH_MAX - 6)) return NULL; - if ( - (*p == ' ') || (*p == '\\') || (*p == '\'') || - (*p == '\"') || (*p == ';') || (*p == '!') || - (*p == '#') || (*p == '$') || (*p == '%') || - (*p == '&') || (*p == '*') || (*p == '(') || - (*p == ')') || (*p == '[') || (*p == ']') || - (*p == '{') || (*p == '}') || (*p == '|') || - (*p == '<') || (*p == '>') || (*p == '?') - ) - { - *q = '\\'; - q++; - } - else if (*p == '\t') - { - *q = '\\'; - q++; - *q = '\\'; - q++; - *q = 't'; - q++; - p++; - continue; - } - else if (*p == '\n') - { - *q = '\\'; - q++; - *q = '\\'; - q++; - *q = 'n'; - q++; - p++; - continue; - } - - *q = *p; - q++; - p++; - } - *q = 0; - return strdup(buf); -} - -/** - * @brief Remove the extension from the given file name. - * - * @param path The name of the file. - * @return A newly allocated string with the extension stripped out or - * @c NULL on errors. - * - * This function removes the extension from @p path and returns the - * result as a newly allocated string. If @p path is @c NULL, or on - * failure, the function returns @c NULL. When not needed anymore, the - * returned value must be freed. - */ -EAPI char * -ecore_file_strip_ext(const char *path) -{ - char *p, *file = NULL; - - if (!path) - return 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; -} - -/** - * @brief Check if the given directory is empty. - * - * @param dir The name of the directory to check. - * @return @c 1 if directory is empty, @c 0 if it has at least one file or - * @c -1 in case of errors. - * - * This functions checks if @p dir is empty. The '.' and '..' files - * will be ignored. If @p dir is empty, 1 is returned, if it contains - * at least one file, @c 0 is returned. On failure, @c -1 is returned. - */ -EAPI int -ecore_file_dir_is_empty(const char *dir) -{ - Eina_File_Direct_Info *info; - Eina_Iterator *it; - - it = eina_file_direct_ls(dir); - if (!it) return -1; - - EINA_ITERATOR_FOREACH(it, info) - { - eina_iterator_free(it); - return 0; - } - - eina_iterator_free(it); - return 1; -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_download.c b/legacy/ecore/src/lib/ecore_file/ecore_file_download.c deleted file mode 100644 index 98d4a1f972..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_download.c +++ /dev/null @@ -1,455 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#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 -#define ECORE_FILE_DOWNLOAD_TIMEOUT 30 - -struct _Ecore_File_Download_Job -{ - ECORE_MAGIC; - - Ecore_Con_Url *url_con; - FILE *file; - - char *dst; - - Ecore_File_Download_Completion_Cb completion_cb; - Ecore_File_Download_Progress_Cb progress_cb; -}; - -#ifdef HAVE_CURL -Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst, - Ecore_File_Download_Completion_Cb completion_cb, - Ecore_File_Download_Progress_Cb progress_cb, - void *data, - Eina_Hash *headers); - -static Eina_Bool _ecore_file_download_url_complete_cb(void *data, int type, void *event); -static Eina_Bool _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; - -static int download_init = 0; - -#endif /* BUILD_ECORE_CON */ - -int -ecore_file_download_init(void) -{ -#ifdef BUILD_ECORE_CON - download_init++; - if (download_init > 1) return 1; - if (!ecore_con_init()) return 0; - if (!ecore_con_url_init()) - { - ecore_con_shutdown(); - 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 - download_init--; - if (download_init > 0) return; - 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(); - ecore_con_shutdown(); -#endif /* BUILD_ECORE_CON */ -} - -#ifdef BUILD_ECORE_CON -# ifdef HAVE_CURL -static Eina_Bool -_ecore_file_download_headers_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata) -{ - Ecore_File_Download_Job *job = fdata; - ecore_con_url_additional_header_add(job->url_con, key, data); - - return EINA_TRUE; -} -# endif -#endif - -static Eina_Bool -_ecore_file_download(const char *url, - const char *dst, - Ecore_File_Download_Completion_Cb completion_cb, - Ecore_File_Download_Progress_Cb progress_cb, - void *data, - Ecore_File_Download_Job **job_ret, - Eina_Hash *headers) -{ -#ifdef BUILD_ECORE_CON - if (!url) - { - CRIT("Download URL is null"); - return EINA_FALSE; - } - - char *dir = ecore_file_dir_get(dst); - - if (!ecore_file_is_dir(dir)) - { - ERR("%s is not a directory", dir); - free(dir); - return EINA_FALSE; - } - free(dir); - if (ecore_file_exists(dst)) - { - WRN("%s already exists", dst); - return EINA_FALSE; - } - - 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, "https://", 8)) || - (!strncmp(url, "ftp://", 6))) - { - /* download */ - Ecore_File_Download_Job *job; - - job = _ecore_file_download_curl(url, dst, completion_cb, progress_cb, data, headers); - if(job_ret) *job_ret = job; - if(job) - return EINA_TRUE; - else - { - ERR("no job returned\n"); - return EINA_FALSE; - } - return job ? EINA_TRUE : EINA_FALSE; - } -# else - else if ((!strncmp(url, "http://", 7)) || (!strncmp(url, "https://", 8)) || - (!strncmp(url, "ftp://", 6))) - { - (void)completion_cb; - (void)progress_cb; - (void)data; - (void)job_ret; - (void)headers; - return EINA_FALSE; - } -# endif - else - { - return EINA_FALSE; - } -#else - (void)url; - (void)dst; - (void)completion_cb; - (void)progress_cb; - (void)data; - (void)job_ret; - (void)headers; - return EINA_FALSE; -#endif /* BUILD_ECORE_CON */ -} - -/** - * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions - * - * @{ - */ - -/** - * @brief Download the given url to the given destination. - * - * @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 Job used to abort the download. - * @return @c EINA_TRUE if the download start or @c EINA_FALSE on failure. - * - * This function starts the download of the URL @p url and saves it to - * @p dst. @p url must provide the protocol, including 'http://', - * 'ftp://' or 'file://'. Ecore_File must be compiled with CURL to - * download using http and ftp protocols. If @p dst is ill-formed, or - * if it already exists, the function returns @c EINA_FALSE. When the - * download is complete, the callback @p completion_cb is called and - * @p data is passed to it. The @p status parameter of @p completion_cb - * will be filled with the status of the download (200, 404,...). The - * @p progress_cb is called during the download operation, each time a - * packet is received or when CURL wants. It can be used to display the - * percentage of the downloaded file. Return 0 from this callback, if provided, - * to continue the operation or anything else to abort the download. The only - * operations that can be aborted are those with protocol 'http' or 'ftp'. In - * that case @p job_ret can be filled. It can be used with - * ecore_file_download_abort() or ecore_file_download_abort_all() to - * respectively abort one or all download operations. This function returns - * @c EINA_TRUE if the download starts, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_file_download(const char *url, - const char *dst, - Ecore_File_Download_Completion_Cb completion_cb, - Ecore_File_Download_Progress_Cb progress_cb, - void *data, - Ecore_File_Download_Job **job_ret) -{ - return _ecore_file_download(url, dst, completion_cb, progress_cb, data, job_ret, NULL); -} - -/** - * @brief Download the given url to the given destination with additional headers. - * - * @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 Job used to abort the download. - * @param headers pointer of header lists. - * @return @c EINA_TRUE if the download start or @c EINA_FALSE on failure. - */ -EAPI Eina_Bool -ecore_file_download_full(const char *url, - const char *dst, - Ecore_File_Download_Completion_Cb completion_cb, - Ecore_File_Download_Progress_Cb progress_cb, - void *data, - Ecore_File_Download_Job **job_ret, - Eina_Hash *headers) -{ - return _ecore_file_download(url, dst, completion_cb, progress_cb, data, job_ret, headers); -} - -/** - * @brief Check if the given protocol is available. - * - * @param protocol The protocol to check. - * @return @c EINA_TRUE if protocol is handled, @c EINA_FALSE otherwise. - * - * This function returns @c EINA_TRUE if @p protocol is supported, - * @c EINA_FALSE otherwise. @p protocol can be 'http://', 'ftp://' or - * 'file://'. Ecore_FILE must be compiled with CURL to handle http and - * ftp protocols. - */ -EAPI Eina_Bool -ecore_file_download_protocol_available(const char *protocol) -{ -#ifdef BUILD_ECORE_CON - if (!strncmp(protocol, "file://", 7)) return EINA_TRUE; -# ifdef HAVE_CURL - else if (!strncmp(protocol, "http://", 7)) return EINA_TRUE; - else if (!strncmp(protocol, "ftp://", 6)) return EINA_TRUE; -# endif -#else - (void)protocol; -#endif /* BUILD_ECORE_CON */ - - return EINA_FALSE; -} - -#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 Eina_Bool -_ecore_file_download_url_complete_cb(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; - - fclose(job->file); - 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); - free(job->dst); - ecore_con_url_free(job->url_con); - free(job); - - return ECORE_CALLBACK_DONE; -} - -static Eina_Bool -_ecore_file_download_url_progress_cb(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; - - 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 ECORE_CALLBACK_PASS_ON; - } - - return ECORE_CALLBACK_DONE; -} - -Ecore_File_Download_Job * -_ecore_file_download_curl(const char *url, const char *dst, - Ecore_File_Download_Completion_Cb completion_cb, - Ecore_File_Download_Progress_Cb progress_cb, - void *data, - Eina_Hash *headers) -{ - 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; - } - - if (headers) eina_hash_foreach(headers, _ecore_file_download_headers_foreach_cb, job); - 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); - - if (!ecore_con_url_get(job->url_con)) - { - ecore_con_url_free(job->url_con); - _job_list = eina_list_remove(_job_list, job); - fclose(job->file); - ecore_file_remove(job->dst); - free(job->dst); - free(job); - return NULL; - } - - return job; -} -# endif -#endif - -/** - * @brief Abort the given download job and call the completion_cb - * callbck with a status of 1 (error). - * - * @param job The download job to abort. - * - * This function aborts a download operation started by - * ecore_file_download(). @p job is the #Ecore_File_Download_Job - * structure filled by ecore_file_download(). If it is @c NULL, this - * function does nothing. To abort all the currently downloading - * operations, call ecore_file_download_abort_all(). - */ -EAPI void -ecore_file_download_abort(Ecore_File_Download_Job *job) -{ - if (!job) - return; - -#ifdef BUILD_ECORE_CON - if (job->completion_cb) - job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, 1); -# ifdef HAVE_CURL - ecore_con_url_free(job->url_con); -# endif - _job_list = eina_list_remove(_job_list, job); - fclose(job->file); - free(job->dst); - free(job); -#endif /* BUILD_ECORE_CON */ -} - -/** - * @brief Abort all downloads. - * - * This function aborts all the downloads that have been started by - * ecore_file_download(). It loops over the started downloads and call - * ecore_file_download_abort() for each of them. To abort only one - * specific download operation, call ecore_file_download_abort(). - */ -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 */ -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c deleted file mode 100644 index 8b07589a9e..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c +++ /dev/null @@ -1,180 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#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 - } -} - -/** - * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions - * - * @{ - */ - -/** - * @brief Monitor the given path using inotify, Windows notification, 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. - * - * This function monitors @p path. If @p path is @c NULL, or is an - * empty string, or none of the notify methods (Inotify, Windows - * notification or polling) is available, or if @p path is not a file, - * the function returns @c NULL. Otherwise, it returns a newly - * allocated Ecore_File_Monitor object and the monitoring begins. When - * one of the Ecore_File_Event event is notified, @p func is called - * and @p data is passed to @p func. Call ecore_file_monitor_del() to - * stop the monitoring. - */ -EAPI Ecore_File_Monitor * -ecore_file_monitor_add(const char *path, - Ecore_File_Monitor_Cb func, - void *data) -{ - if (!path || !*path) - return NULL; - - 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; -} - -/** - * @brief Stop the monitoring of the given path. - * - * @param em The Ecore_File_Monitor to stop. - * - * This function stops the the monitoring of the path that has been - * monitored by ecore_file_monitor_add(). @p em must be the value - * returned by ecore_file_monitor_add(). If @p em is @c NULL, or none - * of the notify methods (Inotify, Windows notification or polling) is - * availablethis function does nothing. - */ -EAPI void -ecore_file_monitor_del(Ecore_File_Monitor *em) -{ - if (!em) - return; - - 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 - } -} - -/** - * @brief Get the monitored path. - * - * @param em The Ecore_File_Monitor to query. - * @return The path that is monitored by @p em. - * - * This function returns the monitored path that has been - * monitored by ecore_file_monitor_add(). @p em must be the value - * returned by ecore_file_monitor_add(). If @p em is @c NULL, the - * function returns @c NULL. - */ -EAPI const char * -ecore_file_monitor_path_get(Ecore_File_Monitor *em) -{ - if (!em) - return NULL; - return em->path; -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c deleted file mode 100644 index 1b682fc4a0..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c +++ /dev/null @@ -1,331 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include - -#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) - * - Listen to IN_IGNORED, emitted when the watch is removed - */ - -#ifdef HAVE_INOTIFY - -#include - - -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 pid_t _inotify_fd_pid = -1; - -static Eina_Bool _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; - } - - _inotify_fd_pid = getpid(); - 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); - } - _inotify_fd_pid = -1; - 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; - - if (_inotify_fd_pid == -1) return NULL; - - if (_inotify_fd_pid != getpid()) - { - ecore_file_monitor_inotify_shutdown(); - ecore_file_monitor_inotify_init(); - } - - 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_monitor_inotify_monitor(em, em->path)) - return NULL; - - return em; -} - -void -ecore_file_monitor_inotify_del(Ecore_File_Monitor *em) -{ - int fd; - - if (_monitors) - _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 Eina_Bool -_ecore_file_monitor_inotify_handler(void *data EINA_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 ECORE_CALLBACK_RENEW; -} - -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(buf, mask); -#endif - - if (mask & IN_ATTRIB) - { - em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf); - } - if (mask & IN_CLOSE_WRITE) - { - if (!isdir) - em->func(em->data, em, ECORE_FILE_EVENT_CLOSED, buf); - } - 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 = - IN_ATTRIB | - IN_CLOSE_WRITE | - IN_MOVED_FROM | - IN_MOVED_TO | - IN_DELETE | - IN_CREATE | - IN_MODIFY | - 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) - { - INF("inotify_add_watch failed, file was deleted"); - ecore_file_monitor_inotify_del(em); - return 0; - } - return 1; -} - -#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_ACCESS) - INF("Inotify accessed %s: %s", type, file); - if (mask & IN_MODIFY) - INF("Inotify modified %s: %s", type, file); - if (mask & IN_ATTRIB) - INF("Inotify attributes %s: %s", type, file); - if (mask & IN_CLOSE_WRITE) - INF("Inotify close write %s: %s", type, file); - if (mask & IN_CLOSE_NOWRITE) - INF("Inotify close write %s: %s", type, file); - if (mask & IN_OPEN) - INF("Inotify open %s: %s", type, file); - if (mask & IN_MOVED_FROM) - INF("Inotify moved from %s: %s", type, file); - if (mask & IN_MOVED_TO) - INF("Inotify moved to %s: %s", type, file); - if (mask & IN_DELETE) - INF("Inotify delete %s: %s", type, file); - if (mask & IN_CREATE) - INF("Inotify create %s: %s", type, file); - if (mask & IN_DELETE_SELF) - INF("Inotify delete self %s: %s", type, file); - if (mask & IN_MOVE_SELF) - INF("Inotify move self %s: %s", type, file); - if (mask & IN_UNMOUNT) - INF("Inotify unmount %s: %s", type, file); -} -#endif -#endif /* HAVE_INOTIFY */ diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c deleted file mode 100644 index 68889a74e8..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c +++ /dev/null @@ -1,340 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#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 Eina_Bool _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); - _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em))); - - 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; - } - - 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 Eina_Bool -_ecore_file_monitor_poll_handler(void *data EINA_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 ECORE_CALLBACK_RENEW; -} - -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 mt; - Ecore_File_Event event; - - l = (Ecore_File *) EINA_INLIST_GET(l)->next; - - snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name); - mt = ecore_file_mod_time(buf); - if (mt < 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 ((mt > f->mtime) && !(f->is_dir)) - { - em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf); - _interval = ECORE_FILE_INTERVAL_MIN; - f->mtime = mt; - } - else - f->mtime = mt; - } - - /* Check for new files */ - if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime) - { - Eina_List *files; - Eina_List *fl; - 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, fl, 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_is_dir(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 diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_win32.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_win32.c deleted file mode 100644 index 7f3af0907b..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_win32.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_NOTIFY_WIN32 - -# define WIN32_LEAN_AND_MEAN -# include -# undef WIN32_LEAN_AND_MEAN -# include - -# include "ecore_file_private.h" - - -typedef struct _Ecore_File_Monitor_Win32 Ecore_File_Monitor_Win32; -typedef struct _Ecore_File_Monitor_Win32_Data Ecore_File_Monitor_Win32_Data; - -/* 4096 = 256 * sizeof(FILE_NOTIFY_INFORMATION) */ -# define ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE 4096 -# define ECORE_FILE_MONITOR_WIN32(x) ((Ecore_File_Monitor_Win32 *)(x)) - -struct _Ecore_File_Monitor_Win32_Data -{ - char buffer[ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE]; - OVERLAPPED overlapped; - HANDLE handle; - HANDLE event; - Ecore_File_Monitor *monitor; - Ecore_Win32_Handler *h; - DWORD buf_length; - int is_dir; -}; - -struct _Ecore_File_Monitor_Win32 -{ - Ecore_File_Monitor monitor; - Ecore_File_Monitor_Win32_Data *file; - Ecore_File_Monitor_Win32_Data *dir; -}; - -static Ecore_File_Monitor *_monitors = NULL; - -static Eina_Bool _ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh); - - -static Ecore_File_Monitor_Win32_Data * -_ecore_file_monitor_win32_data_new(Ecore_File_Monitor *monitor, int type) -{ - Ecore_File_Monitor_Win32_Data *md; - DWORD filter; - - md = (Ecore_File_Monitor_Win32_Data *)calloc(1, sizeof(Ecore_File_Monitor_Win32_Data)); - if (!md) return NULL; - - md->handle = CreateFile(monitor->path, - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | - FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OVERLAPPED, - NULL); - if (md->handle == INVALID_HANDLE_VALUE) - goto free_md; - - md->event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (!md->event) - goto close_handle; - - ZeroMemory (&md->overlapped, sizeof(md->overlapped)); - md->overlapped.hEvent = md->event; - - filter = (type == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME; - filter |= - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_LAST_ACCESS | - FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SECURITY; - - if (!ReadDirectoryChangesW(md->handle, - md->buffer, - ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE, - FALSE, - filter, - &md->buf_length, - &md->overlapped, - NULL)) - goto close_event; - - md->h = ecore_main_win32_handler_add(md->event, - _ecore_file_monitor_win32_cb, - md); - if (!md->h) - goto close_event; - - md->monitor = monitor; - md->is_dir = type; - - return md; - - close_event: - CloseHandle(md->event); - close_handle: - CloseHandle(md->handle); - free_md: - free(md); - - return NULL; -} - -static void -_ecore_file_monitor_win32_data_free(Ecore_File_Monitor_Win32_Data *md) -{ - if (!md) return; - - CloseHandle(md->event); - CloseHandle (md->handle); - free (md); -} - -static Eina_Bool -_ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh) -{ - char filename[PATH_MAX]; - PFILE_NOTIFY_INFORMATION fni; - Ecore_File_Monitor_Win32_Data *md; - wchar_t *wname; - char *name; - DWORD filter; - DWORD offset; - DWORD buf_length; - Ecore_File_Event event = ECORE_FILE_EVENT_NONE; - - md = (Ecore_File_Monitor_Win32_Data *)data; - - if (!GetOverlappedResult (md->handle, &md->overlapped, &buf_length, TRUE)) - return 1; - - fni = (PFILE_NOTIFY_INFORMATION)md->buffer; - do { - if (!fni) - break; - offset = fni->NextEntryOffset; - - wname = (wchar_t *)malloc(sizeof(wchar_t) * (fni->FileNameLength + 1)); - if (!wname) - return 0; - - memcpy(wname, fni->FileName, fni->FileNameLength); - wname[fni->FileNameLength]='\0'; - name = evil_wchar_to_char(wname); - free(wname); - if (!name) - return 0; - - _snprintf(filename, PATH_MAX, "%s\\%s", md->monitor->path, name); - free(name); - - switch (fni->Action) - { - case FILE_ACTION_ADDED: - if (md->is_dir) - event = ECORE_FILE_EVENT_CREATED_DIRECTORY; - else - event = ECORE_FILE_EVENT_CREATED_FILE; - break; - case FILE_ACTION_REMOVED: - if (md->is_dir) - event = ECORE_FILE_EVENT_DELETED_DIRECTORY; - else - event = ECORE_FILE_EVENT_DELETED_FILE; - break; - case FILE_ACTION_MODIFIED: - if (!md->is_dir) - event = ECORE_FILE_EVENT_MODIFIED; - break; - case FILE_ACTION_RENAMED_OLD_NAME: - if (md->is_dir) - event = ECORE_FILE_EVENT_DELETED_DIRECTORY; - else - event = ECORE_FILE_EVENT_DELETED_FILE; - break; - case FILE_ACTION_RENAMED_NEW_NAME: - if (md->is_dir) - event = ECORE_FILE_EVENT_CREATED_DIRECTORY; - else - event = ECORE_FILE_EVENT_CREATED_FILE; - break; - default: - fprintf(stderr, "unknown event\n"); - event = ECORE_FILE_EVENT_NONE; - break; - } - if (event != ECORE_FILE_EVENT_NONE) - md->monitor->func(md->monitor->data, md->monitor, event, filename); - - fni = (PFILE_NOTIFY_INFORMATION)((LPBYTE)fni + offset); - } while (offset); - - filter = (md->is_dir == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME; - filter |= - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_LAST_ACCESS | - FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SECURITY; - - ReadDirectoryChangesW(md->handle, - md->buffer, - ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE, - FALSE, - filter, - &md->buf_length, - &md->overlapped, - NULL); - return 1; -} - -int -ecore_file_monitor_win32_init(void) -{ - return 1; -} - -int -ecore_file_monitor_win32_shutdown(void) -{ - return 1; -} - -Ecore_File_Monitor * -ecore_file_monitor_win32_add(const char *path, - void (*func) (void *data, Ecore_File_Monitor *em, - Ecore_File_Event event, - const char *path), - void *data) -{ - Ecore_File_Monitor_Win32 *m; - Ecore_File_Monitor *em; - size_t len; - - if (!path || (*path == '\0')) return NULL; - if (!ecore_file_exists(path) || !ecore_file_is_dir(path)) - return NULL; - if (!func) return NULL; - - em = (Ecore_File_Monitor *)calloc(1, sizeof(Ecore_File_Monitor_Win32)); - if (!em) return NULL; - - em->func = func; - em->data = data; - - em->path = strdup(path); - if (!em->path) - { - free(em); - return NULL; - } - len = strlen(em->path); - if (em->path[len - 1] == '/' || em->path[len - 1] == '\\') - em->path[len - 1] = '\0'; - - m = ECORE_FILE_MONITOR_WIN32(em); - - m->file = _ecore_file_monitor_win32_data_new(em, 0); - if (!m->file) - { - free(em->path); - free(em); - return NULL; - } - - m->dir = _ecore_file_monitor_win32_data_new(em, 1); - if (!m->dir) - { - _ecore_file_monitor_win32_data_free(m->file); - free(em->path); - free(em); - return NULL; - } - - _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em))); - - return em; -} - -void -ecore_file_monitor_win32_del(Ecore_File_Monitor *em) -{ - Ecore_File_Monitor_Win32 *m; - - if (!em) - return; - - m = ECORE_FILE_MONITOR_WIN32(em); - _ecore_file_monitor_win32_data_free(m->dir); - _ecore_file_monitor_win32_data_free(m->file); - free(em->path); - free(em); -} - -#endif diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_path.c b/legacy/ecore/src/lib/ecore_file/ecore_file_path.c deleted file mode 100644 index c1c54b7c0f..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_path.c +++ /dev/null @@ -1,192 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include -#include -#include - -#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) - eina_stringshare_del(dir); -} - -Eina_List * -_ecore_file_path_from_env(const char *env) -{ - Eina_List *path = NULL; - char *env_tmp, *env_path, *p, *last; - - env_tmp = getenv(env); - if (!env_tmp) - return path; - - env_path = alloca(sizeof(char) * strlen(env_tmp) + 1); - memset(env_path, 0, strlen(env_tmp)); - strcpy(env_path, env_tmp); - 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, eina_stringshare_add(last)); - last = p + 1; - } - } - if (p > last) - path = eina_list_append(path, eina_stringshare_add(last)); - - return path; -} - -/** - * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions - * - * @{ - */ - -/** - * @brief Check if the given directory is in PATH. - * - * @param in_dir The name of the directory to search in PATH. - * @return @c EINA_TRUE if the directory exist in PATH, @c EINA_FALSE otherwise. - * - * This function checks if @p in_dir is in the environment variable - * PATH. If @p in_dir is @c NULL, or if PATH is empty, or @p in_dir is - * not in PATH, the function returns @c EINA_FALSE, otherwise it returns - * @c EINA_TRUE. - */ -EAPI Eina_Bool -ecore_file_path_dir_exists(const char *in_dir) -{ - Eina_List *l; - char *dir; - - if (!in_dir) - return EINA_FALSE; - - if (!__ecore_file_path_bin) return EINA_FALSE; - EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir) - { - if (strcmp(dir, in_dir)) - return EINA_TRUE; - } - - return EINA_FALSE; -} - -/** - * @brief Check if the given application is installed. - * - * @param exe The name of the application - * @return @c EINA_TRUE if the @p exe is in PATH and is executable, - * @c EINA_FALSE otherwise. - * - * This function checks if @p exe exists in PATH and is executable. If - * @p exe is @c NULL or is not executable, the function returns - * @c EINA_FALSE, otherwise it returns @c EINA_TRUE. - */ -EAPI Eina_Bool -ecore_file_app_installed(const char *exe) -{ - Eina_List *l; - char *dir; - char buf[PATH_MAX]; - - if (!exe) return EINA_FALSE; - if (ecore_file_can_exec(exe)) return EINA_TRUE; - - EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir) - { - snprintf(buf, sizeof(buf), "%s/%s", dir, exe); - if (ecore_file_can_exec(buf)) - return EINA_TRUE; - } - - return EINA_FALSE; -} - -/** - * @brief Get a list of all the applications installed on the system. - * - * @return An Eina_List containing all the executable files in the - * system. - * - * This function returns a list of allocated strings of all the - * executable files. If no files are found, the function returns - * @c NULL. When not needed anymore, the element of the list must be - * freed. - */ -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; -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_private.h b/legacy/ecore/src/lib/ecore_file/ecore_file_private.h deleted file mode 100644 index 45d2cbd65c..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_private.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef ECORE_FILE_PRIVATE_H_ -#define ECORE_FILE_PRIVATE_H_ - -#ifdef __linux__ -# include -#endif - -#ifdef HAVE_EVIL -# include -#endif - -#ifdef HAVE_ESCAPE -# include -#endif - -#include -#include - -#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 diff --git a/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h b/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h deleted file mode 100644 index 641ece74a3..0000000000 --- a/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h +++ /dev/null @@ -1,577 +0,0 @@ -#ifndef _ECORE_IMF_H -#define _ECORE_IMF_H - -#include - -#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 - -/** - * @addtogroup Ecore_IMF_Context_Group - * - * @{ - */ -/* ecore_imf_context_input_panel_event_callback_add() flag */ -typedef enum -{ - ECORE_IMF_INPUT_PANEL_STATE_EVENT, /**< called when the state of the input panel is changed. @since 1.7 */ - ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, /**< called when the language of the input panel is changed. @since 1.7 */ - ECORE_IMF_INPUT_PANEL_SHIFT_MODE_EVENT, /**< called when the shift key state of the input panel is changed @since 1.7 */ - ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, /**< called when the size of the input panel is changed. @since 1.7 */ - ECORE_IMF_CANDIDATE_PANEL_STATE_EVENT, /**< called when the state of the candidate word panel is changed. @since 1.7 */ - ECORE_IMF_CANDIDATE_PANEL_GEOMETRY_EVENT /**< called when the size of the candidate word panel is changed. @since 1.7 */ -} Ecore_IMF_Input_Panel_Event; - -typedef enum -{ - ECORE_IMF_INPUT_PANEL_STATE_SHOW, /**< Notification after the display of the input panel @since 1.7 */ - ECORE_IMF_INPUT_PANEL_STATE_HIDE, /**< Notification prior to the dismissal of the input panel @since 1.7 */ - ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW /**< Notification prior to the display of the input panel @since 1.7 */ -} Ecore_IMF_Input_Panel_State; - -typedef enum -{ - ECORE_IMF_INPUT_PANEL_SHIFT_MODE_OFF, /**< @since 1.7 */ - ECORE_IMF_INPUT_PANEL_SHIFT_MODE_ON /**< @since 1.7 */ -} Ecore_IMF_Input_Panel_Shift_Mode; - -typedef enum -{ - ECORE_IMF_CANDIDATE_PANEL_SHOW, /**< Notification after the display of the candidate word panel @since 1.7 */ - ECORE_IMF_CANDIDATE_PANEL_HIDE /**< Notification prior to the dismissal of the candidate word panel @since 1.7 */ -} Ecore_IMF_Candidate_Panel_State; - -/* 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 */ - -/* Preedit attribute info */ -typedef struct _Ecore_IMF_Preedit_Attr Ecore_IMF_Preedit_Attr; - -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 void (*Ecore_IMF_Event_Cb) (void *data, Ecore_IMF_Context *ctx, void *event_info); - -/** - * @typedef Ecore_IMF_Callback_Type - * - * Ecore IMF Event callback types. - * - * @see ecore_imf_context_event_callback_add() - */ -typedef enum -{ - ECORE_IMF_CALLBACK_PREEDIT_START, /**< "PREEDIT_START" is called when a new preediting sequence starts. @since 1.2 */ - ECORE_IMF_CALLBACK_PREEDIT_END, /**< "PREEDIT_END" is called when a preediting sequence has been completed or canceled. @since 1.2 */ - ECORE_IMF_CALLBACK_PREEDIT_CHANGED, /**< "PREEDIT_CHANGED" is called whenever the preedit sequence currently being entered has changed. @since 1.2 */ - ECORE_IMF_CALLBACK_COMMIT, /**< "COMMIT" is called when a complete input sequence has been entered by the user @since 1.2 */ - ECORE_IMF_CALLBACK_DELETE_SURROUNDING /**< "DELETE_SURROUNDING" is called when the input method needs to delete all or part of the context surrounding the cursor @since 1.2 */ -} Ecore_IMF_Callback_Type; - -/** - * @typedef Ecore_IMF_Event_Type - * - * Ecore IMF event types. - * - * @see ecore_imf_context_filter_event() - */ -typedef enum -{ - ECORE_IMF_EVENT_MOUSE_DOWN, /**< Mouse Down event */ - ECORE_IMF_EVENT_MOUSE_UP, /**< Mouse Up event */ - ECORE_IMF_EVENT_MOUSE_IN, /**< Mouse In event */ - ECORE_IMF_EVENT_MOUSE_OUT, /**< Mouse Out event */ - ECORE_IMF_EVENT_MOUSE_MOVE, /**< Mouse Move event */ - ECORE_IMF_EVENT_MOUSE_WHEEL, /**< Mouse Wheel event */ - ECORE_IMF_EVENT_KEY_DOWN, /**< Key Down event */ - ECORE_IMF_EVENT_KEY_UP /**< Key Up event */ -} Ecore_IMF_Event_Type; -/** - * @typedef Ecore_IMF_Keyboard_Modifiers - * Type for Ecore_IMF keyboard modifiers - */ -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_MODIFIER_ALTGR = 1 << 4 /**< "AltGr" is pressed @since 1.7 */ -} Ecore_IMF_Keyboard_Modifiers; - -/** - * @typedef Ecore_IMF_Keyboard_Locks - * Type for Ecore_IMF keyboard locks - */ -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 Ecore_IMF_Mouse_Flags - * Type for Ecore_IMF mouse flags - */ -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; - -/** - * @typedef Ecore_IMF_Preedit_Type - * - * Ecore IMF Preedit style types - * - * @see ecore_imf_context_preedit_string_with_attributes_get() - */ -typedef enum -{ - ECORE_IMF_PREEDIT_TYPE_NONE, /**< None style @since 1.1 */ - ECORE_IMF_PREEDIT_TYPE_SUB1, /**< Substring style 1 @since 1.1 */ - ECORE_IMF_PREEDIT_TYPE_SUB2, /**< Substring style 2 @since 1.1 */ - ECORE_IMF_PREEDIT_TYPE_SUB3, /**< Substring style 3 @since 1.1 */ - ECORE_IMF_PREEDIT_TYPE_SUB4, /**< Substring style 4 @since 1.8 */ - ECORE_IMF_PREEDIT_TYPE_SUB5, /**< Substring style 5 @since 1.8 */ - ECORE_IMF_PREEDIT_TYPE_SUB6, /**< Substring style 6 @since 1.8 */ - ECORE_IMF_PREEDIT_TYPE_SUB7 /**< Substring style 7 @since 1.8 */ -} Ecore_IMF_Preedit_Type; - -/** - * @typedef Ecore_IMF_Autocapital_Type - * - * Autocapitalization Types. - * - * @see ecore_imf_context_autocapital_type_set() - */ -typedef enum -{ - ECORE_IMF_AUTOCAPITAL_TYPE_NONE, /**< No auto-capitalization when typing @since 1.1 */ - ECORE_IMF_AUTOCAPITAL_TYPE_WORD, /**< Autocapitalize each word typed @since 1.1 */ - ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE, /**< Autocapitalize the start of each sentence @since 1.1 */ - ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER, /**< Autocapitalize all letters @since 1.1 */ -} Ecore_IMF_Autocapital_Type; - -/** - * @typedef Ecore_IMF_Input_Panel_Layout - * - * Input panel (virtual keyboard) layout types. - * - * @see ecore_imf_context_input_panel_layout_set() - */ -typedef enum -{ - ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL, /**< Default layout */ - ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER, /**< Number layout */ - ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL, /**< Email layout */ - ECORE_IMF_INPUT_PANEL_LAYOUT_URL, /**< URL layout */ - ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER, /**< Phone Number layout */ - ECORE_IMF_INPUT_PANEL_LAYOUT_IP, /**< IP layout */ - ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH, /**< Month layout */ - ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY, /**< Number Only layout */ - ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID, /**< Never use this */ - ECORE_IMF_INPUT_PANEL_LAYOUT_HEX, /**< Hexadecimal layout @since 1.2 */ - ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL, /**< Command-line terminal layout including esc, alt, ctrl key, so on (no auto-correct, no auto-capitalization) @since 1.2 */ - ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD /**< Like normal, but no auto-correct, no auto-capitalization etc. @since 1.2 */ -} Ecore_IMF_Input_Panel_Layout; - -/** - * @typedef Ecore_IMF_Input_Panel_Lang - * - * Input panel (virtual keyboard) language modes. - * - * @see ecore_imf_context_input_panel_language_set() - */ -typedef enum -{ - ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC, /**< Automatic @since 1.2 */ - ECORE_IMF_INPUT_PANEL_LANG_ALPHABET /**< Alphabet @since 1.2 */ -} Ecore_IMF_Input_Panel_Lang; - -/** - * @typedef Ecore_IMF_Input_Panel_Return_Key_Type - * - * "Return" Key types on the input panel (virtual keyboard). - * - * @see ecore_imf_context_input_panel_return_key_type_set() - */ -typedef enum -{ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT, /**< Default @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE, /**< Done @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO, /**< Go @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN, /**< Join @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN, /**< Login @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT, /**< Next @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH, /**< Search or magnifier icon @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND, /**< Send @since 1.2 */ - ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN /**< Sign-in @since 1.8 */ -} Ecore_IMF_Input_Panel_Return_Key_Type; - -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 occurred */ -}; - -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 occurred */ -}; - -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 occurred */ -}; - -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 occurred */ -}; - -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 occurred */ -}; - -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 occurred */ -}; - -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 occurred */ -}; - -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 occurred */ -}; - -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_Preedit_Attr -{ - Ecore_IMF_Preedit_Type preedit_type; /**< preedit style type */ - unsigned int start_index; /**< start index of the range (in bytes) */ - unsigned int end_index; /**< end index of the range (in bytes) */ -}; - -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, Eina_Bool use_preedit); - void (*input_mode_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); - Eina_Bool (*filter_event) (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); - void (*preedit_string_with_attributes_get) (Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos); - void (*prediction_allow_set)(Ecore_IMF_Context *ctx, Eina_Bool prediction); - void (*autocapital_type_set)(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type); - void (*control_panel_show) (Ecore_IMF_Context *ctx); - void (*control_panel_hide) (Ecore_IMF_Context *ctx); - void (*input_panel_layout_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout); - Ecore_IMF_Input_Panel_Layout (*input_panel_layout_get) (Ecore_IMF_Context *ctx); - void (*input_panel_language_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); - Ecore_IMF_Input_Panel_Lang (*input_panel_language_get) (Ecore_IMF_Context *ctx); - void (*cursor_location_set) (Ecore_IMF_Context *ctx, int x, int y, int w, int h); - void (*input_panel_imdata_set)(Ecore_IMF_Context *ctx, const void* data, int len); - void (*input_panel_imdata_get)(Ecore_IMF_Context *ctx, void* data, int *len); - void (*input_panel_return_key_type_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type); - void (*input_panel_return_key_disabled_set) (Ecore_IMF_Context *ctx, Eina_Bool disabled); - void (*input_panel_caps_lock_mode_set) (Ecore_IMF_Context *ctx, Eina_Bool mode); - void (*input_panel_geometry_get)(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); - Ecore_IMF_Input_Panel_State (*input_panel_state_get) (Ecore_IMF_Context *ctx); - void (*input_panel_event_callback_add) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), void *data); - void (*input_panel_event_callback_del) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)); - void (*input_panel_language_locale_get) (Ecore_IMF_Context *ctx, char **lang); - void (*candidate_panel_geometry_get)(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); -}; - -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_window_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas); -EAPI void *ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx); -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_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, 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_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h); -EAPI void ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit); -EAPI void ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*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 Eina_Bool 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 Eina_Bool 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); -EAPI void ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data); -EAPI void *ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func); -EAPI void ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info); -EAPI void ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction); -EAPI Eina_Bool ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type); -EAPI Ecore_IMF_Autocapital_Type ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx); - -EAPI void ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx); - -EAPI void ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout); -EAPI Ecore_IMF_Input_Panel_Layout ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); -EAPI Ecore_IMF_Input_Panel_Lang ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx, Eina_Bool enable); -EAPI Eina_Bool ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len); -EAPI void ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len); -EAPI void ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type); -EAPI Ecore_IMF_Input_Panel_Return_Key_Type ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled); -EAPI Eina_Bool ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode); -EAPI Eina_Bool ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); -EAPI Ecore_IMF_Input_Panel_State ecore_imf_context_input_panel_state_get(Ecore_IMF_Context *ctx); -EAPI void ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), const void *data); -EAPI void ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)); -EAPI void ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx, char **lang); -EAPI void ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); - -/* 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 diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf.c b/legacy/ecore/src/lib/ecore_imf/ecore_imf.c deleted file mode 100644 index 7cf8a4a9f6..0000000000 --- a/legacy/ecore/src/lib/ecore_imf/ecore_imf.c +++ /dev/null @@ -1,73 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#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 - ("ecore_imf", 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_imf_module_shutdown(); - eina_log_domain_unregister(_ecore_imf_log_dom); - _ecore_imf_log_dom = -1; - ecore_shutdown(); - return _ecore_imf_init_count; -} diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c b/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c deleted file mode 100644 index 3faa5acbd5..0000000000 --- a/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c +++ /dev/null @@ -1,1900 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#include -#include - -#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. - - * Ecore Input Method Context Function defines the interface for EFL input methods. - * An input method is used by EFL text input widgets like elm_entry - * (based on edje_entry) to map from key events to Unicode character strings. - * - * The default input method can be set through setting the ECORE_IMF_MODULE environment variable. - * - * An input method may consume multiple key events in sequence and finally output the composed result. - * This is called preediting, and an input method may provide feedback about - * this process by displaying the intermediate composition states as preedit text. - * - * Immodule is plugin to connect your application and input method framework such as SCIM, ibus, and so on.@n - * ecore_imf_init() should be called to initialize and load immodule.@n - * ecore_imf_shutdown() is used for shutdowning and unloading immodule. - * - * An example of usage of these functions can be found at: - * @li @ref ecore_imf_example_c - */ - -/** - * 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 - * - * Example - * @code - * - * const char *ctx_id; - * const Ecore_IMF_Context_Info *ctx_info; - * Ecore_IMF_Context *imf_context; - * ctx_id = ecore_imf_context_default_id_get(); - * if (ctx_id) - * { - * ctx_info = ecore_imf_context_info_by_id_get(ctx_id); - * if (!ctx_info->canvas_type || - * strcmp(ctx_info->canvas_type, "evas") == 0) - * { - * imf_context = ecore_imf_context_add(ctx_id); - * } - * else - * { - * ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas"); - * if (ctx_id) - * { - * imf_context = ecore_imf_context_add(ctx_id); - * } - * } - * } - * @endcode - */ -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 EINA_TRUE, so let's make sure it's - * set on the immodule */ - ecore_imf_context_use_preedit_set(ctx, EINA_TRUE); - - /* default prediction is EINA_TRUE, so let's make sure it's - * set on the immodule */ - ecore_imf_context_prediction_allow_set(ctx, EINA_TRUE); - - /* default autocapital type is SENTENCE type, so let's make sure it's - * set on the immodule */ - ecore_imf_context_autocapital_type_set(ctx, ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE); - - /* default input panel enabled status is EINA_TRUE, so let's make sure it's - * set on the immodule */ - ecore_imf_context_input_panel_enabled_set(ctx, EINA_TRUE); - - /* default input panel layout type is NORMAL type, so let's make sure it's - * set on the immodule */ - ecore_imf_context_input_panel_layout_set(ctx, ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL); - - /* 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) -{ - Ecore_IMF_Func_Node *fn; - - 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); - - if (ctx->callbacks) - { - EINA_LIST_FREE(ctx->callbacks, fn) - free(fn); - } - - 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 @c 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); - ctx->window = window; -} - -/** - * Get the client window of the Input Method Context - * - * See @ref ecore_imf_context_client_window_set for more details. - * - * @param ctx An #Ecore_IMF_Context. - * @return Return the client window. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void * -ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_client_window_get"); - return NULL; - } - return 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 canvas The client canvas. This may be @c 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_canvas_set"); - return; - } - if (ctx->klass->client_canvas_set) ctx->klass->client_canvas_set(ctx, canvas); - ctx->client_canvas = canvas; -} - -/** - * Get the client canvas of the Input Method Context. - * - * See @ref ecore_imf_context_client_canvas_set for more details. - * - * @param ctx An #Ecore_IMF_Context. - * @return Return the client canvas. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void * -ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_client_canvas_get"); - return NULL; - } - return ctx->client_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; - } -} - -/** - * Retrieve the current preedit string, attributes 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 attrs an Eina_List of attributes - * @param cursor_pos Location to store position of cursor (in characters) - * within the preedit string. - * @ingroup Ecore_IMF_Context_Group - * - * Example - * @code - * char *preedit_string; - * int cursor_pos; - * Eina_List *attrs = NULL, *l = NULL; - * Ecore_IMF_Preedit_Attr *attr; - * - * ecore_imf_context_preedit_string_with_attributes_get(imf_context, - * &preedit_string, - * &attrs, &cursor_pos); - * if (!preedit_string) return; - * - * if (strlen(preedit_string) > 0) - * { - * if (attrs) - * { - * EINA_LIST_FOREACH(attrs, l, attr) - * { - * if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1) - * { - * // Something to do - * } - * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2) - * { - * // Something to do - * } - * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3) - * { - * // Something to do - * } - * } - * } - * } - * - * // delete attribute list - * EINA_LIST_FREE(attrs, attr) free(attr); - * - * free(preedit_string); - * @endcode - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_preedit_string_with_attributes_get"); - return; - } - if (ctx->klass->preedit_string_with_attributes_get) - ctx->klass->preedit_string_with_attributes_get(ctx, str, attrs, cursor_pos); - else - { - if (str) *str = strdup(""); - if (attrs) *attrs = NULL; - 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 - * - * Example - * @code - * static void - * _focus_in_cb(void *data, Evas_Object *o, const char *emission, const char *source) - * { - * ecore_imf_context_reset(imf_context); - * ecore_imf_context_focus_in(imf_context); - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _focus_in_cb, ed); - * @endcode - */ -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 - * - * Example - * @code - * static void - * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source) - * { - * ecore_imf_context_reset(imf_context); - * ecore_imf_context_focus_out(imf_context); - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed); - * @endcode - */ -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 - * - * Example - * @code - * static void - * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source) - * { - * ecore_imf_context_reset(imf_context); - * ecore_imf_context_focus_out(imf_context); - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed); - * @endcode - */ -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); -} - -/** - * Notify the Input Method Context that a change in the cursor - * location has been made. The location is relative to the canvas. - * The cursor location can be used to determine the position of - * candidate word window in the immodule. - * - * @param ctx An #Ecore_IMF_Context. - * @param x cursor x position. - * @param y cursor y position. - * @param w cursor width. - * @param h cursor height. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_cursor_location_set"); - return; - } - if (ctx->klass->cursor_location_set) ctx->klass->cursor_location_set(ctx, x, y, w, h); -} - -/** - * Set whether the IM context should use the preedit string - * to display feedback. If @c use_preedit is @c EINA_FALSE (default - * is @c EINA_TRUE), 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, Eina_Bool 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 whether the IM context should allow to use the text prediction. - * If @p prediction is @c EINA_FALSE (default is @c EINA_TRUE), then the IM - * context will not display the text prediction window. - * - * @param ctx An #Ecore_IMF_Context. - * @param prediction Whether the IM context should allow to use the text prediction. - * @note Default value is EINA_TRUE. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_prediction_allow_set"); - return; - } - - ctx->allow_prediction = prediction; - - if (ctx->klass->prediction_allow_set) - ctx->klass->prediction_allow_set(ctx, prediction); -} - -/** - * Get whether the IM context should allow to use the text prediction. - * - * @param ctx An #Ecore_IMF_Context. - * @return @c EINA_TRUE if it allows to use the text prediction, otherwise - * @c EINA_FALSE. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI Eina_Bool -ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_prediction_allow_get"); - return EINA_FALSE; - } - - return ctx->allow_prediction; -} - -/** - * Set the autocapitalization type on the immodule. - * - * @param ctx An #Ecore_IMF_Context. - * @param autocapital_type the autocapitalization type. - * @note Default type is ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_autocapital_type_set"); - return; - } - - ctx->autocapital_type = autocapital_type; - - if (ctx->klass->autocapital_type_set) ctx->klass->autocapital_type_set(ctx, autocapital_type); -} - -/** - * Get the autocapitalization type. - * - * @param ctx An #Ecore_IMF_Context. - * @return The autocapital type being used by @p ctx. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI Ecore_IMF_Autocapital_Type -ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_autocapital_allow_get"); - return ECORE_IMF_AUTOCAPITAL_TYPE_NONE; - } - - return ctx->autocapital_type; -} - -/** - * Set the callback to be used on surrounding_get 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, Eina_Bool (*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 @c EINA_TRUE, then no further processing - * should be done for this event. - * - * Input methods must be able to accept all types of events (simply - * returning @c EINA_FALSE 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 @c EINA_TRUE if the event was handled; otherwise @c EINA_FALSE. - * @ingroup Ecore_IMF_Context_Group - * - * Example - * @code - * static void - * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) - * { - * Evas_Event_Key_Down *ev = event_info; - * if (!ev->keyname) return; - * - * if (imf_context) - * { - * Ecore_IMF_Event_Key_Down ecore_ev; - * ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev); - * if (ecore_imf_context_filter_event(imf_context, - * ECORE_IMF_EVENT_KEY_DOWN, - * (Ecore_IMF_Event *)&ecore_ev)) - * return; - * } - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data); - * @endcode - */ -EAPI Eina_Bool -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 EINA_FALSE; - } - if (ctx->klass->filter_event) return ctx->klass->filter_event(ctx, type, event); - return EINA_FALSE; -} - -/** - * @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 = calloc(1, 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. - * Input methods typically want context in order to constrain input text based on existing text; - * this is important for languages such as Thai where only some sequences of characters are allowed. - * In addition, the text around the insertion point can be used for supporting autocapital feature. - * - * 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 @c EINA_TRUE, 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 @p text. - * @return @c EINA_TRUE if surrounding text was provided; otherwise - * @c EINA_FALSE. - * @ingroup Ecore_IMF_Context_Module_Group - */ -EAPI Eina_Bool -ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos) -{ - int result = EINA_FALSE; - - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_surrounding_get"); - return EINA_FALSE; - } - - 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 EINA_UNUSED, void *event) -{ - free(event); -} - -/** - * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue. - * - * ECORE_IMF_EVENT_PREEDIT_START should be added when a new preedit sequence starts. - * It's asynchronous method to put event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @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. - * - * ECORE_IMF_EVENT_PREEDIT_END should be added when a new preedit sequence has been completed or canceled. - * It's asynchronous method to put event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @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. - * - * It's asynchronous method to put event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @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 EINA_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. - * - * It's asynchronous method to put event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @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 EINA_UNUSED, void *event) -{ - free(event); -} - -/** - * Adds ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue. - * - * Asks the widget that the input context is attached to to delete characters around the cursor position - * by adding the ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue. - * Note that offset and n_chars are in characters not in bytes. - * - * It's asynchronous method to put ECORE_IMF_EVENT_DELETE_SURROUNDING event to the event queue. - * ecore_imf_context_event_callback_call() can be used as synchronous method. - * - * @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); -} - -/** - * Add (register) a callback function to a given context event. - * - * This function adds a function callback to the context @p ctx when the - * event of type @p type occurs on it. The function pointer is @p - * func. - * - * The event type @p type to trigger the function may be one of - * #ECORE_IMF_CALLBACK_PREEDIT_START, #ECORE_IMF_CALLBACK_PREEDIT_END, - * #ECORE_IMF_CALLBACK_PREEDIT_CHANGED, #ECORE_IMF_CALLBACK_COMMIT and - * #ECORE_IMF_CALLBACK_DELETE_SURROUNDING. - * - * @param ctx Ecore_IMF_Context to attach a callback to. - * @param type The type of event that will trigger the callback - * @param func The (callback) function to be called when the event is - * triggered - * @param data The data pointer to be passed to @p func - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - * - * Example - * @code - * static void - * _imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info) - * { - * char *commit_str = event_info; - * // something to do - * } - * - * ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, data); - * @endcode - */ -EAPI void -ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data) -{ - Ecore_IMF_Func_Node *fn = NULL; - - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_event_callback_add"); - return; - } - - if (!func) return; - - fn = calloc(1, sizeof (Ecore_IMF_Func_Node)); - if (!fn) return; - - fn->func = func; - fn->data = data; - fn->type = type; - - ctx->callbacks = eina_list_append(ctx->callbacks, fn); -} - -/** - * Delete (unregister) a callback function registered to a given - * context event. - * - * This function removes a function callback from the context @p ctx when the - * event of type @p type occurs on it. The function pointer is @p - * func. - * - * @see ecore_imf_context_event_callback_add() for more details - * - * @param ctx Ecore_IMF_Context to remove a callback from. - * @param type The type of event that was triggering the callback - * @param func The (callback) function that was to be called when the event was triggered - * @return the data pointer - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI void * -ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func) -{ - Eina_List *l = NULL; - Eina_List *l_next = NULL; - Ecore_IMF_Func_Node *fn = NULL; - - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_event_callback_del"); - return NULL; - } - - if (!func) return NULL; - if (!ctx->callbacks) return NULL; - - EINA_LIST_FOREACH_SAFE(ctx->callbacks, l, l_next, fn) - { - if ((fn) && (fn->func == func) && (fn->type == type)) - { - void *tmp = (void *)fn->data; - free(fn); - ctx->callbacks = eina_list_remove_list(ctx->callbacks, l); - return tmp; - } - } - return NULL; -} - -/** - * Call a given callback on the context @p ctx. - * - * ecore_imf_context_preedit_start_event_add(), ecore_imf_context_preedit_end_event_add(), - * ecore_imf_context_preedit_changed_event_add(), ecore_imf_context_commit_event_add() and - * ecore_imf_context_delete_surrounding_event_add() APIs are asynchronous - * because those API adds each event to the event queue. - * - * This API provides the way to call each callback function immediately. - * - * @param ctx Ecore_IMF_Context. - * @param type The type of event that will trigger the callback - * @param event_info The pointer to event specific struct or information to - * pass to the callback functions registered on this event - * @ingroup Ecore_IMF_Context_Module_Group - * @since 1.2.0 - */ -EAPI void -ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info) -{ - Ecore_IMF_Func_Node *fn = NULL; - Eina_List *l = NULL; - - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_event_callback_call"); - return; - } - - EINA_LIST_FOREACH(ctx->callbacks, l, fn) - { - if ((fn) && (fn->type == type) && (fn->func)) - fn->func(fn->data, ctx, event_info); - } -} - -/** - * Ask the Input Method Context to show the control panel of using Input Method. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_control_panel_show"); - return; - } - - if (ctx->klass->control_panel_show) ctx->klass->control_panel_show(ctx); -} - -/** - * Ask the Input Method Context to hide the control panel of using Input Method. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_control_panel_hide"); - return; - } - - if (ctx->klass->control_panel_hide) ctx->klass->control_panel_hide(ctx); -} - -/** - * Ask the Input Method Context to show the input panel (virtual keyboard). - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_show"); - return; - } - - if (ctx->klass->show) ctx->klass->show(ctx); -} - -/** - * Ask the Input Method Context to hide the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_hide"); - return; - } - - if (ctx->klass->hide) ctx->klass->hide(ctx); -} - -/** - * Set the layout of the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param layout see #Ecore_IMF_Input_Panel_Layout - * @note Default layout type is ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_layout_set"); - return; - } - - if (ctx->klass->input_panel_layout_set) - ctx->klass->input_panel_layout_set(ctx, layout); - - ctx->input_panel_layout = layout; -} - -/** - * Get the layout of the current active input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @return layout see #Ecore_IMF_Input_Panel_Layout - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI Ecore_IMF_Input_Panel_Layout -ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_layout_get"); - return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID; - } - - if (ctx->klass->input_panel_layout_get) - return ctx->input_panel_layout; - else - return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID; -} - -/** - * Set the language of the input panel. - * This API can be used when you want to show the English keyboard. - * - * @param ctx An #Ecore_IMF_Context. - * @param lang the language to be set to the input panel. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_language_set"); - return; - } - - if (ctx->klass->input_panel_language_set) ctx->klass->input_panel_language_set(ctx, lang); - ctx->input_panel_lang = lang; -} - -/** - * Get the language of the input panel. - * - * See @ref ecore_imf_context_input_panel_language_set for more details. - * - * @param ctx An #Ecore_IMF_Context. - * @return Ecore_IMF_Input_Panel_Lang - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI Ecore_IMF_Input_Panel_Lang -ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_language_get"); - return ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC; - } - - return ctx->input_panel_lang; -} - -/** - * Set whether the Input Method Context should request to show the input panel automatically - * when the widget has focus. - * - * @param ctx An #Ecore_IMF_Context. - * @param enabled If true, the input panel will be shown when the widget is clicked or has focus. - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI void -ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx, - Eina_Bool enabled) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_enabled_set"); - return; - } - - ctx->input_panel_enabled = enabled; -} - -/** - * Get whether the Input Method Context requests to show the input panel automatically. - * - * @param ctx An #Ecore_IMF_Context. - * @return Return the attribute to show the input panel automatically - * @ingroup Ecore_IMF_Context_Group - * @since 1.1.0 - */ -EAPI Eina_Bool -ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_enabled_get"); - return EINA_FALSE; - } - - return ctx->input_panel_enabled; -} - -/** - * Set the input panel-specific data to deliver to the input panel. - * This API is used by applications to deliver specific data to the input panel. - * The data format MUST be negotiated by both application and the input panel. - * The size and format of data are defined by the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param data The specific data to be set to the input panel. - * @param len the length of data, in bytes, to send to the input panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI void -ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_imdata_set"); - return; - } - - if (!data) return; - - if (ctx->klass->input_panel_imdata_set) - ctx->klass->input_panel_imdata_set(ctx, data, len); -} - -/** - * Get the specific data of the current active input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param data The specific data to be got from the input panel - * @param len The length of data - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI void -ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_imdata_get"); - return; - } - - if (!data) return; - - if (ctx->klass->input_panel_imdata_get) - ctx->klass->input_panel_imdata_get(ctx, data, len); -} - -/** - * Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel. - * - * An input panel displays the string or icon associated with this type - * - * @param ctx An #Ecore_IMF_Context. - * @param return_key_type The type of "return" key on the input panel - * @note Default type is ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT. - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI void -ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_return_key_type_set"); - return; - } - - ctx->input_panel_return_key_type = return_key_type; - if (ctx->klass->input_panel_return_key_type_set) ctx->klass->input_panel_return_key_type_set(ctx, return_key_type); -} - -/** - * Get the "return" key type. - * - * @see ecore_imf_context_input_panel_return_key_type_set() for more details - * - * @param ctx An #Ecore_IMF_Context. - * @return The type of "return" key on the input panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI Ecore_IMF_Input_Panel_Return_Key_Type -ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_return_key_type_get"); - return EINA_FALSE; - } - - return ctx->input_panel_return_key_type; -} - -/** - * Set the return key on the input panel to be disabled. - * - * @param ctx An #Ecore_IMF_Context. - * @param disabled The state - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI void -ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_return_key_disabled_set"); - return; - } - - ctx->input_panel_return_key_disabled = disabled; - if (ctx->klass->input_panel_return_key_disabled_set) ctx->klass->input_panel_return_key_disabled_set(ctx, disabled); -} - -/** - * Get whether the return key on the input panel should be disabled or not. - * - * @param ctx An #Ecore_IMF_Context. - * @return @c EINA_TRUE if it should be disabled. - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI Eina_Bool -ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_return_key_disabled_get"); - return EINA_FALSE; - } - - return ctx->input_panel_return_key_disabled; -} - -/** - * Set the caps lock mode on the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param mode Turn on caps lock on the input panel if @c EINA_TRUE. - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI void -ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_caps_lock_mode_set"); - return; - } - - if (ctx->klass->input_panel_caps_lock_mode_set) - ctx->klass->input_panel_caps_lock_mode_set(ctx, mode); - - ctx->input_panel_caps_lock_mode = mode; -} - -/** - * Get the caps lock mode on the input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @return @c EINA_TRUE if the caps lock is turned on. - * @ingroup Ecore_IMF_Context_Group - * @since 1.2.0 - */ -EAPI Eina_Bool -ecore_imf_context_input_panel_caps_lock_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_panel_caps_lock_mode_get"); - return EINA_FALSE; - } - - return ctx->input_panel_caps_lock_mode; -} - -/** - * Get the position of the current active input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param x top-left x co-ordinate of the input panel - * @param y top-left y co-ordinate of the input panel - * @param w width of the input panel - * @param h height of the input panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ -EAPI void -ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_geometry_get"); - return; - } - - if (ctx->klass->input_panel_geometry_get) - ctx->klass->input_panel_geometry_get(ctx, x, y, w, h); -} - -/** - * Get state of current active input panel. - * - * @param ctx An #Ecore_IMF_Context. - * @return The state of input panel. - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ -EAPI Ecore_IMF_Input_Panel_State -ecore_imf_context_input_panel_state_get(Ecore_IMF_Context *ctx) -{ - Ecore_IMF_Input_Panel_State state = ECORE_IMF_INPUT_PANEL_STATE_HIDE; - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_state_get"); - return ECORE_IMF_INPUT_PANEL_STATE_HIDE; - } - - if (ctx->klass->input_panel_state_get) - state = ctx->klass->input_panel_state_get(ctx); - - return state; -} - -/** - * Register a callback function which will be called if there is change in input panel state,language,mode etc. - * In order to deregister the callback function - * Use @ref ecore_imf_context_input_panel_event_callback_del. - * - * @param ctx An #Ecore_IMF_Context - * @param type event type - * @param func the callback function - * @param data application-input panel specific data. - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ -EAPI void -ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context *ctx, - Ecore_IMF_Input_Panel_Event type, - void (*func) (void *data, Ecore_IMF_Context *ctx, int value), - const void *data) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_event_callback_add"); - return; - } - - if (ctx->klass->input_panel_event_callback_add) - ctx->klass->input_panel_event_callback_add(ctx, type, func, (void *)data); -} - -/** - * Unregister a callback function which will be called if there is change in input panel state, language, mode etc. - * - * @param ctx An #Ecore_IMF_Context. - * @param type An #Ecore_IMF_Input_Panel_Event. - * @param func the callback function - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ -EAPI void -ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context *ctx, - Ecore_IMF_Input_Panel_Event type, - void (*func) (void *data, Ecore_IMF_Context *ctx, int value)) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_event_callback_del"); - return; - } - - if (ctx->klass->input_panel_event_callback_del) - ctx->klass->input_panel_event_callback_del(ctx, type, func); -} - -/** - * Get the current language locale of the input panel. - * - * ex) fr_FR - * - * @param ctx An #Ecore_IMF_Context. - * @param lang Location to store the retrieved language string. The - * string retrieved must be freed with free(). - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ -EAPI void -ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx, char **lang) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_input_panel_language_locale_get"); - return; - } - - if (ctx->klass->input_panel_language_locale_get) - ctx->klass->input_panel_language_locale_get(ctx, lang); - else - { - if (lang) *lang = strdup(""); - } -} - -/** - * Get the geometry information of the candidate panel. - * - * @param ctx An #Ecore_IMF_Context. - * @param x top-left x co-ordinate of the candidate panel - * @param y top-left y co-ordinate of the candidate panel - * @param w width of the candidate panel - * @param h height of the candidate panel - * @ingroup Ecore_IMF_Context_Group - * @since 1.3 - */ -EAPI void -ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h) -{ - if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) - { - ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, - "ecore_imf_context_candidate_panel_geometry_get"); - return; - } - - if (ctx->klass->candidate_panel_geometry_get) - ctx->klass->candidate_panel_geometry_get(ctx, x, y, w, h); -} - diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf_module.c b/legacy/ecore/src/lib/ecore_imf/ecore_imf_module.c deleted file mode 100644 index cbdee47178..0000000000 --- a/legacy/ecore/src/lib/ecore_imf/ecore_imf_module.c +++ /dev/null @@ -1,212 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#include -#include - -#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); - eina_array_free(module_list); - module_list = NULL; - } -} - -static Eina_Bool -_hash_module_available_get(const Eina_Hash *hash EINA_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_CB(_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 EINA_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_CB(_hash_ids_get), &l); - eina_iterator_free(it); - - return l; -} - -static Eina_Bool -_hash_ids_by_canvas_type_get(const Eina_Hash *hash EINA_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_CB(_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; -} diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h b/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h deleted file mode 100644 index b4ff0f2ee0..0000000000 --- a/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h +++ /dev/null @@ -1,84 +0,0 @@ -#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; -typedef struct _Ecore_IMF_Func_Node Ecore_IMF_Func_Node; - -struct _Ecore_IMF_Context -{ - ECORE_MAGIC; - const Ecore_IMF_Module *module; - const Ecore_IMF_Context_Class *klass; - void *data; - int input_mode; - void *window; - void *client_canvas; - Eina_Bool (*retrieve_surrounding_func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos); - void *retrieve_surrounding_data; - Eina_List *callbacks; - Ecore_IMF_Autocapital_Type autocapital_type; - Ecore_IMF_Input_Panel_Layout input_panel_layout; - Ecore_IMF_Input_Panel_Lang input_panel_lang; - Ecore_IMF_Input_Panel_Return_Key_Type input_panel_return_key_type; - Eina_Bool allow_prediction : 1; - Eina_Bool input_panel_enabled : 1; - Eina_Bool input_panel_return_key_disabled : 1; - Eina_Bool input_panel_caps_lock_mode : 1; -}; - -struct _Ecore_IMF_Module -{ - const Ecore_IMF_Context_Info *info; - Ecore_IMF_Context *(*create)(void); - Ecore_IMF_Context *(*exit)(void); -}; - -struct _Ecore_IMF_Func_Node -{ - void (*func) (); - const void *data; - Ecore_IMF_Callback_Type type; -}; - -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 diff --git a/legacy/ecore/src/lib/ecore_imf_evas/Ecore_IMF_Evas.h b/legacy/ecore/src/lib/ecore_imf_evas/Ecore_IMF_Evas.h deleted file mode 100644 index 5f7cdb90f3..0000000000 --- a/legacy/ecore/src/lib/ecore_imf_evas/Ecore_IMF_Evas.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _ECORE_IMF_EVAS_H -#define _ECORE_IMF_EVAS_H - -#include -#include - -#ifdef EAPI -# undef EAPI -#endif - -#ifdef _WIN32 -# ifdef EFL_ECORE_IMF_EVAS_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 - -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 diff --git a/legacy/ecore/src/lib/ecore_imf_evas/ecore_imf_evas.c b/legacy/ecore/src/lib/ecore_imf_evas/ecore_imf_evas.c deleted file mode 100644 index 4a5f3dd5f4..0000000000 --- a/legacy/ecore/src/lib/ecore_imf_evas/ecore_imf_evas.c +++ /dev/null @@ -1,324 +0,0 @@ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "ecore_private.h" -#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. - * Converts each event from Evas to the corresponding event of Ecore_IMF. - * - * An example of usage of these functions can be found at: - * @li @ref ecore_imf_example_c - */ - -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; - if (evas_key_modifier_is_set(evas_modifiers, "AltGr")) - *imf_keyboard_modifiers |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR; -} - -/* 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 - * - * Example - * @code - * static void - * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) - * { - * Evas_Event_Key_Down *ev = event_info; - * if (!ev->keyname) return; - * - * if (imf_context) - * { - * Ecore_IMF_Event_Key_Down ecore_ev; - * ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev); - * if (ecore_imf_context_filter_event(imf_context, - * ECORE_IMF_EVENT_KEY_DOWN, - * (Ecore_IMF_Event *)&ecore_ev)) - * return; - * } - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data); - * @endcode - */ -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 - * - * Example - * @code - * static void - * _key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) - * { - * Evas_Event_Key_Up *ev = event_info; - * if (!ev->keyname) return; - * - * if (imf_context) - * { - * Ecore_IMF_Event_Key_Up ecore_ev; - * ecore_imf_evas_event_key_up_wrap(ev, &ecore_ev); - * if (ecore_imf_context_filter_event(imf_context, - * ECORE_IMF_EVENT_KEY_UP, - * (Ecore_IMF_Event *)&ecore_ev)) - * return; - * } - * } - * - * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP, _key_up_cb, data); - * @endcode - */ -EAPI void -ecore_imf_evas_event_key_up_wrap(Evas_Event_Key_Up *evas_event, - Ecore_IMF_Event_Key_Up *imf_event) -{ - if (!evas_event) - { - EINA_LOG_ERR("Evas event is missing"); - return; - } - - if (!imf_event) - { - EINA_LOG_ERR("Imf event is missing"); - 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); -} diff --git a/legacy/ecore/src/lib/ecore_input/Ecore_Input.h b/legacy/ecore/src/lib/ecore_input/Ecore_Input.h deleted file mode 100644 index d1feb220e1..0000000000 --- a/legacy/ecore/src/lib/ecore_input/Ecore_Input.h +++ /dev/null @@ -1,236 +0,0 @@ -#ifndef _ECORE_INPUT_H -#define _ECORE_INPUT_H - -#ifdef _WIN32 -# include -#else -# include -#endif - -#include - -#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 -#define ECORE_EVENT_LOCK_SHIFT 0x0300 -#define ECORE_EVENT_MODIFIER_ALTGR 0x0400 /**< @since 1.7 */ - - typedef uintptr_t Ecore_Window; - typedef struct _Ecore_Event_Key Ecore_Event_Key; - typedef struct _Ecore_Event_Mouse_Button Ecore_Event_Mouse_Button; - typedef struct _Ecore_Event_Mouse_Wheel Ecore_Event_Mouse_Wheel; - typedef struct _Ecore_Event_Mouse_Move Ecore_Event_Mouse_Move; - typedef struct _Ecore_Event_Mouse_IO Ecore_Event_Mouse_IO; - typedef struct _Ecore_Event_Modifiers Ecore_Event_Modifiers; - - typedef enum _Ecore_Event_Modifier - { - ECORE_NONE, - ECORE_SHIFT, - ECORE_CTRL, - ECORE_ALT, - ECORE_WIN, - ECORE_SCROLL, - ECORE_CAPS, - ECORE_MODE, /**< @since 1.7 */ - ECORE_LAST - } Ecore_Event_Modifier; - - typedef enum _Ecore_Event_Press - { - ECORE_DOWN, - ECORE_UP - } Ecore_Event_Press; - - typedef enum _Ecore_Event_IO - { - ECORE_IN, - ECORE_OUT - } Ecore_Event_IO; - - typedef enum _Ecore_Compose_State - { - ECORE_COMPOSE_NONE, - ECORE_COMPOSE_MIDDLE, - ECORE_COMPOSE_DONE - } Ecore_Compose_State; - - 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; - }; - - 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; - }; - - 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; - }; - - 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; - }; - - struct _Ecore_Event_Mouse_IO - { - Ecore_Window window; - Ecore_Window event_window; - - unsigned int timestamp; - unsigned int modifiers; - - int x; - int y; - }; - - 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); - - /** - * @since 1.7 - */ - EAPI Ecore_Compose_State ecore_compose_get(const Eina_List *seq, char **seqstr_ret); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/legacy/ecore/src/lib/ecore_input/ecore_input.c b/legacy/ecore/src/lib/ecore_input/ecore_input.c deleted file mode 100644 index 8f4b1f9bc0..0000000000 --- a/legacy/ecore/src/lib/ecore_input/ecore_input.c +++ /dev/null @@ -1,127 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#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; - if (!ecore_init()) - { - _ecore_event_init_count--; - return 0; - } - - _ecore_input_log_dom = eina_log_domain_register - ("ecore_input", 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; - ecore_shutdown(); - 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 }, - { "ISO_Level3_Shift", ECORE_MODE, ECORE_EVENT_MODIFIER_ALTGR }, - { "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; -} diff --git a/legacy/ecore/src/lib/ecore_input/ecore_input_compose.c b/legacy/ecore/src/lib/ecore_input/ecore_input_compose.c deleted file mode 100644 index 5335a7fe0c..0000000000 --- a/legacy/ecore/src/lib/ecore_input/ecore_input_compose.c +++ /dev/null @@ -1,61 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include "Ecore.h" -#include "ecore_private.h" - -#include "Ecore_Input.h" -#include "ecore_input_private.h" - -// some info on a big big big compose table -// http://cgit.freedesktop.org/xorg/lib/libX11/plain/nls/en_US.UTF-8/Compose.pre -// isolate compose tree into its own file - hand crafted into static const c -#include "ecore_input_compose.h" - -EAPI Ecore_Compose_State -ecore_compose_get(const Eina_List *seq, char **seqstr_ret) -{ - Comp *c, *cend; - Eina_List *l; - const char *s; - int i = 0; - - if (!seq) return ECORE_COMPOSE_NONE; - l = (Eina_List *)seq; - s = l->data; - cend = (Comp *)comp + (sizeof(comp) / sizeof(comp[0])); - for (c = (Comp *)comp; c->s && s;) - { - // doesn't match -> jump to next level entry - if (!(!strcmp(s, c->s))) - { - c += c->jump + 1; - if (c >= cend) - { - return ECORE_COMPOSE_NONE; - } - } - else - { - cend = c + c->jump; - // advance to next sequence member - l = l->next; - i++; - if (l) s = l->data; - else s = NULL; - c++; - // if advanced item jump is an endpoint - it's the string we want - if (c->jump == 0) - { - if (seqstr_ret) *seqstr_ret = strdup(c->s); - return ECORE_COMPOSE_DONE; - } - } - } - if (i == 0) return ECORE_COMPOSE_NONE; - return ECORE_COMPOSE_MIDDLE; -} diff --git a/legacy/ecore/src/lib/ecore_input/ecore_input_compose.h b/legacy/ecore/src/lib/ecore_input/ecore_input_compose.h deleted file mode 100644 index 9fbfb76616..0000000000 --- a/legacy/ecore/src/lib/ecore_input/ecore_input_compose.h +++ /dev/null @@ -1,9895 +0,0 @@ -typedef struct _Comp Comp; -struct _Comp { - const char *s; - int jump; -}; - -static const Comp comp[] = { - {"dead_breve", 124}, - {"dead_breve", 1}, - {"˘", 0}, - {"g", 1}, - {"ğ", 0}, - {"a", 1}, - {"ă", 0}, - {"Greek_IOTA", 1}, - {"Ῐ", 0}, - {"dead_grave", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"Greek_iota", 1}, - {"ῐ", 0}, - {"e", 1}, - {"ĕ", 0}, - {"agrave", 1}, - {"ằ", 0}, - {"o", 1}, - {"ŏ", 0}, - {"Greek_upsilon", 1}, - {"ῠ", 0}, - {"ahook", 1}, - {"ẳ", 0}, - {"dead_belowdot", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"space", 1}, - {"˘", 0}, - {"Cyrillic_I", 1}, - {"Й", 0}, - {"Multi_key", 15}, - {"exclam", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"comma", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"i", 1}, - {"ĭ", 0}, - {"dead_tilde", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"Cyrillic_a", 1}, - {"ӑ", 0}, - {"Cyrillic_U", 1}, - {"Ў", 0}, - {"nobreakspace", 1}, - {"̆", 0}, - {"u", 1}, - {"ŭ", 0}, - {"G", 1}, - {"Ğ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾰ", 0}, - {"atilde", 1}, - {"ẵ", 0}, - {"Cyrillic_ie", 1}, - {"ӗ", 0}, - {"E", 1}, - {"Ĕ", 0}, - {"Cyrillic_i", 1}, - {"й", 0}, - {"Atilde", 1}, - {"Ẵ", 0}, - {"Cyrillic_zhe", 1}, - {"ӂ", 0}, - {"Greek_alpha", 1}, - {"ᾰ", 0}, - {"Ahook", 1}, - {"Ẳ", 0}, - {"O", 1}, - {"Ŏ", 0}, - {"A", 1}, - {"Ă", 0}, - {"Cyrillic_A", 1}, - {"Ӑ", 0}, - {"dead_hook", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӂ", 0}, - {"Cyrillic_IE", 1}, - {"Ӗ", 0}, - {"Aacute", 1}, - {"Ắ", 0}, - {"dead_cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"aacute", 1}, - {"ắ", 0}, - {"dead_acute", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"Agrave", 1}, - {"Ằ", 0}, - {"I", 1}, - {"Ĭ", 0}, - {"U", 1}, - {"Ŭ", 0}, - {"Cyrillic_u", 1}, - {"ў", 0}, - {"Greek_UPSILON", 1}, - {"Ῠ", 0}, - {"dead_grave", 351}, - {"W", 1}, - {"Ẁ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"a", 1}, - {"à", 0}, - {"Greek_IOTA", 1}, - {"Ὶ", 0}, - {"dead_grave", 1}, - {"`", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"Greek_iota", 1}, - {"ὶ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Greek_OMICRON", 1}, - {"Ὸ", 0}, - {"Acircumflex", 1}, - {"Ầ", 0}, - {"Cyrillic_er", 1}, - {"р̀", 0}, - {"e", 1}, - {"è", 0}, - {"o", 1}, - {"ò", 0}, - {"Udiaeresis", 1}, - {"Ǜ", 0}, - {"Greek_upsilon", 1}, - {"ὺ", 0}, - {"uhorn", 1}, - {"ừ", 0}, - {"space", 1}, - {"`", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"acircumflex", 1}, - {"ầ", 0}, - {"Ecircumflex", 1}, - {"Ề", 0}, - {"Cyrillic_I", 1}, - {"Ѝ", 0}, - {"y", 1}, - {"ỳ", 0}, - {"Multi_key", 115}, - {"b", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἲ", 0}, - {"Greek_iota", 1}, - {"ἲ", 0}, - {"Greek_OMICRON", 1}, - {"Ὂ", 0}, - {"Greek_upsilon", 1}, - {"ὒ", 0}, - {"Greek_epsilon", 1}, - {"ἒ", 0}, - {"Greek_ALPHA", 1}, - {"Ἂ", 0}, - {"Greek_omicron", 1}, - {"ὂ", 0}, - {"Greek_eta", 1}, - {"ἢ", 0}, - {"Greek_alpha", 1}, - {"ἂ", 0}, - {"Greek_ETA", 1}, - {"Ἢ", 0}, - {"Greek_EPSILON", 1}, - {"Ἒ", 0}, - {"Greek_omega", 1}, - {"ὢ", 0}, - {"Greek_OMEGA", 1}, - {"Ὢ", 0}, - {"quotedbl", 8}, - {"Greek_iota", 1}, - {"ῒ", 0}, - {"Greek_upsilon", 1}, - {"ῢ", 0}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"plus", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"macron", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἳ", 0}, - {"Greek_iota", 1}, - {"ἳ", 0}, - {"Greek_OMICRON", 1}, - {"Ὃ", 0}, - {"Greek_upsilon", 1}, - {"ὓ", 0}, - {"Greek_epsilon", 1}, - {"ἓ", 0}, - {"Greek_ALPHA", 1}, - {"Ἃ", 0}, - {"Greek_omicron", 1}, - {"ὃ", 0}, - {"Greek_eta", 1}, - {"ἣ", 0}, - {"Greek_alpha", 1}, - {"ἃ", 0}, - {"Greek_ETA", 1}, - {"Ἣ", 0}, - {"Greek_EPSILON", 1}, - {"Ἓ", 0}, - {"Greek_omega", 1}, - {"ὣ", 0}, - {"Greek_OMEGA", 1}, - {"Ὣ", 0}, - {"Greek_UPSILON", 1}, - {"Ὓ", 0}, - {"U", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Cyrillic_O", 1}, - {"О̀", 0}, - {"i", 1}, - {"ì", 0}, - {"n", 1}, - {"ǹ", 0}, - {"Cyrillic_a", 1}, - {"а̀", 0}, - {"Ohorn", 1}, - {"Ờ", 0}, - {"ohorn", 1}, - {"ờ", 0}, - {"Cyrillic_ER", 1}, - {"Р̀", 0}, - {"Greek_epsilon", 1}, - {"ὲ", 0}, - {"Cyrillic_U", 1}, - {"У̀", 0}, - {"nobreakspace", 1}, - {"̀", 0}, - {"V", 1}, - {"Ǜ", 0}, - {"Ocircumflex", 1}, - {"Ồ", 0}, - {"omacron", 1}, - {"ṑ", 0}, - {"ocircumflex", 1}, - {"ồ", 0}, - {"u", 1}, - {"ù", 0}, - {"Greek_ALPHA", 1}, - {"Ὰ", 0}, - {"Cyrillic_ie", 1}, - {"ѐ", 0}, - {"emacron", 1}, - {"ḕ", 0}, - {"E", 1}, - {"È", 0}, - {"Greek_iotadieresis", 1}, - {"ῒ", 0}, - {"Y", 1}, - {"Ỳ", 0}, - {"Cyrillic_i", 1}, - {"ѝ", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἳ", 0}, - {"Greek_iota", 1}, - {"ἳ", 0}, - {"Greek_OMICRON", 1}, - {"Ὃ", 0}, - {"Greek_upsilon", 1}, - {"ὓ", 0}, - {"Greek_epsilon", 1}, - {"ἓ", 0}, - {"Greek_ALPHA", 1}, - {"Ἃ", 0}, - {"Greek_omicron", 1}, - {"ὃ", 0}, - {"Greek_eta", 1}, - {"ἣ", 0}, - {"Greek_alpha", 1}, - {"ἃ", 0}, - {"Greek_ETA", 1}, - {"Ἣ", 0}, - {"Greek_EPSILON", 1}, - {"Ἓ", 0}, - {"Greek_omega", 1}, - {"ὣ", 0}, - {"Greek_OMEGA", 1}, - {"Ὣ", 0}, - {"Greek_UPSILON", 1}, - {"Ὓ", 0}, - {"Greek_upsilondieresis", 1}, - {"ῢ", 0}, - {"Greek_omicron", 1}, - {"ὸ", 0}, - {"Greek_eta", 1}, - {"ὴ", 0}, - {"Abreve", 1}, - {"Ằ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἲ", 0}, - {"Greek_iota", 1}, - {"ἲ", 0}, - {"Greek_OMICRON", 1}, - {"Ὂ", 0}, - {"Greek_upsilon", 1}, - {"ὒ", 0}, - {"Greek_epsilon", 1}, - {"ἒ", 0}, - {"Greek_ALPHA", 1}, - {"Ἂ", 0}, - {"Greek_omicron", 1}, - {"ὂ", 0}, - {"Greek_eta", 1}, - {"ἢ", 0}, - {"Greek_alpha", 1}, - {"ἂ", 0}, - {"Greek_ETA", 1}, - {"Ἢ", 0}, - {"Greek_EPSILON", 1}, - {"Ἒ", 0}, - {"Greek_omega", 1}, - {"ὢ", 0}, - {"Greek_OMEGA", 1}, - {"Ὢ", 0}, - {"Greek_alpha", 1}, - {"ὰ", 0}, - {"ecircumflex", 1}, - {"ề", 0}, - {"w", 1}, - {"ẁ", 0}, - {"Greek_ETA", 1}, - {"Ὴ", 0}, - {"Cyrillic_o", 1}, - {"о̀", 0}, - {"Emacron", 1}, - {"Ḕ", 0}, - {"v", 1}, - {"ǜ", 0}, - {"O", 1}, - {"Ò", 0}, - {"abreve", 1}, - {"ằ", 0}, - {"A", 1}, - {"À", 0}, - {"Greek_EPSILON", 1}, - {"Ὲ", 0}, - {"Cyrillic_A", 1}, - {"А̀", 0}, - {"Omacron", 1}, - {"Ṑ", 0}, - {"Cyrillic_IE", 1}, - {"Ѐ", 0}, - {"Greek_omega", 1}, - {"ὼ", 0}, - {"dead_diaeresis", 8}, - {"Greek_iota", 1}, - {"ῒ", 0}, - {"Greek_upsilon", 1}, - {"ῢ", 0}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"Uhorn", 1}, - {"Ừ", 0}, - {"Greek_OMEGA", 1}, - {"Ὼ", 0}, - {"udiaeresis", 1}, - {"ǜ", 0}, - {"I", 1}, - {"Ì", 0}, - {"N", 1}, - {"Ǹ", 0}, - {"U", 1}, - {"Ù", 0}, - {"Cyrillic_u", 1}, - {"у̀", 0}, - {"Greek_UPSILON", 1}, - {"Ὺ", 0}, - {"dead_horn", 99}, - {"Uhook", 1}, - {"Ử", 0}, - {"Obelowdot", 1}, - {"Ợ", 0}, - {"Ograve", 1}, - {"Ờ", 0}, - {"dead_grave", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"dead_horn", 1}, - {"̛", 0}, - {"Oacute", 1}, - {"Ớ", 0}, - {"ohook", 1}, - {"ở", 0}, - {"o", 1}, - {"ơ", 0}, - {"Utilde", 1}, - {"Ữ", 0}, - {"dead_belowdot", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"space", 1}, - {"̛", 0}, - {"ubelowdot", 1}, - {"ự", 0}, - {"oacute", 1}, - {"ớ", 0}, - {"uhook", 1}, - {"ử", 0}, - {"dead_tilde", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"Uacute", 1}, - {"Ứ", 0}, - {"Ugrave", 1}, - {"Ừ", 0}, - {"nobreakspace", 1}, - {"̛", 0}, - {"uacute", 1}, - {"ứ", 0}, - {"u", 1}, - {"ư", 0}, - {"otilde", 1}, - {"ỡ", 0}, - {"utilde", 1}, - {"ữ", 0}, - {"Otilde", 1}, - {"Ỡ", 0}, - {"ograve", 1}, - {"ờ", 0}, - {"Ohook", 1}, - {"Ở", 0}, - {"O", 1}, - {"Ơ", 0}, - {"Ubelowdot", 1}, - {"Ự", 0}, - {"dead_hook", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"ugrave", 1}, - {"ừ", 0}, - {"obelowdot", 1}, - {"ợ", 0}, - {"dead_acute", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"U", 1}, - {"Ư", 0}, - {"dead_circumflex", 335}, - {"minus", 1}, - {"⁻", 0}, - {"W", 1}, - {"Ŵ", 0}, - {"g", 1}, - {"ĝ", 0}, - {"a", 1}, - {"â", 0}, - {"Ograve", 1}, - {"Ồ", 0}, - {"dead_circumflex", 1}, - {"^", 0}, - {"dead_grave", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Ehook", 1}, - {"Ể", 0}, - {"1", 1}, - {"¹", 0}, - {"C", 1}, - {"Ĉ", 0}, - {"KP_4", 1}, - {"⁴", 0}, - {"Oacute", 1}, - {"Ố", 0}, - {"Cyrillic_er", 1}, - {"р̂", 0}, - {"ohook", 1}, - {"ổ", 0}, - {"e", 1}, - {"ê", 0}, - {"agrave", 1}, - {"ầ", 0}, - {"KP_6", 1}, - {"⁶", 0}, - {"o", 1}, - {"ô", 0}, - {"ahook", 1}, - {"ẩ", 0}, - {"dead_belowdot", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"space", 1}, - {"^", 0}, - {"KP_8", 1}, - {"⁸", 0}, - {"Etilde", 1}, - {"Ễ", 0}, - {"Cyrillic_I", 1}, - {"И̂", 0}, - {"y", 1}, - {"ŷ", 0}, - {"Multi_key", 83}, - {"exclam", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"t", 4}, - {"M", 1}, - {"™", 0}, - {"m", 1}, - {"™", 0}, - {"underbar", 24}, - {"a", 1}, - {"ª", 0}, - {"o", 1}, - {"º", 0}, - {"l", 1}, - {"ˡ", 0}, - {"y", 1}, - {"ʸ", 0}, - {"i", 1}, - {"ⁱ", 0}, - {"n", 1}, - {"ⁿ", 0}, - {"j", 1}, - {"ʲ", 0}, - {"x", 1}, - {"ˣ", 0}, - {"w", 1}, - {"ʷ", 0}, - {"r", 1}, - {"ʳ", 0}, - {"s", 1}, - {"ˢ", 0}, - {"h", 1}, - {"ʰ", 0}, - {"S", 4}, - {"M", 1}, - {"℠", 0}, - {"m", 1}, - {"℠", 0}, - {"underscore", 24}, - {"a", 1}, - {"ª", 0}, - {"o", 1}, - {"º", 0}, - {"l", 1}, - {"ˡ", 0}, - {"y", 1}, - {"ʸ", 0}, - {"i", 1}, - {"ⁱ", 0}, - {"n", 1}, - {"ⁿ", 0}, - {"j", 1}, - {"ʲ", 0}, - {"x", 1}, - {"ˣ", 0}, - {"w", 1}, - {"ʷ", 0}, - {"r", 1}, - {"ʳ", 0}, - {"s", 1}, - {"ˢ", 0}, - {"h", 1}, - {"ʰ", 0}, - {"s", 4}, - {"M", 1}, - {"℠", 0}, - {"m", 1}, - {"℠", 0}, - {"T", 4}, - {"M", 1}, - {"™", 0}, - {"m", 1}, - {"™", 0}, - {"oacute", 1}, - {"ố", 0}, - {"Cyrillic_O", 1}, - {"О̂", 0}, - {"i", 1}, - {"î", 0}, - {"KP_9", 1}, - {"⁹", 0}, - {"equal", 1}, - {"⁼", 0}, - {"KP_Space", 1}, - {"²", 0}, - {"dead_tilde", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"7", 1}, - {"⁷", 0}, - {"Cyrillic_a", 1}, - {"а̂", 0}, - {"j", 1}, - {"ĵ", 0}, - {"parenright", 1}, - {"⁾", 0}, - {"Eacute", 1}, - {"Ế", 0}, - {"Cyrillic_ER", 1}, - {"Р̂", 0}, - {"KP_7", 1}, - {"⁷", 0}, - {"Cyrillic_U", 1}, - {"У̂", 0}, - {"nobreakspace", 1}, - {"̂", 0}, - {"u", 1}, - {"û", 0}, - {"z", 1}, - {"ẑ", 0}, - {"G", 1}, - {"Ĝ", 0}, - {"otilde", 1}, - {"ỗ", 0}, - {"H", 1}, - {"Ĥ", 0}, - {"8", 1}, - {"⁸", 0}, - {"KP_1", 1}, - {"¹", 0}, - {"atilde", 1}, - {"ẫ", 0}, - {"3", 1}, - {"³", 0}, - {"Cyrillic_ie", 1}, - {"е̂", 0}, - {"E", 1}, - {"Ê", 0}, - {"S", 1}, - {"Ŝ", 0}, - {"2", 1}, - {"²", 0}, - {"Y", 1}, - {"Ŷ", 0}, - {"Cyrillic_i", 1}, - {"и̂", 0}, - {"Otilde", 1}, - {"Ỗ", 0}, - {"Atilde", 1}, - {"Ẫ", 0}, - {"egrave", 1}, - {"ề", 0}, - {"ograve", 1}, - {"ồ", 0}, - {"plus", 1}, - {"⁺", 0}, - {"6", 1}, - {"⁶", 0}, - {"Ahook", 1}, - {"Ẩ", 0}, - {"w", 1}, - {"ŵ", 0}, - {"Ohook", 1}, - {"Ổ", 0}, - {"Cyrillic_o", 1}, - {"о̂", 0}, - {"4", 1}, - {"⁴", 0}, - {"KP_3", 1}, - {"³", 0}, - {"eacute", 1}, - {"ế", 0}, - {"J", 1}, - {"Ĵ", 0}, - {"O", 1}, - {"Ô", 0}, - {"s", 1}, - {"ŝ", 0}, - {"Z", 1}, - {"Ẑ", 0}, - {"KP_0", 1}, - {"⁰", 0}, - {"A", 1}, - {"Â", 0}, - {"c", 1}, - {"ĉ", 0}, - {"KP_Add", 1}, - {"⁺", 0}, - {"KP_2", 1}, - {"²", 0}, - {"Cyrillic_A", 1}, - {"А̂", 0}, - {"dead_hook", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"5", 1}, - {"⁵", 0}, - {"KP_5", 1}, - {"⁵", 0}, - {"9", 1}, - {"⁹", 0}, - {"Cyrillic_IE", 1}, - {"Е̂", 0}, - {"Egrave", 1}, - {"Ề", 0}, - {"0", 1}, - {"⁰", 0}, - {"Aacute", 1}, - {"Ấ", 0}, - {"etilde", 1}, - {"ễ", 0}, - {"aacute", 1}, - {"ấ", 0}, - {"dead_acute", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Agrave", 1}, - {"Ầ", 0}, - {"parenleft", 1}, - {"⁽", 0}, - {"h", 1}, - {"ĥ", 0}, - {"I", 1}, - {"Î", 0}, - {"ehook", 1}, - {"ể", 0}, - {"U", 1}, - {"Û", 0}, - {"Cyrillic_u", 1}, - {"у̂", 0}, - {"KP_Equal", 1}, - {"⁼", 0}, - {"dead_currency", 103}, - {"W", 1}, - {"₩", 0}, - {"g", 1}, - {"₲", 0}, - {"a", 1}, - {"؋", 0}, - {"dead_currency", 1}, - {"¤", 0}, - {"C", 1}, - {"₡", 0}, - {"e", 1}, - {"€", 0}, - {"F", 1}, - {"₣", 0}, - {"o", 1}, - {"௹", 0}, - {"l", 1}, - {"£", 0}, - {"t", 1}, - {"৳", 0}, - {"thorn", 1}, - {"৲", 0}, - {"space", 1}, - {"¤", 0}, - {"y", 1}, - {"¥", 0}, - {"b", 1}, - {"฿", 0}, - {"i", 1}, - {"﷼", 0}, - {"k", 1}, - {"₭", 0}, - {"n", 1}, - {"₦", 0}, - {"ccedilla", 1}, - {"₵", 0}, - {"nobreakspace", 1}, - {"¤", 0}, - {"u", 1}, - {"元", 0}, - {"G", 1}, - {"₲", 0}, - {"H", 1}, - {"₴", 0}, - {"E", 1}, - {"₠", 0}, - {"S", 1}, - {"$", 0}, - {"Y", 1}, - {"円", 0}, - {"f", 1}, - {"ƒ", 0}, - {"d", 1}, - {"₫", 0}, - {"D", 1}, - {"₯", 0}, - {"w", 1}, - {"₩", 0}, - {"p", 1}, - {"₰", 0}, - {"P", 1}, - {"₧", 0}, - {"M", 1}, - {"ℳ", 0}, - {"O", 1}, - {"૱", 0}, - {"m", 1}, - {"₥", 0}, - {"r", 1}, - {"₢", 0}, - {"s", 1}, - {"₪", 0}, - {"A", 1}, - {"₳", 0}, - {"R", 1}, - {"₨", 0}, - {"THORN", 1}, - {"৲", 0}, - {"c", 1}, - {"¢", 0}, - {"L", 1}, - {"₤", 0}, - {"T", 1}, - {"₮", 0}, - {"Ccedilla", 1}, - {"₵", 0}, - {"K", 1}, - {"₭", 0}, - {"B", 1}, - {"₱", 0}, - {"dead_cedilla", 4}, - {"C", 1}, - {"₵", 0}, - {"c", 1}, - {"₵", 0}, - {"h", 1}, - {"₴", 0}, - {"I", 1}, - {"៛", 0}, - {"N", 1}, - {"₦", 0}, - {"U", 1}, - {"圓", 0}, - {"dead_belowdiaeresis", 7}, - {"u", 1}, - {"ṳ", 0}, - {"dead_diaeresis", 2}, - {"equal", 1}, - {"⩷", 0}, - {"U", 1}, - {"Ṳ", 0}, - {"dead_belowdot", 167}, - {"minus", 1}, - {"⨪", 0}, - {"W", 1}, - {"Ẉ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"a", 1}, - {"ạ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"Acircumflex", 1}, - {"Ậ", 0}, - {"e", 1}, - {"ẹ", 0}, - {"o", 1}, - {"ọ", 0}, - {"l", 1}, - {"ḷ", 0}, - {"t", 1}, - {"ṭ", 0}, - {"dead_belowdot", 1}, - {"̣", 0}, - {"uhorn", 1}, - {"ự", 0}, - {"space", 1}, - {"̣", 0}, - {"dead_macron", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"acircumflex", 1}, - {"ậ", 0}, - {"Ecircumflex", 1}, - {"Ệ", 0}, - {"y", 1}, - {"ỵ", 0}, - {"b", 1}, - {"ḅ", 0}, - {"Multi_key", 9}, - {"plus", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"i", 1}, - {"ị", 0}, - {"k", 1}, - {"ḳ", 0}, - {"n", 1}, - {"ṇ", 0}, - {"equal", 1}, - {"⩦", 0}, - {"Ohorn", 1}, - {"Ợ", 0}, - {"ohorn", 1}, - {"ợ", 0}, - {"sabovedot", 1}, - {"ṩ", 0}, - {"nobreakspace", 1}, - {"̣", 0}, - {"V", 1}, - {"Ṿ", 0}, - {"Ocircumflex", 1}, - {"Ộ", 0}, - {"ocircumflex", 1}, - {"ộ", 0}, - {"u", 1}, - {"ụ", 0}, - {"z", 1}, - {"ẓ", 0}, - {"H", 1}, - {"Ḥ", 0}, - {"E", 1}, - {"Ẹ", 0}, - {"S", 1}, - {"Ṣ", 0}, - {"Y", 1}, - {"Ỵ", 0}, - {"d", 1}, - {"ḍ", 0}, - {"D", 1}, - {"Ḍ", 0}, - {"Abreve", 1}, - {"Ặ", 0}, - {"plus", 1}, - {"⨥", 0}, - {"ecircumflex", 1}, - {"ệ", 0}, - {"dead_abovedot", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"w", 1}, - {"ẉ", 0}, - {"v", 1}, - {"ṿ", 0}, - {"M", 1}, - {"Ṃ", 0}, - {"O", 1}, - {"Ọ", 0}, - {"abreve", 1}, - {"ặ", 0}, - {"m", 1}, - {"ṃ", 0}, - {"r", 1}, - {"ṛ", 0}, - {"s", 1}, - {"ṣ", 0}, - {"Z", 1}, - {"Ẓ", 0}, - {"A", 1}, - {"Ạ", 0}, - {"R", 1}, - {"Ṛ", 0}, - {"L", 1}, - {"Ḷ", 0}, - {"T", 1}, - {"Ṭ", 0}, - {"K", 1}, - {"Ḳ", 0}, - {"B", 1}, - {"Ḅ", 0}, - {"Sabovedot", 1}, - {"Ṩ", 0}, - {"Uhorn", 1}, - {"Ự", 0}, - {"h", 1}, - {"ḥ", 0}, - {"I", 1}, - {"Ị", 0}, - {"N", 1}, - {"Ṇ", 0}, - {"U", 1}, - {"Ụ", 0}, - {"dead_macron", 224}, - {"adiaeresis", 1}, - {"ǟ", 0}, - {"g", 1}, - {"ḡ", 0}, - {"a", 1}, - {"ā", 0}, - {"Greek_IOTA", 1}, - {"Ῑ", 0}, - {"Ograve", 1}, - {"Ṑ", 0}, - {"dead_grave", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"Greek_iota", 1}, - {"ῑ", 0}, - {"Oacute", 1}, - {"Ṓ", 0}, - {"Cyrillic_er", 1}, - {"р̄", 0}, - {"e", 1}, - {"ē", 0}, - {"o", 1}, - {"ō", 0}, - {"Udiaeresis", 1}, - {"Ǖ", 0}, - {"Greek_upsilon", 1}, - {"ῡ", 0}, - {"dead_belowdot", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"space", 1}, - {"¯", 0}, - {"dead_macron", 1}, - {"¯", 0}, - {"Cyrillic_I", 1}, - {"Ӣ", 0}, - {"y", 1}, - {"ȳ", 0}, - {"Multi_key", 41}, - {"period", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"exclam", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"quotedbl", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"semicolon", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"oacute", 1}, - {"ṓ", 0}, - {"Cyrillic_O", 1}, - {"О̄", 0}, - {"i", 1}, - {"ī", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"Cyrillic_a", 1}, - {"а̄", 0}, - {"Eacute", 1}, - {"Ḗ", 0}, - {"Cyrillic_ER", 1}, - {"Р̄", 0}, - {"Cyrillic_U", 1}, - {"Ӯ", 0}, - {"nobreakspace", 1}, - {"̄", 0}, - {"V", 1}, - {"Ǖ", 0}, - {"AE", 1}, - {"Ǣ", 0}, - {"u", 1}, - {"ū", 0}, - {"G", 1}, - {"Ḡ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾱ", 0}, - {"otilde", 1}, - {"ȭ", 0}, - {"Cyrillic_ie", 1}, - {"е̄", 0}, - {"E", 1}, - {"Ē", 0}, - {"Y", 1}, - {"Ȳ", 0}, - {"Cyrillic_i", 1}, - {"ӣ", 0}, - {"dead_ogonek", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"odiaeresis", 1}, - {"ȫ", 0}, - {"Otilde", 1}, - {"Ȭ", 0}, - {"egrave", 1}, - {"ḕ", 0}, - {"dead_greek", 12}, - {"a", 1}, - {"ᾱ", 0}, - {"i", 1}, - {"ῑ", 0}, - {"u", 1}, - {"ῡ", 0}, - {"A", 1}, - {"Ᾱ", 0}, - {"I", 1}, - {"Ῑ", 0}, - {"U", 1}, - {"Ῡ", 0}, - {"ograve", 1}, - {"ṑ", 0}, - {"Greek_alpha", 1}, - {"ᾱ", 0}, - {"dead_abovedot", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"Cyrillic_o", 1}, - {"о̄", 0}, - {"eacute", 1}, - {"ḗ", 0}, - {"v", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ō", 0}, - {"A", 1}, - {"Ā", 0}, - {"Odiaeresis", 1}, - {"Ȫ", 0}, - {"Cyrillic_A", 1}, - {"А̄", 0}, - {"Cyrillic_IE", 1}, - {"Е̄", 0}, - {"Egrave", 1}, - {"Ḕ", 0}, - {"dead_diaeresis", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"Adiaeresis", 1}, - {"Ǟ", 0}, - {"dead_acute", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"udiaeresis", 1}, - {"ǖ", 0}, - {"I", 1}, - {"Ī", 0}, - {"U", 1}, - {"Ū", 0}, - {"Cyrillic_u", 1}, - {"ӯ", 0}, - {"ae", 1}, - {"ǣ", 0}, - {"Greek_UPSILON", 1}, - {"Ῡ", 0}, - {"dead_doublegrave", 24}, - {"Cyrillic_er", 1}, - {"р̏", 0}, - {"Cyrillic_I", 1}, - {"И̏", 0}, - {"Cyrillic_O", 1}, - {"О̏", 0}, - {"Cyrillic_a", 1}, - {"а̏", 0}, - {"Cyrillic_ER", 1}, - {"Р̏", 0}, - {"Cyrillic_U", 1}, - {"У̏", 0}, - {"Cyrillic_ie", 1}, - {"е̏", 0}, - {"Cyrillic_i", 1}, - {"и̏", 0}, - {"Cyrillic_o", 1}, - {"о̏", 0}, - {"Cyrillic_A", 1}, - {"А̏", 0}, - {"Cyrillic_IE", 1}, - {"Е̏", 0}, - {"Cyrillic_u", 1}, - {"у̏", 0}, - {"Multi_key", 5833}, - {"backslash", 5}, - {"minus", 1}, - {"⍀", 0}, - {"o", 2}, - {"slash", 1}, - {"🙌", 0}, - {"minus", 59}, - {"backslash", 1}, - {"⍀", 0}, - {"minus", 6}, - {"minus", 1}, - {"—", 0}, - {"period", 1}, - {"–", 0}, - {"space", 1}, - {"­", 0}, - {"a", 1}, - {"ā", 0}, - {"e", 1}, - {"ē", 0}, - {"o", 1}, - {"ō", 0}, - {"l", 1}, - {"£", 0}, - {"space", 1}, - {"~", 0}, - {"y", 1}, - {"¥", 0}, - {"i", 1}, - {"ī", 0}, - {"parenright", 1}, - {"}", 0}, - {"u", 1}, - {"ū", 0}, - {"E", 1}, - {"Ē", 0}, - {"Y", 1}, - {"¥", 0}, - {"d", 1}, - {"đ", 0}, - {"D", 1}, - {"Đ", 0}, - {"plus", 1}, - {"±", 0}, - {"colon", 1}, - {"÷", 0}, - {"O", 1}, - {"Ō", 0}, - {"A", 1}, - {"Ā", 0}, - {"L", 1}, - {"£", 0}, - {"comma", 1}, - {"¬", 0}, - {"slash", 1}, - {"⌿", 0}, - {"greater", 1}, - {"→", 0}, - {"parenleft", 1}, - {"{", 0}, - {"I", 1}, - {"Ī", 0}, - {"U", 1}, - {"Ū", 0}, - {"asciicircum", 1}, - {"¯", 0}, - {"period", 130}, - {"minus", 1}, - {"·", 0}, - {"period", 1}, - {"…", 0}, - {"W", 1}, - {"Ẇ", 0}, - {"g", 1}, - {"ġ", 0}, - {"a", 1}, - {"ȧ", 0}, - {"C", 1}, - {"Ċ", 0}, - {"exclam", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"less", 1}, - {"‹", 0}, - {"e", 1}, - {"ė", 0}, - {"F", 1}, - {"Ḟ", 0}, - {"o", 1}, - {"ȯ", 0}, - {"t", 1}, - {"ṫ", 0}, - {"dead_belowdot", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"y", 1}, - {"ẏ", 0}, - {"b", 1}, - {"ḃ", 0}, - {"i", 1}, - {"ı", 0}, - {"n", 1}, - {"ṅ", 0}, - {"equal", 1}, - {"•", 0}, - {"dead_caron", 4}, - {"S", 1}, - {"Ṧ", 0}, - {"s", 1}, - {"ṧ", 0}, - {"x", 1}, - {"ẋ", 0}, - {"z", 1}, - {"ż", 0}, - {"G", 1}, - {"Ġ", 0}, - {"Sacute", 1}, - {"Ṥ", 0}, - {"H", 1}, - {"Ḣ", 0}, - {"E", 1}, - {"Ė", 0}, - {"S", 1}, - {"Ṡ", 0}, - {"Y", 1}, - {"Ẏ", 0}, - {"scaron", 1}, - {"ṧ", 0}, - {"f", 1}, - {"ḟ", 0}, - {"d", 1}, - {"ḋ", 0}, - {"Scaron", 1}, - {"Ṧ", 0}, - {"D", 1}, - {"Ḋ", 0}, - {"acute", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"w", 1}, - {"ẇ", 0}, - {"p", 1}, - {"ṗ", 0}, - {"P", 1}, - {"Ṗ", 0}, - {"apostrophe", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"M", 1}, - {"Ṁ", 0}, - {"O", 1}, - {"Ȯ", 0}, - {"m", 1}, - {"ṁ", 0}, - {"r", 1}, - {"ṙ", 0}, - {"s", 1}, - {"ṡ", 0}, - {"Z", 1}, - {"Ż", 0}, - {"sacute", 1}, - {"ṥ", 0}, - {"A", 1}, - {"Ȧ", 0}, - {"R", 1}, - {"Ṙ", 0}, - {"c", 1}, - {"ċ", 0}, - {"T", 1}, - {"Ṫ", 0}, - {"greater", 1}, - {"›", 0}, - {"B", 1}, - {"Ḃ", 0}, - {"dead_acute", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"X", 1}, - {"Ẋ", 0}, - {"h", 1}, - {"ḣ", 0}, - {"I", 1}, - {"İ", 0}, - {"N", 1}, - {"Ṅ", 0}, - {"asciicircum", 1}, - {"·", 0}, - {"W", 4}, - {"equal", 1}, - {"₩", 0}, - {"asciicircum", 1}, - {"Ŵ", 0}, - {"g", 10}, - {"period", 1}, - {"ġ", 0}, - {"breve", 1}, - {"ğ", 0}, - {"comma", 1}, - {"ģ", 0}, - {"parenleft", 1}, - {"ğ", 0}, - {"U", 1}, - {"ğ", 0}, - {"a", 30}, - {"minus", 1}, - {"ā", 0}, - {"a", 1}, - {"å", 0}, - {"e", 1}, - {"æ", 0}, - {"diaeresis", 1}, - {"ä", 0}, - {"quotedbl", 1}, - {"ä", 0}, - {"acute", 1}, - {"á", 0}, - {"underscore", 1}, - {"ā", 0}, - {"apostrophe", 1}, - {"á", 0}, - {"asterisk", 1}, - {"å", 0}, - {"comma", 1}, - {"ą", 0}, - {"asciitilde", 1}, - {"ã", 0}, - {"greater", 1}, - {"â", 0}, - {"parenleft", 1}, - {"ă", 0}, - {"grave", 1}, - {"à", 0}, - {"asciicircum", 1}, - {"â", 0}, - {"Greek_IOTA", 4}, - {"quotedbl", 1}, - {"Ϊ", 0}, - {"apostrophe", 1}, - {"Ί", 0}, - {"Greek_iota", 485}, - {"dead_grave", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_eta", 1}, - {"ῂ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"Greek_alpha", 1}, - {"ᾲ", 0}, - {"Greek_omega", 1}, - {"ῲ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"dead_tilde", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_eta", 1}, - {"ῇ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"Greek_alpha", 1}, - {"ᾷ", 0}, - {"Greek_omega", 1}, - {"ῷ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾈ", 0}, - {"Greek_eta", 1}, - {"ᾐ", 0}, - {"Greek_alpha", 1}, - {"ᾀ", 0}, - {"Greek_ETA", 1}, - {"ᾘ", 0}, - {"Greek_omega", 1}, - {"ᾠ", 0}, - {"Greek_OMEGA", 1}, - {"ᾨ", 0}, - {"Greek_ALPHA", 1}, - {"ᾼ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾉ", 0}, - {"Greek_eta", 1}, - {"ᾑ", 0}, - {"Greek_alpha", 1}, - {"ᾁ", 0}, - {"Greek_ETA", 1}, - {"ᾙ", 0}, - {"Greek_omega", 1}, - {"ᾡ", 0}, - {"Greek_OMEGA", 1}, - {"ᾩ", 0}, - {"Greek_eta", 1}, - {"ῃ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾈ", 0}, - {"Greek_eta", 1}, - {"ᾐ", 0}, - {"Greek_alpha", 1}, - {"ᾀ", 0}, - {"Greek_ETA", 1}, - {"ᾘ", 0}, - {"Greek_omega", 1}, - {"ᾠ", 0}, - {"Greek_OMEGA", 1}, - {"ᾨ", 0}, - {"quotedbl", 1}, - {"ϊ", 0}, - {"Greek_alpha", 1}, - {"ᾳ", 0}, - {"acute", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_ETA", 1}, - {"ῌ", 0}, - {"apostrophe", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_omegaaccent", 1}, - {"ῴ", 0}, - {"asciitilde", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_eta", 1}, - {"ῇ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"Greek_alpha", 1}, - {"ᾷ", 0}, - {"Greek_omega", 1}, - {"ῷ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_omega", 1}, - {"ῳ", 0}, - {"Greek_OMEGA", 1}, - {"ῼ", 0}, - {"dead_acute", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_alphaaccent", 1}, - {"ᾴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾉ", 0}, - {"Greek_eta", 1}, - {"ᾑ", 0}, - {"Greek_alpha", 1}, - {"ᾁ", 0}, - {"Greek_ETA", 1}, - {"ᾙ", 0}, - {"Greek_omega", 1}, - {"ᾡ", 0}, - {"Greek_OMEGA", 1}, - {"ᾩ", 0}, - {"grave", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_eta", 1}, - {"ῂ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"Greek_alpha", 1}, - {"ᾲ", 0}, - {"Greek_omega", 1}, - {"ῲ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_etaaccent", 1}, - {"ῄ", 0}, - {"1", 21}, - {"1", 2}, - {"0", 1}, - {"⅒", 0}, - {"7", 1}, - {"⅐", 0}, - {"8", 1}, - {"⅛", 0}, - {"3", 1}, - {"⅓", 0}, - {"2", 1}, - {"½", 0}, - {"6", 1}, - {"⅙", 0}, - {"4", 1}, - {"¼", 0}, - {"5", 1}, - {"⅕", 0}, - {"9", 1}, - {"⅑", 0}, - {"asciicircum", 1}, - {"¹", 0}, - {"Greek_OMICRON", 2}, - {"apostrophe", 1}, - {"Ό", 0}, - {"C", 26}, - {"period", 1}, - {"Ċ", 0}, - {"C", 3}, - {"C", 2}, - {"P", 1}, - {"☭", 0}, - {"less", 1}, - {"Č", 0}, - {"o", 1}, - {"©", 0}, - {"equal", 1}, - {"€", 0}, - {"E", 1}, - {"₠", 0}, - {"apostrophe", 1}, - {"Ć", 0}, - {"O", 1}, - {"©", 0}, - {"r", 1}, - {"₢", 0}, - {"bar", 1}, - {"¢", 0}, - {"comma", 1}, - {"Ç", 0}, - {"slash", 1}, - {"₡", 0}, - {"exclam", 108}, - {"W", 1}, - {"Ẉ", 0}, - {"a", 1}, - {"ạ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"exclam", 1}, - {"¡", 0}, - {"e", 1}, - {"ẹ", 0}, - {"o", 1}, - {"ọ", 0}, - {"l", 1}, - {"ḷ", 0}, - {"t", 1}, - {"ṭ", 0}, - {"uhorn", 1}, - {"ự", 0}, - {"y", 1}, - {"ỵ", 0}, - {"b", 1}, - {"ḅ", 0}, - {"i", 1}, - {"ị", 0}, - {"k", 1}, - {"ḳ", 0}, - {"n", 1}, - {"ṇ", 0}, - {"Ohorn", 1}, - {"Ợ", 0}, - {"ohorn", 1}, - {"ợ", 0}, - {"V", 1}, - {"Ṿ", 0}, - {"u", 1}, - {"ụ", 0}, - {"z", 1}, - {"ẓ", 0}, - {"H", 1}, - {"Ḥ", 0}, - {"E", 1}, - {"Ẹ", 0}, - {"S", 1}, - {"Ṣ", 0}, - {"Y", 1}, - {"Ỵ", 0}, - {"d", 1}, - {"ḍ", 0}, - {"D", 1}, - {"Ḍ", 0}, - {"plus", 8}, - {"o", 1}, - {"ợ", 0}, - {"u", 1}, - {"ự", 0}, - {"O", 1}, - {"Ợ", 0}, - {"U", 1}, - {"Ự", 0}, - {"w", 1}, - {"ẉ", 0}, - {"v", 1}, - {"ṿ", 0}, - {"question", 1}, - {"‽", 0}, - {"M", 1}, - {"Ṃ", 0}, - {"O", 1}, - {"Ọ", 0}, - {"m", 1}, - {"ṃ", 0}, - {"r", 1}, - {"ṛ", 0}, - {"s", 1}, - {"ṣ", 0}, - {"Z", 1}, - {"Ẓ", 0}, - {"A", 1}, - {"Ạ", 0}, - {"R", 1}, - {"Ṛ", 0}, - {"L", 1}, - {"Ḷ", 0}, - {"T", 1}, - {"Ṭ", 0}, - {"K", 1}, - {"Ḳ", 0}, - {"B", 1}, - {"Ḅ", 0}, - {"Uhorn", 1}, - {"Ự", 0}, - {"h", 1}, - {"ḥ", 0}, - {"I", 1}, - {"Ị", 0}, - {"N", 1}, - {"Ṇ", 0}, - {"U", 1}, - {"Ụ", 0}, - {"asciicircum", 1}, - {"¦", 0}, - {"less", 56}, - {"minus", 1}, - {"←", 0}, - {"C", 1}, - {"Č", 0}, - {"less", 1}, - {"«", 0}, - {"e", 1}, - {"ě", 0}, - {"l", 1}, - {"ľ", 0}, - {"t", 1}, - {"ť", 0}, - {"space", 1}, - {"ˇ", 0}, - {"n", 1}, - {"ň", 0}, - {"equal", 1}, - {"≤", 0}, - {"z", 1}, - {"ž", 0}, - {"3", 1}, - {"♥", 0}, - {"E", 1}, - {"Ě", 0}, - {"S", 1}, - {"Š", 0}, - {"d", 1}, - {"ď", 0}, - {"D", 1}, - {"Ď", 0}, - {"quotedbl", 1}, - {"“", 0}, - {"underscore", 1}, - {"≤", 0}, - {"apostrophe", 1}, - {"‘", 0}, - {"r", 1}, - {"ř", 0}, - {"s", 1}, - {"š", 0}, - {"Z", 1}, - {"Ž", 0}, - {"R", 1}, - {"Ř", 0}, - {"c", 1}, - {"č", 0}, - {"L", 1}, - {"Ľ", 0}, - {"T", 1}, - {"Ť", 0}, - {"slash", 1}, - {"\\", 0}, - {"greater", 1}, - {"⋄", 0}, - {"N", 1}, - {"Ň", 0}, - {"KP_Divide", 46}, - {"g", 1}, - {"ǥ", 0}, - {"o", 1}, - {"ø", 0}, - {"l", 1}, - {"ł", 0}, - {"t", 1}, - {"ŧ", 0}, - {"b", 1}, - {"ƀ", 0}, - {"i", 1}, - {"ɨ", 0}, - {"Cyrillic_GHE", 1}, - {"Ғ", 0}, - {"leftarrow", 1}, - {"↚", 0}, - {"Cyrillic_KA", 1}, - {"Ҟ", 0}, - {"rightarrow", 1}, - {"↛", 0}, - {"z", 1}, - {"ƶ", 0}, - {"G", 1}, - {"Ǥ", 0}, - {"H", 1}, - {"Ħ", 0}, - {"d", 1}, - {"đ", 0}, - {"Cyrillic_ka", 1}, - {"ҟ", 0}, - {"D", 1}, - {"Đ", 0}, - {"O", 1}, - {"Ø", 0}, - {"Z", 1}, - {"Ƶ", 0}, - {"L", 1}, - {"Ł", 0}, - {"T", 1}, - {"Ŧ", 0}, - {"Cyrillic_ghe", 1}, - {"ғ", 0}, - {"h", 1}, - {"ħ", 0}, - {"I", 1}, - {"Ɨ", 0}, - {"F", 8}, - {"period", 1}, - {"Ḟ", 0}, - {"l", 1}, - {"ffl", 0}, - {"i", 1}, - {"ffi", 0}, - {"r", 1}, - {"₣", 0}, - {"e", 28}, - {"minus", 1}, - {"ē", 0}, - {"period", 1}, - {"ė", 0}, - {"less", 1}, - {"ě", 0}, - {"e", 1}, - {"ə", 0}, - {"diaeresis", 1}, - {"ë", 0}, - {"equal", 1}, - {"€", 0}, - {"quotedbl", 1}, - {"ë", 0}, - {"acute", 1}, - {"é", 0}, - {"underscore", 1}, - {"ē", 0}, - {"apostrophe", 1}, - {"é", 0}, - {"comma", 1}, - {"ę", 0}, - {"greater", 1}, - {"ê", 0}, - {"grave", 1}, - {"è", 0}, - {"asciicircum", 1}, - {"ê", 0}, - {"o", 52}, - {"minus", 1}, - {"ō", 0}, - {"a", 1}, - {"å", 0}, - {"C", 1}, - {"©", 0}, - {"e", 1}, - {"œ", 0}, - {"o", 1}, - {"°", 0}, - {"diaeresis", 1}, - {"ö", 0}, - {"y", 1}, - {"ẙ", 0}, - {"x", 1}, - {"¤", 0}, - {"u", 1}, - {"ů", 0}, - {"quotedbl", 1}, - {"ö", 0}, - {"acute", 1}, - {"ó", 0}, - {"w", 1}, - {"ẘ", 0}, - {"underscore", 1}, - {"ō", 0}, - {"apostrophe", 1}, - {"ó", 0}, - {"r", 1}, - {"®", 0}, - {"s", 1}, - {"§", 0}, - {"A", 1}, - {"Å", 0}, - {"R", 1}, - {"®", 0}, - {"c", 1}, - {"©", 0}, - {"asciitilde", 1}, - {"õ", 0}, - {"slash", 1}, - {"ø", 0}, - {"greater", 1}, - {"ô", 0}, - {"X", 1}, - {"¤", 0}, - {"grave", 1}, - {"ò", 0}, - {"U", 1}, - {"Ů", 0}, - {"asciicircum", 1}, - {"ô", 0}, - {"l", 12}, - {"minus", 1}, - {"£", 0}, - {"less", 1}, - {"ľ", 0}, - {"v", 1}, - {"|", 0}, - {"apostrophe", 1}, - {"ĺ", 0}, - {"comma", 1}, - {"ļ", 0}, - {"slash", 1}, - {"ł", 0}, - {"Greek_upsilon", 4}, - {"quotedbl", 1}, - {"ϋ", 0}, - {"apostrophe", 1}, - {"ύ", 0}, - {"t", 16}, - {"minus", 1}, - {"ŧ", 0}, - {"period", 1}, - {"ṫ", 0}, - {"less", 1}, - {"ť", 0}, - {"M", 1}, - {"™", 0}, - {"m", 1}, - {"™", 0}, - {"comma", 1}, - {"ţ", 0}, - {"slash", 1}, - {"ŧ", 0}, - {"h", 1}, - {"þ", 0}, - {"diaeresis", 42}, - {"a", 1}, - {"ä", 0}, - {"dead_grave", 1}, - {"῭", 0}, - {"e", 1}, - {"ë", 0}, - {"o", 1}, - {"ö", 0}, - {"y", 1}, - {"ÿ", 0}, - {"i", 1}, - {"ï", 0}, - {"dead_tilde", 1}, - {"῁", 0}, - {"u", 1}, - {"ü", 0}, - {"E", 1}, - {"Ë", 0}, - {"Y", 1}, - {"Ÿ", 0}, - {"acute", 1}, - {"΅", 0}, - {"apostrophe", 1}, - {"΅", 0}, - {"O", 1}, - {"Ö", 0}, - {"asterisk", 1}, - {"⍣", 0}, - {"A", 1}, - {"Ä", 0}, - {"asciitilde", 1}, - {"῁", 0}, - {"greater", 1}, - {"⍩", 0}, - {"dead_acute", 1}, - {"΅", 0}, - {"I", 1}, - {"Ï", 0}, - {"grave", 1}, - {"῭", 0}, - {"U", 1}, - {"Ü", 0}, - {"space", 22}, - {"minus", 1}, - {"~", 0}, - {"period", 1}, - {" ", 0}, - {"less", 1}, - {"ˇ", 0}, - {"space", 1}, - {" ", 0}, - {"apostrophe", 1}, - {"'", 0}, - {"comma", 1}, - {"¸", 0}, - {"asciitilde", 1}, - {"~", 0}, - {"greater", 1}, - {"^", 0}, - {"parenleft", 1}, - {"˘", 0}, - {"grave", 1}, - {"`", 0}, - {"asciicircum", 1}, - {"^", 0}, - {"percent", 2}, - {"o", 1}, - {"‰", 0}, - {"y", 14}, - {"minus", 1}, - {"¥", 0}, - {"diaeresis", 1}, - {"ÿ", 0}, - {"equal", 1}, - {"¥", 0}, - {"quotedbl", 1}, - {"ÿ", 0}, - {"acute", 1}, - {"ý", 0}, - {"apostrophe", 1}, - {"ý", 0}, - {"asciicircum", 1}, - {"ŷ", 0}, - {"b", 83}, - {"period", 1}, - {"ḃ", 0}, - {"g", 1}, - {"ğ", 0}, - {"a", 1}, - {"ă", 0}, - {"Greek_IOTA", 1}, - {"Ῐ", 0}, - {"Greek_iota", 1}, - {"ῐ", 0}, - {"exclam", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"e", 1}, - {"ĕ", 0}, - {"o", 1}, - {"ŏ", 0}, - {"Greek_upsilon", 1}, - {"ῠ", 0}, - {"dead_belowdot", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"Cyrillic_I", 1}, - {"Й", 0}, - {"i", 1}, - {"ĭ", 0}, - {"Cyrillic_a", 1}, - {"ӑ", 0}, - {"Cyrillic_U", 1}, - {"Ў", 0}, - {"u", 1}, - {"ŭ", 0}, - {"G", 1}, - {"Ğ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾰ", 0}, - {"Cyrillic_ie", 1}, - {"ӗ", 0}, - {"E", 1}, - {"Ĕ", 0}, - {"Cyrillic_i", 1}, - {"й", 0}, - {"Cyrillic_zhe", 1}, - {"ӂ", 0}, - {"cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"Greek_alpha", 1}, - {"ᾰ", 0}, - {"O", 1}, - {"Ŏ", 0}, - {"A", 1}, - {"Ă", 0}, - {"Cyrillic_A", 1}, - {"Ӑ", 0}, - {"comma", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӂ", 0}, - {"Cyrillic_IE", 1}, - {"Ӗ", 0}, - {"dead_cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"I", 1}, - {"Ĭ", 0}, - {"U", 1}, - {"Ŭ", 0}, - {"Cyrillic_u", 1}, - {"ў", 0}, - {"Greek_UPSILON", 1}, - {"Ῠ", 0}, - {"i", 28}, - {"minus", 1}, - {"ī", 0}, - {"period", 1}, - {"ı", 0}, - {"diaeresis", 1}, - {"ï", 0}, - {"j", 1}, - {"ij", 0}, - {"quotedbl", 1}, - {"ï", 0}, - {"acute", 1}, - {"í", 0}, - {"underscore", 1}, - {"ī", 0}, - {"apostrophe", 1}, - {"í", 0}, - {"comma", 1}, - {"į", 0}, - {"asciitilde", 1}, - {"ĩ", 0}, - {"greater", 1}, - {"î", 0}, - {"semicolon", 1}, - {"į", 0}, - {"grave", 1}, - {"ì", 0}, - {"asciicircum", 1}, - {"î", 0}, - {"k", 4}, - {"k", 1}, - {"ĸ", 0}, - {"comma", 1}, - {"ķ", 0}, - {"n", 10}, - {"g", 1}, - {"ŋ", 0}, - {"less", 1}, - {"ň", 0}, - {"apostrophe", 1}, - {"ń", 0}, - {"comma", 1}, - {"ņ", 0}, - {"asciitilde", 1}, - {"ñ", 0}, - {"equal", 40}, - {"W", 1}, - {"₩", 0}, - {"C", 1}, - {"€", 0}, - {"e", 1}, - {"€", 0}, - {"o", 1}, - {"ő", 0}, - {"y", 1}, - {"¥", 0}, - {"Cyrillic_U", 1}, - {"Ӳ", 0}, - {"u", 1}, - {"ű", 0}, - {"E", 1}, - {"€", 0}, - {"Y", 1}, - {"¥", 0}, - {"d", 1}, - {"₫", 0}, - {"underscore", 1}, - {"≡", 0}, - {"O", 1}, - {"Ő", 0}, - {"Cyrillic_ES", 1}, - {"€", 0}, - {"c", 1}, - {"€", 0}, - {"L", 1}, - {"₤", 0}, - {"slash", 1}, - {"≠", 0}, - {"Cyrillic_IE", 1}, - {"€", 0}, - {"N", 1}, - {"₦", 0}, - {"U", 1}, - {"Ű", 0}, - {"Cyrillic_u", 1}, - {"ӳ", 0}, - {"7", 2}, - {"8", 1}, - {"⅞", 0}, - {"parenright", 32}, - {"minus", 1}, - {"}", 0}, - {"Greek_IOTA", 1}, - {"Ἰ", 0}, - {"Greek_iota", 1}, - {"ἰ", 0}, - {"Greek_OMICRON", 1}, - {"Ὀ", 0}, - {"Greek_upsilon", 1}, - {"ὐ", 0}, - {"parenright", 1}, - {"]", 0}, - {"Greek_epsilon", 1}, - {"ἐ", 0}, - {"Greek_ALPHA", 1}, - {"Ἀ", 0}, - {"Greek_omicron", 1}, - {"ὀ", 0}, - {"Greek_eta", 1}, - {"ἠ", 0}, - {"Greek_rho", 1}, - {"ῤ", 0}, - {"Greek_alpha", 1}, - {"ἀ", 0}, - {"Greek_ETA", 1}, - {"Ἠ", 0}, - {"Greek_EPSILON", 1}, - {"Ἐ", 0}, - {"Greek_omega", 1}, - {"ὠ", 0}, - {"Greek_OMEGA", 1}, - {"Ὠ", 0}, - {"x", 6}, - {"o", 1}, - {"¤", 0}, - {"x", 1}, - {"×", 0}, - {"O", 1}, - {"¤", 0}, - {"Greek_epsilon", 2}, - {"apostrophe", 1}, - {"έ", 0}, - {"braceleft", 2}, - {"braceright", 1}, - {"∅", 0}, - {"underbar", 54}, - {"1", 1}, - {"₁", 0}, - {"KP_4", 1}, - {"₄", 0}, - {"KP_6", 1}, - {"₆", 0}, - {"KP_8", 1}, - {"₈", 0}, - {"KP_9", 1}, - {"₉", 0}, - {"equal", 1}, - {"₌", 0}, - {"KP_Space", 1}, - {"₂", 0}, - {"7", 1}, - {"₇", 0}, - {"parenright", 1}, - {"₎", 0}, - {"KP_7", 1}, - {"₇", 0}, - {"8", 1}, - {"₈", 0}, - {"KP_1", 1}, - {"₁", 0}, - {"3", 1}, - {"₃", 0}, - {"2", 1}, - {"₂", 0}, - {"plus", 1}, - {"₊", 0}, - {"6", 1}, - {"₆", 0}, - {"4", 1}, - {"₄", 0}, - {"KP_3", 1}, - {"₃", 0}, - {"KP_0", 1}, - {"₀", 0}, - {"KP_Add", 1}, - {"₊", 0}, - {"KP_2", 1}, - {"₂", 0}, - {"5", 1}, - {"₅", 0}, - {"KP_5", 1}, - {"₅", 0}, - {"9", 1}, - {"₉", 0}, - {"0", 1}, - {"₀", 0}, - {"parenleft", 1}, - {"₍", 0}, - {"KP_Equal", 1}, - {"₌", 0}, - {"V", 2}, - {"L", 1}, - {"|", 0}, - {"u", 28}, - {"minus", 1}, - {"ū", 0}, - {"diaeresis", 1}, - {"ü", 0}, - {"u", 1}, - {"ŭ", 0}, - {"quotedbl", 1}, - {"ü", 0}, - {"acute", 1}, - {"ú", 0}, - {"underscore", 1}, - {"ū", 0}, - {"apostrophe", 1}, - {"ú", 0}, - {"asterisk", 1}, - {"ů", 0}, - {"comma", 1}, - {"ų", 0}, - {"asciitilde", 1}, - {"ũ", 0}, - {"slash", 1}, - {"µ", 0}, - {"greater", 1}, - {"û", 0}, - {"grave", 1}, - {"ù", 0}, - {"asciicircum", 1}, - {"û", 0}, - {"breve", 4}, - {"g", 1}, - {"ğ", 0}, - {"G", 1}, - {"Ğ", 0}, - {"z", 6}, - {"period", 1}, - {"ż", 0}, - {"less", 1}, - {"ž", 0}, - {"apostrophe", 1}, - {"ź", 0}, - {"G", 10}, - {"period", 1}, - {"Ġ", 0}, - {"breve", 1}, - {"Ğ", 0}, - {"comma", 1}, - {"Ģ", 0}, - {"parenleft", 1}, - {"Ğ", 0}, - {"U", 1}, - {"Ğ", 0}, - {"Greek_ALPHA", 2}, - {"apostrophe", 1}, - {"Ά", 0}, - {"bracketleft", 2}, - {"bracketright", 1}, - {"⌷", 0}, - {"H", 2}, - {"comma", 1}, - {"Ḩ", 0}, - {"8", 2}, - {"8", 1}, - {"∞", 0}, - {"3", 8}, - {"8", 1}, - {"⅜", 0}, - {"4", 1}, - {"¾", 0}, - {"5", 1}, - {"⅗", 0}, - {"asciicircum", 1}, - {"³", 0}, - {"E", 26}, - {"minus", 1}, - {"Ē", 0}, - {"period", 1}, - {"Ė", 0}, - {"less", 1}, - {"Ě", 0}, - {"diaeresis", 1}, - {"Ë", 0}, - {"equal", 1}, - {"€", 0}, - {"quotedbl", 1}, - {"Ë", 0}, - {"acute", 1}, - {"É", 0}, - {"underscore", 1}, - {"Ē", 0}, - {"apostrophe", 1}, - {"É", 0}, - {"comma", 1}, - {"Ę", 0}, - {"greater", 1}, - {"Ê", 0}, - {"grave", 1}, - {"È", 0}, - {"asciicircum", 1}, - {"Ê", 0}, - {"S", 18}, - {"period", 1}, - {"Ṡ", 0}, - {"exclam", 1}, - {"§", 0}, - {"less", 1}, - {"Š", 0}, - {"S", 1}, - {"ẞ", 0}, - {"apostrophe", 1}, - {"Ś", 0}, - {"M", 1}, - {"℠", 0}, - {"O", 1}, - {"§", 0}, - {"m", 1}, - {"℠", 0}, - {"comma", 1}, - {"Ş", 0}, - {"2", 6}, - {"3", 1}, - {"⅔", 0}, - {"5", 1}, - {"⅖", 0}, - {"asciicircum", 1}, - {"²", 0}, - {"Y", 14}, - {"minus", 1}, - {"¥", 0}, - {"diaeresis", 1}, - {"Ÿ", 0}, - {"equal", 1}, - {"¥", 0}, - {"quotedbl", 1}, - {"Ÿ", 0}, - {"acute", 1}, - {"Ý", 0}, - {"apostrophe", 1}, - {"Ý", 0}, - {"asciicircum", 1}, - {"Ŷ", 0}, - {"f", 12}, - {"period", 1}, - {"ḟ", 0}, - {"l", 1}, - {"fl", 0}, - {"i", 1}, - {"fi", 0}, - {"S", 1}, - {"ſ", 0}, - {"f", 1}, - {"ff", 0}, - {"s", 1}, - {"ſ", 0}, - {"Greek_omicron", 2}, - {"apostrophe", 1}, - {"ό", 0}, - {"Greek_eta", 2}, - {"apostrophe", 1}, - {"ή", 0}, - {"d", 14}, - {"minus", 1}, - {"đ", 0}, - {"period", 1}, - {"ḋ", 0}, - {"less", 1}, - {"ď", 0}, - {"i", 1}, - {"⌀", 0}, - {"equal", 1}, - {"₫", 0}, - {"comma", 1}, - {"ḑ", 0}, - {"h", 1}, - {"ð", 0}, - {"D", 10}, - {"minus", 1}, - {"Đ", 0}, - {"period", 1}, - {"Ḋ", 0}, - {"less", 1}, - {"Ď", 0}, - {"H", 1}, - {"Ð", 0}, - {"comma", 1}, - {"Ḑ", 0}, - {"quotedbl", 137}, - {"W", 1}, - {"Ẅ", 0}, - {"a", 1}, - {"ä", 0}, - {"Greek_IOTA", 1}, - {"Ϊ", 0}, - {"Greek_iota", 1}, - {"ϊ", 0}, - {"less", 1}, - {"“", 0}, - {"Umacron", 1}, - {"Ṻ", 0}, - {"Cyrillic_ZE", 1}, - {"Ӟ", 0}, - {"e", 1}, - {"ë", 0}, - {"o", 1}, - {"ö", 0}, - {"Cyrillic_ze", 1}, - {"ӟ", 0}, - {"t", 1}, - {"ẗ", 0}, - {"Greek_upsilon", 1}, - {"ϋ", 0}, - {"dead_macron", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"Cyrillic_I", 1}, - {"Ӥ", 0}, - {"y", 1}, - {"ÿ", 0}, - {"Cyrillic_O", 1}, - {"Ӧ", 0}, - {"i", 1}, - {"ï", 0}, - {"Ukrainian_I", 1}, - {"Ї", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ṏ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"Cyrillic_che", 1}, - {"ӵ", 0}, - {"Cyrillic_a", 1}, - {"ӓ", 0}, - {"x", 1}, - {"ẍ", 0}, - {"Cyrillic_U", 1}, - {"Ӱ", 0}, - {"u", 1}, - {"ü", 0}, - {"otilde", 1}, - {"ṏ", 0}, - {"H", 1}, - {"Ḧ", 0}, - {"Cyrillic_YERU", 1}, - {"Ӹ", 0}, - {"Cyrillic_ie", 1}, - {"ё", 0}, - {"E", 1}, - {"Ë", 0}, - {"Y", 1}, - {"Ÿ", 0}, - {"Cyrillic_i", 1}, - {"ӥ", 0}, - {"Otilde", 1}, - {"Ṏ", 0}, - {"Cyrillic_zhe", 1}, - {"ӝ", 0}, - {"quotedbl", 1}, - {"¨", 0}, - {"umacron", 1}, - {"ṻ", 0}, - {"Cyrillic_yeru", 1}, - {"ӹ", 0}, - {"acute", 1}, - {"̈́", 0}, - {"w", 1}, - {"ẅ", 0}, - {"Cyrillic_CHE", 1}, - {"Ӵ", 0}, - {"Cyrillic_o", 1}, - {"ӧ", 0}, - {"Ukrainian_i", 1}, - {"ї", 0}, - {"Cyrillic_E", 1}, - {"Ӭ", 0}, - {"underscore", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"apostrophe", 1}, - {"̈́", 0}, - {"O", 1}, - {"Ö", 0}, - {"macron", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"A", 1}, - {"Ä", 0}, - {"Cyrillic_A", 1}, - {"Ӓ", 0}, - {"comma", 1}, - {"„", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ṏ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"greater", 1}, - {"”", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӝ", 0}, - {"Cyrillic_IE", 1}, - {"Ё", 0}, - {"Cyrillic_e", 1}, - {"ӭ", 0}, - {"dead_acute", 1}, - {"̈́", 0}, - {"X", 1}, - {"Ẍ", 0}, - {"h", 1}, - {"ḧ", 0}, - {"I", 1}, - {"Ï", 0}, - {"U", 1}, - {"Ü", 0}, - {"Cyrillic_u", 1}, - {"ӱ", 0}, - {"Greek_UPSILON", 1}, - {"Ϋ", 0}, - {"plus", 12}, - {"minus", 1}, - {"±", 0}, - {"o", 1}, - {"ơ", 0}, - {"u", 1}, - {"ư", 0}, - {"plus", 1}, - {"#", 0}, - {"O", 1}, - {"Ơ", 0}, - {"U", 1}, - {"Ư", 0}, - {"cedilla", 44}, - {"g", 1}, - {"ģ", 0}, - {"C", 1}, - {"Ç", 0}, - {"e", 1}, - {"ȩ", 0}, - {"l", 1}, - {"ļ", 0}, - {"t", 1}, - {"ţ", 0}, - {"k", 1}, - {"ķ", 0}, - {"n", 1}, - {"ņ", 0}, - {"G", 1}, - {"Ģ", 0}, - {"H", 1}, - {"Ḩ", 0}, - {"E", 1}, - {"Ȩ", 0}, - {"S", 1}, - {"Ş", 0}, - {"d", 1}, - {"ḑ", 0}, - {"D", 1}, - {"Ḑ", 0}, - {"r", 1}, - {"ŗ", 0}, - {"s", 1}, - {"ş", 0}, - {"R", 1}, - {"Ŗ", 0}, - {"c", 1}, - {"ç", 0}, - {"L", 1}, - {"Ļ", 0}, - {"T", 1}, - {"Ţ", 0}, - {"K", 1}, - {"Ķ", 0}, - {"h", 1}, - {"ḩ", 0}, - {"N", 1}, - {"Ņ", 0}, - {"Greek_alpha", 2}, - {"apostrophe", 1}, - {"ά", 0}, - {"dead_abovedot", 3}, - {"f", 2}, - {"s", 1}, - {"ẛ", 0}, - {"acute", 463}, - {"W", 1}, - {"Ẃ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"g", 1}, - {"ǵ", 0}, - {"a", 1}, - {"á", 0}, - {"Greek_IOTA", 1}, - {"Ί", 0}, - {"Greek_iota", 1}, - {"ί", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_OMICRON", 1}, - {"Ό", 0}, - {"Acircumflex", 1}, - {"Ấ", 0}, - {"C", 1}, - {"Ć", 0}, - {"Cyrillic_er", 1}, - {"р́", 0}, - {"e", 1}, - {"é", 0}, - {"KP_Divide", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"Utilde", 1}, - {"Ṹ", 0}, - {"o", 1}, - {"ó", 0}, - {"l", 1}, - {"ĺ", 0}, - {"Udiaeresis", 1}, - {"Ǘ", 0}, - {"Greek_upsilon", 1}, - {"ύ", 0}, - {"uhorn", 1}, - {"ứ", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"acircumflex", 1}, - {"ấ", 0}, - {"Ecircumflex", 1}, - {"Ế", 0}, - {"Cyrillic_I", 1}, - {"И́", 0}, - {"y", 1}, - {"ý", 0}, - {"b", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"idiaeresis", 1}, - {"ḯ", 0}, - {"Cyrillic_O", 1}, - {"О́", 0}, - {"i", 1}, - {"í", 0}, - {"k", 1}, - {"ḱ", 0}, - {"n", 1}, - {"ń", 0}, - {"ccedilla", 1}, - {"ḉ", 0}, - {"Cyrillic_GHE", 1}, - {"Ѓ", 0}, - {"dead_tilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Cyrillic_a", 1}, - {"а́", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"Ohorn", 1}, - {"Ớ", 0}, - {"ohorn", 1}, - {"ớ", 0}, - {"Cyrillic_ER", 1}, - {"Р́", 0}, - {"Greek_epsilon", 1}, - {"έ", 0}, - {"Cyrillic_KA", 1}, - {"Ќ", 0}, - {"Cyrillic_U", 1}, - {"У́", 0}, - {"dead_abovering", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"Ocircumflex", 1}, - {"Ố", 0}, - {"AE", 1}, - {"Ǽ", 0}, - {"omacron", 1}, - {"ṓ", 0}, - {"ocircumflex", 1}, - {"ố", 0}, - {"u", 1}, - {"ú", 0}, - {"z", 1}, - {"ź", 0}, - {"G", 1}, - {"Ǵ", 0}, - {"Greek_ALPHA", 1}, - {"Ά", 0}, - {"otilde", 1}, - {"ṍ", 0}, - {"utilde", 1}, - {"ṹ", 0}, - {"Cyrillic_ie", 1}, - {"е́", 0}, - {"emacron", 1}, - {"ḗ", 0}, - {"E", 1}, - {"É", 0}, - {"S", 1}, - {"Ś", 0}, - {"Greek_iotadieresis", 1}, - {"ΐ", 0}, - {"Y", 1}, - {"Ý", 0}, - {"Cyrillic_i", 1}, - {"и́", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"Greek_upsilondieresis", 1}, - {"ΰ", 0}, - {"Greek_omicron", 1}, - {"ό", 0}, - {"Greek_eta", 1}, - {"ή", 0}, - {"Otilde", 1}, - {"Ṍ", 0}, - {"Cyrillic_ka", 1}, - {"ќ", 0}, - {"Aring", 1}, - {"Ǻ", 0}, - {"Abreve", 1}, - {"Ắ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"quotedbl", 12}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"plus", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_alpha", 1}, - {"ά", 0}, - {"ecircumflex", 1}, - {"ế", 0}, - {"w", 1}, - {"ẃ", 0}, - {"Greek_ETA", 1}, - {"Ή", 0}, - {"Cyrillic_o", 1}, - {"о́", 0}, - {"Emacron", 1}, - {"Ḗ", 0}, - {"Ooblique", 1}, - {"Ǿ", 0}, - {"p", 1}, - {"ṕ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"P", 1}, - {"Ṕ", 0}, - {"M", 1}, - {"Ḿ", 0}, - {"O", 1}, - {"Ó", 0}, - {"abreve", 1}, - {"ắ", 0}, - {"m", 1}, - {"ḿ", 0}, - {"r", 1}, - {"ŕ", 0}, - {"s", 1}, - {"ś", 0}, - {"Z", 1}, - {"Ź", 0}, - {"macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"A", 1}, - {"Á", 0}, - {"R", 1}, - {"Ŕ", 0}, - {"c", 1}, - {"ć", 0}, - {"Idiaeresis", 1}, - {"Ḯ", 0}, - {"L", 1}, - {"Ĺ", 0}, - {"Greek_EPSILON", 1}, - {"Έ", 0}, - {"Cyrillic_A", 1}, - {"А́", 0}, - {"comma", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"asciitilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Ccedilla", 1}, - {"Ḉ", 0}, - {"slash", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"aring", 1}, - {"ǻ", 0}, - {"K", 1}, - {"Ḱ", 0}, - {"Omacron", 1}, - {"Ṓ", 0}, - {"Cyrillic_IE", 1}, - {"Е́", 0}, - {"dead_cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_omega", 1}, - {"ώ", 0}, - {"dead_diaeresis", 12}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"Uhorn", 1}, - {"Ứ", 0}, - {"Greek_OMEGA", 1}, - {"Ώ", 0}, - {"oslash", 1}, - {"ǿ", 0}, - {"Cyrillic_ghe", 1}, - {"ѓ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"udiaeresis", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Í", 0}, - {"N", 1}, - {"Ń", 0}, - {"U", 1}, - {"Ú", 0}, - {"Cyrillic_u", 1}, - {"у́", 0}, - {"ae", 1}, - {"ǽ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_UPSILON", 1}, - {"Ύ", 0}, - {"Cyrillic_pe", 2}, - {"Cyrillic_a", 1}, - {"§", 0}, - {"w", 2}, - {"asciicircum", 1}, - {"ŵ", 0}, - {"Greek_ETA", 2}, - {"apostrophe", 1}, - {"Ή", 0}, - {"4", 2}, - {"5", 1}, - {"⅘", 0}, - {"bracketright", 2}, - {"bracketleft", 1}, - {"⌷", 0}, - {"colon", 6}, - {"minus", 1}, - {"÷", 0}, - {"parenright", 1}, - {"☺", 0}, - {"parenleft", 1}, - {"☹", 0}, - {"p", 4}, - {"period", 1}, - {"ṗ", 0}, - {"exclam", 1}, - {"¶", 0}, - {"underscore", 230}, - {"adiaeresis", 1}, - {"ǟ", 0}, - {"period", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"g", 1}, - {"ḡ", 0}, - {"a", 1}, - {"ā", 0}, - {"Greek_IOTA", 1}, - {"Ῑ", 0}, - {"Greek_iota", 1}, - {"ῑ", 0}, - {"1", 1}, - {"₁", 0}, - {"exclam", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"KP_4", 1}, - {"₄", 0}, - {"less", 1}, - {"≤", 0}, - {"Cyrillic_er", 1}, - {"р̄", 0}, - {"o", 1}, - {"ō", 0}, - {"e", 1}, - {"ē", 0}, - {"KP_6", 1}, - {"₆", 0}, - {"Udiaeresis", 1}, - {"Ǖ", 0}, - {"Greek_upsilon", 1}, - {"ῡ", 0}, - {"dead_belowdot", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"KP_8", 1}, - {"₈", 0}, - {"Cyrillic_I", 1}, - {"Ӣ", 0}, - {"y", 1}, - {"ȳ", 0}, - {"Cyrillic_O", 1}, - {"О̄", 0}, - {"i", 1}, - {"ī", 0}, - {"KP_9", 1}, - {"₉", 0}, - {"equal", 1}, - {"₌", 0}, - {"KP_Space", 1}, - {"₂", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"7", 1}, - {"₇", 0}, - {"Cyrillic_a", 1}, - {"а̄", 0}, - {"parenright", 1}, - {"₎", 0}, - {"Cyrillic_ER", 1}, - {"Р̄", 0}, - {"KP_7", 1}, - {"₇", 0}, - {"Cyrillic_U", 1}, - {"Ӯ", 0}, - {"AE", 1}, - {"Ǣ", 0}, - {"u", 1}, - {"ū", 0}, - {"G", 1}, - {"Ḡ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾱ", 0}, - {"otilde", 1}, - {"ȭ", 0}, - {"8", 1}, - {"₈", 0}, - {"KP_1", 1}, - {"₁", 0}, - {"3", 1}, - {"₃", 0}, - {"Cyrillic_ie", 1}, - {"е̄", 0}, - {"E", 1}, - {"Ē", 0}, - {"2", 1}, - {"₂", 0}, - {"Y", 1}, - {"Ȳ", 0}, - {"Cyrillic_i", 1}, - {"ӣ", 0}, - {"dead_ogonek", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"odiaeresis", 1}, - {"ȫ", 0}, - {"Otilde", 1}, - {"Ȭ", 0}, - {"quotedbl", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"plus", 1}, - {"₊", 0}, - {"6", 1}, - {"₆", 0}, - {"Greek_alpha", 1}, - {"ᾱ", 0}, - {"dead_abovedot", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"Cyrillic_o", 1}, - {"о̄", 0}, - {"4", 1}, - {"₄", 0}, - {"KP_3", 1}, - {"₃", 0}, - {"underscore", 1}, - {"¯", 0}, - {"apostrophe", 1}, - {"⍘", 0}, - {"O", 1}, - {"Ō", 0}, - {"KP_0", 1}, - {"₀", 0}, - {"A", 1}, - {"Ā", 0}, - {"KP_Add", 1}, - {"₊", 0}, - {"Odiaeresis", 1}, - {"Ȫ", 0}, - {"KP_2", 1}, - {"₂", 0}, - {"Cyrillic_A", 1}, - {"А̄", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"5", 1}, - {"₅", 0}, - {"greater", 1}, - {"≥", 0}, - {"semicolon", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"KP_5", 1}, - {"₅", 0}, - {"9", 1}, - {"₉", 0}, - {"Cyrillic_IE", 1}, - {"Е̄", 0}, - {"0", 1}, - {"₀", 0}, - {"dead_diaeresis", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"Adiaeresis", 1}, - {"Ǟ", 0}, - {"parenleft", 1}, - {"₍", 0}, - {"udiaeresis", 1}, - {"ǖ", 0}, - {"I", 1}, - {"Ī", 0}, - {"U", 1}, - {"Ū", 0}, - {"Cyrillic_u", 1}, - {"ӯ", 0}, - {"ae", 1}, - {"ǣ", 0}, - {"asciicircum", 1}, - {"¯", 0}, - {"Greek_UPSILON", 1}, - {"Ῡ", 0}, - {"KP_Equal", 1}, - {"₌", 0}, - {"v", 8}, - {"l", 1}, - {"|", 0}, - {"z", 1}, - {"ž", 0}, - {"Z", 1}, - {"Ž", 0}, - {"slash", 1}, - {"√", 0}, - {"P", 8}, - {"period", 1}, - {"Ṗ", 0}, - {"exclam", 1}, - {"¶", 0}, - {"t", 1}, - {"₧", 0}, - {"P", 1}, - {"¶", 0}, - {"question", 106}, - {"dead_breve", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"a", 1}, - {"ả", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"Acircumflex", 1}, - {"Ẩ", 0}, - {"exclam", 1}, - {"⸘", 0}, - {"e", 1}, - {"ẻ", 0}, - {"o", 1}, - {"ỏ", 0}, - {"uhorn", 1}, - {"ử", 0}, - {"acircumflex", 1}, - {"ẩ", 0}, - {"Ecircumflex", 1}, - {"Ể", 0}, - {"y", 1}, - {"ỷ", 0}, - {"b", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"i", 1}, - {"ỉ", 0}, - {"Ohorn", 1}, - {"Ở", 0}, - {"ohorn", 1}, - {"ở", 0}, - {"Ocircumflex", 1}, - {"Ổ", 0}, - {"ocircumflex", 1}, - {"ổ", 0}, - {"u", 1}, - {"ủ", 0}, - {"E", 1}, - {"Ẻ", 0}, - {"Y", 1}, - {"Ỷ", 0}, - {"Abreve", 1}, - {"Ẳ", 0}, - {"plus", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"ecircumflex", 1}, - {"ể", 0}, - {"question", 1}, - {"¿", 0}, - {"O", 1}, - {"Ỏ", 0}, - {"abreve", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ả", 0}, - {"Uhorn", 1}, - {"Ử", 0}, - {"I", 1}, - {"Ỉ", 0}, - {"U", 1}, - {"Ủ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"apostrophe", 470}, - {"W", 1}, - {"Ẃ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"g", 1}, - {"ǵ", 0}, - {"a", 1}, - {"á", 0}, - {"Greek_IOTA", 1}, - {"Ί", 0}, - {"Greek_iota", 1}, - {"ί", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_OMICRON", 1}, - {"Ό", 0}, - {"Acircumflex", 1}, - {"Ấ", 0}, - {"C", 1}, - {"Ć", 0}, - {"less", 1}, - {"‘", 0}, - {"Cyrillic_er", 1}, - {"р́", 0}, - {"e", 1}, - {"é", 0}, - {"KP_Divide", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"Utilde", 1}, - {"Ṹ", 0}, - {"o", 1}, - {"ó", 0}, - {"l", 1}, - {"ĺ", 0}, - {"Udiaeresis", 1}, - {"Ǘ", 0}, - {"Greek_upsilon", 1}, - {"ύ", 0}, - {"uhorn", 1}, - {"ứ", 0}, - {"space", 1}, - {"'", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"acircumflex", 1}, - {"ấ", 0}, - {"Ecircumflex", 1}, - {"Ế", 0}, - {"Cyrillic_I", 1}, - {"И́", 0}, - {"y", 1}, - {"ý", 0}, - {"b", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"idiaeresis", 1}, - {"ḯ", 0}, - {"Cyrillic_O", 1}, - {"О́", 0}, - {"i", 1}, - {"í", 0}, - {"k", 1}, - {"ḱ", 0}, - {"n", 1}, - {"ń", 0}, - {"ccedilla", 1}, - {"ḉ", 0}, - {"Cyrillic_GHE", 1}, - {"Ѓ", 0}, - {"dead_tilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Cyrillic_a", 1}, - {"а́", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"Ohorn", 1}, - {"Ớ", 0}, - {"ohorn", 1}, - {"ớ", 0}, - {"Cyrillic_ER", 1}, - {"Р́", 0}, - {"Greek_epsilon", 1}, - {"έ", 0}, - {"Cyrillic_KA", 1}, - {"Ќ", 0}, - {"Cyrillic_U", 1}, - {"У́", 0}, - {"dead_abovering", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"Ocircumflex", 1}, - {"Ố", 0}, - {"AE", 1}, - {"Ǽ", 0}, - {"omacron", 1}, - {"ṓ", 0}, - {"ocircumflex", 1}, - {"ố", 0}, - {"u", 1}, - {"ú", 0}, - {"z", 1}, - {"ź", 0}, - {"G", 1}, - {"Ǵ", 0}, - {"Greek_ALPHA", 1}, - {"Ά", 0}, - {"otilde", 1}, - {"ṍ", 0}, - {"utilde", 1}, - {"ṹ", 0}, - {"Cyrillic_ie", 1}, - {"е́", 0}, - {"emacron", 1}, - {"ḗ", 0}, - {"E", 1}, - {"É", 0}, - {"S", 1}, - {"Ś", 0}, - {"Greek_iotadieresis", 1}, - {"ΐ", 0}, - {"Y", 1}, - {"Ý", 0}, - {"Cyrillic_i", 1}, - {"и́", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"Greek_upsilondieresis", 1}, - {"ΰ", 0}, - {"Greek_omicron", 1}, - {"ό", 0}, - {"Greek_eta", 1}, - {"ή", 0}, - {"Otilde", 1}, - {"Ṍ", 0}, - {"Cyrillic_ka", 1}, - {"ќ", 0}, - {"Aring", 1}, - {"Ǻ", 0}, - {"Abreve", 1}, - {"Ắ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"quotedbl", 14}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"space", 1}, - {"΅", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"plus", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_alpha", 1}, - {"ά", 0}, - {"ecircumflex", 1}, - {"ế", 0}, - {"w", 1}, - {"ẃ", 0}, - {"Greek_ETA", 1}, - {"Ή", 0}, - {"Cyrillic_o", 1}, - {"о́", 0}, - {"Emacron", 1}, - {"Ḗ", 0}, - {"Ooblique", 1}, - {"Ǿ", 0}, - {"p", 1}, - {"ṕ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"P", 1}, - {"Ṕ", 0}, - {"apostrophe", 1}, - {"´", 0}, - {"M", 1}, - {"Ḿ", 0}, - {"O", 1}, - {"Ó", 0}, - {"abreve", 1}, - {"ắ", 0}, - {"m", 1}, - {"ḿ", 0}, - {"r", 1}, - {"ŕ", 0}, - {"s", 1}, - {"ś", 0}, - {"Z", 1}, - {"Ź", 0}, - {"macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"A", 1}, - {"Á", 0}, - {"R", 1}, - {"Ŕ", 0}, - {"c", 1}, - {"ć", 0}, - {"Idiaeresis", 1}, - {"Ḯ", 0}, - {"L", 1}, - {"Ĺ", 0}, - {"Greek_EPSILON", 1}, - {"Έ", 0}, - {"Cyrillic_A", 1}, - {"А́", 0}, - {"comma", 1}, - {"‚", 0}, - {"asciitilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Ccedilla", 1}, - {"Ḉ", 0}, - {"slash", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"aring", 1}, - {"ǻ", 0}, - {"greater", 1}, - {"’", 0}, - {"K", 1}, - {"Ḱ", 0}, - {"Omacron", 1}, - {"Ṓ", 0}, - {"Cyrillic_IE", 1}, - {"Е́", 0}, - {"dead_cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_omega", 1}, - {"ώ", 0}, - {"dead_diaeresis", 12}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"Uhorn", 1}, - {"Ứ", 0}, - {"Greek_OMEGA", 1}, - {"Ώ", 0}, - {"oslash", 1}, - {"ǿ", 0}, - {"Cyrillic_ghe", 1}, - {"ѓ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"udiaeresis", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Í", 0}, - {"N", 1}, - {"Ń", 0}, - {"U", 1}, - {"Ú", 0}, - {"Cyrillic_u", 1}, - {"у́", 0}, - {"ae", 1}, - {"ǽ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_UPSILON", 1}, - {"Ύ", 0}, - {"M", 2}, - {"period", 1}, - {"Ṁ", 0}, - {"O", 40}, - {"minus", 1}, - {"Ō", 0}, - {"C", 1}, - {"©", 0}, - {"diaeresis", 1}, - {"Ö", 0}, - {"x", 1}, - {"¤", 0}, - {"E", 1}, - {"Œ", 0}, - {"S", 1}, - {"§", 0}, - {"quotedbl", 1}, - {"Ö", 0}, - {"acute", 1}, - {"Ó", 0}, - {"underscore", 1}, - {"Ō", 0}, - {"apostrophe", 1}, - {"Ó", 0}, - {"r", 1}, - {"®", 0}, - {"A", 1}, - {"Ⓐ", 0}, - {"R", 1}, - {"®", 0}, - {"c", 1}, - {"©", 0}, - {"asciitilde", 1}, - {"Õ", 0}, - {"slash", 1}, - {"Ø", 0}, - {"greater", 1}, - {"Ô", 0}, - {"X", 1}, - {"¤", 0}, - {"grave", 1}, - {"Ò", 0}, - {"asciicircum", 1}, - {"Ô", 0}, - {"m", 6}, - {"period", 1}, - {"ṁ", 0}, - {"u", 1}, - {"µ", 0}, - {"slash", 1}, - {"₥", 0}, - {"r", 6}, - {"less", 1}, - {"ř", 0}, - {"apostrophe", 1}, - {"ŕ", 0}, - {"comma", 1}, - {"ŗ", 0}, - {"s", 20}, - {"period", 1}, - {"ṡ", 0}, - {"exclam", 1}, - {"§", 0}, - {"less", 1}, - {"š", 0}, - {"o", 1}, - {"§", 0}, - {"cedilla", 1}, - {"ş", 0}, - {"apostrophe", 1}, - {"ś", 0}, - {"M", 1}, - {"℠", 0}, - {"m", 1}, - {"℠", 0}, - {"s", 1}, - {"ß", 0}, - {"comma", 1}, - {"ş", 0}, - {"asterisk", 17}, - {"a", 1}, - {"å", 0}, - {"diaeresis", 1}, - {"⍣", 0}, - {"u", 1}, - {"ů", 0}, - {"apostrophe", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"A", 1}, - {"Å", 0}, - {"0", 1}, - {"°", 0}, - {"U", 1}, - {"Ů", 0}, - {"Z", 6}, - {"period", 1}, - {"Ż", 0}, - {"less", 1}, - {"Ž", 0}, - {"apostrophe", 1}, - {"Ź", 0}, - {"bar", 6}, - {"C", 1}, - {"¢", 0}, - {"c", 1}, - {"¢", 0}, - {"asciitilde", 1}, - {"⍭", 0}, - {"macron", 166}, - {"adiaeresis", 1}, - {"ǟ", 0}, - {"period", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"g", 1}, - {"ḡ", 0}, - {"a", 1}, - {"ā", 0}, - {"Greek_IOTA", 1}, - {"Ῑ", 0}, - {"Greek_iota", 1}, - {"ῑ", 0}, - {"exclam", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"Cyrillic_er", 1}, - {"р̄", 0}, - {"e", 1}, - {"ē", 0}, - {"o", 1}, - {"ō", 0}, - {"Udiaeresis", 1}, - {"Ǖ", 0}, - {"Greek_upsilon", 1}, - {"ῡ", 0}, - {"dead_belowdot", 8}, - {"l", 1}, - {"ḹ", 0}, - {"r", 1}, - {"ṝ", 0}, - {"R", 1}, - {"Ṝ", 0}, - {"L", 1}, - {"Ḹ", 0}, - {"Cyrillic_I", 1}, - {"Ӣ", 0}, - {"y", 1}, - {"ȳ", 0}, - {"Cyrillic_O", 1}, - {"О̄", 0}, - {"i", 1}, - {"ī", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"Cyrillic_a", 1}, - {"а̄", 0}, - {"Cyrillic_ER", 1}, - {"Р̄", 0}, - {"Cyrillic_U", 1}, - {"Ӯ", 0}, - {"AE", 1}, - {"Ǣ", 0}, - {"u", 1}, - {"ū", 0}, - {"G", 1}, - {"Ḡ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾱ", 0}, - {"otilde", 1}, - {"ȭ", 0}, - {"Cyrillic_ie", 1}, - {"е̄", 0}, - {"E", 1}, - {"Ē", 0}, - {"Y", 1}, - {"Ȳ", 0}, - {"Cyrillic_i", 1}, - {"ӣ", 0}, - {"dead_ogonek", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"odiaeresis", 1}, - {"ȫ", 0}, - {"Otilde", 1}, - {"Ȭ", 0}, - {"quotedbl", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"Greek_alpha", 1}, - {"ᾱ", 0}, - {"dead_abovedot", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"Cyrillic_o", 1}, - {"о̄", 0}, - {"O", 1}, - {"Ō", 0}, - {"A", 1}, - {"Ā", 0}, - {"Odiaeresis", 1}, - {"Ȫ", 0}, - {"Cyrillic_A", 1}, - {"А̄", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"semicolon", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"Cyrillic_IE", 1}, - {"Е̄", 0}, - {"dead_diaeresis", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ǖ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ǖ", 0}, - {"Adiaeresis", 1}, - {"Ǟ", 0}, - {"udiaeresis", 1}, - {"ǖ", 0}, - {"I", 1}, - {"Ī", 0}, - {"U", 1}, - {"Ū", 0}, - {"Cyrillic_u", 1}, - {"ӯ", 0}, - {"ae", 1}, - {"ǣ", 0}, - {"Greek_UPSILON", 1}, - {"Ῡ", 0}, - {"A", 32}, - {"minus", 1}, - {"Ā", 0}, - {"diaeresis", 1}, - {"Ä", 0}, - {"E", 1}, - {"Æ", 0}, - {"quotedbl", 1}, - {"Ä", 0}, - {"acute", 1}, - {"Á", 0}, - {"underscore", 1}, - {"Ā", 0}, - {"apostrophe", 1}, - {"Á", 0}, - {"asterisk", 1}, - {"Å", 0}, - {"A", 1}, - {"Å", 0}, - {"comma", 1}, - {"Ą", 0}, - {"T", 1}, - {"@", 0}, - {"asciitilde", 1}, - {"Ã", 0}, - {"greater", 1}, - {"Â", 0}, - {"parenleft", 1}, - {"Ă", 0}, - {"grave", 1}, - {"À", 0}, - {"asciicircum", 1}, - {"Â", 0}, - {"R", 10}, - {"less", 1}, - {"Ř", 0}, - {"apostrophe", 1}, - {"Ŕ", 0}, - {"O", 1}, - {"®", 0}, - {"s", 1}, - {"₨", 0}, - {"comma", 1}, - {"Ŗ", 0}, - {"Cyrillic_ES", 2}, - {"equal", 1}, - {"€", 0}, - {"c", 98}, - {"period", 1}, - {"ċ", 0}, - {"g", 1}, - {"ǧ", 0}, - {"a", 1}, - {"ǎ", 0}, - {"ezh", 1}, - {"ǯ", 0}, - {"C", 1}, - {"Č", 0}, - {"less", 1}, - {"č", 0}, - {"e", 1}, - {"ě", 0}, - {"o", 1}, - {"ǒ", 0}, - {"l", 1}, - {"ľ", 0}, - {"Udiaeresis", 1}, - {"Ǚ", 0}, - {"t", 1}, - {"ť", 0}, - {"i", 1}, - {"ǐ", 0}, - {"k", 1}, - {"ǩ", 0}, - {"n", 1}, - {"ň", 0}, - {"equal", 1}, - {"€", 0}, - {"j", 1}, - {"ǰ", 0}, - {"u", 1}, - {"ǔ", 0}, - {"z", 1}, - {"ž", 0}, - {"G", 1}, - {"Ǧ", 0}, - {"H", 1}, - {"Ȟ", 0}, - {"E", 1}, - {"Ě", 0}, - {"S", 1}, - {"Š", 0}, - {"d", 1}, - {"ď", 0}, - {"D", 1}, - {"Ď", 0}, - {"quotedbl", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"apostrophe", 1}, - {"ć", 0}, - {"O", 1}, - {"Ǒ", 0}, - {"r", 1}, - {"ř", 0}, - {"s", 1}, - {"š", 0}, - {"Z", 1}, - {"Ž", 0}, - {"bar", 1}, - {"¢", 0}, - {"EZH", 1}, - {"Ǯ", 0}, - {"A", 1}, - {"Ǎ", 0}, - {"R", 1}, - {"Ř", 0}, - {"c", 1}, - {"č", 0}, - {"L", 1}, - {"Ľ", 0}, - {"comma", 1}, - {"ç", 0}, - {"T", 1}, - {"Ť", 0}, - {"slash", 1}, - {"¢", 0}, - {"K", 1}, - {"Ǩ", 0}, - {"dead_diaeresis", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"h", 1}, - {"ȟ", 0}, - {"udiaeresis", 1}, - {"ǚ", 0}, - {"I", 1}, - {"Ǐ", 0}, - {"N", 1}, - {"Ň", 0}, - {"U", 1}, - {"Ǔ", 0}, - {"numbersign", 14}, - {"e", 1}, - {"♪", 0}, - {"b", 1}, - {"♭", 0}, - {"q", 1}, - {"♩", 0}, - {"E", 1}, - {"♫", 0}, - {"S", 1}, - {"♬", 0}, - {"f", 1}, - {"♮", 0}, - {"numbersign", 1}, - {"♯", 0}, - {"L", 14}, - {"minus", 1}, - {"£", 0}, - {"less", 1}, - {"Ľ", 0}, - {"equal", 1}, - {"₤", 0}, - {"V", 1}, - {"|", 0}, - {"apostrophe", 1}, - {"Ĺ", 0}, - {"comma", 1}, - {"Ļ", 0}, - {"slash", 1}, - {"Ł", 0}, - {"Greek_EPSILON", 2}, - {"apostrophe", 1}, - {"Έ", 0}, - {"comma", 66}, - {"minus", 1}, - {"¬", 0}, - {"g", 1}, - {"ģ", 0}, - {"a", 1}, - {"ą", 0}, - {"C", 1}, - {"Ç", 0}, - {"e", 1}, - {"ę", 0}, - {"l", 1}, - {"ļ", 0}, - {"t", 1}, - {"ţ", 0}, - {"space", 1}, - {"¸", 0}, - {"i", 1}, - {"į", 0}, - {"k", 1}, - {"ķ", 0}, - {"n", 1}, - {"ņ", 0}, - {"u", 1}, - {"ų", 0}, - {"G", 1}, - {"Ģ", 0}, - {"H", 1}, - {"Ḩ", 0}, - {"E", 1}, - {"Ę", 0}, - {"S", 1}, - {"Ş", 0}, - {"d", 1}, - {"ḑ", 0}, - {"D", 1}, - {"Ḑ", 0}, - {"quotedbl", 1}, - {"„", 0}, - {"apostrophe", 1}, - {"‚", 0}, - {"r", 1}, - {"ŗ", 0}, - {"s", 1}, - {"ş", 0}, - {"A", 1}, - {"Ą", 0}, - {"R", 1}, - {"Ŗ", 0}, - {"c", 1}, - {"ç", 0}, - {"L", 1}, - {"Ļ", 0}, - {"comma", 1}, - {"¸", 0}, - {"T", 1}, - {"Ţ", 0}, - {"K", 1}, - {"Ķ", 0}, - {"h", 1}, - {"ḩ", 0}, - {"I", 1}, - {"Į", 0}, - {"N", 1}, - {"Ņ", 0}, - {"U", 1}, - {"Ų", 0}, - {"T", 16}, - {"minus", 1}, - {"Ŧ", 0}, - {"period", 1}, - {"Ṫ", 0}, - {"less", 1}, - {"Ť", 0}, - {"H", 1}, - {"Þ", 0}, - {"M", 1}, - {"™", 0}, - {"m", 1}, - {"™", 0}, - {"comma", 1}, - {"Ţ", 0}, - {"slash", 1}, - {"Ŧ", 0}, - {"asciitilde", 222}, - {"dead_breve", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"a", 1}, - {"ã", 0}, - {"Greek_iota", 1}, - {"ῖ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"Acircumflex", 1}, - {"Ẫ", 0}, - {"e", 1}, - {"ẽ", 0}, - {"o", 1}, - {"õ", 0}, - {"Greek_upsilon", 1}, - {"ῦ", 0}, - {"diaeresis", 1}, - {"⍨", 0}, - {"uhorn", 1}, - {"ữ", 0}, - {"space", 1}, - {"~", 0}, - {"acircumflex", 1}, - {"ẫ", 0}, - {"Ecircumflex", 1}, - {"Ễ", 0}, - {"y", 1}, - {"ỹ", 0}, - {"b", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"i", 1}, - {"ĩ", 0}, - {"n", 1}, - {"ñ", 0}, - {"parenright", 18}, - {"Greek_IOTA", 1}, - {"Ἶ", 0}, - {"Greek_iota", 1}, - {"ἶ", 0}, - {"Greek_upsilon", 1}, - {"ὖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἆ", 0}, - {"Greek_eta", 1}, - {"ἦ", 0}, - {"Greek_alpha", 1}, - {"ἆ", 0}, - {"Greek_ETA", 1}, - {"Ἦ", 0}, - {"Greek_omega", 1}, - {"ὦ", 0}, - {"Greek_OMEGA", 1}, - {"Ὦ", 0}, - {"Ohorn", 1}, - {"Ỡ", 0}, - {"ohorn", 1}, - {"ỡ", 0}, - {"Ocircumflex", 1}, - {"Ỗ", 0}, - {"V", 1}, - {"Ṽ", 0}, - {"ocircumflex", 1}, - {"ỗ", 0}, - {"u", 1}, - {"ũ", 0}, - {"E", 1}, - {"Ẽ", 0}, - {"Greek_iotadieresis", 1}, - {"ῗ", 0}, - {"Y", 1}, - {"Ỹ", 0}, - {"dead_dasia", 20}, - {"Greek_IOTA", 1}, - {"Ἷ", 0}, - {"Greek_iota", 1}, - {"ἷ", 0}, - {"Greek_upsilon", 1}, - {"ὗ", 0}, - {"Greek_ALPHA", 1}, - {"Ἇ", 0}, - {"Greek_eta", 1}, - {"ἧ", 0}, - {"Greek_alpha", 1}, - {"ἇ", 0}, - {"Greek_ETA", 1}, - {"Ἧ", 0}, - {"Greek_omega", 1}, - {"ὧ", 0}, - {"Greek_OMEGA", 1}, - {"Ὧ", 0}, - {"Greek_UPSILON", 1}, - {"Ὗ", 0}, - {"Greek_upsilondieresis", 1}, - {"ῧ", 0}, - {"Greek_eta", 1}, - {"ῆ", 0}, - {"Abreve", 1}, - {"Ẵ", 0}, - {"dead_psili", 18}, - {"Greek_IOTA", 1}, - {"Ἶ", 0}, - {"Greek_iota", 1}, - {"ἶ", 0}, - {"Greek_upsilon", 1}, - {"ὖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἆ", 0}, - {"Greek_eta", 1}, - {"ἦ", 0}, - {"Greek_alpha", 1}, - {"ἆ", 0}, - {"Greek_ETA", 1}, - {"Ἦ", 0}, - {"Greek_omega", 1}, - {"ὦ", 0}, - {"Greek_OMEGA", 1}, - {"Ὦ", 0}, - {"quotedbl", 4}, - {"Greek_iota", 1}, - {"ῗ", 0}, - {"Greek_upsilon", 1}, - {"ῧ", 0}, - {"plus", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"Greek_alpha", 1}, - {"ᾶ", 0}, - {"ecircumflex", 1}, - {"ễ", 0}, - {"v", 1}, - {"ṽ", 0}, - {"O", 1}, - {"Õ", 0}, - {"abreve", 1}, - {"ẵ", 0}, - {"bar", 1}, - {"⍭", 0}, - {"A", 1}, - {"Ã", 0}, - {"0", 1}, - {"⍬", 0}, - {"Greek_omega", 1}, - {"ῶ", 0}, - {"dead_diaeresis", 4}, - {"Greek_iota", 1}, - {"ῗ", 0}, - {"Greek_upsilon", 1}, - {"ῧ", 0}, - {"Uhorn", 1}, - {"Ữ", 0}, - {"parenleft", 20}, - {"Greek_IOTA", 1}, - {"Ἷ", 0}, - {"Greek_iota", 1}, - {"ἷ", 0}, - {"Greek_upsilon", 1}, - {"ὗ", 0}, - {"Greek_ALPHA", 1}, - {"Ἇ", 0}, - {"Greek_eta", 1}, - {"ἧ", 0}, - {"Greek_alpha", 1}, - {"ἇ", 0}, - {"Greek_ETA", 1}, - {"Ἧ", 0}, - {"Greek_omega", 1}, - {"ὧ", 0}, - {"Greek_OMEGA", 1}, - {"Ὧ", 0}, - {"Greek_UPSILON", 1}, - {"Ὗ", 0}, - {"I", 1}, - {"Ĩ", 0}, - {"N", 1}, - {"Ñ", 0}, - {"U", 1}, - {"Ũ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"slash", 66}, - {"minus", 1}, - {"⌿", 0}, - {"g", 1}, - {"ǥ", 0}, - {"C", 1}, - {"₡", 0}, - {"less", 1}, - {"\\", 0}, - {"o", 1}, - {"ø", 0}, - {"l", 1}, - {"ł", 0}, - {"t", 1}, - {"ŧ", 0}, - {"b", 1}, - {"ƀ", 0}, - {"i", 1}, - {"ɨ", 0}, - {"equal", 1}, - {"≠", 0}, - {"Cyrillic_GHE", 1}, - {"Ғ", 0}, - {"leftarrow", 1}, - {"↚", 0}, - {"Cyrillic_KA", 1}, - {"Ҟ", 0}, - {"u", 1}, - {"µ", 0}, - {"rightarrow", 1}, - {"↛", 0}, - {"z", 1}, - {"ƶ", 0}, - {"G", 1}, - {"Ǥ", 0}, - {"H", 1}, - {"Ħ", 0}, - {"d", 1}, - {"đ", 0}, - {"Cyrillic_ka", 1}, - {"ҟ", 0}, - {"D", 1}, - {"Đ", 0}, - {"v", 1}, - {"√", 0}, - {"O", 1}, - {"Ø", 0}, - {"m", 1}, - {"₥", 0}, - {"Z", 1}, - {"Ƶ", 0}, - {"c", 1}, - {"¢", 0}, - {"L", 1}, - {"Ł", 0}, - {"T", 1}, - {"Ŧ", 0}, - {"slash", 1}, - {"\\", 0}, - {"Cyrillic_ghe", 1}, - {"ғ", 0}, - {"h", 1}, - {"ħ", 0}, - {"I", 1}, - {"Ɨ", 0}, - {"asciicircum", 1}, - {"|", 0}, - {"5", 4}, - {"8", 1}, - {"⅝", 0}, - {"6", 1}, - {"⅚", 0}, - {"Cyrillic_EN", 4}, - {"Cyrillic_O", 1}, - {"№", 0}, - {"Cyrillic_o", 1}, - {"№", 0}, - {"greater", 36}, - {"a", 1}, - {"â", 0}, - {"less", 1}, - {"⋄", 0}, - {"e", 1}, - {"ê", 0}, - {"o", 1}, - {"ô", 0}, - {"diaeresis", 1}, - {"⍩", 0}, - {"space", 1}, - {"^", 0}, - {"i", 1}, - {"î", 0}, - {"equal", 1}, - {"≥", 0}, - {"u", 1}, - {"û", 0}, - {"E", 1}, - {"Ê", 0}, - {"quotedbl", 1}, - {"”", 0}, - {"underscore", 1}, - {"≥", 0}, - {"apostrophe", 1}, - {"’", 0}, - {"O", 1}, - {"Ô", 0}, - {"A", 1}, - {"Â", 0}, - {"greater", 1}, - {"»", 0}, - {"I", 1}, - {"Î", 0}, - {"U", 1}, - {"Û", 0}, - {"semicolon", 22}, - {"a", 1}, - {"ą", 0}, - {"e", 1}, - {"ę", 0}, - {"o", 1}, - {"ǫ", 0}, - {"i", 1}, - {"į", 0}, - {"u", 1}, - {"ų", 0}, - {"E", 1}, - {"Ę", 0}, - {"underscore", 1}, - {"⍮", 0}, - {"O", 1}, - {"Ǫ", 0}, - {"A", 1}, - {"Ą", 0}, - {"I", 1}, - {"Į", 0}, - {"U", 1}, - {"Ų", 0}, - {"K", 2}, - {"comma", 1}, - {"Ķ", 0}, - {"Cyrillic_IE", 2}, - {"equal", 1}, - {"€", 0}, - {"B", 2}, - {"period", 1}, - {"Ḃ", 0}, - {"0", 6}, - {"3", 1}, - {"↉", 0}, - {"asterisk", 1}, - {"°", 0}, - {"asciitilde", 1}, - {"⍬", 0}, - {"Greek_omega", 2}, - {"apostrophe", 1}, - {"ώ", 0}, - {"Greek_OMEGA", 2}, - {"apostrophe", 1}, - {"Ώ", 0}, - {"X", 4}, - {"o", 1}, - {"¤", 0}, - {"O", 1}, - {"¤", 0}, - {"parenleft", 971}, - {"minus", 1}, - {"{", 0}, - {"W", 2}, - {"parenright", 1}, - {"Ⓦ", 0}, - {"g", 2}, - {"parenright", 1}, - {"ⓖ", 0}, - {"kana_KE", 2}, - {"parenright", 1}, - {"㋘", 0}, - {"a", 2}, - {"parenright", 1}, - {"ⓐ", 0}, - {"Greek_IOTA", 1}, - {"Ἱ", 0}, - {"Greek_iota", 1}, - {"ἱ", 0}, - {"1", 65}, - {"1", 2}, - {"parenright", 1}, - {"⑪", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"⑭", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"⑯", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"⑱", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"⑲", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"7", 2}, - {"parenright", 1}, - {"⑰", 0}, - {"parenright", 1}, - {"①", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"⑰", 0}, - {"8", 2}, - {"parenright", 1}, - {"⑱", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"⑪", 0}, - {"3", 2}, - {"parenright", 1}, - {"⑬", 0}, - {"2", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"6", 2}, - {"parenright", 1}, - {"⑯", 0}, - {"4", 2}, - {"parenright", 1}, - {"⑭", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"⑬", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑩", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"5", 2}, - {"parenright", 1}, - {"⑮", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"⑮", 0}, - {"9", 2}, - {"parenright", 1}, - {"⑲", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑩", 0}, - {"Greek_OMICRON", 1}, - {"Ὁ", 0}, - {"C", 2}, - {"parenright", 1}, - {"Ⓒ", 0}, - {"KP_4", 65}, - {"1", 2}, - {"parenright", 1}, - {"㊶", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㊹", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㊻", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㊽", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㊾", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"7", 2}, - {"parenright", 1}, - {"㊼", 0}, - {"parenright", 1}, - {"④", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㊼", 0}, - {"8", 2}, - {"parenright", 1}, - {"㊽", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㊶", 0}, - {"3", 2}, - {"parenright", 1}, - {"㊸", 0}, - {"2", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"6", 2}, - {"parenright", 1}, - {"㊻", 0}, - {"4", 2}, - {"parenright", 1}, - {"㊹", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㊸", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㊵", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"5", 2}, - {"parenright", 1}, - {"㊺", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㊺", 0}, - {"9", 2}, - {"parenright", 1}, - {"㊾", 0}, - {"0", 2}, - {"parenright", 1}, - {"㊵", 0}, - {"kana_SA", 2}, - {"parenright", 1}, - {"㋚", 0}, - {"e", 2}, - {"parenright", 1}, - {"ⓔ", 0}, - {"F", 2}, - {"parenright", 1}, - {"Ⓕ", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"⑥", 0}, - {"o", 2}, - {"parenright", 1}, - {"ⓞ", 0}, - {"l", 2}, - {"parenright", 1}, - {"ⓛ", 0}, - {"kana_SE", 2}, - {"parenright", 1}, - {"㋝", 0}, - {"kana_SU", 2}, - {"parenright", 1}, - {"㋜", 0}, - {"t", 2}, - {"parenright", 1}, - {"ⓣ", 0}, - {"kana_ME", 2}, - {"parenright", 1}, - {"㋱", 0}, - {"Greek_upsilon", 1}, - {"ὑ", 0}, - {"kana_WO", 2}, - {"parenright", 1}, - {"㋾", 0}, - {"space", 1}, - {"˘", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"⑧", 0}, - {"Greek_RHO", 1}, - {"Ῥ", 0}, - {"Q", 2}, - {"parenright", 1}, - {"Ⓠ", 0}, - {"y", 2}, - {"parenright", 1}, - {"ⓨ", 0}, - {"b", 2}, - {"parenright", 1}, - {"ⓑ", 0}, - {"kana_YO", 2}, - {"parenright", 1}, - {"㋵", 0}, - {"i", 2}, - {"parenright", 1}, - {"ⓘ", 0}, - {"kana_MA", 2}, - {"parenright", 1}, - {"㋮", 0}, - {"k", 2}, - {"parenright", 1}, - {"ⓚ", 0}, - {"n", 2}, - {"parenright", 1}, - {"ⓝ", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"⑨", 0}, - {"KP_Space", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"parenright", 1}, - {"②", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"kana_YU", 2}, - {"parenright", 1}, - {"㋴", 0}, - {"kana_TE", 2}, - {"parenright", 1}, - {"㋢", 0}, - {"7", 2}, - {"parenright", 1}, - {"⑦", 0}, - {"kana_NU", 2}, - {"parenright", 1}, - {"㋦", 0}, - {"kana_HO", 2}, - {"parenright", 1}, - {"㋭", 0}, - {"kana_HI", 2}, - {"parenright", 1}, - {"㋪", 0}, - {"j", 2}, - {"parenright", 1}, - {"ⓙ", 0}, - {"kana_E", 2}, - {"parenright", 1}, - {"㋓", 0}, - {"x", 2}, - {"parenright", 1}, - {"ⓧ", 0}, - {"Greek_epsilon", 1}, - {"ἑ", 0}, - {"q", 2}, - {"parenright", 1}, - {"ⓠ", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"⑦", 0}, - {"kana_I", 2}, - {"parenright", 1}, - {"㋑", 0}, - {"kana_WA", 2}, - {"parenright", 1}, - {"㋻", 0}, - {"kana_RU", 2}, - {"parenright", 1}, - {"㋸", 0}, - {"V", 2}, - {"parenright", 1}, - {"Ⓥ", 0}, - {"u", 2}, - {"parenright", 1}, - {"ⓤ", 0}, - {"kana_NI", 2}, - {"parenright", 1}, - {"㋥", 0}, - {"kana_MU", 2}, - {"parenright", 1}, - {"㋰", 0}, - {"kana_CHI", 2}, - {"parenright", 1}, - {"㋠", 0}, - {"kana_HA", 2}, - {"parenright", 1}, - {"㋩", 0}, - {"z", 2}, - {"parenright", 1}, - {"ⓩ", 0}, - {"G", 2}, - {"parenright", 1}, - {"Ⓖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἁ", 0}, - {"H", 2}, - {"parenright", 1}, - {"Ⓗ", 0}, - {"8", 2}, - {"parenright", 1}, - {"⑧", 0}, - {"KP_1", 65}, - {"1", 2}, - {"parenright", 1}, - {"⑪", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"⑭", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"⑯", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"⑱", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"⑲", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"7", 2}, - {"parenright", 1}, - {"⑰", 0}, - {"parenright", 1}, - {"①", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"⑰", 0}, - {"8", 2}, - {"parenright", 1}, - {"⑱", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"⑪", 0}, - {"3", 2}, - {"parenright", 1}, - {"⑬", 0}, - {"2", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"6", 2}, - {"parenright", 1}, - {"⑯", 0}, - {"4", 2}, - {"parenright", 1}, - {"⑭", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"⑬", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑩", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"⑫", 0}, - {"5", 2}, - {"parenright", 1}, - {"⑮", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"⑮", 0}, - {"9", 2}, - {"parenright", 1}, - {"⑲", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑩", 0}, - {"3", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉛", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉞", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㊱", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㊳", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㊴", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"7", 2}, - {"parenright", 1}, - {"㊲", 0}, - {"parenright", 1}, - {"③", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㊲", 0}, - {"8", 2}, - {"parenright", 1}, - {"㊳", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉛", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉝", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"6", 2}, - {"parenright", 1}, - {"㊱", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉞", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉝", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㉚", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉟", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉟", 0}, - {"9", 2}, - {"parenright", 1}, - {"㊴", 0}, - {"0", 2}, - {"parenright", 1}, - {"㉚", 0}, - {"E", 2}, - {"parenright", 1}, - {"Ⓔ", 0}, - {"S", 2}, - {"parenright", 1}, - {"Ⓢ", 0}, - {"2", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"parenright", 1}, - {"②", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"Y", 2}, - {"parenright", 1}, - {"Ⓨ", 0}, - {"kana_RA", 2}, - {"parenright", 1}, - {"㋶", 0}, - {"f", 2}, - {"parenright", 1}, - {"ⓕ", 0}, - {"Greek_omicron", 1}, - {"ὁ", 0}, - {"Greek_eta", 1}, - {"ἡ", 0}, - {"kana_HE", 2}, - {"parenright", 1}, - {"㋬", 0}, - {"Greek_rho", 1}, - {"ῥ", 0}, - {"kana_KO", 2}, - {"parenright", 1}, - {"㋙", 0}, - {"d", 2}, - {"parenright", 1}, - {"ⓓ", 0}, - {"kana_NE", 2}, - {"parenright", 1}, - {"㋧", 0}, - {"D", 2}, - {"parenright", 1}, - {"Ⓓ", 0}, - {"kana_FU", 2}, - {"parenright", 1}, - {"㋫", 0}, - {"6", 2}, - {"parenright", 1}, - {"⑥", 0}, - {"Greek_alpha", 1}, - {"ἁ", 0}, - {"kana_A", 2}, - {"parenright", 1}, - {"㋐", 0}, - {"w", 2}, - {"parenright", 1}, - {"ⓦ", 0}, - {"Greek_ETA", 1}, - {"Ἡ", 0}, - {"4", 65}, - {"1", 2}, - {"parenright", 1}, - {"㊶", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㊹", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㊻", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㊽", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㊾", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"7", 2}, - {"parenright", 1}, - {"㊼", 0}, - {"parenright", 1}, - {"④", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㊼", 0}, - {"8", 2}, - {"parenright", 1}, - {"㊽", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㊶", 0}, - {"3", 2}, - {"parenright", 1}, - {"㊸", 0}, - {"2", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"6", 2}, - {"parenright", 1}, - {"㊻", 0}, - {"4", 2}, - {"parenright", 1}, - {"㊹", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㊸", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㊵", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㊷", 0}, - {"5", 2}, - {"parenright", 1}, - {"㊺", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㊺", 0}, - {"9", 2}, - {"parenright", 1}, - {"㊾", 0}, - {"0", 2}, - {"parenright", 1}, - {"㊵", 0}, - {"kana_KU", 2}, - {"parenright", 1}, - {"㋗", 0}, - {"KP_3", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉛", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉞", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㊱", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㊳", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㊴", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"7", 2}, - {"parenright", 1}, - {"㊲", 0}, - {"parenright", 1}, - {"③", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㊲", 0}, - {"8", 2}, - {"parenright", 1}, - {"㊳", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉛", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉝", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"6", 2}, - {"parenright", 1}, - {"㊱", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉞", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉝", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㉚", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉜", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉟", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉟", 0}, - {"9", 2}, - {"parenright", 1}, - {"㊴", 0}, - {"0", 2}, - {"parenright", 1}, - {"㉚", 0}, - {"p", 2}, - {"parenright", 1}, - {"ⓟ", 0}, - {"J", 2}, - {"parenright", 1}, - {"Ⓙ", 0}, - {"kana_YA", 2}, - {"parenright", 1}, - {"㋳", 0}, - {"v", 2}, - {"parenright", 1}, - {"ⓥ", 0}, - {"P", 2}, - {"parenright", 1}, - {"Ⓟ", 0}, - {"M", 2}, - {"parenright", 1}, - {"Ⓜ", 0}, - {"O", 2}, - {"parenright", 1}, - {"Ⓞ", 0}, - {"m", 2}, - {"parenright", 1}, - {"ⓜ", 0}, - {"r", 2}, - {"parenright", 1}, - {"ⓡ", 0}, - {"s", 2}, - {"parenright", 1}, - {"ⓢ", 0}, - {"Z", 2}, - {"parenright", 1}, - {"Ⓩ", 0}, - {"kana_U", 2}, - {"parenright", 1}, - {"㋒", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⓪", 0}, - {"A", 2}, - {"parenright", 1}, - {"Ⓐ", 0}, - {"R", 2}, - {"parenright", 1}, - {"Ⓡ", 0}, - {"kana_TO", 2}, - {"parenright", 1}, - {"㋣", 0}, - {"kana_TA", 2}, - {"parenright", 1}, - {"㋟", 0}, - {"c", 2}, - {"parenright", 1}, - {"ⓒ", 0}, - {"kana_RO", 2}, - {"parenright", 1}, - {"㋺", 0}, - {"L", 2}, - {"parenright", 1}, - {"Ⓛ", 0}, - {"Greek_EPSILON", 1}, - {"Ἑ", 0}, - {"KP_2", 65}, - {"1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"KP_4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"KP_8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"KP_Space", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"parenright", 1}, - {"②", 0}, - {"KP_7", 2}, - {"parenright", 1}, - {"㉗", 0}, - {"8", 2}, - {"parenright", 1}, - {"㉘", 0}, - {"KP_1", 2}, - {"parenright", 1}, - {"㉑", 0}, - {"3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"6", 2}, - {"parenright", 1}, - {"㉖", 0}, - {"4", 2}, - {"parenright", 1}, - {"㉔", 0}, - {"KP_3", 2}, - {"parenright", 1}, - {"㉓", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"KP_2", 2}, - {"parenright", 1}, - {"㉒", 0}, - {"5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"KP_5", 2}, - {"parenright", 1}, - {"㉕", 0}, - {"9", 2}, - {"parenright", 1}, - {"㉙", 0}, - {"0", 2}, - {"parenright", 1}, - {"⑳", 0}, - {"kana_O", 2}, - {"parenright", 1}, - {"㋔", 0}, - {"kana_RI", 2}, - {"parenright", 1}, - {"㋷", 0}, - {"T", 2}, - {"parenright", 1}, - {"Ⓣ", 0}, - {"kana_KA", 2}, - {"parenright", 1}, - {"㋕", 0}, - {"kana_MI", 2}, - {"parenright", 1}, - {"㋯", 0}, - {"5", 8}, - {"parenright", 1}, - {"⑤", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㊿", 0}, - {"0", 2}, - {"parenright", 1}, - {"㊿", 0}, - {"kana_KI", 2}, - {"parenright", 1}, - {"㋖", 0}, - {"KP_5", 8}, - {"parenright", 1}, - {"⑤", 0}, - {"KP_0", 2}, - {"parenright", 1}, - {"㊿", 0}, - {"0", 2}, - {"parenright", 1}, - {"㊿", 0}, - {"K", 2}, - {"parenright", 1}, - {"Ⓚ", 0}, - {"9", 2}, - {"parenright", 1}, - {"⑨", 0}, - {"kana_SO", 2}, - {"parenright", 1}, - {"㋞", 0}, - {"B", 2}, - {"parenright", 1}, - {"Ⓑ", 0}, - {"kana_TSU", 2}, - {"parenright", 1}, - {"㋡", 0}, - {"0", 2}, - {"parenright", 1}, - {"⓪", 0}, - {"kana_MO", 2}, - {"parenright", 1}, - {"㋲", 0}, - {"Greek_omega", 1}, - {"ὡ", 0}, - {"kana_NO", 2}, - {"parenright", 1}, - {"㋨", 0}, - {"Greek_OMEGA", 1}, - {"Ὡ", 0}, - {"kana_NA", 2}, - {"parenright", 1}, - {"㋤", 0}, - {"X", 2}, - {"parenright", 1}, - {"Ⓧ", 0}, - {"parenleft", 1}, - {"[", 0}, - {"h", 2}, - {"parenright", 1}, - {"ⓗ", 0}, - {"I", 2}, - {"parenright", 1}, - {"Ⓘ", 0}, - {"N", 2}, - {"parenright", 1}, - {"Ⓝ", 0}, - {"kana_SHI", 2}, - {"parenright", 1}, - {"㋛", 0}, - {"U", 2}, - {"parenright", 1}, - {"Ⓤ", 0}, - {"kana_RE", 2}, - {"parenright", 1}, - {"㋹", 0}, - {"Greek_UPSILON", 1}, - {"Ὑ", 0}, - {"h", 2}, - {"comma", 1}, - {"ḩ", 0}, - {"I", 28}, - {"minus", 1}, - {"Ī", 0}, - {"period", 1}, - {"İ", 0}, - {"diaeresis", 1}, - {"Ï", 0}, - {"j", 1}, - {"IJ", 0}, - {"quotedbl", 1}, - {"Ï", 0}, - {"acute", 1}, - {"Í", 0}, - {"underscore", 1}, - {"Ī", 0}, - {"J", 1}, - {"IJ", 0}, - {"apostrophe", 1}, - {"Í", 0}, - {"comma", 1}, - {"Į", 0}, - {"asciitilde", 1}, - {"Ĩ", 0}, - {"greater", 1}, - {"Î", 0}, - {"grave", 1}, - {"Ì", 0}, - {"asciicircum", 1}, - {"Î", 0}, - {"N", 16}, - {"less", 1}, - {"Ň", 0}, - {"o", 1}, - {"№", 0}, - {"equal", 1}, - {"₦", 0}, - {"G", 1}, - {"Ŋ", 0}, - {"apostrophe", 1}, - {"Ń", 0}, - {"O", 1}, - {"№", 0}, - {"comma", 1}, - {"Ņ", 0}, - {"asciitilde", 1}, - {"Ñ", 0}, - {"grave", 362}, - {"W", 1}, - {"Ẁ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"a", 1}, - {"à", 0}, - {"Greek_IOTA", 1}, - {"Ὶ", 0}, - {"Greek_iota", 1}, - {"ὶ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Greek_OMICRON", 1}, - {"Ὸ", 0}, - {"Acircumflex", 1}, - {"Ầ", 0}, - {"Cyrillic_er", 1}, - {"р̀", 0}, - {"e", 1}, - {"è", 0}, - {"o", 1}, - {"ò", 0}, - {"Udiaeresis", 1}, - {"Ǜ", 0}, - {"Greek_upsilon", 1}, - {"ὺ", 0}, - {"uhorn", 1}, - {"ừ", 0}, - {"space", 1}, - {"`", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"acircumflex", 1}, - {"ầ", 0}, - {"Ecircumflex", 1}, - {"Ề", 0}, - {"Cyrillic_I", 1}, - {"Ѝ", 0}, - {"y", 1}, - {"ỳ", 0}, - {"b", 4}, - {"a", 1}, - {"ằ", 0}, - {"A", 1}, - {"Ằ", 0}, - {"Cyrillic_O", 1}, - {"О̀", 0}, - {"i", 1}, - {"ì", 0}, - {"n", 1}, - {"ǹ", 0}, - {"Cyrillic_a", 1}, - {"а̀", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἲ", 0}, - {"Greek_iota", 1}, - {"ἲ", 0}, - {"Greek_OMICRON", 1}, - {"Ὂ", 0}, - {"Greek_upsilon", 1}, - {"ὒ", 0}, - {"Greek_epsilon", 1}, - {"ἒ", 0}, - {"Greek_ALPHA", 1}, - {"Ἂ", 0}, - {"Greek_omicron", 1}, - {"ὂ", 0}, - {"Greek_eta", 1}, - {"ἢ", 0}, - {"Greek_alpha", 1}, - {"ἂ", 0}, - {"Greek_ETA", 1}, - {"Ἢ", 0}, - {"Greek_EPSILON", 1}, - {"Ἒ", 0}, - {"Greek_omega", 1}, - {"ὢ", 0}, - {"Greek_OMEGA", 1}, - {"Ὢ", 0}, - {"Ohorn", 1}, - {"Ờ", 0}, - {"ohorn", 1}, - {"ờ", 0}, - {"Cyrillic_ER", 1}, - {"Р̀", 0}, - {"Greek_epsilon", 1}, - {"ὲ", 0}, - {"Cyrillic_U", 1}, - {"У̀", 0}, - {"Ocircumflex", 1}, - {"Ồ", 0}, - {"omacron", 1}, - {"ṑ", 0}, - {"ocircumflex", 1}, - {"ồ", 0}, - {"u", 1}, - {"ù", 0}, - {"Greek_ALPHA", 1}, - {"Ὰ", 0}, - {"Cyrillic_ie", 1}, - {"ѐ", 0}, - {"emacron", 1}, - {"ḕ", 0}, - {"E", 1}, - {"È", 0}, - {"Greek_iotadieresis", 1}, - {"ῒ", 0}, - {"Y", 1}, - {"Ỳ", 0}, - {"Cyrillic_i", 1}, - {"ѝ", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἳ", 0}, - {"Greek_iota", 1}, - {"ἳ", 0}, - {"Greek_OMICRON", 1}, - {"Ὃ", 0}, - {"Greek_upsilon", 1}, - {"ὓ", 0}, - {"Greek_epsilon", 1}, - {"ἓ", 0}, - {"Greek_ALPHA", 1}, - {"Ἃ", 0}, - {"Greek_omicron", 1}, - {"ὃ", 0}, - {"Greek_eta", 1}, - {"ἣ", 0}, - {"Greek_alpha", 1}, - {"ἃ", 0}, - {"Greek_ETA", 1}, - {"Ἣ", 0}, - {"Greek_EPSILON", 1}, - {"Ἓ", 0}, - {"Greek_omega", 1}, - {"ὣ", 0}, - {"Greek_OMEGA", 1}, - {"Ὣ", 0}, - {"Greek_UPSILON", 1}, - {"Ὓ", 0}, - {"Greek_upsilondieresis", 1}, - {"ῢ", 0}, - {"Greek_omicron", 1}, - {"ὸ", 0}, - {"Greek_eta", 1}, - {"ὴ", 0}, - {"Abreve", 1}, - {"Ằ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἲ", 0}, - {"Greek_iota", 1}, - {"ἲ", 0}, - {"Greek_OMICRON", 1}, - {"Ὂ", 0}, - {"Greek_upsilon", 1}, - {"ὒ", 0}, - {"Greek_epsilon", 1}, - {"ἒ", 0}, - {"Greek_ALPHA", 1}, - {"Ἂ", 0}, - {"Greek_omicron", 1}, - {"ὂ", 0}, - {"Greek_eta", 1}, - {"ἢ", 0}, - {"Greek_alpha", 1}, - {"ἂ", 0}, - {"Greek_ETA", 1}, - {"Ἢ", 0}, - {"Greek_EPSILON", 1}, - {"Ἒ", 0}, - {"Greek_omega", 1}, - {"ὢ", 0}, - {"Greek_OMEGA", 1}, - {"Ὢ", 0}, - {"quotedbl", 8}, - {"Greek_iota", 1}, - {"ῒ", 0}, - {"Greek_upsilon", 1}, - {"ῢ", 0}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"plus", 8}, - {"o", 1}, - {"ờ", 0}, - {"u", 1}, - {"ừ", 0}, - {"O", 1}, - {"Ờ", 0}, - {"U", 1}, - {"Ừ", 0}, - {"Greek_alpha", 1}, - {"ὰ", 0}, - {"ecircumflex", 1}, - {"ề", 0}, - {"w", 1}, - {"ẁ", 0}, - {"Greek_ETA", 1}, - {"Ὴ", 0}, - {"Cyrillic_o", 1}, - {"о̀", 0}, - {"Emacron", 1}, - {"Ḕ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"O", 1}, - {"Ò", 0}, - {"abreve", 1}, - {"ằ", 0}, - {"macron", 8}, - {"e", 1}, - {"ḕ", 0}, - {"o", 1}, - {"ṑ", 0}, - {"E", 1}, - {"Ḕ", 0}, - {"O", 1}, - {"Ṑ", 0}, - {"A", 1}, - {"À", 0}, - {"Greek_EPSILON", 1}, - {"Ὲ", 0}, - {"Cyrillic_A", 1}, - {"А̀", 0}, - {"Omacron", 1}, - {"Ṑ", 0}, - {"Cyrillic_IE", 1}, - {"Ѐ", 0}, - {"Greek_omega", 1}, - {"ὼ", 0}, - {"dead_diaeresis", 8}, - {"Greek_iota", 1}, - {"ῒ", 0}, - {"Greek_upsilon", 1}, - {"ῢ", 0}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"Uhorn", 1}, - {"Ừ", 0}, - {"Greek_OMEGA", 1}, - {"Ὼ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἳ", 0}, - {"Greek_iota", 1}, - {"ἳ", 0}, - {"Greek_OMICRON", 1}, - {"Ὃ", 0}, - {"Greek_upsilon", 1}, - {"ὓ", 0}, - {"Greek_epsilon", 1}, - {"ἓ", 0}, - {"Greek_ALPHA", 1}, - {"Ἃ", 0}, - {"Greek_omicron", 1}, - {"ὃ", 0}, - {"Greek_eta", 1}, - {"ἣ", 0}, - {"Greek_alpha", 1}, - {"ἃ", 0}, - {"Greek_ETA", 1}, - {"Ἣ", 0}, - {"Greek_EPSILON", 1}, - {"Ἓ", 0}, - {"Greek_omega", 1}, - {"ὣ", 0}, - {"Greek_OMEGA", 1}, - {"Ὣ", 0}, - {"Greek_UPSILON", 1}, - {"Ὓ", 0}, - {"udiaeresis", 1}, - {"ǜ", 0}, - {"I", 1}, - {"Ì", 0}, - {"N", 1}, - {"Ǹ", 0}, - {"grave", 24}, - {"Cyrillic_er", 1}, - {"р̏", 0}, - {"Cyrillic_I", 1}, - {"И̏", 0}, - {"Cyrillic_O", 1}, - {"О̏", 0}, - {"Cyrillic_a", 1}, - {"а̏", 0}, - {"Cyrillic_ER", 1}, - {"Р̏", 0}, - {"Cyrillic_U", 1}, - {"У̏", 0}, - {"Cyrillic_ie", 1}, - {"е̏", 0}, - {"Cyrillic_i", 1}, - {"и̏", 0}, - {"Cyrillic_o", 1}, - {"о̏", 0}, - {"Cyrillic_A", 1}, - {"А̏", 0}, - {"Cyrillic_IE", 1}, - {"Е̏", 0}, - {"Cyrillic_u", 1}, - {"у̏", 0}, - {"U", 1}, - {"Ù", 0}, - {"Cyrillic_u", 1}, - {"у̀", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ầ", 0}, - {"e", 1}, - {"ề", 0}, - {"o", 1}, - {"ồ", 0}, - {"E", 1}, - {"Ề", 0}, - {"O", 1}, - {"Ồ", 0}, - {"A", 1}, - {"Ầ", 0}, - {"Greek_UPSILON", 1}, - {"Ὺ", 0}, - {"U", 106}, - {"minus", 1}, - {"Ū", 0}, - {"g", 1}, - {"ğ", 0}, - {"a", 1}, - {"ă", 0}, - {"Greek_IOTA", 1}, - {"Ῐ", 0}, - {"Greek_iota", 1}, - {"ῐ", 0}, - {"exclam", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"e", 1}, - {"ĕ", 0}, - {"o", 1}, - {"ŏ", 0}, - {"Greek_upsilon", 1}, - {"ῠ", 0}, - {"diaeresis", 1}, - {"Ü", 0}, - {"dead_belowdot", 4}, - {"a", 1}, - {"ặ", 0}, - {"A", 1}, - {"Ặ", 0}, - {"space", 5}, - {"comma", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"Cyrillic_I", 1}, - {"Й", 0}, - {"i", 1}, - {"ĭ", 0}, - {"Cyrillic_a", 1}, - {"ӑ", 0}, - {"Cyrillic_U", 1}, - {"Ў", 0}, - {"u", 1}, - {"ŭ", 0}, - {"G", 1}, - {"Ğ", 0}, - {"Greek_ALPHA", 1}, - {"Ᾰ", 0}, - {"Cyrillic_ie", 1}, - {"ӗ", 0}, - {"E", 1}, - {"Ĕ", 0}, - {"Cyrillic_i", 1}, - {"й", 0}, - {"Cyrillic_zhe", 1}, - {"ӂ", 0}, - {"quotedbl", 1}, - {"Ü", 0}, - {"cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"Greek_alpha", 1}, - {"ᾰ", 0}, - {"acute", 1}, - {"Ú", 0}, - {"underscore", 1}, - {"Ū", 0}, - {"apostrophe", 1}, - {"Ú", 0}, - {"O", 1}, - {"Ŏ", 0}, - {"asterisk", 1}, - {"Ů", 0}, - {"A", 1}, - {"Ă", 0}, - {"Cyrillic_A", 1}, - {"Ӑ", 0}, - {"comma", 1}, - {"Ų", 0}, - {"asciitilde", 1}, - {"Ũ", 0}, - {"greater", 1}, - {"Û", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӂ", 0}, - {"Cyrillic_IE", 1}, - {"Ӗ", 0}, - {"dead_cedilla", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"I", 1}, - {"Ĭ", 0}, - {"grave", 1}, - {"Ù", 0}, - {"U", 1}, - {"Ŭ", 0}, - {"Cyrillic_u", 1}, - {"ў", 0}, - {"asciicircum", 1}, - {"Û", 0}, - {"Greek_UPSILON", 1}, - {"Ῠ", 0}, - {"asciicircum", 214}, - {"minus", 1}, - {"¯", 0}, - {"period", 1}, - {"·", 0}, - {"W", 1}, - {"Ŵ", 0}, - {"g", 1}, - {"ĝ", 0}, - {"a", 1}, - {"â", 0}, - {"1", 1}, - {"¹", 0}, - {"C", 1}, - {"Ĉ", 0}, - {"KP_4", 1}, - {"⁴", 0}, - {"exclam", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"Cyrillic_er", 1}, - {"р̂", 0}, - {"o", 1}, - {"ô", 0}, - {"e", 1}, - {"ê", 0}, - {"KP_6", 1}, - {"⁶", 0}, - {"dead_belowdot", 12}, - {"a", 1}, - {"ậ", 0}, - {"e", 1}, - {"ệ", 0}, - {"o", 1}, - {"ộ", 0}, - {"E", 1}, - {"Ệ", 0}, - {"O", 1}, - {"Ộ", 0}, - {"A", 1}, - {"Ậ", 0}, - {"space", 1}, - {"^", 0}, - {"KP_8", 1}, - {"⁸", 0}, - {"Cyrillic_I", 1}, - {"И̂", 0}, - {"y", 1}, - {"ŷ", 0}, - {"Cyrillic_O", 1}, - {"О̂", 0}, - {"i", 1}, - {"î", 0}, - {"KP_9", 1}, - {"⁹", 0}, - {"equal", 1}, - {"⁼", 0}, - {"KP_Space", 1}, - {"²", 0}, - {"7", 1}, - {"⁷", 0}, - {"Cyrillic_a", 1}, - {"а̂", 0}, - {"j", 1}, - {"ĵ", 0}, - {"parenright", 1}, - {"⁾", 0}, - {"Cyrillic_ER", 1}, - {"Р̂", 0}, - {"KP_7", 1}, - {"⁷", 0}, - {"underbar", 24}, - {"a", 1}, - {"ª", 0}, - {"o", 1}, - {"º", 0}, - {"l", 1}, - {"ˡ", 0}, - {"y", 1}, - {"ʸ", 0}, - {"i", 1}, - {"ⁱ", 0}, - {"n", 1}, - {"ⁿ", 0}, - {"j", 1}, - {"ʲ", 0}, - {"x", 1}, - {"ˣ", 0}, - {"w", 1}, - {"ʷ", 0}, - {"r", 1}, - {"ʳ", 0}, - {"s", 1}, - {"ˢ", 0}, - {"h", 1}, - {"ʰ", 0}, - {"Cyrillic_U", 1}, - {"У̂", 0}, - {"u", 1}, - {"û", 0}, - {"z", 1}, - {"ẑ", 0}, - {"G", 1}, - {"Ĝ", 0}, - {"H", 1}, - {"Ĥ", 0}, - {"8", 1}, - {"⁸", 0}, - {"KP_1", 1}, - {"¹", 0}, - {"3", 1}, - {"³", 0}, - {"Cyrillic_ie", 1}, - {"е̂", 0}, - {"E", 1}, - {"Ê", 0}, - {"S", 1}, - {"Ŝ", 0}, - {"2", 1}, - {"²", 0}, - {"Y", 1}, - {"Ŷ", 0}, - {"Cyrillic_i", 1}, - {"и̂", 0}, - {"plus", 1}, - {"⁺", 0}, - {"6", 1}, - {"⁶", 0}, - {"w", 1}, - {"ŵ", 0}, - {"Cyrillic_o", 1}, - {"о̂", 0}, - {"4", 1}, - {"⁴", 0}, - {"KP_3", 1}, - {"³", 0}, - {"underscore", 24}, - {"a", 1}, - {"ª", 0}, - {"o", 1}, - {"º", 0}, - {"l", 1}, - {"ˡ", 0}, - {"y", 1}, - {"ʸ", 0}, - {"i", 1}, - {"ⁱ", 0}, - {"n", 1}, - {"ⁿ", 0}, - {"j", 1}, - {"ʲ", 0}, - {"x", 1}, - {"ˣ", 0}, - {"w", 1}, - {"ʷ", 0}, - {"r", 1}, - {"ʳ", 0}, - {"s", 1}, - {"ˢ", 0}, - {"h", 1}, - {"ʰ", 0}, - {"J", 1}, - {"Ĵ", 0}, - {"O", 1}, - {"Ô", 0}, - {"s", 1}, - {"ŝ", 0}, - {"Z", 1}, - {"Ẑ", 0}, - {"KP_0", 1}, - {"⁰", 0}, - {"A", 1}, - {"Â", 0}, - {"c", 1}, - {"ĉ", 0}, - {"KP_Add", 1}, - {"⁺", 0}, - {"KP_2", 1}, - {"²", 0}, - {"Cyrillic_A", 1}, - {"А̂", 0}, - {"slash", 1}, - {"|", 0}, - {"5", 1}, - {"⁵", 0}, - {"KP_5", 1}, - {"⁵", 0}, - {"9", 1}, - {"⁹", 0}, - {"Cyrillic_IE", 1}, - {"Е̂", 0}, - {"0", 1}, - {"⁰", 0}, - {"parenleft", 1}, - {"⁽", 0}, - {"h", 1}, - {"ĥ", 0}, - {"I", 1}, - {"Î", 0}, - {"U", 1}, - {"Û", 0}, - {"Cyrillic_u", 1}, - {"у̂", 0}, - {"KP_Equal", 1}, - {"⁼", 0}, - {"Greek_UPSILON", 4}, - {"quotedbl", 1}, - {"Ϋ", 0}, - {"apostrophe", 1}, - {"Ύ", 0}, - {"dead_belowcircumflex", 24}, - {"e", 1}, - {"ḙ", 0}, - {"l", 1}, - {"ḽ", 0}, - {"t", 1}, - {"ṱ", 0}, - {"n", 1}, - {"ṋ", 0}, - {"u", 1}, - {"ṷ", 0}, - {"E", 1}, - {"Ḙ", 0}, - {"d", 1}, - {"ḓ", 0}, - {"D", 1}, - {"Ḓ", 0}, - {"L", 1}, - {"Ḽ", 0}, - {"T", 1}, - {"Ṱ", 0}, - {"N", 1}, - {"Ṋ", 0}, - {"U", 1}, - {"Ṷ", 0}, - {"dead_caron", 134}, - {"minus", 1}, - {"₋", 0}, - {"g", 1}, - {"ǧ", 0}, - {"a", 1}, - {"ǎ", 0}, - {"1", 1}, - {"₁", 0}, - {"ezh", 1}, - {"ǯ", 0}, - {"C", 1}, - {"Č", 0}, - {"e", 1}, - {"ě", 0}, - {"o", 1}, - {"ǒ", 0}, - {"l", 1}, - {"ľ", 0}, - {"Udiaeresis", 1}, - {"Ǚ", 0}, - {"t", 1}, - {"ť", 0}, - {"space", 1}, - {"ˇ", 0}, - {"Multi_key", 5}, - {"quotedbl", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"i", 1}, - {"ǐ", 0}, - {"k", 1}, - {"ǩ", 0}, - {"n", 1}, - {"ň", 0}, - {"equal", 1}, - {"₌", 0}, - {"dead_caron", 1}, - {"ˇ", 0}, - {"7", 1}, - {"₇", 0}, - {"j", 1}, - {"ǰ", 0}, - {"parenright", 1}, - {"₎", 0}, - {"sabovedot", 1}, - {"ṧ", 0}, - {"nobreakspace", 1}, - {"̌", 0}, - {"V", 1}, - {"Ǚ", 0}, - {"u", 1}, - {"ǔ", 0}, - {"z", 1}, - {"ž", 0}, - {"G", 1}, - {"Ǧ", 0}, - {"H", 1}, - {"Ȟ", 0}, - {"8", 1}, - {"₈", 0}, - {"3", 1}, - {"₃", 0}, - {"E", 1}, - {"Ě", 0}, - {"S", 1}, - {"Š", 0}, - {"2", 1}, - {"₂", 0}, - {"d", 1}, - {"ď", 0}, - {"D", 1}, - {"Ď", 0}, - {"plus", 1}, - {"₊", 0}, - {"6", 1}, - {"₆", 0}, - {"dead_abovedot", 4}, - {"S", 1}, - {"Ṧ", 0}, - {"s", 1}, - {"ṧ", 0}, - {"4", 1}, - {"₄", 0}, - {"v", 1}, - {"ǚ", 0}, - {"O", 1}, - {"Ǒ", 0}, - {"r", 1}, - {"ř", 0}, - {"s", 1}, - {"š", 0}, - {"Z", 1}, - {"Ž", 0}, - {"EZH", 1}, - {"Ǯ", 0}, - {"A", 1}, - {"Ǎ", 0}, - {"R", 1}, - {"Ř", 0}, - {"c", 1}, - {"č", 0}, - {"L", 1}, - {"Ľ", 0}, - {"T", 1}, - {"Ť", 0}, - {"5", 1}, - {"₅", 0}, - {"K", 1}, - {"Ǩ", 0}, - {"9", 1}, - {"₉", 0}, - {"0", 1}, - {"₀", 0}, - {"Sabovedot", 1}, - {"Ṧ", 0}, - {"dead_diaeresis", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"parenleft", 1}, - {"₍", 0}, - {"h", 1}, - {"ȟ", 0}, - {"udiaeresis", 1}, - {"ǚ", 0}, - {"I", 1}, - {"Ǐ", 0}, - {"N", 1}, - {"Ň", 0}, - {"U", 1}, - {"Ǔ", 0}, - {"dead_tilde", 266}, - {"dead_breve", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"a", 1}, - {"ã", 0}, - {"Greek_iota", 1}, - {"ῖ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"Acircumflex", 1}, - {"Ẫ", 0}, - {"less", 1}, - {"≲", 0}, - {"Oacute", 1}, - {"Ṍ", 0}, - {"e", 1}, - {"ẽ", 0}, - {"o", 1}, - {"õ", 0}, - {"Greek_upsilon", 1}, - {"ῦ", 0}, - {"uhorn", 1}, - {"ữ", 0}, - {"space", 1}, - {"~", 0}, - {"dead_macron", 4}, - {"o", 1}, - {"ȭ", 0}, - {"O", 1}, - {"Ȭ", 0}, - {"acircumflex", 1}, - {"ẫ", 0}, - {"Ecircumflex", 1}, - {"Ễ", 0}, - {"y", 1}, - {"ỹ", 0}, - {"Multi_key", 77}, - {"b", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"parenright", 18}, - {"Greek_IOTA", 1}, - {"Ἶ", 0}, - {"Greek_iota", 1}, - {"ἶ", 0}, - {"Greek_upsilon", 1}, - {"ὖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἆ", 0}, - {"Greek_eta", 1}, - {"ἦ", 0}, - {"Greek_alpha", 1}, - {"ἆ", 0}, - {"Greek_ETA", 1}, - {"Ἦ", 0}, - {"Greek_omega", 1}, - {"ὦ", 0}, - {"Greek_OMEGA", 1}, - {"Ὦ", 0}, - {"quotedbl", 4}, - {"Greek_iota", 1}, - {"ῗ", 0}, - {"Greek_upsilon", 1}, - {"ῧ", 0}, - {"plus", 8}, - {"o", 1}, - {"ỡ", 0}, - {"u", 1}, - {"ữ", 0}, - {"O", 1}, - {"Ỡ", 0}, - {"U", 1}, - {"Ữ", 0}, - {"parenleft", 20}, - {"Greek_IOTA", 1}, - {"Ἷ", 0}, - {"Greek_iota", 1}, - {"ἷ", 0}, - {"Greek_upsilon", 1}, - {"ὗ", 0}, - {"Greek_ALPHA", 1}, - {"Ἇ", 0}, - {"Greek_eta", 1}, - {"ἧ", 0}, - {"Greek_alpha", 1}, - {"ἇ", 0}, - {"Greek_ETA", 1}, - {"Ἧ", 0}, - {"Greek_omega", 1}, - {"ὧ", 0}, - {"Greek_OMEGA", 1}, - {"Ὧ", 0}, - {"Greek_UPSILON", 1}, - {"Ὗ", 0}, - {"U", 4}, - {"a", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ẵ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ẫ", 0}, - {"e", 1}, - {"ễ", 0}, - {"o", 1}, - {"ỗ", 0}, - {"E", 1}, - {"Ễ", 0}, - {"O", 1}, - {"Ỗ", 0}, - {"A", 1}, - {"Ẫ", 0}, - {"oacute", 1}, - {"ṍ", 0}, - {"i", 1}, - {"ĩ", 0}, - {"n", 1}, - {"ñ", 0}, - {"equal", 1}, - {"≃", 0}, - {"dead_tilde", 1}, - {"~", 0}, - {"Uacute", 1}, - {"Ṹ", 0}, - {"Ohorn", 1}, - {"Ỡ", 0}, - {"ohorn", 1}, - {"ỡ", 0}, - {"nobreakspace", 1}, - {"̃", 0}, - {"V", 1}, - {"Ṽ", 0}, - {"Ocircumflex", 1}, - {"Ỗ", 0}, - {"omacron", 1}, - {"ȭ", 0}, - {"uacute", 1}, - {"ṹ", 0}, - {"ocircumflex", 1}, - {"ỗ", 0}, - {"u", 1}, - {"ũ", 0}, - {"E", 1}, - {"Ẽ", 0}, - {"Greek_iotadieresis", 1}, - {"ῗ", 0}, - {"Y", 1}, - {"Ỹ", 0}, - {"dead_dasia", 20}, - {"Greek_IOTA", 1}, - {"Ἷ", 0}, - {"Greek_iota", 1}, - {"ἷ", 0}, - {"Greek_upsilon", 1}, - {"ὗ", 0}, - {"Greek_ALPHA", 1}, - {"Ἇ", 0}, - {"Greek_eta", 1}, - {"ἧ", 0}, - {"Greek_alpha", 1}, - {"ἇ", 0}, - {"Greek_ETA", 1}, - {"Ἧ", 0}, - {"Greek_omega", 1}, - {"ὧ", 0}, - {"Greek_OMEGA", 1}, - {"Ὧ", 0}, - {"Greek_UPSILON", 1}, - {"Ὗ", 0}, - {"Greek_upsilondieresis", 1}, - {"ῧ", 0}, - {"odiaeresis", 1}, - {"ṏ", 0}, - {"Greek_eta", 1}, - {"ῆ", 0}, - {"Abreve", 1}, - {"Ẵ", 0}, - {"dead_psili", 18}, - {"Greek_IOTA", 1}, - {"Ἶ", 0}, - {"Greek_iota", 1}, - {"ἶ", 0}, - {"Greek_upsilon", 1}, - {"ὖ", 0}, - {"Greek_ALPHA", 1}, - {"Ἆ", 0}, - {"Greek_eta", 1}, - {"ἦ", 0}, - {"Greek_alpha", 1}, - {"ἆ", 0}, - {"Greek_ETA", 1}, - {"Ἦ", 0}, - {"Greek_omega", 1}, - {"ὦ", 0}, - {"Greek_OMEGA", 1}, - {"Ὦ", 0}, - {"Greek_alpha", 1}, - {"ᾶ", 0}, - {"ecircumflex", 1}, - {"ễ", 0}, - {"v", 1}, - {"ṽ", 0}, - {"O", 1}, - {"Õ", 0}, - {"abreve", 1}, - {"ẵ", 0}, - {"A", 1}, - {"Ã", 0}, - {"Odiaeresis", 1}, - {"Ṏ", 0}, - {"greater", 1}, - {"≳", 0}, - {"Omacron", 1}, - {"Ȭ", 0}, - {"Greek_omega", 1}, - {"ῶ", 0}, - {"dead_diaeresis", 8}, - {"Greek_iota", 1}, - {"ῗ", 0}, - {"o", 1}, - {"ṏ", 0}, - {"Greek_upsilon", 1}, - {"ῧ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"Uhorn", 1}, - {"Ữ", 0}, - {"dead_acute", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"I", 1}, - {"Ĩ", 0}, - {"N", 1}, - {"Ñ", 0}, - {"U", 1}, - {"Ũ", 0}, - {"dead_belowcomma", 14}, - {"t", 1}, - {"ț", 0}, - {"space", 1}, - {",", 0}, - {"dead_belowcomma", 1}, - {",", 0}, - {"nobreakspace", 1}, - {"̦", 0}, - {"S", 1}, - {"Ș", 0}, - {"s", 1}, - {"ș", 0}, - {"T", 1}, - {"Ț", 0}, - {"dead_doubleacute", 18}, - {"o", 1}, - {"ő", 0}, - {"space", 1}, - {"˝", 0}, - {"Cyrillic_U", 1}, - {"Ӳ", 0}, - {"dead_doubleacute", 1}, - {"˝", 0}, - {"nobreakspace", 1}, - {"̋", 0}, - {"u", 1}, - {"ű", 0}, - {"O", 1}, - {"Ő", 0}, - {"U", 1}, - {"Ű", 0}, - {"Cyrillic_u", 1}, - {"ӳ", 0}, - {"dead_abovering", 27}, - {"a", 1}, - {"å", 0}, - {"space", 1}, - {"°", 0}, - {"y", 1}, - {"ẙ", 0}, - {"dead_abovering", 1}, - {"°", 0}, - {"nobreakspace", 1}, - {"̊", 0}, - {"u", 1}, - {"ů", 0}, - {"w", 1}, - {"ẘ", 0}, - {"A", 1}, - {"Å", 0}, - {"Aacute", 1}, - {"Ǻ", 0}, - {"aacute", 1}, - {"ǻ", 0}, - {"dead_acute", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"U", 1}, - {"Ů", 0}, - {"Greek_accentdieresis", 4}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"dead_voiced_sound", 46}, - {"kana_KE", 1}, - {"ゲ", 0}, - {"kana_SA", 1}, - {"ザ", 0}, - {"kana_SE", 1}, - {"ゼ", 0}, - {"kana_SU", 1}, - {"ズ", 0}, - {"kana_WO", 1}, - {"ヺ", 0}, - {"kana_TE", 1}, - {"デ", 0}, - {"kana_HO", 1}, - {"ボ", 0}, - {"kana_HI", 1}, - {"ビ", 0}, - {"kana_WA", 1}, - {"ヷ", 0}, - {"kana_CHI", 1}, - {"ヂ", 0}, - {"kana_HA", 1}, - {"バ", 0}, - {"kana_HE", 1}, - {"ベ", 0}, - {"kana_KO", 1}, - {"ゴ", 0}, - {"kana_FU", 1}, - {"ブ", 0}, - {"kana_KU", 1}, - {"グ", 0}, - {"kana_U", 1}, - {"ヴ", 0}, - {"kana_TO", 1}, - {"ド", 0}, - {"kana_TA", 1}, - {"ダ", 0}, - {"kana_KA", 1}, - {"ガ", 0}, - {"kana_KI", 1}, - {"ギ", 0}, - {"kana_SO", 1}, - {"ゾ", 0}, - {"kana_TSU", 1}, - {"ヅ", 0}, - {"kana_SHI", 1}, - {"ジ", 0}, - {"dead_belowtilde", 14}, - {"e", 1}, - {"ḛ", 0}, - {"i", 1}, - {"ḭ", 0}, - {"u", 1}, - {"ṵ", 0}, - {"E", 1}, - {"Ḛ", 0}, - {"plus", 1}, - {"⨦", 0}, - {"I", 1}, - {"Ḭ", 0}, - {"U", 1}, - {"Ṵ", 0}, - {"dead_ogonek", 35}, - {"a", 1}, - {"ą", 0}, - {"e", 1}, - {"ę", 0}, - {"o", 1}, - {"ǫ", 0}, - {"space", 1}, - {"˛", 0}, - {"dead_macron", 4}, - {"o", 1}, - {"ǭ", 0}, - {"O", 1}, - {"Ǭ", 0}, - {"i", 1}, - {"į", 0}, - {"nobreakspace", 1}, - {"̨", 0}, - {"omacron", 1}, - {"ǭ", 0}, - {"u", 1}, - {"ų", 0}, - {"E", 1}, - {"Ę", 0}, - {"dead_ogonek", 1}, - {"˛", 0}, - {"O", 1}, - {"Ǫ", 0}, - {"A", 1}, - {"Ą", 0}, - {"Omacron", 1}, - {"Ǭ", 0}, - {"I", 1}, - {"Į", 0}, - {"U", 1}, - {"Ų", 0}, - {"dead_dasia", 32}, - {"Greek_IOTA", 1}, - {"Ἱ", 0}, - {"Greek_iota", 1}, - {"ἱ", 0}, - {"Greek_OMICRON", 1}, - {"Ὁ", 0}, - {"Greek_upsilon", 1}, - {"ὑ", 0}, - {"Greek_RHO", 1}, - {"Ῥ", 0}, - {"Greek_epsilon", 1}, - {"ἑ", 0}, - {"Greek_ALPHA", 1}, - {"Ἁ", 0}, - {"Greek_omicron", 1}, - {"ὁ", 0}, - {"Greek_eta", 1}, - {"ἡ", 0}, - {"Greek_rho", 1}, - {"ῥ", 0}, - {"Greek_alpha", 1}, - {"ἁ", 0}, - {"Greek_ETA", 1}, - {"Ἡ", 0}, - {"Greek_EPSILON", 1}, - {"Ἑ", 0}, - {"Greek_omega", 1}, - {"ὡ", 0}, - {"Greek_OMEGA", 1}, - {"Ὡ", 0}, - {"Greek_UPSILON", 1}, - {"Ὑ", 0}, - {"dead_iota", 491}, - {"dead_grave", 59}, - {"Multi_key", 26}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_eta", 1}, - {"ῂ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"Greek_alpha", 1}, - {"ᾲ", 0}, - {"Greek_omega", 1}, - {"ῲ", 0}, - {"space", 1}, - {"ͺ", 0}, - {"Multi_key", 262}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾈ", 0}, - {"Greek_eta", 1}, - {"ᾐ", 0}, - {"Greek_alpha", 1}, - {"ᾀ", 0}, - {"Greek_ETA", 1}, - {"ᾘ", 0}, - {"Greek_omega", 1}, - {"ᾠ", 0}, - {"Greek_OMEGA", 1}, - {"ᾨ", 0}, - {"acute", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"apostrophe", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"asciitilde", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_eta", 1}, - {"ῇ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"Greek_alpha", 1}, - {"ᾷ", 0}, - {"Greek_omega", 1}, - {"ῷ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾉ", 0}, - {"Greek_eta", 1}, - {"ᾑ", 0}, - {"Greek_alpha", 1}, - {"ᾁ", 0}, - {"Greek_ETA", 1}, - {"ᾙ", 0}, - {"Greek_omega", 1}, - {"ᾡ", 0}, - {"Greek_OMEGA", 1}, - {"ᾩ", 0}, - {"grave", 58}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"Greek_eta", 1}, - {"ῂ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾊ", 0}, - {"Greek_eta", 1}, - {"ᾒ", 0}, - {"Greek_alpha", 1}, - {"ᾂ", 0}, - {"Greek_ETA", 1}, - {"ᾚ", 0}, - {"Greek_omega", 1}, - {"ᾢ", 0}, - {"Greek_OMEGA", 1}, - {"ᾪ", 0}, - {"Greek_alpha", 1}, - {"ᾲ", 0}, - {"Greek_omega", 1}, - {"ῲ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾋ", 0}, - {"Greek_eta", 1}, - {"ᾓ", 0}, - {"Greek_alpha", 1}, - {"ᾃ", 0}, - {"Greek_ETA", 1}, - {"ᾛ", 0}, - {"Greek_omega", 1}, - {"ᾣ", 0}, - {"Greek_OMEGA", 1}, - {"ᾫ", 0}, - {"dead_tilde", 59}, - {"Multi_key", 26}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾏ", 0}, - {"Greek_eta", 1}, - {"ᾗ", 0}, - {"Greek_alpha", 1}, - {"ᾇ", 0}, - {"Greek_ETA", 1}, - {"ᾟ", 0}, - {"Greek_omega", 1}, - {"ᾧ", 0}, - {"Greek_OMEGA", 1}, - {"ᾯ", 0}, - {"Greek_eta", 1}, - {"ῇ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾎ", 0}, - {"Greek_eta", 1}, - {"ᾖ", 0}, - {"Greek_alpha", 1}, - {"ᾆ", 0}, - {"Greek_ETA", 1}, - {"ᾞ", 0}, - {"Greek_omega", 1}, - {"ᾦ", 0}, - {"Greek_OMEGA", 1}, - {"ᾮ", 0}, - {"Greek_alpha", 1}, - {"ᾷ", 0}, - {"Greek_omega", 1}, - {"ῷ", 0}, - {"Greek_ALPHA", 1}, - {"ᾼ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾉ", 0}, - {"Greek_eta", 1}, - {"ᾑ", 0}, - {"Greek_alpha", 1}, - {"ᾁ", 0}, - {"Greek_ETA", 1}, - {"ᾙ", 0}, - {"Greek_omega", 1}, - {"ᾡ", 0}, - {"Greek_OMEGA", 1}, - {"ᾩ", 0}, - {"Greek_eta", 1}, - {"ῃ", 0}, - {"dead_iota", 1}, - {"ͺ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾈ", 0}, - {"Greek_eta", 1}, - {"ᾐ", 0}, - {"Greek_alpha", 1}, - {"ᾀ", 0}, - {"Greek_ETA", 1}, - {"ᾘ", 0}, - {"Greek_omega", 1}, - {"ᾠ", 0}, - {"Greek_OMEGA", 1}, - {"ᾨ", 0}, - {"Greek_alpha", 1}, - {"ᾳ", 0}, - {"Greek_ETA", 1}, - {"ῌ", 0}, - {"Greek_omegaaccent", 1}, - {"ῴ", 0}, - {"Greek_omega", 1}, - {"ῳ", 0}, - {"Greek_OMEGA", 1}, - {"ῼ", 0}, - {"dead_acute", 59}, - {"Multi_key", 26}, - {"parenright", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"parenleft", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"dead_dasia", 12}, - {"Greek_ALPHA", 1}, - {"ᾍ", 0}, - {"Greek_eta", 1}, - {"ᾕ", 0}, - {"Greek_alpha", 1}, - {"ᾅ", 0}, - {"Greek_ETA", 1}, - {"ᾝ", 0}, - {"Greek_omega", 1}, - {"ᾥ", 0}, - {"Greek_OMEGA", 1}, - {"ᾭ", 0}, - {"Greek_eta", 1}, - {"ῄ", 0}, - {"dead_psili", 12}, - {"Greek_ALPHA", 1}, - {"ᾌ", 0}, - {"Greek_eta", 1}, - {"ᾔ", 0}, - {"Greek_alpha", 1}, - {"ᾄ", 0}, - {"Greek_ETA", 1}, - {"ᾜ", 0}, - {"Greek_omega", 1}, - {"ᾤ", 0}, - {"Greek_OMEGA", 1}, - {"ᾬ", 0}, - {"Greek_alpha", 1}, - {"ᾴ", 0}, - {"Greek_omega", 1}, - {"ῴ", 0}, - {"Greek_alphaaccent", 1}, - {"ᾴ", 0}, - {"Greek_etaaccent", 1}, - {"ῄ", 0}, - {"dead_greek", 121}, - {"W", 1}, - {"Ω", 0}, - {"g", 1}, - {"γ", 0}, - {"a", 1}, - {"α", 0}, - {"e", 1}, - {"ε", 0}, - {"F", 1}, - {"Φ", 0}, - {"o", 1}, - {"ο", 0}, - {"l", 1}, - {"λ", 0}, - {"t", 1}, - {"τ", 0}, - {"space", 1}, - {"µ", 0}, - {"dead_macron", 12}, - {"a", 1}, - {"ᾱ", 0}, - {"i", 1}, - {"ῑ", 0}, - {"u", 1}, - {"ῡ", 0}, - {"A", 1}, - {"Ᾱ", 0}, - {"I", 1}, - {"Ῑ", 0}, - {"U", 1}, - {"Ῡ", 0}, - {"Q", 1}, - {"Χ", 0}, - {"y", 1}, - {"ψ", 0}, - {"b", 1}, - {"β", 0}, - {"i", 1}, - {"ι", 0}, - {"k", 1}, - {"κ", 0}, - {"n", 1}, - {"ν", 0}, - {"j", 1}, - {"θ", 0}, - {"x", 1}, - {"ξ", 0}, - {"q", 1}, - {"χ", 0}, - {"nobreakspace", 1}, - {"µ", 0}, - {"u", 1}, - {"υ", 0}, - {"z", 1}, - {"ζ", 0}, - {"G", 1}, - {"Γ", 0}, - {"H", 1}, - {"Η", 0}, - {"E", 1}, - {"Ε", 0}, - {"S", 1}, - {"Σ", 0}, - {"Y", 1}, - {"Ψ", 0}, - {"f", 1}, - {"φ", 0}, - {"d", 1}, - {"δ", 0}, - {"dead_greek", 1}, - {"µ", 0}, - {"D", 1}, - {"Δ", 0}, - {"w", 1}, - {"ω", 0}, - {"p", 1}, - {"π", 0}, - {"J", 1}, - {"Θ", 0}, - {"P", 1}, - {"Π", 0}, - {"M", 1}, - {"Μ", 0}, - {"O", 1}, - {"Ο", 0}, - {"m", 1}, - {"μ", 0}, - {"r", 1}, - {"ρ", 0}, - {"s", 1}, - {"σ", 0}, - {"Z", 1}, - {"Ζ", 0}, - {"dead_stroke", 2}, - {"r", 1}, - {"ϼ", 0}, - {"A", 1}, - {"Α", 0}, - {"R", 1}, - {"Ρ", 0}, - {"L", 1}, - {"Λ", 0}, - {"T", 1}, - {"Τ", 0}, - {"dead_hook", 2}, - {"U", 1}, - {"ϒ", 0}, - {"K", 1}, - {"Κ", 0}, - {"B", 1}, - {"Β", 0}, - {"X", 1}, - {"Ξ", 0}, - {"h", 1}, - {"η", 0}, - {"I", 1}, - {"Ι", 0}, - {"N", 1}, - {"Ν", 0}, - {"U", 1}, - {"Υ", 0}, - {"dead_invertedbreve", 24}, - {"Cyrillic_er", 1}, - {"р̑", 0}, - {"Cyrillic_I", 1}, - {"И̑", 0}, - {"Cyrillic_O", 1}, - {"О̑", 0}, - {"Cyrillic_a", 1}, - {"а̑", 0}, - {"Cyrillic_ER", 1}, - {"Р̑", 0}, - {"Cyrillic_U", 1}, - {"У̑", 0}, - {"Cyrillic_ie", 1}, - {"е̑", 0}, - {"Cyrillic_i", 1}, - {"и̑", 0}, - {"Cyrillic_o", 1}, - {"о̑", 0}, - {"Cyrillic_A", 1}, - {"А̑", 0}, - {"Cyrillic_IE", 1}, - {"Е̑", 0}, - {"Cyrillic_u", 1}, - {"у̑", 0}, - {"dead_psili", 28}, - {"Greek_IOTA", 1}, - {"Ἰ", 0}, - {"Greek_iota", 1}, - {"ἰ", 0}, - {"Greek_OMICRON", 1}, - {"Ὀ", 0}, - {"Greek_upsilon", 1}, - {"ὐ", 0}, - {"Greek_epsilon", 1}, - {"ἐ", 0}, - {"Greek_ALPHA", 1}, - {"Ἀ", 0}, - {"Greek_omicron", 1}, - {"ὀ", 0}, - {"Greek_eta", 1}, - {"ἠ", 0}, - {"Greek_rho", 1}, - {"ῤ", 0}, - {"Greek_alpha", 1}, - {"ἀ", 0}, - {"Greek_ETA", 1}, - {"Ἠ", 0}, - {"Greek_EPSILON", 1}, - {"Ἐ", 0}, - {"Greek_omega", 1}, - {"ὠ", 0}, - {"Greek_OMEGA", 1}, - {"Ὠ", 0}, - {"dead_abovedot", 159}, - {"W", 1}, - {"Ẇ", 0}, - {"g", 1}, - {"ġ", 0}, - {"a", 1}, - {"ȧ", 0}, - {"C", 1}, - {"Ċ", 0}, - {"e", 1}, - {"ė", 0}, - {"F", 1}, - {"Ḟ", 0}, - {"o", 1}, - {"ȯ", 0}, - {"l", 1}, - {"ŀ", 0}, - {"t", 1}, - {"ṫ", 0}, - {"dead_belowdot", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"space", 1}, - {"˙", 0}, - {"dead_macron", 8}, - {"a", 1}, - {"ǡ", 0}, - {"o", 1}, - {"ȱ", 0}, - {"O", 1}, - {"Ȱ", 0}, - {"A", 1}, - {"Ǡ", 0}, - {"y", 1}, - {"ẏ", 0}, - {"b", 1}, - {"ḃ", 0}, - {"Multi_key", 23}, - {"exclam", 4}, - {"S", 1}, - {"Ṩ", 0}, - {"s", 1}, - {"ṩ", 0}, - {"f", 2}, - {"s", 1}, - {"ẛ", 0}, - {"acute", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"apostrophe", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"c", 4}, - {"S", 1}, - {"Ṧ", 0}, - {"s", 1}, - {"ṧ", 0}, - {"i", 1}, - {"ı", 0}, - {"n", 1}, - {"ṅ", 0}, - {"dead_caron", 4}, - {"S", 1}, - {"Ṧ", 0}, - {"s", 1}, - {"ṧ", 0}, - {"j", 1}, - {"ȷ", 0}, - {"x", 1}, - {"ẋ", 0}, - {"amacron", 1}, - {"ǡ", 0}, - {"nobreakspace", 1}, - {"̇", 0}, - {"omacron", 1}, - {"ȱ", 0}, - {"z", 1}, - {"ż", 0}, - {"G", 1}, - {"Ġ", 0}, - {"Sacute", 1}, - {"Ṥ", 0}, - {"H", 1}, - {"Ḣ", 0}, - {"E", 1}, - {"Ė", 0}, - {"S", 1}, - {"Ṡ", 0}, - {"Y", 1}, - {"Ẏ", 0}, - {"scaron", 1}, - {"ṧ", 0}, - {"f", 1}, - {"ḟ", 0}, - {"d", 1}, - {"ḋ", 0}, - {"Scaron", 1}, - {"Ṧ", 0}, - {"D", 1}, - {"Ḋ", 0}, - {"dead_abovedot", 1}, - {"˙", 0}, - {"w", 1}, - {"ẇ", 0}, - {"p", 1}, - {"ṗ", 0}, - {"P", 1}, - {"Ṗ", 0}, - {"M", 1}, - {"Ṁ", 0}, - {"O", 1}, - {"Ȯ", 0}, - {"m", 1}, - {"ṁ", 0}, - {"r", 1}, - {"ṙ", 0}, - {"s", 1}, - {"ṡ", 0}, - {"Z", 1}, - {"Ż", 0}, - {"sacute", 1}, - {"ṥ", 0}, - {"dead_stroke", 2}, - {"j", 1}, - {"ɟ", 0}, - {"A", 1}, - {"Ȧ", 0}, - {"R", 1}, - {"Ṙ", 0}, - {"c", 1}, - {"ċ", 0}, - {"L", 1}, - {"Ŀ", 0}, - {"T", 1}, - {"Ṫ", 0}, - {"Omacron", 1}, - {"Ȱ", 0}, - {"B", 1}, - {"Ḃ", 0}, - {"Amacron", 1}, - {"Ǡ", 0}, - {"dead_acute", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"X", 1}, - {"Ẋ", 0}, - {"h", 1}, - {"ḣ", 0}, - {"I", 1}, - {"İ", 0}, - {"N", 1}, - {"Ṅ", 0}, - {"dead_double_grave", 24}, - {"a", 1}, - {"ȁ", 0}, - {"e", 1}, - {"ȅ", 0}, - {"o", 1}, - {"ȍ", 0}, - {"i", 1}, - {"ȉ", 0}, - {"u", 1}, - {"ȕ", 0}, - {"E", 1}, - {"Ȅ", 0}, - {"O", 1}, - {"Ȍ", 0}, - {"r", 1}, - {"ȑ", 0}, - {"A", 1}, - {"Ȁ", 0}, - {"R", 1}, - {"Ȑ", 0}, - {"I", 1}, - {"Ȉ", 0}, - {"U", 1}, - {"Ȕ", 0}, - {"dead_semivoiced_sound", 10}, - {"kana_HO", 1}, - {"ポ", 0}, - {"kana_HI", 1}, - {"ピ", 0}, - {"kana_HA", 1}, - {"パ", 0}, - {"kana_HE", 1}, - {"ペ", 0}, - {"kana_FU", 1}, - {"プ", 0}, - {"dead_stroke", 101}, - {"g", 1}, - {"ǥ", 0}, - {"a", 1}, - {"ⱥ", 0}, - {"C", 1}, - {"Ȼ", 0}, - {"less", 1}, - {"≮", 0}, - {"Oacute", 1}, - {"Ǿ", 0}, - {"e", 1}, - {"ɇ", 0}, - {"o", 1}, - {"ø", 0}, - {"l", 1}, - {"ł", 0}, - {"t", 1}, - {"ŧ", 0}, - {"space", 1}, - {"/", 0}, - {"y", 1}, - {"ɏ", 0}, - {"b", 1}, - {"ƀ", 0}, - {"oacute", 1}, - {"ǿ", 0}, - {"i", 1}, - {"ɨ", 0}, - {"equal", 1}, - {"≠", 0}, - {"j", 1}, - {"ɉ", 0}, - {"nobreakspace", 1}, - {"̸", 0}, - {"u", 1}, - {"ʉ", 0}, - {"greaterthanequal", 1}, - {"≱", 0}, - {"z", 1}, - {"ƶ", 0}, - {"G", 1}, - {"Ǥ", 0}, - {"H", 1}, - {"Ħ", 0}, - {"E", 1}, - {"Ɇ", 0}, - {"2", 1}, - {"ƻ", 0}, - {"Y", 1}, - {"Ɏ", 0}, - {"d", 1}, - {"đ", 0}, - {"dead_greek", 2}, - {"r", 1}, - {"ϼ", 0}, - {"D", 1}, - {"Đ", 0}, - {"dead_abovedot", 2}, - {"j", 1}, - {"ɟ", 0}, - {"lessthanequal", 1}, - {"≰", 0}, - {"p", 1}, - {"ᵽ", 0}, - {"J", 1}, - {"Ɉ", 0}, - {"P", 1}, - {"Ᵽ", 0}, - {"O", 1}, - {"Ø", 0}, - {"r", 1}, - {"ɍ", 0}, - {"Z", 1}, - {"Ƶ", 0}, - {"dead_stroke", 1}, - {"/", 0}, - {"A", 1}, - {"Ⱥ", 0}, - {"R", 1}, - {"Ɍ", 0}, - {"c", 1}, - {"ȼ", 0}, - {"L", 1}, - {"Ł", 0}, - {"T", 1}, - {"Ŧ", 0}, - {"greater", 1}, - {"≯", 0}, - {"B", 1}, - {"Ƀ", 0}, - {"dead_acute", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"h", 1}, - {"ħ", 0}, - {"I", 1}, - {"Ɨ", 0}, - {"U", 1}, - {"Ʉ", 0}, - {"dead_hook", 179}, - {"W", 1}, - {"Ⱳ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"g", 1}, - {"ɠ", 0}, - {"a", 1}, - {"ả", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"Acircumflex", 1}, - {"Ẩ", 0}, - {"C", 1}, - {"Ƈ", 0}, - {"e", 1}, - {"ẻ", 0}, - {"F", 1}, - {"Ƒ", 0}, - {"o", 1}, - {"ỏ", 0}, - {"t", 1}, - {"ƭ", 0}, - {"schwa", 1}, - {"ɚ", 0}, - {"uhorn", 1}, - {"ử", 0}, - {"space", 1}, - {"̉", 0}, - {"acircumflex", 1}, - {"ẩ", 0}, - {"Ecircumflex", 1}, - {"Ể", 0}, - {"y", 1}, - {"ỷ", 0}, - {"b", 1}, - {"ɓ", 0}, - {"Multi_key", 32}, - {"b", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"plus", 8}, - {"o", 1}, - {"ở", 0}, - {"u", 1}, - {"ử", 0}, - {"O", 1}, - {"Ở", 0}, - {"U", 1}, - {"Ử", 0}, - {"U", 4}, - {"a", 1}, - {"ẳ", 0}, - {"A", 1}, - {"Ẳ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ẩ", 0}, - {"e", 1}, - {"ể", 0}, - {"o", 1}, - {"ổ", 0}, - {"E", 1}, - {"Ể", 0}, - {"O", 1}, - {"Ổ", 0}, - {"A", 1}, - {"Ẩ", 0}, - {"i", 1}, - {"ỉ", 0}, - {"k", 1}, - {"ƙ", 0}, - {"n", 1}, - {"ɲ", 0}, - {"Ohorn", 1}, - {"Ở", 0}, - {"ohorn", 1}, - {"ở", 0}, - {"q", 1}, - {"ʠ", 0}, - {"nobreakspace", 1}, - {"̉", 0}, - {"V", 1}, - {"Ʋ", 0}, - {"Ocircumflex", 1}, - {"Ổ", 0}, - {"ocircumflex", 1}, - {"ổ", 0}, - {"u", 1}, - {"ủ", 0}, - {"z", 1}, - {"ȥ", 0}, - {"G", 1}, - {"Ɠ", 0}, - {"E", 1}, - {"Ẻ", 0}, - {"Y", 1}, - {"Ỷ", 0}, - {"f", 1}, - {"ƒ", 0}, - {"d", 1}, - {"ɗ", 0}, - {"dead_greek", 2}, - {"U", 1}, - {"ϒ", 0}, - {"D", 1}, - {"Ɗ", 0}, - {"Abreve", 1}, - {"Ẳ", 0}, - {"ecircumflex", 1}, - {"ể", 0}, - {"w", 1}, - {"ⱳ", 0}, - {"p", 1}, - {"ƥ", 0}, - {"v", 1}, - {"ʋ", 0}, - {"P", 1}, - {"Ƥ", 0}, - {"M", 1}, - {"Ɱ", 0}, - {"O", 1}, - {"Ỏ", 0}, - {"abreve", 1}, - {"ẳ", 0}, - {"m", 1}, - {"ɱ", 0}, - {"r", 1}, - {"ɼ", 0}, - {"s", 1}, - {"ʂ", 0}, - {"Z", 1}, - {"Ȥ", 0}, - {"A", 1}, - {"Ả", 0}, - {"c", 1}, - {"ƈ", 0}, - {"T", 1}, - {"Ƭ", 0}, - {"dead_hook", 1}, - {"̉", 0}, - {"K", 1}, - {"Ƙ", 0}, - {"B", 1}, - {"Ɓ", 0}, - {"Uhorn", 1}, - {"Ử", 0}, - {"h", 1}, - {"ɦ", 0}, - {"I", 1}, - {"Ỉ", 0}, - {"N", 1}, - {"Ɲ", 0}, - {"U", 1}, - {"Ủ", 0}, - {"dead_belowbreve", 4}, - {"H", 1}, - {"Ḫ", 0}, - {"h", 1}, - {"ḫ", 0}, - {"dead_cedilla", 73}, - {"dead_breve", 4}, - {"e", 1}, - {"ḝ", 0}, - {"E", 1}, - {"Ḝ", 0}, - {"g", 1}, - {"ģ", 0}, - {"dead_currency", 4}, - {"C", 1}, - {"₵", 0}, - {"c", 1}, - {"₵", 0}, - {"C", 1}, - {"Ç", 0}, - {"e", 1}, - {"ȩ", 0}, - {"l", 1}, - {"ļ", 0}, - {"t", 1}, - {"ţ", 0}, - {"ColonSign", 1}, - {"₵", 0}, - {"space", 1}, - {"¸", 0}, - {"k", 1}, - {"ķ", 0}, - {"n", 1}, - {"ņ", 0}, - {"nobreakspace", 1}, - {"̧", 0}, - {"G", 1}, - {"Ģ", 0}, - {"H", 1}, - {"Ḩ", 0}, - {"E", 1}, - {"Ȩ", 0}, - {"S", 1}, - {"Ş", 0}, - {"Cacute", 1}, - {"Ḉ", 0}, - {"d", 1}, - {"ḑ", 0}, - {"D", 1}, - {"Ḑ", 0}, - {"cent", 1}, - {"₵", 0}, - {"cacute", 1}, - {"ḉ", 0}, - {"r", 1}, - {"ŗ", 0}, - {"s", 1}, - {"ş", 0}, - {"R", 1}, - {"Ŗ", 0}, - {"c", 1}, - {"ç", 0}, - {"L", 1}, - {"Ļ", 0}, - {"T", 1}, - {"Ţ", 0}, - {"K", 1}, - {"Ķ", 0}, - {"dead_cedilla", 1}, - {"¸", 0}, - {"dead_acute", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"h", 1}, - {"ḩ", 0}, - {"N", 1}, - {"Ņ", 0}, - {"dead_inverted_breve", 24}, - {"a", 1}, - {"ȃ", 0}, - {"e", 1}, - {"ȇ", 0}, - {"o", 1}, - {"ȏ", 0}, - {"i", 1}, - {"ȋ", 0}, - {"u", 1}, - {"ȗ", 0}, - {"E", 1}, - {"Ȇ", 0}, - {"O", 1}, - {"Ȏ", 0}, - {"r", 1}, - {"ȓ", 0}, - {"A", 1}, - {"Ȃ", 0}, - {"R", 1}, - {"Ȓ", 0}, - {"I", 1}, - {"Ȋ", 0}, - {"U", 1}, - {"Ȗ", 0}, - {"dead_diaeresis", 190}, - {"W", 1}, - {"Ẅ", 0}, - {"a", 1}, - {"ä", 0}, - {"Greek_IOTA", 1}, - {"Ϊ", 0}, - {"dead_grave", 4}, - {"u", 1}, - {"ǜ", 0}, - {"U", 1}, - {"Ǜ", 0}, - {"Greek_iota", 1}, - {"ϊ", 0}, - {"Umacron", 1}, - {"Ṻ", 0}, - {"Cyrillic_ZE", 1}, - {"Ӟ", 0}, - {"dead_belowdiaeresis", 2}, - {"equal", 1}, - {"⩷", 0}, - {"e", 1}, - {"ë", 0}, - {"o", 1}, - {"ö", 0}, - {"iacute", 1}, - {"ḯ", 0}, - {"Cyrillic_ze", 1}, - {"ӟ", 0}, - {"t", 1}, - {"ẗ", 0}, - {"Greek_upsilon", 1}, - {"ϋ", 0}, - {"space", 1}, - {"\"", 0}, - {"dead_macron", 12}, - {"a", 1}, - {"ǟ", 0}, - {"o", 1}, - {"ȫ", 0}, - {"u", 1}, - {"ṻ", 0}, - {"O", 1}, - {"Ȫ", 0}, - {"A", 1}, - {"Ǟ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"Cyrillic_I", 1}, - {"Ӥ", 0}, - {"y", 1}, - {"ÿ", 0}, - {"Multi_key", 15}, - {"underscore", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"macron", 4}, - {"u", 1}, - {"ṻ", 0}, - {"U", 1}, - {"Ṻ", 0}, - {"asciitilde", 4}, - {"o", 1}, - {"ṏ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"Cyrillic_O", 1}, - {"Ӧ", 0}, - {"i", 1}, - {"ï", 0}, - {"Ukrainian_I", 1}, - {"Ї", 0}, - {"dead_caron", 4}, - {"u", 1}, - {"ǚ", 0}, - {"U", 1}, - {"Ǚ", 0}, - {"dead_tilde", 4}, - {"o", 1}, - {"ṏ", 0}, - {"O", 1}, - {"Ṏ", 0}, - {"Cyrillic_che", 1}, - {"ӵ", 0}, - {"Uacute", 1}, - {"Ǘ", 0}, - {"Cyrillic_a", 1}, - {"ӓ", 0}, - {"Ugrave", 1}, - {"Ǜ", 0}, - {"x", 1}, - {"ẍ", 0}, - {"amacron", 1}, - {"ǟ", 0}, - {"Cyrillic_U", 1}, - {"Ӱ", 0}, - {"nobreakspace", 1}, - {"̈", 0}, - {"omacron", 1}, - {"ȫ", 0}, - {"uacute", 1}, - {"ǘ", 0}, - {"u", 1}, - {"ü", 0}, - {"otilde", 1}, - {"ṏ", 0}, - {"Iacute", 1}, - {"Ḯ", 0}, - {"H", 1}, - {"Ḧ", 0}, - {"Cyrillic_YERU", 1}, - {"Ӹ", 0}, - {"Cyrillic_ie", 1}, - {"ё", 0}, - {"E", 1}, - {"Ë", 0}, - {"Y", 1}, - {"Ÿ", 0}, - {"Cyrillic_i", 1}, - {"ӥ", 0}, - {"Otilde", 1}, - {"Ṏ", 0}, - {"Cyrillic_zhe", 1}, - {"ӝ", 0}, - {"umacron", 1}, - {"ṻ", 0}, - {"Cyrillic_yeru", 1}, - {"ӹ", 0}, - {"acute", 1}, - {"̈́", 0}, - {"w", 1}, - {"ẅ", 0}, - {"Cyrillic_CHE", 1}, - {"Ӵ", 0}, - {"Cyrillic_o", 1}, - {"ӧ", 0}, - {"Ukrainian_i", 1}, - {"ї", 0}, - {"Cyrillic_E", 1}, - {"Ӭ", 0}, - {"apostrophe", 1}, - {"̈́", 0}, - {"O", 1}, - {"Ö", 0}, - {"A", 1}, - {"Ä", 0}, - {"Cyrillic_A", 1}, - {"Ӓ", 0}, - {"ugrave", 1}, - {"ǜ", 0}, - {"Omacron", 1}, - {"Ȫ", 0}, - {"Cyrillic_ZHE", 1}, - {"Ӝ", 0}, - {"Cyrillic_IE", 1}, - {"Ё", 0}, - {"dead_diaeresis", 1}, - {"¨", 0}, - {"Amacron", 1}, - {"Ǟ", 0}, - {"Cyrillic_e", 1}, - {"ӭ", 0}, - {"dead_acute", 14}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"space", 1}, - {"΅", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"X", 1}, - {"Ẍ", 0}, - {"h", 1}, - {"ḧ", 0}, - {"I", 1}, - {"Ï", 0}, - {"U", 1}, - {"Ü", 0}, - {"Cyrillic_u", 1}, - {"ӱ", 0}, - {"Greek_UPSILON", 1}, - {"Ϋ", 0}, - {"dead_acute", 500}, - {"W", 1}, - {"Ẃ", 0}, - {"dead_breve", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"g", 1}, - {"ǵ", 0}, - {"a", 1}, - {"á", 0}, - {"Greek_IOTA", 1}, - {"Ί", 0}, - {"Greek_iota", 1}, - {"ί", 0}, - {"dead_horn", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"dead_circumflex", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"Greek_OMICRON", 1}, - {"Ό", 0}, - {"Acircumflex", 1}, - {"Ấ", 0}, - {"C", 1}, - {"Ć", 0}, - {"Cyrillic_er", 1}, - {"р́", 0}, - {"e", 1}, - {"é", 0}, - {"Utilde", 1}, - {"Ṹ", 0}, - {"o", 1}, - {"ó", 0}, - {"l", 1}, - {"ĺ", 0}, - {"Udiaeresis", 1}, - {"Ǘ", 0}, - {"Greek_upsilon", 1}, - {"ύ", 0}, - {"uhorn", 1}, - {"ứ", 0}, - {"space", 1}, - {"'", 0}, - {"dead_macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"acircumflex", 1}, - {"ấ", 0}, - {"Ecircumflex", 1}, - {"Ế", 0}, - {"Cyrillic_I", 1}, - {"И́", 0}, - {"y", 1}, - {"ý", 0}, - {"Multi_key", 153}, - {"KP_Divide", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"o", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"b", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"parenright", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"quotedbl", 12}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"plus", 8}, - {"o", 1}, - {"ớ", 0}, - {"u", 1}, - {"ứ", 0}, - {"O", 1}, - {"Ớ", 0}, - {"U", 1}, - {"Ứ", 0}, - {"cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"underscore", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"macron", 8}, - {"e", 1}, - {"ḗ", 0}, - {"o", 1}, - {"ṓ", 0}, - {"E", 1}, - {"Ḗ", 0}, - {"O", 1}, - {"Ṓ", 0}, - {"comma", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"asciitilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"slash", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"parenleft", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"U", 4}, - {"a", 1}, - {"ắ", 0}, - {"A", 1}, - {"Ắ", 0}, - {"asciicircum", 12}, - {"a", 1}, - {"ấ", 0}, - {"e", 1}, - {"ế", 0}, - {"o", 1}, - {"ố", 0}, - {"E", 1}, - {"Ế", 0}, - {"O", 1}, - {"Ố", 0}, - {"A", 1}, - {"Ấ", 0}, - {"idiaeresis", 1}, - {"ḯ", 0}, - {"Cyrillic_O", 1}, - {"О́", 0}, - {"i", 1}, - {"í", 0}, - {"k", 1}, - {"ḱ", 0}, - {"n", 1}, - {"ń", 0}, - {"ccedilla", 1}, - {"ḉ", 0}, - {"Cyrillic_GHE", 1}, - {"Ѓ", 0}, - {"dead_tilde", 8}, - {"o", 1}, - {"ṍ", 0}, - {"u", 1}, - {"ṹ", 0}, - {"O", 1}, - {"Ṍ", 0}, - {"U", 1}, - {"Ṹ", 0}, - {"Cyrillic_a", 1}, - {"а́", 0}, - {"Ohorn", 1}, - {"Ớ", 0}, - {"ohorn", 1}, - {"ớ", 0}, - {"sabovedot", 1}, - {"ṥ", 0}, - {"Cyrillic_ER", 1}, - {"Р́", 0}, - {"Greek_epsilon", 1}, - {"έ", 0}, - {"Cyrillic_KA", 1}, - {"Ќ", 0}, - {"Cyrillic_U", 1}, - {"У́", 0}, - {"dead_abovering", 4}, - {"a", 1}, - {"ǻ", 0}, - {"A", 1}, - {"Ǻ", 0}, - {"nobreakspace", 1}, - {"́", 0}, - {"V", 1}, - {"Ǘ", 0}, - {"Ocircumflex", 1}, - {"Ố", 0}, - {"AE", 1}, - {"Ǽ", 0}, - {"omacron", 1}, - {"ṓ", 0}, - {"ocircumflex", 1}, - {"ố", 0}, - {"u", 1}, - {"ú", 0}, - {"z", 1}, - {"ź", 0}, - {"G", 1}, - {"Ǵ", 0}, - {"Greek_ALPHA", 1}, - {"Ά", 0}, - {"otilde", 1}, - {"ṍ", 0}, - {"utilde", 1}, - {"ṹ", 0}, - {"Cyrillic_ie", 1}, - {"е́", 0}, - {"emacron", 1}, - {"ḗ", 0}, - {"E", 1}, - {"É", 0}, - {"S", 1}, - {"Ś", 0}, - {"Greek_iotadieresis", 1}, - {"ΐ", 0}, - {"Y", 1}, - {"Ý", 0}, - {"Cyrillic_i", 1}, - {"и́", 0}, - {"dead_dasia", 28}, - {"Greek_IOTA", 1}, - {"Ἵ", 0}, - {"Greek_iota", 1}, - {"ἵ", 0}, - {"Greek_OMICRON", 1}, - {"Ὅ", 0}, - {"Greek_upsilon", 1}, - {"ὕ", 0}, - {"Greek_epsilon", 1}, - {"ἕ", 0}, - {"Greek_ALPHA", 1}, - {"Ἅ", 0}, - {"Greek_omicron", 1}, - {"ὅ", 0}, - {"Greek_eta", 1}, - {"ἥ", 0}, - {"Greek_alpha", 1}, - {"ἅ", 0}, - {"Greek_ETA", 1}, - {"Ἥ", 0}, - {"Greek_EPSILON", 1}, - {"Ἕ", 0}, - {"Greek_omega", 1}, - {"ὥ", 0}, - {"Greek_OMEGA", 1}, - {"Ὥ", 0}, - {"Greek_UPSILON", 1}, - {"Ὕ", 0}, - {"Greek_upsilondieresis", 1}, - {"ΰ", 0}, - {"Greek_omicron", 1}, - {"ό", 0}, - {"Greek_eta", 1}, - {"ή", 0}, - {"Otilde", 1}, - {"Ṍ", 0}, - {"Cyrillic_ka", 1}, - {"ќ", 0}, - {"Aring", 1}, - {"Ǻ", 0}, - {"Abreve", 1}, - {"Ắ", 0}, - {"dead_psili", 26}, - {"Greek_IOTA", 1}, - {"Ἴ", 0}, - {"Greek_iota", 1}, - {"ἴ", 0}, - {"Greek_OMICRON", 1}, - {"Ὄ", 0}, - {"Greek_upsilon", 1}, - {"ὔ", 0}, - {"Greek_epsilon", 1}, - {"ἔ", 0}, - {"Greek_ALPHA", 1}, - {"Ἄ", 0}, - {"Greek_omicron", 1}, - {"ὄ", 0}, - {"Greek_eta", 1}, - {"ἤ", 0}, - {"Greek_alpha", 1}, - {"ἄ", 0}, - {"Greek_ETA", 1}, - {"Ἤ", 0}, - {"Greek_EPSILON", 1}, - {"Ἔ", 0}, - {"Greek_omega", 1}, - {"ὤ", 0}, - {"Greek_OMEGA", 1}, - {"Ὤ", 0}, - {"Greek_alpha", 1}, - {"ά", 0}, - {"ecircumflex", 1}, - {"ế", 0}, - {"dead_abovedot", 4}, - {"S", 1}, - {"Ṥ", 0}, - {"s", 1}, - {"ṥ", 0}, - {"w", 1}, - {"ẃ", 0}, - {"Greek_ETA", 1}, - {"Ή", 0}, - {"Cyrillic_o", 1}, - {"о́", 0}, - {"Emacron", 1}, - {"Ḗ", 0}, - {"Ooblique", 1}, - {"Ǿ", 0}, - {"p", 1}, - {"ṕ", 0}, - {"v", 1}, - {"ǘ", 0}, - {"P", 1}, - {"Ṕ", 0}, - {"M", 1}, - {"Ḿ", 0}, - {"O", 1}, - {"Ó", 0}, - {"abreve", 1}, - {"ắ", 0}, - {"m", 1}, - {"ḿ", 0}, - {"r", 1}, - {"ŕ", 0}, - {"s", 1}, - {"ś", 0}, - {"Z", 1}, - {"Ź", 0}, - {"dead_stroke", 4}, - {"o", 1}, - {"ǿ", 0}, - {"O", 1}, - {"Ǿ", 0}, - {"A", 1}, - {"Á", 0}, - {"R", 1}, - {"Ŕ", 0}, - {"c", 1}, - {"ć", 0}, - {"Idiaeresis", 1}, - {"Ḯ", 0}, - {"L", 1}, - {"Ĺ", 0}, - {"Greek_EPSILON", 1}, - {"Έ", 0}, - {"Cyrillic_A", 1}, - {"А́", 0}, - {"Ccedilla", 1}, - {"Ḉ", 0}, - {"aring", 1}, - {"ǻ", 0}, - {"K", 1}, - {"Ḱ", 0}, - {"Omacron", 1}, - {"Ṓ", 0}, - {"Cyrillic_IE", 1}, - {"Е́", 0}, - {"Sabovedot", 1}, - {"Ṥ", 0}, - {"dead_cedilla", 4}, - {"C", 1}, - {"Ḉ", 0}, - {"c", 1}, - {"ḉ", 0}, - {"Greek_omega", 1}, - {"ώ", 0}, - {"dead_diaeresis", 14}, - {"Greek_iota", 1}, - {"ΐ", 0}, - {"Greek_upsilon", 1}, - {"ΰ", 0}, - {"space", 1}, - {"΅", 0}, - {"i", 1}, - {"ḯ", 0}, - {"u", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Ḯ", 0}, - {"U", 1}, - {"Ǘ", 0}, - {"Uhorn", 1}, - {"Ứ", 0}, - {"Greek_OMEGA", 1}, - {"Ώ", 0}, - {"dead_acute", 1}, - {"´", 0}, - {"oslash", 1}, - {"ǿ", 0}, - {"Cyrillic_ghe", 1}, - {"ѓ", 0}, - {"udiaeresis", 1}, - {"ǘ", 0}, - {"I", 1}, - {"Í", 0}, - {"N", 1}, - {"Ń", 0}, - {"U", 1}, - {"Ú", 0}, - {"Cyrillic_u", 1}, - {"у́", 0}, - {"ae", 1}, - {"ǽ", 0}, - {"Greek_UPSILON", 1}, - {"Ύ", 0}, - {"dead_belowmacron", 34}, - {"l", 1}, - {"ḻ", 0}, - {"t", 1}, - {"ṯ", 0}, - {"b", 1}, - {"ḇ", 0}, - {"k", 1}, - {"ḵ", 0}, - {"n", 1}, - {"ṉ", 0}, - {"z", 1}, - {"ẕ", 0}, - {"d", 1}, - {"ḏ", 0}, - {"D", 1}, - {"Ḏ", 0}, - {"r", 1}, - {"ṟ", 0}, - {"Z", 1}, - {"Ẕ", 0}, - {"R", 1}, - {"Ṟ", 0}, - {"L", 1}, - {"Ḻ", 0}, - {"T", 1}, - {"Ṯ", 0}, - {"K", 1}, - {"Ḵ", 0}, - {"B", 1}, - {"Ḇ", 0}, - {"h", 1}, - {"ẖ", 0}, - {"N", 1}, - {"Ṉ", 0}, - {"dead_belowring", 6}, - {"a", 1}, - {"ḁ", 0}, - {"bar", 1}, - {"⫰", 0}, - {"A", 1}, - {"Ḁ", 0}, - {NULL, 0}, -}; diff --git a/legacy/ecore/src/lib/ecore_input/ecore_input_private.h b/legacy/ecore/src/lib/ecore_input/ecore_input_private.h deleted file mode 100644 index 5660a2024a..0000000000 --- a/legacy/ecore/src/lib/ecore_input/ecore_input_private.h +++ /dev/null @@ -1,37 +0,0 @@ -#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 diff --git a/legacy/ecore/src/lib/ecore_input_evas/Ecore_Input_Evas.h b/legacy/ecore/src/lib/ecore_input_evas/Ecore_Input_Evas.h deleted file mode 100644 index c97274eb0b..0000000000 --- a/legacy/ecore/src/lib/ecore_input_evas/Ecore_Input_Evas.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _ECORE_INPUT_EVAS_H -#define _ECORE_INPUT_EVAS_H - -#include - -#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_EVAS_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); -typedef void (*Ecore_Event_Multi_Move_Cb)(void *window, int device, int x, int y, double radius, double radius_x, double radius_y, double pressure, double angle, double mx, double my, unsigned int timestamp); -typedef void (*Ecore_Event_Multi_Down_Cb)(void *window, int device, int x, int y, double radius, double radius_x, double radius_y, double pressure, double angle, double mx, double my, Evas_Button_Flags flags, unsigned int timestamp); -typedef void (*Ecore_Event_Multi_Up_Cb)(void *window, int device, int x, int y, double radius, double radius_x, double radius_y, double pressure, double angle, double mx, double my, Evas_Button_Flags flags, unsigned int timestamp); - -EAPI int ecore_event_evas_init(void); -EAPI int ecore_event_evas_shutdown(void); - -EAPI Eina_Bool ecore_event_evas_key_down(void *data, int type, void *event); -EAPI Eina_Bool ecore_event_evas_key_up(void *data, int type, void *event); -EAPI Eina_Bool ecore_event_evas_mouse_button_up(void *data, int type, void *event); -EAPI Eina_Bool ecore_event_evas_mouse_button_down(void *data, int type, void *event); -EAPI Eina_Bool ecore_event_evas_mouse_wheel(void *data, int type, void *event); -EAPI Eina_Bool ecore_event_evas_mouse_move(void *data, int type, void *event); -EAPI Eina_Bool ecore_event_evas_mouse_in(void *data, int type, void *event); -EAPI Eina_Bool 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, Ecore_Event_Multi_Move_Cb move_multi, Ecore_Event_Multi_Down_Cb down_multi, Ecore_Event_Multi_Up_Cb up_multi); -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 diff --git a/legacy/ecore/src/lib/ecore_input_evas/ecore_input_evas.c b/legacy/ecore/src/lib/ecore_input_evas/ecore_input_evas.c deleted file mode 100644 index 1f5b38e03c..0000000000 --- a/legacy/ecore/src/lib/ecore_input_evas/ecore_input_evas.c +++ /dev/null @@ -1,418 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#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; - Ecore_Event_Multi_Move_Cb move_multi; - Ecore_Event_Multi_Down_Cb down_multi; - Ecore_Event_Multi_Up_Cb up_multi; - 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_MODIFIER_ALTGR) - evas_key_modifier_on(e, "AltGr"); - else evas_key_modifier_off(e, "AltGr"); - - 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"); - - if (modifiers & ECORE_EVENT_LOCK_SHIFT) - evas_key_lock_on(e, "Shift_Lock"); - else evas_key_lock_off(e, "Shift_Lock"); -} - -EAPI void -ecore_event_window_register(Ecore_Window id, void *window, Evas *evas, - Ecore_Event_Mouse_Move_Cb move_mouse, - Ecore_Event_Multi_Move_Cb move_multi, - Ecore_Event_Multi_Down_Cb down_multi, - Ecore_Event_Multi_Up_Cb up_multi) -{ - 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->move_multi = move_multi; - w->down_multi = down_multi; - w->up_multi = up_multi; - 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_modifier_add(evas, "AltGr"); - 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 Eina_Bool -_ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press) -{ - Ecore_Input_Window *lookup; - - lookup = _ecore_event_window_match(e->event_window); - if (!lookup) return ECORE_CALLBACK_PASS_ON; - 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 ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_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->event_window); - if (!lookup) return ECORE_CALLBACK_PASS_ON; - 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) - { - if (lookup->down_multi) - lookup->down_multi(lookup->window, 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); - else - 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 - { - if (lookup->up_multi) - lookup->up_multi(lookup->window, 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); - 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 ECORE_CALLBACK_PASS_ON; -} - -EAPI Eina_Bool -ecore_event_evas_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Event_Mouse_Move *e; - Ecore_Input_Window *lookup; - - e = event; - lookup = _ecore_event_window_match(e->event_window); - if (!lookup) return ECORE_CALLBACK_PASS_ON; - if (e->multi.device == 0) - { - ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); - if (lookup->move_mouse) - lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp); - else - evas_event_feed_mouse_move(lookup->evas, e->x, e->y, e->timestamp, - NULL); - } - else - { - if (lookup->move_multi) - lookup->move_multi(lookup->window, 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); - 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 ECORE_CALLBACK_PASS_ON; -} - -EAPI Eina_Bool -ecore_event_evas_mouse_button_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_DOWN); -} - -EAPI Eina_Bool -ecore_event_evas_mouse_button_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP); -} - -static Eina_Bool -_ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io) -{ - Ecore_Input_Window *lookup; - - lookup = _ecore_event_window_match(e->event_window); - if (!lookup) return ECORE_CALLBACK_PASS_ON; - 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 ECORE_CALLBACK_PASS_ON; -} - -EAPI Eina_Bool -ecore_event_evas_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_DOWN); -} - -EAPI Eina_Bool -ecore_event_evas_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_UP); -} - -EAPI Eina_Bool -ecore_event_evas_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - Ecore_Event_Mouse_Wheel *e; - Ecore_Input_Window *lookup; - - e = event; - lookup = _ecore_event_window_match(e->event_window); - if (!lookup) return ECORE_CALLBACK_PASS_ON; - 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 ECORE_CALLBACK_PASS_ON; -} - -EAPI Eina_Bool -ecore_event_evas_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - return _ecore_event_evas_mouse_io((Ecore_Event_Mouse_IO *)event, ECORE_IN); -} - -EAPI Eina_Bool -ecore_event_evas_mouse_out(void *data EINA_UNUSED, int type EINA_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 - ("ecore_input_evas", 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; -} diff --git a/legacy/ecore/src/lib/ecore_input_evas/ecore_input_evas_private.h b/legacy/ecore/src/lib/ecore_input_evas/ecore_input_evas_private.h deleted file mode 100644 index c19cfbf675..0000000000 --- a/legacy/ecore/src/lib/ecore_input_evas/ecore_input_evas_private.h +++ /dev/null @@ -1,37 +0,0 @@ -#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 diff --git a/legacy/ecore/src/lib/ecore_ipc/Ecore_Ipc.h b/legacy/ecore/src/lib/ecore_ipc/Ecore_Ipc.h deleted file mode 100644 index f77870f84d..0000000000 --- a/legacy/ecore/src/lib/ecore_ipc/Ecore_Ipc.h +++ /dev/null @@ -1,328 +0,0 @@ -#ifndef _ECORE_IPC_H -#define _ECORE_IPC_H - -#include - -#ifdef EAPI -# undef EAPI -#endif - -#ifdef _WIN32 -# ifdef EFL_ECORE_IPC_BUILD -# ifdef DLL_EXPORT -# define EAPI __declspec(dllexport) -# else -# define EAPI -# endif -# 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 - -typedef struct _Ecore_Ipc_Server Ecore_Ipc_Server; /**< An IPC connection handle */ -typedef struct _Ecore_Ipc_Client Ecore_Ipc_Client; /**< An IPC connection handle */ - -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 = (1 << 4), - ECORE_IPC_NO_PROXY = (1 << 5) -} 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 Eina_Bool 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 const 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 const 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 diff --git a/legacy/ecore/src/lib/ecore_ipc/ecore_ipc.c b/legacy/ecore/src/lib/ecore_ipc/ecore_ipc.c deleted file mode 100644 index a421febdf9..0000000000 --- a/legacy/ecore/src/lib/ecore_ipc/ecore_ipc.c +++ /dev/null @@ -1,1599 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#ifdef HAVE_NETINET_IN_H -# include -# include -#endif - -#ifdef HAVE_WINSOCK2_H -# include -#endif - -#include -#include -#include - -#include "Ecore_Ipc.h" -#include "ecore_ipc_private.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; - -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 Eina_Bool _ecore_ipc_event_client_add(void *data, int ev_type, void *ev); -static Eina_Bool _ecore_ipc_event_client_del(void *data, int ev_type, void *ev); -static Eina_Bool _ecore_ipc_event_server_add(void *data, int ev_type, void *ev); -static Eina_Bool _ecore_ipc_event_server_del(void *data, int ev_type, void *ev); -static Eina_Bool _ecore_ipc_event_client_data(void *data, int ev_type, void *ev); -static Eina_Bool _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 - ("ecore_ipc", 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; - - Eina_List *l, *l2; - Ecore_Ipc_Server *svr; - EINA_LIST_FOREACH_SAFE(servers, l, l2, svr) - ecore_ipc_server_del(svr); - - 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; - - if (!name) return NULL; - - 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; - int features; - - svr = calloc(1, sizeof(Ecore_Ipc_Server)); - if (!svr) return NULL; - type = compl_type & ECORE_IPC_TYPE; - features = compl_type & ECORE_IPC_SSL; - if ((features & ECORE_IPC_USE_SSL) == ECORE_IPC_USE_SSL) - extra |= ECORE_CON_USE_SSL; - if ((features & ECORE_IPC_NO_PROXY) == ECORE_IPC_NO_PROXY) - extra |= ECORE_CON_NO_PROXY; - 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); - if (svr->server) 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 EINA_TRUE if the server is connected, @c EINA_FALSE otherwise. - * @ingroup Ecore_IPC_Server_Group - */ -EAPI Eina_Bool -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 EINA_FALSE; - } - 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->clients; -} - -#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 const 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; - } - EINA_SAFETY_ON_TRUE_RETURN_VAL(!cl->client, 0); - EINA_SAFETY_ON_TRUE_RETURN_VAL(!ecore_con_client_connected_get(cl->client), 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 cl->svr; -} - -/** - * 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 = cl->svr; - if (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 cl 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; -} - -/** - * Gets the max data payload size for an Ipc message in bytes - * - * @param cl The given client. - * @return The maximum data payload size in bytes on success, @c -1 on failure. - * @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 @c NULL is - * returned. - * @ingroup Ecore_Ipc_Client_Group - */ -EAPI const 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 Eina_Bool -_ecore_ipc_event_client_add(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev) -{ - Ecore_Con_Event_Client_Add *e; - Ecore_Ipc_Server *svr; - - e = ev; - svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client)); - if (!eina_list_data_find(servers, svr)) return ECORE_CALLBACK_RENEW; - /* handling code here */ - { - Ecore_Ipc_Client *cl; - - cl = calloc(1, sizeof(Ecore_Ipc_Client)); - if (!cl) return ECORE_CALLBACK_CANCEL; - cl->svr = svr; - 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); - 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 ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_ecore_ipc_event_client_del(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev) -{ - Ecore_Con_Event_Client_Del *e; - Ecore_Ipc_Server *svr; - - e = ev; - if (!e->client) return ECORE_CALLBACK_RENEW; - svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client)); - if (!eina_list_data_find(servers, svr)) return ECORE_CALLBACK_RENEW; - /* handling code here */ - { - Ecore_Ipc_Client *cl; - - cl = ecore_con_client_data_get(e->client); - cl->client = NULL; - { - Ecore_Ipc_Event_Client_Del *e2; - - 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 ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_ecore_ipc_event_server_add(void *data EINA_UNUSED, int ev_type EINA_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 ECORE_CALLBACK_RENEW; - /* 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 ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_ecore_ipc_event_server_del(void *data EINA_UNUSED, int ev_type EINA_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 ECORE_CALLBACK_RENEW; - /* handling code here */ - { - Ecore_Ipc_Server *svr; - - svr = ecore_con_server_data_get(e->server); - svr->server = NULL; - 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 ECORE_CALLBACK_CANCEL; -} - -#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 Eina_Bool -_ecore_ipc_event_client_data(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev) -{ - Ecore_Con_Event_Client_Data *e; - Ecore_Ipc_Server *svr; - - e = ev; - svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client)); - if (!eina_list_data_find(servers, svr)) return ECORE_CALLBACK_RENEW; - /* 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 ECORE_CALLBACK_CANCEL; - } - 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 ECORE_CALLBACK_CANCEL; - } - - 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; - int max, max2; - - buf = NULL; - 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 ECORE_CALLBACK_CANCEL; - 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 ECORE_CALLBACK_CANCEL; - } - 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 ECORE_CALLBACK_CANCEL; - } - memcpy(buf, cl->buf + offset, cl->buf_size - offset); - free(cl->buf); - cl->buf = buf; - cl->buf_size -= offset; - } - } - return ECORE_CALLBACK_CANCEL; -} - -#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 Eina_Bool -_ecore_ipc_event_server_data(void *data EINA_UNUSED, int ev_type EINA_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 ECORE_CALLBACK_RENEW; - /* 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 ECORE_CALLBACK_CANCEL; - } - 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 ECORE_CALLBACK_CANCEL; - } - - 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 ECORE_CALLBACK_CANCEL; - 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 ECORE_CALLBACK_CANCEL; - } - 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 ECORE_CALLBACK_CANCEL; - } - memcpy(buf, svr->buf + offset, svr->buf_size - offset); - free(svr->buf); - svr->buf = buf; - svr->buf_size -= offset; - } - } - return ECORE_CALLBACK_CANCEL; -} - -static void -_ecore_ipc_event_client_add_free(void *data EINA_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 EINA_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 EINA_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 EINA_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 EINA_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 EINA_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); -} diff --git a/legacy/ecore/src/lib/ecore_ipc/ecore_ipc_private.h b/legacy/ecore/src/lib/ecore_ipc/ecore_ipc_private.h deleted file mode 100644 index bedaab167c..0000000000 --- a/legacy/ecore/src/lib/ecore_ipc/ecore_ipc_private.h +++ /dev/null @@ -1,105 +0,0 @@ -#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__) - -#define ECORE_MAGIC_IPC_SERVER 0x87786556 -#define ECORE_MAGIC_IPC_CLIENT 0x78875665 - -typedef struct _Ecore_Ipc_Msg_Head Ecore_Ipc_Msg_Head; -#define ECORE_IPC_TYPE 0x0f -#define ECORE_IPC_SSL 0xf0 - -#if defined (_MSC_VER) || (defined (__SUNPRO_C) && __SUNPRO_C < 0x5100) -# pragma pack(1) -# define ECORE_IPC_STRUCT_PACKED -#elif defined (__GNUC__) || (defined (__SUNPRO_C) && __SUNPRO_C >= 0x5100) -# define ECORE_IPC_STRUCT_PACKED __attribute__((packed)) -#else -# define ECORE_IPC_STRUCT_PACKED -#endif - -#ifdef __sgi -#pragma pack 4 -#endif -struct _Ecore_Ipc_Msg_Head -{ - int major; - int minor; - int ref; - int ref_to; - int response; - int size; -} ECORE_IPC_STRUCT_PACKED; -#ifdef __sgi -#pragma pack 0 -#endif - -struct _Ecore_Ipc_Client -{ - ECORE_MAGIC; - Ecore_Con_Client *client; - Ecore_Ipc_Server *svr; - 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; - 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 diff --git a/legacy/ecore/src/lib/ecore_sdl/Ecore_Sdl.h b/legacy/ecore/src/lib/ecore_sdl/Ecore_Sdl.h deleted file mode 100644 index 359e974718..0000000000 --- a/legacy/ecore/src/lib/ecore_sdl/Ecore_Sdl.h +++ /dev/null @@ -1,114 +0,0 @@ -#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_GOT_FOCUS; -EAPI extern int ECORE_SDL_EVENT_LOST_FOCUS; -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 diff --git a/legacy/ecore/src/lib/ecore_sdl/Ecore_Sdl_Keys.h b/legacy/ecore/src/lib/ecore_sdl/Ecore_Sdl_Keys.h deleted file mode 100644 index 4d0b60b854..0000000000 --- a/legacy/ecore/src/lib/ecore_sdl/Ecore_Sdl_Keys.h +++ /dev/null @@ -1,266 +0,0 @@ -#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", "" }, -#ifndef BUILD_ECORE_EVAS_SDL_130 - { SDLK_FIRST, "First", "First" }, -#endif - { 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, "asterisk", "*" }, - { 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 */ - -#ifndef BUILD_ECORE_EVAS_SDL_130 - /* 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", "" }, -#endif - /* 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__ */ diff --git a/legacy/ecore/src/lib/ecore_sdl/ecore_sdl.c b/legacy/ecore/src/lib/ecore_sdl/ecore_sdl.c deleted file mode 100644 index d9f2775004..0000000000 --- a/legacy/ecore/src/lib/ecore_sdl/ecore_sdl.c +++ /dev/null @@ -1,333 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include -#include -#include -#include -#include "Ecore_Sdl.h" -#include "Ecore_Sdl_Keys.h" -#include "ecore_sdl_private.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, - EINA_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, - EINA_UNUSED int length, - EINA_UNUSED void *data) -{ - return node->key - *key; -} - -/** - * @defgroup Ecore_Sdl_Library_Group SDL Library Functions - * - * Functions used to set up and shut down the Ecore_Sdl 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 EINA_UNUSED) -{ - if(++_ecore_sdl_init_count != 1) - return _ecore_sdl_init_count; - _ecore_sdl_log_dom = eina_log_domain_register - ("ecore_sdl", 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 timestamp) -{ - Ecore_Event_Key *ev; - unsigned int i; - - ev = malloc(sizeof(Ecore_Event_Key)); - if (!ev) return NULL; - - ev->timestamp = timestamp; - ev->window = 0; - ev->event_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 timestamp; - - while(SDL_PollEvent(&event)) - { - timestamp = (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 = timestamp; - ev->window = 0; - ev->event_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; - - /* Must set multi touch device to 0 or it will get ignored */ - ev->multi.device = 0; - ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; - ev->multi.pressure = ev->multi.angle = 0; - ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 0; - - 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 = timestamp; - ev->window = 0; - ev->event_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 = timestamp; - ev->window = 0; - ev->event_window = 0; - ev->modifiers = 0; /* FIXME: keep modifier around. */ - ev->buttons = event.button.button; - ev->double_click = 0; - ev->triple_click = 0; - - /* Must set multi touch device to 0 or it will get ignored */ - ev->multi.device = 0; - ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; - ev->multi.pressure = ev->multi.angle = 0; - ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 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 = timestamp; - ev->window = 0; - ev->event_window = 0; - ev->modifiers = 0; /* FIXME: keep modifier around. */ - ev->buttons = event.button.button; - ev->double_click = 0; - ev->triple_click = 0; - - /* Must set multi touch device to 0 or it will get ignored */ - ev->multi.device = 0; - ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; - ev->multi.pressure = ev->multi.angle = 0; - ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 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, timestamp); - if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL); - } - - ev = _ecore_sdl_event_key(&event, timestamp); - 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, timestamp); - 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; - } - } -} diff --git a/legacy/ecore/src/lib/ecore_sdl/ecore_sdl_private.h b/legacy/ecore/src/lib/ecore_sdl/ecore_sdl_private.h deleted file mode 100644 index 37e957015d..0000000000 --- a/legacy/ecore/src/lib/ecore_sdl/ecore_sdl_private.h +++ /dev/null @@ -1,36 +0,0 @@ -#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 diff --git a/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h b/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h deleted file mode 100644 index 5281c6f8f3..0000000000 --- a/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h +++ /dev/null @@ -1,392 +0,0 @@ -#ifndef _ECORE_WAYLAND_H_ -# define _ECORE_WAYLAND_H_ - -/* - * Wayland supoprt is considered experimental as wayland itself is still - * unstable and liable to change core protocol. If you use this api, it is - * possible it will break in future, until this notice is removed. - */ - -# include -# include -# include -# include - -# ifdef EAPI -# undef EAPI -# endif - -# ifdef __GNUC__ -# if __GNUC__ >= 4 -# define EAPI __attribute__ ((visibility("default"))) -# else -# define EAPI -# endif -# else -# define EAPI -# endif - -typedef enum _Ecore_Wl_Window_Type Ecore_Wl_Window_Type; -typedef enum _Ecore_Wl_Window_Buffer_Type Ecore_Wl_Window_Buffer_Type; - -typedef struct _Ecore_Wl_Display Ecore_Wl_Display; -typedef struct _Ecore_Wl_Output Ecore_Wl_Output; -typedef struct _Ecore_Wl_Input Ecore_Wl_Input; -# ifndef _ECORE_WAYLAND_WINDOW_PREDEF -typedef struct _Ecore_Wl_Window Ecore_Wl_Window; -# endif -typedef struct _Ecore_Wl_Dnd Ecore_Wl_Dnd; /** @since 1.7 */ -typedef struct _Ecore_Wl_Dnd_Source Ecore_Wl_Dnd_Source; -typedef struct _Ecore_Wl_Dnd_Target Ecore_Wl_Dnd_Target; - -typedef struct _Ecore_Wl_Event_Mouse_In Ecore_Wl_Event_Mouse_In; -typedef struct _Ecore_Wl_Event_Mouse_Out Ecore_Wl_Event_Mouse_Out; -typedef struct _Ecore_Wl_Event_Focus_In Ecore_Wl_Event_Focus_In; -typedef struct _Ecore_Wl_Event_Focus_Out Ecore_Wl_Event_Focus_Out; -typedef struct _Ecore_Wl_Event_Window_Configure Ecore_Wl_Event_Window_Configure; -typedef struct _Ecore_Wl_Event_Dnd_Enter Ecore_Wl_Event_Dnd_Enter; -typedef struct _Ecore_Wl_Event_Dnd_Position Ecore_Wl_Event_Dnd_Position; -typedef struct _Ecore_Wl_Event_Dnd_Leave Ecore_Wl_Event_Dnd_Leave; -typedef struct _Ecore_Wl_Event_Dnd_Drop Ecore_Wl_Event_Dnd_Drop; -typedef struct _Ecore_Wl_Event_Data_Source_Send Ecore_Wl_Event_Data_Source_Send; /** @since 1.7 */ -typedef struct _Ecore_Wl_Event_Selection_Data_Ready Ecore_Wl_Event_Selection_Data_Ready; /** @since 1.7 */ -typedef struct _Ecore_Wl_Event_Interfaces_Bound Ecore_Wl_Event_Interfaces_Bound; - -enum _Ecore_Wl_Window_Type -{ - ECORE_WL_WINDOW_TYPE_NONE, - ECORE_WL_WINDOW_TYPE_TOPLEVEL, - ECORE_WL_WINDOW_TYPE_FULLSCREEN, - ECORE_WL_WINDOW_TYPE_MAXIMIZED, - ECORE_WL_WINDOW_TYPE_TRANSIENT, - ECORE_WL_WINDOW_TYPE_MENU, - ECORE_WL_WINDOW_TYPE_CUSTOM -}; - -enum _Ecore_Wl_Window_Buffer_Type -{ - ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW, - ECORE_WL_WINDOW_BUFFER_TYPE_EGL_IMAGE, - ECORE_WL_WINDOW_BUFFER_TYPE_SHM -}; - -struct _Ecore_Wl_Display -{ - struct - { - struct wl_display *display; - struct wl_registry *registry; - struct wl_compositor *compositor; - struct wl_shell *shell; - struct wl_shell *desktop_shell; - struct wl_shm *shm; - struct wl_data_device_manager *data_device_manager; - } wl; - - int fd; - unsigned int mask; - unsigned int serial; - Ecore_Fd_Handler *fd_hdl; - - struct wl_list inputs; - struct wl_list outputs; - - struct - { - struct xkb_context *context; - } xkb; - - struct wl_cursor_theme *cursor_theme; - - Ecore_Wl_Output *output; - Ecore_Wl_Input *input; - - void (*output_configure)(Ecore_Wl_Output *output, void *data); - void *data; -}; - -struct _Ecore_Wl_Output -{ - Ecore_Wl_Display *display; - struct wl_output *output; - Eina_Rectangle allocation; - int mw, mh; - struct wl_list link; - - void (*destroy) (Ecore_Wl_Output *output, void *data); - void *data; -}; - -struct _Ecore_Wl_Input -{ - Ecore_Wl_Display *display; - struct wl_seat *seat; - struct wl_pointer *pointer; - struct wl_keyboard *keyboard; - struct wl_touch *touch; - - const char *cursor_name; - struct wl_surface *cursor_surface; - struct wl_callback *cursor_frame_cb; - - struct wl_data_device *data_device; - - Ecore_Wl_Window *pointer_focus; - Ecore_Wl_Window *keyboard_focus; - - unsigned int button; - unsigned int timestamp; - unsigned int modifiers; - unsigned int pointer_enter_serial; - int sx, sy; - - struct wl_list link; - - Ecore_Wl_Window *grab; - unsigned int grab_button; - - Ecore_Wl_Dnd_Source *drag_source; - Ecore_Wl_Dnd_Source *selection_source; - Ecore_Wl_Dnd *dnd; /** @since 1.7 */ - - struct - { - struct xkb_keymap *keymap; - struct xkb_state *state; - xkb_mod_mask_t control_mask; - xkb_mod_mask_t alt_mask; - xkb_mod_mask_t shift_mask; - } xkb; - - struct - { - Ecore_Fd_Handler *hdlr; - int timerfd; - unsigned int sym, key, time; - } repeat; -}; - -struct _Ecore_Wl_Window -{ - Ecore_Wl_Display *display; - Ecore_Wl_Window *parent; - - struct wl_surface *surface; - struct wl_shell_surface *shell_surface; - - struct - { - struct wl_region *input, *opaque; - } region; - - int id; - int x, y; - int edges; - - Eina_Rectangle allocation, pending_allocation; - Eina_Rectangle saved_allocation, server_allocation; - - /* Eina_Bool redraw_scheduled : 1; */ - /* Eina_Bool resize_scheduled : 1; */ - Eina_Bool alpha : 1; - Eina_Bool transparent : 1; - Eina_Bool moving : 1; - Eina_Bool resizing : 1; - - Ecore_Wl_Window_Type type; - Ecore_Wl_Window_Buffer_Type buffer_type; - - Ecore_Wl_Input *pointer_device; - Ecore_Wl_Input *keyboard_device; - - Eina_Bool frame_pending; - struct wl_callback *frame_callback; - /* FIXME: Ideally we should record the cursor name for this window - * so we can compare and avoid unnecessary cursor set calls to wayland */ - - void *data; -}; - -struct _Ecore_Wl_Event_Mouse_In -{ - int modifiers; - int x, y; - struct - { - int x, y; - } root; - unsigned int window; - unsigned int event_window; - unsigned int root_window; - unsigned int timestamp; -}; - -struct _Ecore_Wl_Event_Mouse_Out -{ - int modifiers; - int x, y; - struct - { - int x, y; - } root; - unsigned int window; - unsigned int event_window; - unsigned int root_window; - unsigned int timestamp; -}; - -struct _Ecore_Wl_Event_Focus_In -{ - unsigned int win; - unsigned int timestamp; -}; - -struct _Ecore_Wl_Event_Focus_Out -{ - unsigned int win; - unsigned int timestamp; -}; - -struct _Ecore_Wl_Event_Window_Configure -{ - unsigned int win; - unsigned int event_win; - int x, y, w, h; -}; - -struct _Ecore_Wl_Event_Dnd_Enter -{ - unsigned int win, source; - char **types; - int num_types; - struct - { - int x, y; - } position; -}; - -struct _Ecore_Wl_Event_Dnd_Position -{ - unsigned int win, source; - struct - { - int x, y; - } position; -}; - -struct _Ecore_Wl_Event_Dnd_Leave -{ - unsigned int win, source; -}; - -struct _Ecore_Wl_Event_Dnd_Drop -{ - unsigned int win, source; - struct - { - int x, y; - } position; -}; - -/** @since 1.7 */ -struct _Ecore_Wl_Event_Data_Source_Send -{ - char *type; - int fd; -}; - -/** @since 1.7 */ -struct _Ecore_Wl_Event_Selection_Data_Ready -{ - char *data; - int len; - Eina_Bool done; -}; - -struct _Ecore_Wl_Event_Interfaces_Bound -{ - Eina_Bool compositor : 1; - Eina_Bool shm : 1; - Eina_Bool shell : 1; -}; - -/** - * @file - * @brief Ecore functions for dealing with the Wayland window system - * - * Ecore_Wl provides a wrapper and convenience functions for using the - * Wayland window system. Function groups for this part of the library - * include the following: - * - * @li @ref Ecore_Wl_Init_Group - * @li @ref Ecore_Wl_Display_Group - * @li @ref Ecore_Wl_Flush_Group - * @li @ref Ecore_Wl_Window_Group - */ - -EAPI extern int ECORE_WL_EVENT_MOUSE_IN; -EAPI extern int ECORE_WL_EVENT_MOUSE_OUT; -EAPI extern int ECORE_WL_EVENT_FOCUS_IN; -EAPI extern int ECORE_WL_EVENT_FOCUS_OUT; -EAPI extern int ECORE_WL_EVENT_WINDOW_CONFIGURE; -EAPI extern int ECORE_WL_EVENT_DND_ENTER; -EAPI extern int ECORE_WL_EVENT_DND_POSITION; -EAPI extern int ECORE_WL_EVENT_DND_LEAVE; -EAPI extern int ECORE_WL_EVENT_DND_DROP; -EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_TARGET; /** @since 1.7 */ -EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_SEND; /** @since 1.7 */ -EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_CANCELLED; /** @since 1.7 */ -EAPI extern int ECORE_WL_EVENT_SELECTION_DATA_READY; /** @since 1.7 */ -EAPI extern int ECORE_WL_EVENT_INTERFACES_BOUND; - -EAPI int ecore_wl_init(const char *name); -EAPI int ecore_wl_shutdown(void); -EAPI void ecore_wl_flush(void); -EAPI void ecore_wl_sync(void); -EAPI struct wl_shm *ecore_wl_shm_get(void); -EAPI struct wl_display *ecore_wl_display_get(void); -EAPI void ecore_wl_screen_size_get(int *w, int *h); -EAPI void ecore_wl_pointer_xy_get(int *x, int *y); -EAPI int ecore_wl_dpi_get(void); -EAPI void ecore_wl_display_iterate(void); -EAPI struct wl_cursor *ecore_wl_cursor_get(const char *cursor_name); - -EAPI void ecore_wl_input_grab(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button); -EAPI void ecore_wl_input_ungrab(Ecore_Wl_Input *input); -EAPI void ecore_wl_input_pointer_set(Ecore_Wl_Input *input, struct wl_surface *surface, int hot_x, int hot_y); -EAPI void ecore_wl_input_cursor_from_name_set(Ecore_Wl_Input *input, const char *cursor_name); -EAPI void ecore_wl_input_cursor_default_restore(Ecore_Wl_Input *input); - -EAPI struct wl_list ecore_wl_outputs_get(void); - -EAPI Ecore_Wl_Window *ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buffer_type); -EAPI void ecore_wl_window_free(Ecore_Wl_Window *win); -EAPI void ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y); -EAPI void ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location); -EAPI void ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h); -EAPI void ecore_wl_window_buffer_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer, int x, int y); -EAPI void ecore_wl_window_show(Ecore_Wl_Window *win); -EAPI void ecore_wl_window_hide(Ecore_Wl_Window *win); -EAPI void ecore_wl_window_raise(Ecore_Wl_Window *win); -EAPI void ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized); -EAPI void ecore_wl_window_fullscreen_set(Ecore_Wl_Window *win, Eina_Bool fullscreen); -EAPI void ecore_wl_window_transparent_set(Ecore_Wl_Window *win, Eina_Bool transparent); -EAPI void ecore_wl_window_update_size(Ecore_Wl_Window *win, int w, int h); -EAPI void ecore_wl_window_update_location(Ecore_Wl_Window *win, int x, int y); -EAPI struct wl_surface *ecore_wl_window_surface_get(Ecore_Wl_Window *win); -EAPI struct wl_shell_surface *ecore_wl_window_shell_surface_get(Ecore_Wl_Window *win); -EAPI Ecore_Wl_Window *ecore_wl_window_find(unsigned int id); -EAPI void ecore_wl_window_type_set(Ecore_Wl_Window *win, Ecore_Wl_Window_Type type); -EAPI void ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_surface *surface, int hot_x, int hot_y); -EAPI void ecore_wl_window_cursor_from_name_set(Ecore_Wl_Window *win, const char *cursor_name); -EAPI void ecore_wl_window_cursor_default_restore(Ecore_Wl_Window *win); -EAPI void ecore_wl_window_parent_set(Ecore_Wl_Window *win, Ecore_Wl_Window *parent); - -/** @since 1.7 */ -EAPI Eina_Bool ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered); -EAPI Eina_Bool ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type); -EAPI Ecore_Wl_Dnd *ecore_wl_dnd_get(); -EAPI Eina_Bool ecore_wl_dnd_start_drag(); -EAPI Eina_Bool ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd); - -#endif diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c deleted file mode 100644 index 481ba790b6..0000000000 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c +++ /dev/null @@ -1,497 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include "ecore_wl_private.h" - -/* local function prototypes */ -static Eina_Bool _ecore_wl_shutdown(Eina_Bool close); -static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl); -static void _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version EINA_UNUSED); -static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd); -static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd); - -/* local variables */ -static int _ecore_wl_init_count = 0; -static const struct wl_registry_listener _ecore_wl_registry_listener = -{ - _ecore_wl_cb_handle_global, - NULL // handle_global_remove -}; - -/* external variables */ -int _ecore_wl_log_dom = -1; -Ecore_Wl_Display *_ecore_wl_disp = NULL; - -EAPI int ECORE_WL_EVENT_MOUSE_IN = 0; -EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0; -EAPI int ECORE_WL_EVENT_FOCUS_IN = 0; -EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0; -EAPI int ECORE_WL_EVENT_WINDOW_CONFIGURE = 0; -EAPI int ECORE_WL_EVENT_DND_ENTER = 0; -EAPI int ECORE_WL_EVENT_DND_POSITION = 0; -EAPI int ECORE_WL_EVENT_DND_LEAVE = 0; -EAPI int ECORE_WL_EVENT_DND_DROP = 0; -EAPI int ECORE_WL_EVENT_DATA_SOURCE_TARGET = 0; -EAPI int ECORE_WL_EVENT_DATA_SOURCE_SEND = 0; -EAPI int ECORE_WL_EVENT_SELECTION_DATA_READY = 0; -EAPI int ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = 0; -EAPI int ECORE_WL_EVENT_INTERFACES_BOUND = 0; - -/** - * @defgroup Ecore_Wl_Init_Group Wayland Library Init and Shutdown Functions - * - * Functions that start and shutdown the Ecore Wayland Library. - */ - -/** - * Initialize the Wayland 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_Wl_Init_Group - */ -EAPI int -ecore_wl_init(const char *name) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (++_ecore_wl_init_count != 1) return _ecore_wl_init_count; - - if (!eina_init()) return --_ecore_wl_init_count; - - _ecore_wl_log_dom = - eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR); - if (_ecore_wl_log_dom < 0) - { - EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland"); - eina_shutdown(); - return --_ecore_wl_init_count; - } - - if (!ecore_init()) - { - ERR("Could not initialize ecore"); - eina_log_domain_unregister(_ecore_wl_log_dom); - _ecore_wl_log_dom = -1; - eina_shutdown(); - return --_ecore_wl_init_count; - } - - if (!ecore_event_init()) - { - ERR("Could not initialize ecore_event"); - eina_log_domain_unregister(_ecore_wl_log_dom); - _ecore_wl_log_dom = -1; - ecore_shutdown(); - eina_shutdown(); - return --_ecore_wl_init_count; - } - - if (!ECORE_WL_EVENT_MOUSE_IN) - { - ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new(); - ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new(); - ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new(); - ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new(); - ECORE_WL_EVENT_WINDOW_CONFIGURE = ecore_event_type_new(); - ECORE_WL_EVENT_DND_ENTER = ecore_event_type_new(); - ECORE_WL_EVENT_DND_POSITION = ecore_event_type_new(); - ECORE_WL_EVENT_DND_LEAVE = ecore_event_type_new(); - ECORE_WL_EVENT_DND_DROP = ecore_event_type_new(); - ECORE_WL_EVENT_DATA_SOURCE_TARGET = ecore_event_type_new(); - ECORE_WL_EVENT_DATA_SOURCE_SEND = ecore_event_type_new(); - ECORE_WL_EVENT_SELECTION_DATA_READY = ecore_event_type_new(); - ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = ecore_event_type_new(); - ECORE_WL_EVENT_INTERFACES_BOUND = ecore_event_type_new(); - } - - if (!(_ecore_wl_disp = malloc(sizeof(Ecore_Wl_Display)))) - { - ERR("Could not allocate memory for Ecore_Wl_Display structure"); - eina_log_domain_unregister(_ecore_wl_log_dom); - _ecore_wl_log_dom = -1; - ecore_event_shutdown(); - ecore_shutdown(); - eina_shutdown(); - return --_ecore_wl_init_count; - } - - memset(_ecore_wl_disp, 0, sizeof(Ecore_Wl_Display)); - - if (!(_ecore_wl_disp->wl.display = wl_display_connect(name))) - { - ERR("Could not connect to Wayland display"); - eina_log_domain_unregister(_ecore_wl_log_dom); - _ecore_wl_log_dom = -1; - ecore_event_shutdown(); - ecore_shutdown(); - eina_shutdown(); - return --_ecore_wl_init_count; - } - - _ecore_wl_disp->fd = wl_display_get_fd(_ecore_wl_disp->wl.display); - - _ecore_wl_disp->fd_hdl = - ecore_main_fd_handler_add(_ecore_wl_disp->fd, - ECORE_FD_READ | ECORE_FD_WRITE, - _ecore_wl_cb_handle_data, _ecore_wl_disp, - NULL, NULL); - - wl_list_init(&_ecore_wl_disp->inputs); - wl_list_init(&_ecore_wl_disp->outputs); - - _ecore_wl_disp->wl.registry = - wl_display_get_registry(_ecore_wl_disp->wl.display); - wl_registry_add_listener(_ecore_wl_disp->wl.registry, - &_ecore_wl_registry_listener, _ecore_wl_disp); - - wl_display_dispatch(_ecore_wl_disp->wl.display); - - if (!_ecore_wl_xkb_init(_ecore_wl_disp)) - { - ERR("Could not initialize XKB"); - free(_ecore_wl_disp); - eina_log_domain_unregister(_ecore_wl_log_dom); - _ecore_wl_log_dom = -1; - ecore_event_shutdown(); - ecore_shutdown(); - eina_shutdown(); - return --_ecore_wl_init_count; - } - - _ecore_wl_window_init(); - - return _ecore_wl_init_count; -} - -/** - * Shuts down the Ecore Wayland Library - * - * In shutting down the library, the Wayland 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_Wl_Init_Group - */ -EAPI int -ecore_wl_shutdown(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_wl_shutdown(EINA_TRUE); -} - -/** - * @defgroup Ecore_Wl_Flush_Group Wayland Synchronization Functions - * - * Functions that ensure that all commands which have been issued by the - * Ecore Wayland library have been sent to the server. - */ - -/** - * Sends all Wayland commands to the Wayland Display. - * - * @ingroup Ecore_Wl_Flush_Group - * @since 1.2 - */ -EAPI void -ecore_wl_flush(void) -{ -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - - wl_display_flush(_ecore_wl_disp->wl.display); -} - -/** - * Flushes the command buffer and waits until all requests have been - * processed by the server. - * - * @ingroup Ecore_Wl_Flush_Group - * @since 1.2 - */ -EAPI void -ecore_wl_sync(void) -{ -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - - wl_display_sync(_ecore_wl_disp->wl.display); -} - -/** - * @defgroup Ecore_Wl_Display_Group Wayland Display Functions - * - * Functions that set and retrieve various information about the Wayland Display. - */ - -/** - * Retrieves the Wayland Shm Interface used for the current Wayland connection. - * - * @return The current wayland shm interface - * - * @ingroup Ecore_Wl_Display_Group - * @since 1.2 - */ -EAPI struct wl_shm * -ecore_wl_shm_get(void) -{ - return _ecore_wl_disp->wl.shm; -} - -/** - * Retrieves the Wayland Display Interface used for the current Wayland connection. - * - * @return The current wayland display interface - * - * @ingroup Ecore_Wl_Display_Group - * @since 1.2 - */ -EAPI struct wl_display * -ecore_wl_display_get(void) -{ - return _ecore_wl_disp->wl.display; -} - -/** - * Retrieves the size of the current screen. - * - * @param w where to return the width. May be NULL. Returns 0 on error. - * @param h where to return the height. May be NULL. Returns 0 on error. - * - * @ingroup Ecore_Wl_Display_Group - * @since 1.2 - */ -EAPI void -ecore_wl_screen_size_get(int *w, int *h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (w) *w = 0; - if (h) *h = 0; - - if (!_ecore_wl_disp->output) return; - - if (w) *w = _ecore_wl_disp->output->allocation.w; - if (h) *h = _ecore_wl_disp->output->allocation.h; -} - -/* @since 1.2 */ -EAPI void -ecore_wl_pointer_xy_get(int *x, int *y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_wl_input_pointer_xy_get(x, y); -} - -/** - * Return the screen DPI - * - * This is a simplistic call to get DPI. It does not account for differing - * DPI in the x and y axes nor does it account for multihead or xinerama and - * xrandr where different parts of the screen may have different DPI etc. - * - * @return the general screen DPI (dots/pixels per inch). - * - * @since 1.2 - */ -EAPI int -ecore_wl_dpi_get(void) -{ - int w, mw; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!_ecore_wl_disp->output) return 75; - - mw = _ecore_wl_disp->output->mw; - if (mw <= 0) return 75; - - w = _ecore_wl_disp->output->allocation.w; - /* FIXME: NB: Hrrrmmm, need to verify this. xorg code is using a different - * formula to calc this */ - return (((w * 254) / mw) + 5) / 10; -} - -EAPI void -ecore_wl_display_iterate(void) -{ - wl_display_dispatch(_ecore_wl_disp->wl.display); -} - -/** - * Retrieves the requested cursor from the cursor theme - * - * @param cursor_name The desired cursor name to be looked up in the theme - * @return the cursor or NULL if the cursor cannot be found - * - * @since 1.2 - */ -EAPI struct wl_cursor * -ecore_wl_cursor_get(const char *cursor_name) -{ - if ((!_ecore_wl_disp) || (!_ecore_wl_disp->cursor_theme)) - return NULL; - - return wl_cursor_theme_get_cursor(_ecore_wl_disp->cursor_theme, - cursor_name); -} - -/* local functions */ -static Eina_Bool -_ecore_wl_shutdown(Eina_Bool close) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (--_ecore_wl_init_count != 0) return _ecore_wl_init_count; - if (!_ecore_wl_disp) return _ecore_wl_init_count; - - _ecore_wl_window_shutdown(); - - if (_ecore_wl_disp->fd_hdl) - ecore_main_fd_handler_del(_ecore_wl_disp->fd_hdl); - - if (close) - { - Ecore_Wl_Output *out, *tout; - Ecore_Wl_Input *in, *tin; - - wl_list_for_each_safe(out, tout, &_ecore_wl_disp->outputs, link) - _ecore_wl_output_del(out); - - wl_list_for_each_safe(in, tin, &_ecore_wl_disp->inputs, link) - _ecore_wl_input_del(in); - - _ecore_wl_xkb_shutdown(_ecore_wl_disp); - - if (_ecore_wl_disp->wl.shell) - wl_shell_destroy(_ecore_wl_disp->wl.shell); - if (_ecore_wl_disp->wl.shm) wl_shm_destroy(_ecore_wl_disp->wl.shm); - if (_ecore_wl_disp->wl.data_device_manager) - wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager); - if (_ecore_wl_disp->wl.compositor) - wl_compositor_destroy(_ecore_wl_disp->wl.compositor); - if (_ecore_wl_disp->wl.display) - { - wl_registry_destroy(_ecore_wl_disp->wl.registry); - wl_display_flush(_ecore_wl_disp->wl.display); - wl_display_disconnect(_ecore_wl_disp->wl.display); - } - free(_ecore_wl_disp); - } - - ecore_event_shutdown(); - ecore_shutdown(); - - eina_log_domain_unregister(_ecore_wl_log_dom); - _ecore_wl_log_dom = -1; - eina_shutdown(); - - return _ecore_wl_init_count; -} - -static Eina_Bool -_ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl) -{ - Ecore_Wl_Display *ewd; - - /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ - - if (!(ewd = data)) return ECORE_CALLBACK_RENEW; - - /* FIXME: This should also catch ECORE_FD_ERROR and exit */ - - /* wl_display_dispatch_pending(ewd->wl.display); */ - - if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ)) - wl_display_dispatch(ewd->wl.display); - else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE)) - wl_display_flush(ewd->wl.display); - - return ECORE_CALLBACK_RENEW; -} - -static void -_ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version EINA_UNUSED) -{ - Ecore_Wl_Display *ewd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ewd = data; - - if (!strcmp(interface, "wl_compositor")) - { - ewd->wl.compositor = - wl_registry_bind(registry, id, &wl_compositor_interface, 1); - } - else if (!strcmp(interface, "wl_output")) - _ecore_wl_output_add(ewd, id); - else if (!strcmp(interface, "wl_seat")) - _ecore_wl_input_add(ewd, id); - else if (!strcmp(interface, "wl_shell")) - { - ewd->wl.shell = - wl_registry_bind(registry, id, &wl_shell_interface, 1); - } - else if (!strcmp(interface, "wl_shm")) - { - ewd->wl.shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); - - /* FIXME: We should not hard-code a cursor size here, and we should - * also import the theme name from a config or env variable */ - ewd->cursor_theme = wl_cursor_theme_load(NULL, 32, ewd->wl.shm); - } - else if (!strcmp(interface, "wl_data_device_manager")) - { - ewd->wl.data_device_manager = - wl_registry_bind(registry, id, &wl_data_device_manager_interface, 1); - } - - if ((ewd->wl.compositor) && (ewd->wl.shm) && (ewd->wl.shell)) - { - Ecore_Wl_Event_Interfaces_Bound *ev; - - if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Interfaces_Bound)))) - return; - - ev->compositor = (ewd->wl.compositor != NULL); - ev->shm = (ewd->wl.shm != NULL); - ev->shell = (ewd->wl.shell != NULL); - - ecore_event_add(ECORE_WL_EVENT_INTERFACES_BOUND, ev, NULL, NULL); - } -} - -static Eina_Bool -_ecore_wl_xkb_init(Ecore_Wl_Display *ewd) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ewd->xkb.context = xkb_context_new(0))) - return EINA_FALSE; - - return EINA_TRUE; -} - -static Eina_Bool -_ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xkb_context_unref(ewd->xkb.context); - - return EINA_TRUE; -} - -struct wl_data_source * -_ecore_wl_create_data_source(Ecore_Wl_Display *ewd) -{ - return wl_data_device_manager_create_data_source(ewd->wl.data_device_manager); -} diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_dnd.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_dnd.c deleted file mode 100644 index 403e3b9f6b..0000000000 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_dnd.c +++ /dev/null @@ -1,485 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include "ecore_wl_private.h" - -struct _dnd_task -{ - void *data; - Ecore_Fd_Cb cb; -}; - -struct _dnd_read_ctx -{ - int epoll_fd; - struct epoll_event *ep; -}; - -/* local function prototypes */ -static void _ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, const char *type); -static void _ecore_wl_dnd_cb_enter_free(void *data EINA_UNUSED, void *event); - -static void _ecore_wl_dnd_data_source_target(void *data, struct wl_data_source *source, const char *mime_type); -static void _ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd); -static void _ecore_wl_dnd_data_source_cancelled(void *data, struct wl_data_source *source); -static void _ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char *type); - -/* wayland listeners */ -static const struct wl_data_offer_listener _ecore_wl_data_offer_listener = -{ - _ecore_wl_dnd_offer, -}; - -static const struct wl_data_source_listener _ecore_wl_data_source_listener = -{ - _ecore_wl_dnd_data_source_target, - _ecore_wl_dnd_data_source_send, - _ecore_wl_dnd_data_source_cancelled -}; - -extern Ecore_Wl_Dnd *glb_dnd; - -EAPI Ecore_Wl_Dnd * -ecore_wl_dnd_get() -{ - return glb_dnd; -} - -EAPI Eina_Bool -ecore_wl_dnd_start_drag(Ecore_Wl_Dnd *dnd EINA_UNUSED) -{ - //TODO: - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered) -{ - char **p; - const char **type; - - dnd->data_source = _ecore_wl_create_data_source(dnd->ewd); - - /* free old types */ - if (dnd->types_offered.data) - { - wl_array_for_each(p, &dnd->types_offered) - free(*p); - wl_array_release(&dnd->types_offered); - wl_array_init(&dnd->types_offered); - } - - for (type = types_offered; *type; type++) - { - p = wl_array_add(&dnd->types_offered, sizeof(*p)); - *p = strdup(*type); - wl_data_source_offer(dnd->data_source, *p); - } - - wl_data_source_add_listener(dnd->data_source, &_ecore_wl_data_source_listener, dnd); - - _ecore_wl_input_set_selection(dnd->input, dnd->data_source); - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type) -{ - char **p; - Ecore_Wl_Input *input; - - input = dnd->input; - - if (!input->selection_source) return EINA_FALSE; - - wl_array_for_each(p, &input->selection_source->types) - if (strcmp(type, *p) == 0) break; - - if (!*p) return EINA_FALSE; - - _ecore_wl_dnd_source_receive_data(input->selection_source, type); - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd) -{ - Ecore_Wl_Input *input; - - input = dnd->input; - return (input->selection_source != NULL); -} - -/* local functions */ -static void -_ecore_wl_dnd_data_source_target(void *data EINA_UNUSED, struct wl_data_source *source EINA_UNUSED, const char *mime_type EINA_UNUSED) -{ - //TODO: -} - -static void -_ecore_wl_dnd_cb_data_source_send_free(void *data EINA_UNUSED, void *event) -{ - Ecore_Wl_Event_Data_Source_Send *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = event)) return; - - free(ev->type); - free(ev); -} - -static void -_ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd) -{ - Ecore_Wl_Event_Data_Source_Send *event; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!data) return; - - if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Send)))) return; - - event->type = strdup(mime_type); - event->fd = fd; - - ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, event, _ecore_wl_dnd_cb_data_source_send_free, NULL); -} - -static void -_ecore_wl_dnd_data_source_cancelled(void *data EINA_UNUSED, struct wl_data_source *source) -{ - wl_data_source_destroy(source); -} - -void -_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer) -{ - Ecore_Wl_Dnd_Source *source; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source)))) return; - wl_array_init(&source->types); - source->refcount = 1; - source->input = input; - source->offer = offer; - wl_data_offer_add_listener(source->offer, - &_ecore_wl_data_offer_listener, source); -} - -void -_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp EINA_UNUSED, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer) -{ - Ecore_Wl_Event_Dnd_Enter *event; - Ecore_Wl_Input *input; - Ecore_Wl_Window *win; - char **p; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!(input = data)) || (!offer)) return; - - if (!(input->drag_source = wl_data_offer_get_user_data(offer))) - return; - - win = wl_surface_get_user_data(surface); -// input->pointer_focus = win; - - p = wl_array_add(&input->drag_source->types, sizeof(*p)); - *p = NULL; - - if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return; - - event->win = win->id; - if (input->drag_source->input) - { - if (input->drag_source->input->keyboard_focus) - event->source = input->drag_source->input->keyboard_focus->id; - } - - event->position.x = wl_fixed_to_int(x); - event->position.y = wl_fixed_to_int(y); - event->num_types = input->drag_source->types.size; - event->types = input->drag_source->types.data; - - ecore_event_add(ECORE_WL_EVENT_DND_ENTER, event, - _ecore_wl_dnd_cb_enter_free, NULL); -} - -void -_ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device EINA_UNUSED) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - /* FIXME: NB: This MAY need to raise a wl_event_dnd_leave for the - * source window */ - _ecore_wl_dnd_del(input->drag_source); - input->drag_source = NULL; -} - -void -_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x, wl_fixed_t y) -{ - Ecore_Wl_Event_Dnd_Position *event; - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - - input->sx = wl_fixed_to_int(x); - input->sy = wl_fixed_to_int(y); - - if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return; - - if (input->drag_source) - { - if (input->drag_source->input) - { - if (input->drag_source->input->pointer_focus) - event->win = input->drag_source->input->pointer_focus->id; - if (input->drag_source->input->keyboard_focus) - event->source = input->drag_source->input->keyboard_focus->id; - } - } - - event->position.x = input->sx; - event->position.y = input->sy; - - ecore_event_add(ECORE_WL_EVENT_DND_POSITION, event, NULL, NULL); -} - -void -_ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device EINA_UNUSED) -{ - Ecore_Wl_Event_Dnd_Drop *event; - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - - if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return; - - if (input->drag_source) - { - if (input->drag_source->input) - { - if (input->drag_source->input->pointer_focus) - event->win = input->drag_source->input->pointer_focus->id; - if (input->drag_source->input->keyboard_focus) - event->source = input->drag_source->input->keyboard_focus->id; - } - } - - event->position.x = input->sx; - event->position.y = input->sy; - - ecore_event_add(ECORE_WL_EVENT_DND_DROP, event, NULL, NULL); -} - -void -_ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - if (input->selection_source) _ecore_wl_dnd_del(input->selection_source); - input->selection_source = NULL; - if (offer) - { - char **p; - - input->selection_source = wl_data_offer_get_user_data(offer); - p = wl_array_add(&input->selection_source->types, sizeof(*p)); - *p = NULL; - } -} - -void -_ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!source) return; - source->refcount--; - if (source->refcount == 0) - { - char **p; - - wl_data_offer_destroy(source->offer); - for (p = source->types.data; *p; p++) - free(*p); - wl_array_release(&source->types); - free(source); - } -} - -/* local functions */ -static void -_ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, const char *type) -{ - Ecore_Wl_Dnd_Source *source; - char **p; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(source = data)) return; - p = wl_array_add(&source->types, sizeof(*p)); - *p = strdup(type); -} - -static void -_ecore_wl_dnd_cb_enter_free(void *data EINA_UNUSED, void *event) -{ - Ecore_Wl_Event_Dnd_Enter *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = event)) return; - free(ev); -} - -static void -_ecore_wl_dnd_cb_selection_data_ready_free(void *data EINA_UNUSED, void *event) -{ - Ecore_Wl_Event_Selection_Data_Ready *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = event)) return; - - free(ev->data); - free(ev); -} - -static Eina_Bool -_ecore_wl_dnd_read_data(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - int len; - char buffer[4096]; - Ecore_Wl_Dnd_Source *source; - Ecore_Wl_Event_Selection_Data_Ready *event; - Eina_Bool ret; - - source = data; - - len = read(source->fd, buffer, sizeof buffer); - - if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Selection_Data_Ready)))) - return ECORE_CALLBACK_CANCEL; - - if (len <= 0) - { - close(source->fd); - _ecore_wl_dnd_del(source); - event->done = EINA_TRUE; - event->data = NULL; - event->len = 0; - ret = ECORE_CALLBACK_CANCEL; - } - else - { - event->data = malloc(len + 1); - if (!event->data) return ECORE_CALLBACK_CANCEL; - strncpy(event->data, buffer, len); - event->data[len] = '\0'; - event->len = len; - event->done = EINA_FALSE; - ret = ECORE_CALLBACK_RENEW; - } - - ecore_event_add(ECORE_WL_EVENT_SELECTION_DATA_READY, event, - _ecore_wl_dnd_cb_selection_data_ready_free, NULL); - return ret; -} - - -static Eina_Bool -_ecore_wl_dnd_idler_cb(void *data) -{ - struct _dnd_read_ctx *ctx; - struct _dnd_task *task; - int count, i; - - ctx = data; - count = epoll_wait(ctx->epoll_fd, ctx->ep, 1, 0); - for (i = 0; i < count; i++) - { - task = ctx->ep->data.ptr; - if (task->cb(task->data, NULL) == ECORE_CALLBACK_CANCEL) - { - free(ctx->ep); - free(task); - free(ctx); - return ECORE_CALLBACK_CANCEL; - } - } - return ECORE_CALLBACK_RENEW; -} - -static void -_ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char *type) -{ - int epoll_fd; - struct epoll_event *ep = NULL; - struct _dnd_task *task = NULL; - struct _dnd_read_ctx *read_ctx = NULL; - int p[2]; - - if (pipe2(p, O_CLOEXEC) == -1) - return; - - wl_data_offer_receive(source->offer, type, p[1]); - close(p[1]); - - /* Due to http://trac.enlightenment.org/e/ticket/1208, - * use epoll and idle handler instead of ecore_main_fd_handler_add() */ - - ep = calloc(1, sizeof(struct epoll_event)); - if (!ep) goto err; - - task = calloc(1, sizeof(struct _dnd_task)); - if (!task) goto err; - - read_ctx = calloc(1, sizeof(struct _dnd_read_ctx)); - if (!read_ctx) goto err; - - epoll_fd = epoll_create1(0); - if (epoll_fd < 0) goto err; - - task->data = source; - task->cb = _ecore_wl_dnd_read_data; - ep->events = EPOLLIN; - ep->data.ptr = task; - - if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err; - - read_ctx->epoll_fd = epoll_fd; - read_ctx->ep = ep; - - if (!ecore_idler_add(_ecore_wl_dnd_idler_cb, read_ctx)) goto err; - - source->refcount++; - source->fd = p[0]; - return; - -err: - if (ep) free(ep); - if (task) free(task); - if (read_ctx) free(read_ctx); - close(p[0]); - return; -} diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_input.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_input.c deleted file mode 100644 index b8485fb625..0000000000 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_input.c +++ /dev/null @@ -1,1208 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -/** - * NB: Events that receive a 'serial' instead of timestamp - * - * input_device_attach (for pointer image) - * input_device_button_event (button press/release) - * input_device_key_press - * input_device_pointer_enter - * input_device_pointer_leave - * input_device_keyboard_enter - * input_device_keyboard_leave - * input_device_touch_down - * input_device_touch_up - * - **/ - -#include "ecore_wl_private.h" -#include -#include - -/* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... - * What about other OSs ?? */ -#ifdef __linux__ -# include -#else -# define BTN_LEFT 0x110 -# define BTN_RIGHT 0x111 -# define BTN_MIDDLE 0x112 -# define BTN_SIDE 0x113 -# define BTN_EXTRA 0x114 -# define BTN_FORWARD 0x115 -# define BTN_BACK 0x116 -#endif - -Ecore_Wl_Dnd *glb_dnd = NULL; - -/* local function prototypes */ -static void _ecore_wl_input_seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps); - -static void _ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy); -static void _ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface); -static void _ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy); -static void _ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state); -static void _ecore_wl_input_cb_pointer_axis(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, unsigned int axis, wl_fixed_t value); -static void _ecore_wl_input_cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED); -static void _ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size); -static void _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface, struct wl_array *keys EINA_UNUSED); -static void _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface); -static void _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int key, unsigned int state); -static void _ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial EINA_UNUSED, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group); -static Eina_Bool _ecore_wl_input_cb_keyboard_repeat(void *data, Ecore_Fd_Handler *handler EINA_UNUSED); -static void _ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface EINA_UNUSED, int id EINA_UNUSED, wl_fixed_t x, wl_fixed_t y); -static void _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id EINA_UNUSED); -static void _ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id EINA_UNUSED, wl_fixed_t x, wl_fixed_t y); -static void _ecore_wl_input_cb_touch_frame(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED); -static void _ecore_wl_input_cb_touch_cancel(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED); -static void _ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); -static void _ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer); -static void _ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device); -static void _ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, wl_fixed_t x, wl_fixed_t y); -static void _ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device); -static void _ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); - -static void _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); -static void _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); -static void _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); -static void _ecore_wl_input_focus_in_send(Ecore_Wl_Input *input EINA_UNUSED, Ecore_Wl_Window *win, unsigned int timestamp); -static void _ecore_wl_input_focus_out_send(Ecore_Wl_Input *input EINA_UNUSED, Ecore_Wl_Window *win, unsigned int timestamp); -static void _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); -static void _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); -static void _ecore_wl_input_mouse_wheel_send(Ecore_Wl_Input *input, unsigned int axis, int value, unsigned int timestamp); - -/* static int _ecore_wl_input_keysym_to_string(unsigned int symbol, char *buffer, int len); */ - -/* wayland interfaces */ -static const struct wl_pointer_listener pointer_listener = -{ - _ecore_wl_input_cb_pointer_enter, - _ecore_wl_input_cb_pointer_leave, - _ecore_wl_input_cb_pointer_motion, - _ecore_wl_input_cb_pointer_button, - _ecore_wl_input_cb_pointer_axis, -}; - -static const struct wl_keyboard_listener keyboard_listener = -{ - _ecore_wl_input_cb_keyboard_keymap, - _ecore_wl_input_cb_keyboard_enter, - _ecore_wl_input_cb_keyboard_leave, - _ecore_wl_input_cb_keyboard_key, - _ecore_wl_input_cb_keyboard_modifiers, -}; - -static const struct wl_touch_listener touch_listener = -{ - _ecore_wl_input_cb_touch_down, - _ecore_wl_input_cb_touch_up, - _ecore_wl_input_cb_touch_motion, - _ecore_wl_input_cb_touch_frame, - _ecore_wl_input_cb_touch_cancel -}; - -static const struct wl_seat_listener _ecore_wl_seat_listener = -{ - _ecore_wl_input_seat_handle_capabilities, -}; - -static const struct wl_data_device_listener _ecore_wl_data_listener = -{ - _ecore_wl_input_cb_data_offer, - _ecore_wl_input_cb_data_enter, - _ecore_wl_input_cb_data_leave, - _ecore_wl_input_cb_data_motion, - _ecore_wl_input_cb_data_drop, - _ecore_wl_input_cb_data_selection -}; - -static const struct wl_callback_listener _ecore_wl_pointer_surface_listener = -{ - _ecore_wl_input_cb_pointer_frame -}; - -/* local variables */ -static int _pointer_x, _pointer_y; - -EAPI void -ecore_wl_input_grab(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!input) return; - input->grab = win; - input->grab_button = button; -} - -EAPI void -ecore_wl_input_ungrab(Ecore_Wl_Input *input) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!input) return; - input->grab = NULL; - input->grab_button = 0; -} - -EAPI void -ecore_wl_input_pointer_set(Ecore_Wl_Input *input, struct wl_surface *surface, int hot_x, int hot_y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (input) - wl_pointer_set_cursor(input->pointer, input->pointer_enter_serial, - surface, hot_x, hot_y); -} - -EAPI void -ecore_wl_input_cursor_from_name_set(Ecore_Wl_Input *input, const char *cursor_name) -{ - struct wl_cursor_image *cursor_image; - struct wl_buffer *buffer; - struct wl_cursor *cursor; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!input) return; - - eina_stringshare_replace(&input->cursor_name, cursor_name); - - /* No cursor. Set to default Left Pointer */ - if (!cursor_name) - eina_stringshare_replace(&input->cursor_name, "left_ptr"); - - /* try to get this cursor from the theme */ - if (!(cursor = ecore_wl_cursor_get(input->cursor_name))) - { - /* if the theme does not have this cursor, default to left pointer */ - if (!(cursor = ecore_wl_cursor_get("left_ptr"))) - return; - } - - if ((!cursor->images) || (!cursor->images[0])) - { - ecore_wl_input_pointer_set(input, NULL, 0, 0); - return; - } - - cursor_image = cursor->images[0]; - if ((buffer = wl_cursor_image_get_buffer(cursor_image))) - { - ecore_wl_input_pointer_set(input, input->cursor_surface, - cursor_image->hotspot_x, - cursor_image->hotspot_y); - wl_surface_attach(input->cursor_surface, buffer, 0, 0); - wl_surface_damage(input->cursor_surface, 0, 0, - cursor_image->width, cursor_image->height); - wl_surface_commit(input->cursor_surface); - - if (!input->cursor_frame_cb) - _ecore_wl_input_cb_pointer_frame(input, NULL, 0); - } -} - -EAPI void -ecore_wl_input_cursor_default_restore(Ecore_Wl_Input *input) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!input) return; - - /* Restore to default wayland cursor */ - ecore_wl_input_cursor_from_name_set(input, "left_ptr"); -} - -/* local functions */ -void -_ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = malloc(sizeof(Ecore_Wl_Input)))) return; - - memset(input, 0, sizeof(Ecore_Wl_Input)); - - input->display = ewd; - input->pointer_focus = NULL; - input->keyboard_focus = NULL; - - input->seat = - wl_registry_bind(ewd->wl.registry, id, &wl_seat_interface, 1); - wl_list_insert(ewd->inputs.prev, &input->link); - - wl_seat_add_listener(input->seat, - &_ecore_wl_seat_listener, input); - wl_seat_set_user_data(input->seat, input); - - input->data_device = - wl_data_device_manager_get_data_device(ewd->wl.data_device_manager, - input->seat); - wl_data_device_add_listener(input->data_device, - &_ecore_wl_data_listener, input); - input->cursor_surface = - wl_compositor_create_surface(_ecore_wl_disp->wl.compositor); - - input->repeat.timerfd = - timerfd_create(CLOCK_MONOTONIC, (TFD_CLOEXEC | TFD_NONBLOCK)); - - input->repeat.hdlr = - ecore_main_fd_handler_add(input->repeat.timerfd, ECORE_FD_READ, - _ecore_wl_input_cb_keyboard_repeat, input, - NULL, NULL); - - ewd->input = input; - - /* create Ecore_Wl_Dnd */ - if (!glb_dnd) - if (!(glb_dnd = calloc(1, sizeof(Ecore_Wl_Dnd)))) return; - glb_dnd->ewd = ewd; - glb_dnd->input = input; - input->dnd = glb_dnd; - wl_array_init(&glb_dnd->types_offered); -} - -void -_ecore_wl_input_del(Ecore_Wl_Input *input) -{ - if (!input) return; - - if (input->cursor_name) eina_stringshare_del(input->cursor_name); - input->cursor_name = NULL; - - if (input->keyboard_focus) - { - Ecore_Wl_Window *win = NULL; - - if ((win = input->keyboard_focus)) - win->keyboard_device = NULL; - - input->keyboard_focus = NULL; - } - - if (input->drag_source) _ecore_wl_dnd_del(input->drag_source); - input->drag_source = NULL; - - if (input->selection_source) _ecore_wl_dnd_del(input->selection_source); - input->selection_source = NULL; - - if (input->data_device) wl_data_device_destroy(input->data_device); - - if (input->xkb.state) - xkb_state_unref(input->xkb.state); - if (input->xkb.keymap) - xkb_map_unref(input->xkb.keymap); - - if (input->cursor_surface) - wl_surface_destroy(input->cursor_surface); - - wl_list_remove(&input->link); - if (input->seat) wl_seat_destroy(input->seat); - - if (input->repeat.hdlr) ecore_main_fd_handler_del(input->repeat.hdlr); - input->repeat.hdlr = NULL; - - if (input->repeat.timerfd) close(input->repeat.timerfd); - input->repeat.timerfd = 0; - - free(input); -} - -void -_ecore_wl_input_pointer_xy_get(int *x, int *y) -{ - if (x) *x = _pointer_x; - if (y) *y = _pointer_y; -} - -static void -_ecore_wl_input_seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) -{ - Ecore_Wl_Input *input; - - if (!(input = data)) return; - - if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!input->pointer)) - { - input->pointer = wl_seat_get_pointer(seat); - wl_pointer_set_user_data(input->pointer, input); - wl_pointer_add_listener(input->pointer, &pointer_listener, input); - } - else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->pointer)) - { - wl_pointer_destroy(input->pointer); - input->pointer = NULL; - } - - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && (!input->keyboard)) - { - input->keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_set_user_data(input->keyboard, input); - wl_keyboard_add_listener(input->keyboard, &keyboard_listener, input); - } - else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->keyboard)) - { - wl_keyboard_destroy(input->keyboard); - input->keyboard = NULL; - } - - if ((caps & WL_SEAT_CAPABILITY_TOUCH) && (!input->touch)) - { - input->touch = wl_seat_get_touch(seat); - wl_touch_set_user_data(input->touch, input); - wl_touch_add_listener(input->touch, &touch_listener, input); - } - else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->touch)) - { - wl_touch_destroy(input->touch); - input->touch = NULL; - } -} - - -static void -_ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy) -{ - Ecore_Wl_Input *input; - - /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ - - if (!(input = data)) return; - - _pointer_x = input->sx = wl_fixed_to_int(sx); - _pointer_y = input->sy = wl_fixed_to_int(sy); - - input->timestamp = timestamp; - - if (input->pointer_focus) - _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp); -} - -static void -_ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - - input->timestamp = timestamp; - input->display->serial = serial; - -// _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp); - - if (state) - { - if ((input->pointer_focus) && (!input->grab) && (state)) - ecore_wl_input_grab(input, input->pointer_focus, button); - - input->button = button; - _ecore_wl_input_mouse_down_send(input, input->pointer_focus, - timestamp); - } - else - { - _ecore_wl_input_mouse_up_send(input, input->pointer_focus, - timestamp); - input->button = 0; - - if ((input->grab) && (input->grab_button == button) && (!state)) - ecore_wl_input_ungrab(input); - } - -// _ecore_wl_input_mouse_move_send(input, timestamp); -} - -static void -_ecore_wl_input_cb_pointer_axis(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, unsigned int axis, wl_fixed_t value) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - _ecore_wl_input_mouse_wheel_send(input, axis, wl_fixed_to_int(value), - timestamp); -} - -static void -_ecore_wl_input_cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - - if (callback) - { - if (callback != input->cursor_frame_cb) return; - wl_callback_destroy(callback); - input->cursor_frame_cb = NULL; - } - - if (!input->cursor_name) - { - ecore_wl_input_pointer_set(input, NULL, 0, 0); - return; - } - - if (!input->cursor_frame_cb) - { - input->cursor_frame_cb = wl_surface_frame(input->cursor_surface); - wl_callback_add_listener(input->cursor_frame_cb, - &_ecore_wl_pointer_surface_listener, input); - } -} - -static void -_ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size) -{ - Ecore_Wl_Input *input; - char *map = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) - { - close(fd); - return; - } - - if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) - { - close(fd); - return; - } - - map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - if (map == MAP_FAILED) - { - close(fd); - return; - } - - input->xkb.keymap = - xkb_map_new_from_string(input->display->xkb.context, map, - XKB_KEYMAP_FORMAT_TEXT_V1, 0); - - munmap(map, size); - close(fd); - - if (!(input->xkb.keymap)) return; - if (!(input->xkb.state = xkb_state_new(input->xkb.keymap))) - { - xkb_map_unref(input->xkb.keymap); - input->xkb.keymap = NULL; - return; - } - - input->xkb.control_mask = - 1 << xkb_map_mod_get_index(input->xkb.keymap, "Control"); - input->xkb.alt_mask = - 1 << xkb_map_mod_get_index(input->xkb.keymap, "Mod1"); - input->xkb.shift_mask = - 1 << xkb_map_mod_get_index(input->xkb.keymap, "Shift"); -} - -static void -_ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state) -{ - Ecore_Wl_Input *input; - Ecore_Wl_Window *win; - unsigned int code, num; - const xkb_keysym_t *syms; - xkb_keysym_t sym = XKB_KEY_NoSymbol; - xkb_mod_mask_t mask; - char string[32], key[32], keyname[32];// compose[32]; - Ecore_Event_Key *e; - struct itimerspec ts; - int len = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - input->display->serial = serial; - - /* xkb rules reflect X broken keycodes, so offset by 8 */ - code = keycode + 8; - - win = input->keyboard_focus; - if ((!win) || (win->keyboard_device != input) || (!input->xkb.state)) - return; - - mask = xkb_state_serialize_mods(input->xkb.state, - XKB_STATE_DEPRESSED | XKB_STATE_LATCHED); - - input->modifiers = 0; - - /* The Ecore_Event_Modifiers don't quite match the X mask bits */ - if (mask & input->xkb.control_mask) - input->modifiers |= ECORE_EVENT_MODIFIER_CTRL; - if (mask & input->xkb.alt_mask) - input->modifiers |= ECORE_EVENT_MODIFIER_ALT; - if (mask & input->xkb.shift_mask) - input->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - - num = xkb_key_get_syms(input->xkb.state, code, &syms); - if (num == 1) sym = syms[0]; - - memset(key, 0, sizeof(key)); - xkb_keysym_get_name(sym, key, sizeof(key)); - - memset(keyname, 0, sizeof(keyname)); - xkb_keysym_get_name(sym, keyname, sizeof(keyname)); - if (keyname[0] == '\0') - snprintf(keyname, sizeof(keyname), "Keycode-%i", code); - - memset(string, 0, sizeof(string)); - if (xkb_keysym_to_utf8(sym, string, 32) <= 0) - { - /* FIXME: NB: We may need to add more checks here for other - * non-printable characters */ - if ((sym == XKB_KEY_Tab) || (sym == XKB_KEY_ISO_Left_Tab)) - string[len++] = '\t'; - } - - /* FIXME: NB: Start hacking on compose key support */ - /* memset(compose, 0, sizeof(compose)); */ - /* if (sym == XKB_KEY_Multi_key) */ - /* { */ - /* if (xkb_keysym_to_utf8(sym, compose, 32) <= 0) */ - /* compose[0] = '\0'; */ - /* } */ - - e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + - ((string[0] != '\0') ? strlen(string) : 0) + 3); - if (!e) return; - - e->keyname = (char *)(e + 1); - e->key = e->keyname + strlen(keyname) + 1; - e->string = strlen(string) ? e->key + strlen(key) + 1 : NULL; - e->compose = e->string; - - strcpy((char *)e->keyname, keyname); - strcpy((char *)e->key, key); - if (strlen(string)) strcpy((char *)e->string, string); - - e->window = win->id; - e->event_window = win->id; - e->timestamp = timestamp; - e->modifiers = input->modifiers; - - if (state) - ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); - else - ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); - - if ((!state) && (keycode == input->repeat.key)) - { - input->repeat.sym = 0; - input->repeat.key = 0; - input->repeat.time = 0; - - ts.it_interval.tv_sec = 0; - ts.it_interval.tv_nsec = 0; - ts.it_value.tv_sec = 0; - ts.it_value.tv_nsec = 0; - - timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); - } - else if ((state) && - ((!input->repeat.key) || - ((keycode) && (keycode != input->repeat.key)))) - { - input->repeat.sym = sym; - input->repeat.key = keycode; - input->repeat.time = timestamp; - - /* interval after expires */ - ts.it_interval.tv_sec = 0; - ts.it_interval.tv_nsec = 35 * 1000 * 1000; - - /* initial expiration */ - ts.it_value.tv_sec = 0; - ts.it_value.tv_nsec = 500 * 1000 * 1000; - - timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); - } -} - -static void -_ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial EINA_UNUSED, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - xkb_state_update_mask(input->xkb.state, depressed, latched, - locked, 0, 0, group); -} - -static Eina_Bool -_ecore_wl_input_cb_keyboard_repeat(void *data, Ecore_Fd_Handler *handler EINA_UNUSED) -{ - Ecore_Wl_Input *input; - Ecore_Wl_Window *win = NULL; - unsigned long long int xp; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return ECORE_CALLBACK_RENEW; - - /* Trap for EAGAIN */ - if (read(input->repeat.timerfd, &xp, sizeof(xp)) != sizeof(xp)) - return ECORE_CALLBACK_RENEW; - - if ((win = input->keyboard_focus)) - _ecore_wl_input_cb_keyboard_key(input, NULL, input->display->serial, - input->repeat.time, - input->repeat.key, EINA_TRUE); - - return ECORE_CALLBACK_RENEW; -} - -static void -_ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) -{ - Ecore_Wl_Input *input; - Ecore_Wl_Window *win = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!surface) return; - if (!(input = data)) return; - - if (!input->timestamp) - { - struct timeval tv; - - gettimeofday(&tv, NULL); - input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000); - } - - input->sx = wl_fixed_to_double(sx); - input->sy = wl_fixed_to_double(sy); - input->display->serial = serial; - input->pointer_enter_serial = serial; - - /* The cursor on the surface is undefined until we set it */ - ecore_wl_input_cursor_from_name_set(input, "left_ptr"); - - if ((win = wl_surface_get_user_data(surface))) - { - win->pointer_device = input; - input->pointer_focus = win; - - _ecore_wl_input_mouse_in_send(input, win, input->timestamp); - } - - /* NB: This whole 'if' below is a major HACK due to wayland's stupidness - * of not sending a mouse_up (or any notification at all for that matter) - * when a move or resize grab is finished */ - if (input->grab) - { - /* NB: This COULD mean a move has finished, or it could mean that - * a 'drag' is being done to a different surface */ - - if ((input->grab == win) && (win->moving)) - { - /* NB: 'Fake' a mouse_up for move finished */ - win->moving = EINA_FALSE; - _ecore_wl_input_mouse_up_send(input, win, input->timestamp); - - input->button = 0; - - if ((input->grab) && (input->grab_button == BTN_LEFT)) - ecore_wl_input_ungrab(input); - } - else if ((input->grab == win) && (win->resizing)) - { - /* NB: 'Fake' a mouse_up for resize finished */ - win->resizing = EINA_FALSE; - _ecore_wl_input_mouse_up_send(input, win, input->timestamp); - - input->button = 0; - - if ((input->grab) && (input->grab_button == BTN_LEFT)) - ecore_wl_input_ungrab(input); - } - /* FIXME: Test d-n-d and potentially add needed case here */ - } -} - -static void -_ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface) -{ - Ecore_Wl_Input *input; - Ecore_Wl_Window *win; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!surface) return; - if (!(input = data)) return; - - input->display->serial = serial; - - if (!surface) return; - if (!(win = wl_surface_get_user_data(surface))) return; - - win->pointer_device = NULL; - input->pointer_focus = NULL; - - /* _ecore_wl_input_mouse_move_send(input, win, input->timestamp); */ - _ecore_wl_input_mouse_out_send(input, win, input->timestamp); - - if (input->grab) - { - /* move or resize started */ - - /* printf("Pointer Leave WITH a Grab\n"); */ - } -} - -static void -_ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface, struct wl_array *keys EINA_UNUSED) -{ - Ecore_Wl_Input *input; - Ecore_Wl_Window *win = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!surface) return; - if (!(input = data)) return; - - if (!input->timestamp) - { - struct timeval tv; - - gettimeofday(&tv, NULL); - input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000); - } - - input->display->serial = serial; - - if (!(win = wl_surface_get_user_data(surface))) return; - - win->keyboard_device = input; - input->keyboard_focus = win; - - _ecore_wl_input_focus_in_send(input, win, input->timestamp); -} - -static void -_ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface) -{ - Ecore_Wl_Input *input; - Ecore_Wl_Window *win; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!surface) return; - if (!(input = data)) return; - - if (input->repeat.timerfd) - { - struct itimerspec ts; - - ts.it_interval.tv_sec = 0; - ts.it_interval.tv_nsec = 0; - ts.it_value.tv_sec = 0; - ts.it_value.tv_nsec = 0; - - timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); - } - - if (!input->timestamp) - { - struct timeval tv; - - gettimeofday(&tv, NULL); - input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000); - } - - input->display->serial = serial; - - if (!surface) return; - if (!(win = wl_surface_get_user_data(surface))) return; - - win->keyboard_device = NULL; - _ecore_wl_input_focus_out_send(input, win, input->timestamp); - - input->keyboard_focus = NULL; -} - -static void -_ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface EINA_UNUSED, int id EINA_UNUSED, wl_fixed_t x, wl_fixed_t y) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!surface) return; - if (!(input = data)) return; - - /* FIXME: NB: Not sure yet if input->timestamp should be set here. - * This needs to be tested with an actual touch device */ - /* input->timestamp = timestamp; */ - input->display->serial = serial; - input->button = BTN_LEFT; - input->sx = wl_fixed_to_int(x); - input->sy = wl_fixed_to_int(y); - _ecore_wl_input_cb_pointer_enter(data, NULL, serial, surface, x, y); - _ecore_wl_input_mouse_down_send(input, input->pointer_focus, timestamp); -} - -static void -_ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id EINA_UNUSED) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - - /* FIXME: NB: Not sure yet if input->timestamp should be set here. - * This needs to be tested with an actual touch device */ - /* input->timestamp = timestamp; */ - input->button = BTN_LEFT; - input->display->serial = serial; - _ecore_wl_input_mouse_up_send(input, input->pointer_focus, timestamp); - input->button = 0; -} - -static void -_ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id EINA_UNUSED, wl_fixed_t x, wl_fixed_t y) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(input = data)) return; - - /* FIXME: NB: Not sure yet if input->timestamp should be set here. - * This needs to be tested with an actual touch device */ - /* input->timestamp = timestamp; */ - input->sx = wl_fixed_to_int(x); - input->sy = wl_fixed_to_int(y); - - _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp); -} - -static void -_ecore_wl_input_cb_touch_frame(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); -} - -static void -_ecore_wl_input_cb_touch_cancel(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); -} - -static void -_ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_wl_dnd_add(data, data_device, offer); -} - -static void -_ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!surface) return; - - _ecore_wl_dnd_enter(data, data_device, timestamp, surface, x, y, offer); -} - -static void -_ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_wl_dnd_leave(data, data_device); -} - -static void -_ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, wl_fixed_t x, wl_fixed_t y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_wl_dnd_motion(data, data_device, timestamp, x, y); -} - -static void -_ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_wl_dnd_drop(data, data_device); -} - -static void -_ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_wl_dnd_selection(data, data_device, offer); -} - -static void -_ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) -{ - Ecore_Event_Mouse_Move *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return; - - ev->timestamp = timestamp; - ev->x = input->sx; - ev->y = input->sy; - /* ev->root.x = input->sx; */ - /* ev->root.y = input->sy; */ - ev->modifiers = input->modifiers; - ev->multi.device = 0; - ev->multi.radius = 1; - ev->multi.radius_x = 1; - ev->multi.radius_y = 1; - ev->multi.pressure = 1.0; - ev->multi.angle = 0.0; - ev->multi.x = input->sx; - ev->multi.y = input->sy; - - if (win) - { - ev->window = win->id; - ev->event_window = win->id; - } - - ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); -} - -static void -_ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) -{ - Ecore_Wl_Event_Mouse_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return; - - ev->x = input->sx; - ev->y = input->sy; - /* ev->root.x = input->sx; */ - /* ev->root.y = input->sy; */ - ev->modifiers = input->modifiers; - ev->timestamp = timestamp; - - if (win) - { - ev->window = win->id; - ev->event_window = win->id; - } - - ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL); -} - -static void -_ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) -{ - Ecore_Wl_Event_Mouse_Out *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return; - - ev->x = input->sx; - ev->y = input->sy; - /* ev->root.x = input->sx; */ - /* ev->root.y = input->sy; */ - ev->modifiers = input->modifiers; - ev->timestamp = timestamp; - - if (win) - { - ev->window = win->id; - ev->event_window = win->id; - } - - ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL); -} - -static void -_ecore_wl_input_focus_in_send(Ecore_Wl_Input *input EINA_UNUSED, Ecore_Wl_Window *win, unsigned int timestamp) -{ - Ecore_Wl_Event_Focus_In *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return; - ev->timestamp = timestamp; - if (win) ev->win = win->id; - ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL); -} - -static void -_ecore_wl_input_focus_out_send(Ecore_Wl_Input *input EINA_UNUSED, Ecore_Wl_Window *win, unsigned int timestamp) -{ - Ecore_Wl_Event_Focus_Out *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return; - ev->timestamp = timestamp; - if (win) ev->win = win->id; - ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL); -} - -static void -_ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) -{ - Ecore_Event_Mouse_Button *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return; - - if (input->button == BTN_LEFT) - ev->buttons = 1; - else if (input->button == BTN_MIDDLE) - ev->buttons = 2; - else if (input->button == BTN_RIGHT) - ev->buttons = 3; - else - ev->buttons = input->button; - - ev->timestamp = timestamp; - ev->x = input->sx; - ev->y = input->sy; - /* ev->root.x = input->sx; */ - /* ev->root.y = input->sy; */ - ev->modifiers = input->modifiers; - - /* FIXME: Need to get these from wayland somehow */ - ev->double_click = 0; - ev->triple_click = 0; - - ev->multi.device = 0; - ev->multi.radius = 1; - ev->multi.radius_x = 1; - ev->multi.radius_y = 1; - ev->multi.pressure = 1.0; - ev->multi.angle = 0.0; - ev->multi.x = input->sx; - ev->multi.y = input->sy; - - if (win) - { - ev->window = win->id; - ev->event_window = win->id; - } - - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); -} - -static void -_ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) -{ - Ecore_Event_Mouse_Button *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return; - - if (input->button == BTN_LEFT) - ev->buttons = 1; - else if (input->button == BTN_MIDDLE) - ev->buttons = 2; - else if (input->button == BTN_RIGHT) - ev->buttons = 3; - else - ev->buttons = input->button; - - ev->timestamp = timestamp; - ev->x = input->sx; - ev->y = input->sy; - /* ev->root.x = input->sx; */ - /* ev->root.y = input->sy; */ - ev->modifiers = input->modifiers; - - /* FIXME: Need to get these from wayland somehow */ - ev->double_click = 0; - ev->triple_click = 0; - - ev->multi.device = 0; - ev->multi.radius = 1; - ev->multi.radius_x = 1; - ev->multi.radius_y = 1; - ev->multi.pressure = 1.0; - ev->multi.angle = 0.0; - ev->multi.x = input->sx; - ev->multi.y = input->sy; - - if (win) - { - ev->window = win->id; - ev->event_window = win->id; - } - - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); -} - -static void -_ecore_wl_input_mouse_wheel_send(Ecore_Wl_Input *input, unsigned int axis, int value, unsigned int timestamp) -{ - Ecore_Event_Mouse_Wheel *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return; - - ev->timestamp = timestamp; - ev->modifiers = input->modifiers; - ev->x = input->sx; - ev->y = input->sy; - /* ev->root.x = input->sx; */ - /* ev->root.y = input->sy; */ - - if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) - { - ev->direction = 0; - ev->z = value; - } - else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) - { - ev->direction = 1; - ev->z = value; - } - - if (input->grab) - { - ev->window = input->grab->id; - ev->event_window = input->grab->id; - } - else if (input->pointer_focus) - { - ev->window = input->pointer_focus->id; - ev->event_window = input->pointer_focus->id; - } - - ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); -} - -void -_ecore_wl_input_set_selection(Ecore_Wl_Input *input, struct wl_data_source *source) -{ - wl_data_device_set_selection(input->data_device, source, input->display->serial); -} - diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_output.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_output.c deleted file mode 100644 index 5498895007..0000000000 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_output.c +++ /dev/null @@ -1,87 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "ecore_wl_private.h" - -/* local function prototypes */ -static void _ecore_wl_output_cb_geometry(void *data, struct wl_output *wl_output EINA_UNUSED, int x, int y, int w, int h, int subpixel EINA_UNUSED, const char *make EINA_UNUSED, const char *model EINA_UNUSED, int transform EINA_UNUSED); -static void _ecore_wl_output_cb_mode(void *data, struct wl_output *wl_output EINA_UNUSED, unsigned int flags, int w, int h, int refresh EINA_UNUSED); - -/* wayland listeners */ -static const struct wl_output_listener _ecore_wl_output_listener = -{ - _ecore_wl_output_cb_geometry, - _ecore_wl_output_cb_mode -}; - -/* @since 1.2 */ -EAPI struct wl_list -ecore_wl_outputs_get(void) -{ - return _ecore_wl_disp->outputs; -} - -void -_ecore_wl_output_add(Ecore_Wl_Display *ewd, unsigned int id) -{ - Ecore_Wl_Output *output; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(output = malloc(sizeof(Ecore_Wl_Output)))) return; - - memset(output, 0, sizeof(Ecore_Wl_Output)); - - output->display = ewd; - - output->output = - wl_registry_bind(ewd->wl.registry, id, &wl_output_interface, 1); - - wl_list_insert(ewd->outputs.prev, &output->link); - wl_output_add_listener(output->output, &_ecore_wl_output_listener, output); -} - -void -_ecore_wl_output_del(Ecore_Wl_Output *output) -{ - if (!output) return; - if (output->destroy) (*output->destroy)(output, output->data); - if (output->output) wl_output_destroy(output->output); - wl_list_remove(&output->link); - free(output); -} - -/* local functions */ -static void -_ecore_wl_output_cb_geometry(void *data, struct wl_output *wl_output EINA_UNUSED, int x, int y, int w, int h, int subpixel EINA_UNUSED, const char *make EINA_UNUSED, const char *model EINA_UNUSED, int transform EINA_UNUSED) -{ - Ecore_Wl_Output *output; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - output = data; - output->allocation.x = x; - output->allocation.y = y; - output->mw = w; - output->mh = h; -} - -static void -_ecore_wl_output_cb_mode(void *data, struct wl_output *wl_output EINA_UNUSED, unsigned int flags, int w, int h, int refresh EINA_UNUSED) -{ - Ecore_Wl_Output *output; - Ecore_Wl_Display *ewd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - output = data; - ewd = output->display; - if (flags & WL_OUTPUT_MODE_CURRENT) - { - output->allocation.w = w; - output->allocation.h = h; - _ecore_wl_disp->output = output; - if (ewd->output_configure) (*ewd->output_configure)(output, ewd->data); - } -} diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h deleted file mode 100644 index ecd7a110b3..0000000000 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _ECORE_WAYLAND_PRIVATE_H -# define _ECORE_WAYLAND_PRIVATE_H - -# include -# include - -# include "Ecore.h" -# include "Ecore_Input.h" -# include "Ecore_Wayland.h" - -//# define LOGFNS 1 - -# ifdef LOGFNS -# include -# define LOGFN(fl, ln, fn) printf("-ECORE-WL: %25s: %5i - %s\n", fl, ln, fn); -# else -# define LOGFN(fl, ln, fn) -# endif - -extern int _ecore_wl_log_dom; -extern Ecore_Wl_Display *_ecore_wl_disp; - -# ifdef ECORE_WL_DEFAULT_LOG_COLOR -# undef ECORE_WL_DEFAULT_LOG_COLOR -# endif -# define ECORE_WL_DEFAULT_LOG_COLOR EINA_COLOR_BLUE - -# ifdef ERR -# undef ERR -# endif -# define ERR(...) EINA_LOG_DOM_ERR(_ecore_wl_log_dom, __VA_ARGS__) - -# ifdef DBG -# undef DBG -# endif -# define DBG(...) EINA_LOG_DOM_DBG(_ecore_wl_log_dom, __VA_ARGS__) - -# ifdef INF -# undef INF -# endif -# define INF(...) EINA_LOG_DOM_INFO(_ecore_wl_log_dom, __VA_ARGS__) - -# ifdef WRN -# undef WRN -# endif -# define WRN(...) EINA_LOG_DOM_WARN(_ecore_wl_log_dom, __VA_ARGS__) - -# ifdef CRIT -# undef CRIT -# endif -# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_wl_log_dom, __VA_ARGS__) - -struct _Ecore_Wl_Dnd -{ - Ecore_Wl_Display *ewd; - Ecore_Wl_Input *input; - - /* As provider */ - struct wl_data_source *data_source; - struct wl_array types_offered; - - /* TODO: dnd specific fields */ -}; - -struct _Ecore_Wl_Dnd_Source -{ - struct wl_data_offer *offer; - Ecore_Wl_Input *input; - struct wl_array types; - int refcount; - int fd; - int x, y; - - /* TODO: task & data_func */ - void *data; -}; - -struct _Ecore_Wl_Dnd_Target -{ - Ecore_Wl_Dnd_Source *source; -}; - -void _ecore_wl_window_init(void); -void _ecore_wl_window_shutdown(void); - -void _ecore_wl_output_add(Ecore_Wl_Display *ewd, unsigned int id); -void _ecore_wl_output_del(Ecore_Wl_Output *output); - -void _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id); -void _ecore_wl_input_del(Ecore_Wl_Input *input); -void _ecore_wl_input_pointer_xy_get(int *x, int *y); -void _ecore_wl_input_set_selection(Ecore_Wl_Input *input, struct wl_data_source *source); - -void _ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device, struct wl_data_offer *offer); -void _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer); -void _ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device); -void _ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, int x, int y); -void _ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device); -void _ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); -void _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source); - -struct wl_data_source *_ecore_wl_create_data_source(Ecore_Wl_Display *ewd); -#endif diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c deleted file mode 100644 index 3d221e9f2a..0000000000 --- a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c +++ /dev/null @@ -1,707 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "ecore_wl_private.h" - -/* local function prototypes */ -static void _ecore_wl_window_cb_ping(void *data EINA_UNUSED, struct wl_shell_surface *shell_surface, unsigned int serial); -static void _ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED, unsigned int edges, int w, int h); -static void _ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED); -static void _ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output EINA_UNUSED); -static void _ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output EINA_UNUSED); -static void _ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h); -static char *_ecore_wl_window_id_str_get(unsigned int win_id); - -/* local variables */ -static Eina_Hash *_windows = NULL; - -/* wayland listeners */ -static const struct wl_surface_listener _ecore_wl_surface_listener = -{ - _ecore_wl_window_cb_surface_enter, - _ecore_wl_window_cb_surface_leave -}; - -static const struct wl_shell_surface_listener _ecore_wl_shell_surface_listener = -{ - _ecore_wl_window_cb_ping, - _ecore_wl_window_cb_configure, - _ecore_wl_window_cb_popup_done -}; - -/* internal functions */ -void -_ecore_wl_window_init(void) -{ - if (!_windows) - _windows = eina_hash_string_superfast_new(NULL); -} - -void -_ecore_wl_window_shutdown(void) -{ - eina_hash_free(_windows); - _windows = NULL; -} - -/** - * @defgroup Ecore_Wl_Window_Group Wayland Library Init and Shutdown Functions - * - * Functions that can be used to create a Wayland 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 - * @param buffer_type The type of the buffer to be used to create a new Ecore_Wl_Window. - * - * @return The new window - * - * @ingroup Ecore_Wl_Window_Group - * @since 1.2 - */ -EAPI Ecore_Wl_Window * -ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buffer_type) -{ - Ecore_Wl_Window *win; - static int _win_id = 1; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(win = malloc(sizeof(Ecore_Wl_Window)))) - { - ERR("Failed to allocate an Ecore Wayland Window"); - return NULL; - } - - memset(win, 0, sizeof(Ecore_Wl_Window)); - - win->display = _ecore_wl_disp; - win->parent = parent; - win->allocation.x = x; - win->allocation.y = y; - win->allocation.w = w; - win->allocation.h = h; - win->saved_allocation = win->allocation; - win->transparent = EINA_FALSE; - /* win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; */ - win->type = ECORE_WL_WINDOW_TYPE_NONE; - win->buffer_type = buffer_type; - win->id = _win_id++; - - eina_hash_add(_windows, _ecore_wl_window_id_str_get(win->id), win); - return win; -} - -/** - * Deletes the given window - * - * @param win The given window - * - * @ingroup Ecore_Wl_Window_Group - * @since 1.2 - */ -EAPI void -ecore_wl_window_free(Ecore_Wl_Window *win) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - - eina_hash_del(_windows, _ecore_wl_window_id_str_get(win->id), win); - - wl_list_for_each(input, &_ecore_wl_disp->inputs, link) - { - if ((input->pointer_focus) && (input->pointer_focus == win)) - input->pointer_focus = NULL; - if ((input->keyboard_focus) && (input->keyboard_focus == win)) - input->keyboard_focus = NULL; - } - - if (win->region.input) wl_region_destroy(win->region.input); - win->region.input = NULL; - if (win->region.opaque) wl_region_destroy(win->region.opaque); - win->region.opaque = NULL; - if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface); - win->shell_surface = NULL; - - if (win->surface) wl_surface_destroy(win->surface); - win->surface = NULL; - - /* HMMM, why was this disabled ? */ - free(win); -} - -/** - * Signals for Wayland to initiate a window move. - * - * The position requested (@p x, @p y) is not honored by Wayland because - * Wayland does not allow specific window placement to be set. - * - * @param win The window to move. - * @param x X Position - * @param y Y Position - * - * @ingroup Ecore_Wl_Window_Group - * @since 1.2 - */ -EAPI void -ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - - win->allocation.x = x; - win->allocation.y = y; - - if (win->shell_surface) - { - Ecore_Wl_Input *input; - - if (!(input = win->keyboard_device)) - { - if (win->parent) - { - if (!(input = win->parent->keyboard_device)) - input = win->parent->pointer_device; - } - } - - if ((!input) || (!input->seat)) return; - - wl_shell_surface_move(win->shell_surface, input->seat, - input->display->serial); - } -} - -/** - * Signals for Wayland to initiate a window resize. - * - * The size requested (@p w, @p h) is not honored by Wayland because - * Wayland does not allow specific window sizes to be set. - * - * @param win The window to resize. - * @param w Width - * @param h Height - * @param location The edge of the window from where the resize should start. - * - * @ingroup Ecore_Wl_Window_Group - * @since 1.2 - */ -EAPI void -ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - - if (win->type != ECORE_WL_WINDOW_TYPE_FULLSCREEN) - { - win->allocation.w = w; - win->allocation.h = h; - - win->region.input = - wl_compositor_create_region(_ecore_wl_disp->wl.compositor); - wl_region_add(win->region.input, win->allocation.x, win->allocation.y, - win->allocation.w, win->allocation.h); - } - - if (!win->transparent) - { - win->region.opaque = - wl_compositor_create_region(_ecore_wl_disp->wl.compositor); - wl_region_add(win->region.opaque, win->allocation.x, win->allocation.y, - win->allocation.w, win->allocation.h); - } - - if (win->shell_surface) - { - Ecore_Wl_Input *input; - - if (!(input = win->keyboard_device)) - { - if (win->parent) - { - if (!(input = win->parent->keyboard_device)) - input = win->parent->pointer_device; - } - } - - if ((!input) || (!input->seat)) return; - - wl_shell_surface_resize(win->shell_surface, input->seat, - input->display->serial, location); - } -} - -EAPI void -ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - if (win->surface) - { - wl_surface_damage(win->surface, x, y, w, h); - wl_surface_commit(win->surface); - } -} - -EAPI void -ecore_wl_window_buffer_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer, int x, int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - - switch (win->buffer_type) - { - case ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW: - win->server_allocation = win->allocation; - break; - case ECORE_WL_WINDOW_BUFFER_TYPE_EGL_IMAGE: - case ECORE_WL_WINDOW_BUFFER_TYPE_SHM: - if (win->surface) - { - if (win->edges & 4) // resizing from the left - x = win->server_allocation.w - win->allocation.w; - else - x = 0; - - if (win->edges & 1) // resizing from the top - y = win->server_allocation.h - win->allocation.h; - else - y = 0; - - win->edges = 0; - - /* if (buffer) */ - wl_surface_attach(win->surface, buffer, x, y); - wl_surface_damage(win->surface, 0, 0, - win->allocation.w, win->allocation.h); - wl_surface_commit(win->surface); - - win->server_allocation = win->allocation; - } - break; - default: - return; - } - - if (win->region.input) - { - wl_surface_set_input_region(win->surface, win->region.input); - wl_region_destroy(win->region.input); - win->region.input = NULL; - } - - if (win->region.opaque) - { - wl_surface_set_opaque_region(win->surface, win->region.opaque); - wl_region_destroy(win->region.opaque); - win->region.opaque = NULL; - } -} - -/** - * Shows a window - * - * Synonymous to "mapping" a window in Wayland System terminology. - * - * @param win The window to show. - * - * @ingroup Ecore_Wl_Window_Group - * @since 1.2 - */ -EAPI void -ecore_wl_window_show(Ecore_Wl_Window *win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - if (win->surface) return; - - win->surface = wl_compositor_create_surface(_ecore_wl_disp->wl.compositor); - wl_surface_set_user_data(win->surface, win); - /* wl_surface_add_listener(win->surface, &_ecore_wl_surface_listener, win); */ - - win->shell_surface = - wl_shell_get_shell_surface(_ecore_wl_disp->wl.shell, win->surface); - wl_shell_surface_add_listener(win->shell_surface, - &_ecore_wl_shell_surface_listener, win); - - switch (win->type) - { - case ECORE_WL_WINDOW_TYPE_FULLSCREEN: - wl_shell_surface_set_fullscreen(win->shell_surface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, - 0, NULL); - break; - case ECORE_WL_WINDOW_TYPE_MAXIMIZED: - wl_shell_surface_set_maximized(win->shell_surface, NULL); - break; - case ECORE_WL_WINDOW_TYPE_TRANSIENT: - wl_shell_surface_set_transient(win->shell_surface, - win->parent->surface, - win->allocation.x, win->allocation.y, 0); - break; - case ECORE_WL_WINDOW_TYPE_MENU: - wl_shell_surface_set_popup(win->shell_surface, - _ecore_wl_disp->input->seat, - _ecore_wl_disp->serial, - win->parent->surface, - win->allocation.x, win->allocation.y, 0); - break; - case ECORE_WL_WINDOW_TYPE_NONE: - win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; - /* fallthrough */ - case ECORE_WL_WINDOW_TYPE_TOPLEVEL: - wl_shell_surface_set_toplevel(win->shell_surface); - break; - default: - break; - } - - /* if (win->type != ECORE_WL_WINDOW_TYPE_FULLSCREEN) */ - /* { */ - /* win->region.input = */ - /* wl_compositor_create_region(_ecore_wl_disp->wl.compositor); */ - /* wl_region_add(win->region.input, win->allocation.x, win->allocation.y, */ - /* win->allocation.w, win->allocation.h); */ - /* } */ - - /* if (!win->transparent) */ - /* { */ - /* win->region.opaque = */ - /* wl_compositor_create_region(_ecore_wl_disp->wl.compositor); */ - /* wl_region_add(win->region.opaque, win->allocation.x, win->allocation.y, */ - /* win->allocation.w, win->allocation.h); */ - /* } */ -} - -/** - * Hides a window - * - * Synonymous to "unmapping" a window in Wayland System terminology. - * - * @param win The window to hide. - * - * @ingroup Ecore_Wl_Window_Group - * @since 1.2 - */ -EAPI void -ecore_wl_window_hide(Ecore_Wl_Window *win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface); - win->shell_surface = NULL; - if (win->surface) wl_surface_destroy(win->surface); - win->surface = NULL; -} - -/** - * Raises a window - * - * @param win The window to raise. - * - * @ingroup Ecore_Wl_Window_Group - * @since 1.2 - */ -EAPI void -ecore_wl_window_raise(Ecore_Wl_Window *win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - if (win->shell_surface) - wl_shell_surface_set_toplevel(win->shell_surface); -} - -EAPI void -ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - - if ((win->type == ECORE_WL_WINDOW_TYPE_MAXIMIZED) == maximized) return; - if (win->type == ECORE_WL_WINDOW_TYPE_TOPLEVEL) - { - win->saved_allocation = win->allocation; - if (win->shell_surface) - wl_shell_surface_set_maximized(win->shell_surface, NULL); - win->type = ECORE_WL_WINDOW_TYPE_MAXIMIZED; - } - else if (win->type == ECORE_WL_WINDOW_TYPE_MAXIMIZED) - { - if (win->shell_surface) - wl_shell_surface_set_toplevel(win->shell_surface); - win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; - _ecore_wl_window_configure_send(win, win->saved_allocation.w, - win->saved_allocation.h); - } -} - -EAPI void -ecore_wl_window_fullscreen_set(Ecore_Wl_Window *win, Eina_Bool fullscreen) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - if ((win->type == ECORE_WL_WINDOW_TYPE_FULLSCREEN) == fullscreen) return; - if (fullscreen) - { - win->type = ECORE_WL_WINDOW_TYPE_FULLSCREEN; - win->saved_allocation = win->allocation; - if (win->shell_surface) - wl_shell_surface_set_fullscreen(win->shell_surface, - WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, - 0, NULL); - } - else - { - if (win->shell_surface) - wl_shell_surface_set_toplevel(win->shell_surface); - win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; - _ecore_wl_window_configure_send(win, win->saved_allocation.w, - win->saved_allocation.h); - } -} - -EAPI void -ecore_wl_window_transparent_set(Ecore_Wl_Window *win, Eina_Bool transparent) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - win->transparent = transparent; - if (win->region.opaque) wl_region_destroy(win->region.opaque); - win->region.opaque = NULL; - if (!win->transparent) - { - win->region.opaque = - wl_compositor_create_region(_ecore_wl_disp->wl.compositor); - wl_region_add(win->region.opaque, win->allocation.x, win->allocation.y, - win->allocation.w, win->allocation.h); - } -} - -EAPI void -ecore_wl_window_update_size(Ecore_Wl_Window *win, int w, int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - win->allocation.w = w; - win->allocation.h = h; -} - -EAPI void -ecore_wl_window_update_location(Ecore_Wl_Window *win, int x, int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - win->allocation.x = x; - win->allocation.y = y; -} - -EAPI struct wl_surface * -ecore_wl_window_surface_get(Ecore_Wl_Window *win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return NULL; - return win->surface; -} - -/* @since 1.2 */ -EAPI struct wl_shell_surface * -ecore_wl_window_shell_surface_get(Ecore_Wl_Window *win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return NULL; - return win->shell_surface; -} - -EAPI Ecore_Wl_Window * -ecore_wl_window_find(unsigned int id) -{ - Ecore_Wl_Window *win = NULL; - - win = eina_hash_find(_windows, _ecore_wl_window_id_str_get(id)); - return win; -} - -EAPI void -ecore_wl_window_type_set(Ecore_Wl_Window *win, Ecore_Wl_Window_Type type) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - win->type = type; -} - -EAPI void -ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_surface *surface, int hot_x, int hot_y) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - - if ((input = win->pointer_device)) - ecore_wl_input_pointer_set(input, surface, hot_x, hot_y); -} - -EAPI void -ecore_wl_window_cursor_from_name_set(Ecore_Wl_Window *win, const char *cursor_name) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - - if ((input = win->pointer_device)) - ecore_wl_input_cursor_from_name_set(input, cursor_name); -} - -EAPI void -ecore_wl_window_cursor_default_restore(Ecore_Wl_Window *win) -{ - Ecore_Wl_Input *input; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - - if ((input = win->pointer_device)) - ecore_wl_input_cursor_default_restore(input); -} - -/* @since 1.2 */ -EAPI void -ecore_wl_window_parent_set(Ecore_Wl_Window *win, Ecore_Wl_Window *parent) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - win->parent = parent; -} - -/* local functions */ -static void -_ecore_wl_window_cb_ping(void *data EINA_UNUSED, struct wl_shell_surface *shell_surface, unsigned int serial) -{ - if (!shell_surface) return; - wl_shell_surface_pong(shell_surface, serial); -} - -static void -_ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED, unsigned int edges, int w, int h) -{ - Ecore_Wl_Window *win; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(win = data)) return; - - if ((w <= 0) || (h <= 0)) return; - - if ((win->allocation.w != w) || (win->allocation.h != h)) - { - win->edges = edges; - if (win->region.input) wl_region_destroy(win->region.input); - win->region.input = NULL; - if (win->region.opaque) wl_region_destroy(win->region.opaque); - win->region.opaque = NULL; - - _ecore_wl_window_configure_send(win, w, h); - } -} - -static void -_ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED) -{ - Ecore_Wl_Window *win; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!shell_surface) return; - if (!(win = data)) return; - ecore_wl_input_ungrab(win->pointer_device); -} - -static void -_ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output EINA_UNUSED) -{ - Ecore_Wl_Window *win; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!surface) return; - if (!(win = data)) return; -} - -static void -_ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output EINA_UNUSED) -{ - Ecore_Wl_Window *win; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!surface) return; - if (!(win = data)) return; -} - -static void -_ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h) -{ - Ecore_Wl_Event_Window_Configure *ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Window_Configure)))) return; - ev->win = win->id; - ev->event_win = win->id; - ev->x = win->allocation.x; - ev->y = win->allocation.y; - ev->w = w; - ev->h = h; - ecore_event_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL); -} - -static char * -_ecore_wl_window_id_str_get(unsigned int win_id) -{ - const char *vals = "qWeRtYuIoP5$&<~"; - static char id[9]; - unsigned int val; - - val = win_id; - 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; -} diff --git a/legacy/ecore/src/lib/ecore_win32/Ecore_Win32.h b/legacy/ecore/src/lib/ecore_win32/Ecore_Win32.h deleted file mode 100644 index ae1bd4ec8c..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/Ecore_Win32.h +++ /dev/null @@ -1,526 +0,0 @@ -#ifndef __ECORE_WIN32_H__ -#define __ECORE_WIN32_H__ - -/* - * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND - * THE API MAY CHANGE. - */ - -#ifndef ECORE_WIN32_WIP_POZEFLKSD -# ifdef _MSC_VER -# pragma message ("You are using a work in progress API. This API is not stable") -# pragma message ("and is subject to change. You use this at your own risk.") -# else -# warning "You are using a work in progress API. This API is not stable" -# warning "and is subject to change. You use this at your own risk." -# endif -#endif - -#include - -#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 - -/** - * @defgroup Ecore_Win32_Group Ecore_Win32 library - * - * @{ - */ - -/** - * @typedef Ecore_Win32_Window_State - * State of a window. - */ -typedef enum -{ - ECORE_WIN32_WINDOW_STATE_ICONIFIED, /**< iconified window */ - ECORE_WIN32_WINDOW_STATE_MODAL, /**< modal dialog box */ - ECORE_WIN32_WINDOW_STATE_STICKY, /**< sticky window */ - ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT, /**< maximum vertical sized window */ - ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ, /**< maximum horizontal sized window */ - ECORE_WIN32_WINDOW_STATE_MAXIMIZED, /**< maximum sized window */ - ECORE_WIN32_WINDOW_STATE_SHADED, /**< shaded window */ - ECORE_WIN32_WINDOW_STATE_HIDDEN, /**< hidden (minimized or iconified) window */ - ECORE_WIN32_WINDOW_STATE_FULLSCREEN, /**< fullscreen window */ - ECORE_WIN32_WINDOW_STATE_ABOVE, /**< above window */ - ECORE_WIN32_WINDOW_STATE_BELOW, /**< below window */ - ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION, /**< To document */ - ECORE_WIN32_WINDOW_STATE_UNKNOWN /**< Unknown state */ -} Ecore_Win32_Window_State; - -/** - * @typedef Ecore_Win32_Window_Type - * Type of a window. - */ -typedef enum -{ - ECORE_WIN32_WINDOW_TYPE_DESKTOP, /**< Desktop feature */ - ECORE_WIN32_WINDOW_TYPE_DOCK, /**< Dock window (should be on top of other windows) */ - ECORE_WIN32_WINDOW_TYPE_TOOLBAR, /**< Toolbar window */ - ECORE_WIN32_WINDOW_TYPE_MENU, /**< Menu window */ - ECORE_WIN32_WINDOW_TYPE_UTILITY, /**< Small persistent utility window, such as a palette or toolbox */ - ECORE_WIN32_WINDOW_TYPE_SPLASH, /**< Splash screen window displayed as an application is starting up */ - ECORE_WIN32_WINDOW_TYPE_DIALOG, /**< Dialog window */ - ECORE_WIN32_WINDOW_TYPE_NORMAL, /**< Normal top-level window */ - ECORE_WIN32_WINDOW_TYPE_UNKNOWN /**< Unknown type */ -} Ecore_Win32_Window_Type; - -/** - * @typedef Ecore_Win32_Cursor_Shape - * Shape of a cursor. - */ -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; - -/** - * @typedef Ecore_Win32_DnD_State - * State of a DnD operation. - */ -typedef enum -{ - ECORE_WIN32_DND_EVENT_DRAG_ENTER = 1, /**< Drag enter */ - ECORE_WIN32_DND_EVENT_DRAG_OVER = 2, /**< Drag over */ - ECORE_WIN32_DND_EVENT_DRAG_LEAVE = 3, /**< Drag leave */ - ECORE_WIN32_DND_EVENT_DROP = 4 /**< Drop */ -} Ecore_Win32_DnD_State; - -/** - * @typedef Ecore_Win32_Window - * Abstract type for a window. - */ -typedef struct _Ecore_Win32_Window Ecore_Win32_Window; - -/** - * @typedef Ecore_Win32_Cursor - * Abstract type for a cursor. - */ -typedef void Ecore_Win32_Cursor; - - -/** - * @typedef Ecore_Win32_Event_Mouse_In - * Event sent when the mouse enters the window. - */ -typedef struct _Ecore_Win32_Event_Mouse_In Ecore_Win32_Event_Mouse_In; - -/** - * @typedef Ecore_Win32_Event_Mouse_Out - * Event sent when the mouse leaves the window. - */ -typedef struct _Ecore_Win32_Event_Mouse_Out Ecore_Win32_Event_Mouse_Out; - -/** - * @typedef Ecore_Win32_Event_Window_Focus_In - * Event sent when the window gets the focus. - */ -typedef struct _Ecore_Win32_Event_Window_Focus_In Ecore_Win32_Event_Window_Focus_In; - -/** - * @typedef Ecore_Win32_Event_Window_Focus_Out - * Event sent when the window looses the focus. - */ -typedef struct _Ecore_Win32_Event_Window_Focus_Out Ecore_Win32_Event_Window_Focus_Out; - -/** - * @typedef Ecore_Win32_Event_Window_Damage - * Event sent when the window is damaged. - */ -typedef struct _Ecore_Win32_Event_Window_Damage Ecore_Win32_Event_Window_Damage; - -/** - * @typedef Ecore_Win32_Event_Window_Create - * Event sent when the window is created. - */ -typedef struct _Ecore_Win32_Event_Window_Create Ecore_Win32_Event_Window_Create; - -/** - * @typedef Ecore_Win32_Event_Window_Destroy - * Event sent when the window is destroyed. - */ -typedef struct _Ecore_Win32_Event_Window_Destroy Ecore_Win32_Event_Window_Destroy; - -/** - * @typedef Ecore_Win32_Event_Window_Hide - * Event sent when the window is hidden. - */ -typedef struct _Ecore_Win32_Event_Window_Hide Ecore_Win32_Event_Window_Hide; - -/** - * @typedef Ecore_Win32_Event_Window_Show - * Event sent when the window is shown. - */ -typedef struct _Ecore_Win32_Event_Window_Show Ecore_Win32_Event_Window_Show; - -/** - * @typedef Ecore_Win32_Event_Window_Configure - * Event sent when the window is configured. - */ -typedef struct _Ecore_Win32_Event_Window_Configure Ecore_Win32_Event_Window_Configure; - -/** - * @typedef Ecore_Win32_Event_Window_Resize - * Event sent when the window is resized. - */ -typedef struct _Ecore_Win32_Event_Window_Resize Ecore_Win32_Event_Window_Resize; - -/** - * @typedef Ecore_Win32_Event_Window_Delete_Request - * Event sent when the window is deleted. - */ -typedef struct _Ecore_Win32_Event_Window_Delete_Request Ecore_Win32_Event_Window_Delete_Request; - -/** - * @struct _Ecore_Win32_Event_Mouse_In - * Event sent when the mouse enters the window. - */ -struct _Ecore_Win32_Event_Mouse_In -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate where the mouse leaved */ - int y; /**< The y coordinate where the mouse entered */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Mouse_Out - * Event sent when the mouse leaves the window. - */ -struct _Ecore_Win32_Event_Mouse_Out -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate where the mouse leaved */ - int y; /**< The y coordinate where the mouse leaved */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Focus_In - * Event sent when the window gets the focus. - */ -struct _Ecore_Win32_Event_Window_Focus_In -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Focus_Out - * Event sent when the window looses the focus. - */ -struct _Ecore_Win32_Event_Window_Focus_Out -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Damage - * Event sent when the window is damaged. - */ -struct _Ecore_Win32_Event_Window_Damage -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate of the top left corner of the damaged region */ - int y; /**< The y coordinate of the top left corner of the damaged region */ - int width; /**< The width of the damaged region */ - int height; /**< The time the event occurred */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Create - * Event sent when the window is created. - */ -struct _Ecore_Win32_Event_Window_Create -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Destroy - * Event sent when the window is destroyed. - */ -struct _Ecore_Win32_Event_Window_Destroy -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Hide - * Event sent when the window is hidden. - */ -struct _Ecore_Win32_Event_Window_Hide -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Show - * Event sent when the window is shown. - */ -struct _Ecore_Win32_Event_Window_Show -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Configure - * Event sent when the window is configured. - */ -struct _Ecore_Win32_Event_Window_Configure -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - Ecore_Win32_Window *abovewin; - int x; /**< The new x coordinate of the top left corner */ - int y; /**< The new y coordinate of the top left corner */ - int width; /**< The new width */ - int height; /**< The new height */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Resize - * Event sent when the window is resized. - */ -struct _Ecore_Win32_Event_Window_Resize -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - int width; /**< The new width */ - int height; /**< The new height */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_Win32_Event_Window_Delete_Request - * Event sent when the window is deleted. - */ -struct _Ecore_Win32_Event_Window_Delete_Request -{ - Ecore_Win32_Window *window; /**< The window that received the event */ - unsigned long timestamp; /**< The time the event occurred */ -}; - -/** - * @typedef Ecore_Win32_Dnd_DropTarget_Callback - * Callback type for Drop operations. See ecore_win32_dnd_register_drop_target(). - */ -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; /**< Ecore_Event for the #Ecore_Win32_Event_Mouse_In event */ -EAPI extern int ECORE_WIN32_EVENT_MOUSE_OUT; /**< Ecore_Event for the #Ecore_Win32_Event_Mouse_Out event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_IN; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Focus_In event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Focus_Out event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the Ecore_Win32_Event_Damage event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_CREATE; /**< Ecore_Event for the Ecore_Win32_Event_Create event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the Ecore_Win32_Event_Destroy event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_HIDE; /**< Ecore_Event for the Ecore_Win32_Event_Hide event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_SHOW; /**< Ecore_Event for the Ecore_Win32_Event_Show event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_CONFIGURE; /**< Ecore_Event for the Ecore_Win32_Event_Configure event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_RESIZE; /**< Ecore_Event for the Ecore_Win32_Event_Resize event */ -EAPI extern int ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Delete_Request event */ - - -/* Core */ - -EAPI int ecore_win32_init(); -EAPI int ecore_win32_shutdown(); -EAPI int ecore_win32_screen_depth_get(); -EAPI void ecore_win32_double_click_time_set(double t); -EAPI double ecore_win32_double_click_time_get(void); -EAPI unsigned long ecore_win32_current_time_get(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(Ecore_Win32_Window *window); - -EAPI void *ecore_win32_window_focus_get(void); - -EAPI void ecore_win32_window_iconified_set(Ecore_Win32_Window *window, - Eina_Bool on); - -EAPI void ecore_win32_window_borderless_set(Ecore_Win32_Window *window, - Eina_Bool on); - -EAPI void ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window, - Eina_Bool on); - -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_shaped_new(Ecore_Win32_Cursor_Shape shape); - -EAPI void ecore_win32_cursor_size_get(int *width, int *height); - - - -/* Drag and drop */ -EAPI int ecore_win32_dnd_init(); -EAPI int ecore_win32_dnd_shutdown(); -EAPI Eina_Bool ecore_win32_dnd_begin(const char *data, - int size); -EAPI Eina_Bool 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__ */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32.c b/legacy/ecore/src/lib/ecore_win32/ecore_win32.c deleted file mode 100644 index b571d74d1b..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32.c +++ /dev/null @@ -1,841 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include - -#include -#include -#include - -#include "Ecore_Win32.h" -#include "ecore_win32_private.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - -/* OLE IID for Drag'n Drop */ - -# define INITGUID -# include -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); - -#define IDI_ICON 101 - -static int _ecore_win32_init_count = 0; - -static void -_ecore_win32_size_check(Ecore_Win32_Window *win, int w, int h, int *dx, int *dy) -{ - int minimal_width; - int minimal_height; - - minimal_width = GetSystemMetrics(SM_CXMIN); - minimal_height = GetSystemMetrics(SM_CYMIN); - if ((w) < MAX(minimal_width, (int)win->min_width)) - *dx = 0; - if ((w) > (int)win->max_width) - *dx = 0; - if ((h) < MAX(minimal_height, (int)win->min_height)) - *dy = 0; - if ((h) > (int)win->max_height) - *dy = 0; -} - -LRESULT CALLBACK -_ecore_win32_window_procedure(HWND window, - UINT message, - WPARAM window_param, - LPARAM data_param) -{ - Ecore_Win32_Callback_Data *data; - POINTS point; - 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->timestamp = GetMessageTime(); - coord = GetMessagePos(); - point = MAKEPOINTS(coord); - data->x = point.x; - data->y = point.y; - data->discard_ctrl = EINA_FALSE; - - switch (data->message) - { - /* Keyboard input notifications */ - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - if ((data->message == WM_KEYDOWN) && - (data->window_param == VK_CONTROL) && - ((HIWORD(data->data_param) & KF_EXTENDED) == 0)) - { - /* Ctrl left key is pressed */ - BOOL res; - MSG next_msg; - - /* - * we check if the next message - * - is a WM_KEYDOWN - * - has the same timestamp than the Ctrl one - * - is the key press of the right Alt key - */ - res = PeekMessage(&next_msg, data->window, - WM_KEYDOWN, WM_KEYDOWN, - PM_NOREMOVE); - if (res && - (next_msg.wParam == VK_MENU) && - (next_msg.time == data->timestamp) && - (HIWORD(next_msg.lParam) & KF_EXTENDED)) - { - INF("discard left Ctrl key press (sent by AltGr key press)"); - data->discard_ctrl = EINA_TRUE; - } - } - _ecore_win32_event_handle_key_press(data, 1); - return 0; - case WM_CHAR: - case WM_SYSCHAR: - INF("char message"); - _ecore_win32_event_handle_key_press(data, 0); - return 0; - case WM_KEYUP: - case WM_SYSKEYUP: - INF("keyup message"); - if ((data->window_param == VK_CONTROL) && - ((HIWORD(data->data_param) & KF_EXTENDED) == 0)) - { - /* Ctrl left key is pressed */ - BOOL res; - MSG next_msg; - - /* - * we check if the next message - * - is a WM_KEYUP or WM_SYSKEYUP - * - has the same timestamp than the Ctrl one - * - is the key release of the right Alt key - */ - res = PeekMessage(&next_msg, data->window, - WM_KEYUP, WM_SYSKEYUP, - PM_NOREMOVE); - if (res && - ((next_msg.message == WM_KEYUP) || - (next_msg.message == WM_SYSKEYUP)) && - (next_msg.wParam == VK_MENU) && - (next_msg.time == data->timestamp) && - (HIWORD(next_msg.lParam) & KF_EXTENDED)) - { - INF("discard left Ctrl key release (sent by AltGr key release)"); - data->discard_ctrl = EINA_TRUE; - } - } - _ecore_win32_event_handle_key_release(data); - return 0; - case WM_SETFOCUS: - INF("setfocus message"); - _ecore_win32_event_handle_focus_in(data); - return 0; - case WM_KILLFOCUS: - INF("kill focus message"); - _ecore_win32_event_handle_focus_out(data); - return 0; - /* Mouse input notifications */ - case WM_LBUTTONDOWN: - INF("left button down message"); - SetCapture(window); - _ecore_win32_event_handle_button_press(data, 1); - return 0; - case WM_MBUTTONDOWN: - INF("middle button down message"); - _ecore_win32_event_handle_button_press(data, 2); - return 0; - case WM_RBUTTONDOWN: - INF("right button down message"); - _ecore_win32_event_handle_button_press(data, 3); - return 0; - case WM_LBUTTONUP: - { - Ecore_Win32_Window *w = NULL; - - INF("left button up message"); - - ReleaseCapture(); - w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA); - if (w->drag.dragging) - { - w->drag.dragging = 0; - return 0; - } - - _ecore_win32_event_handle_button_release(data, 1); - return 0; - } - case WM_MBUTTONUP: - INF("middle button up message"); - _ecore_win32_event_handle_button_release(data, 2); - return 0; - case WM_RBUTTONUP: - INF("right button up message"); - _ecore_win32_event_handle_button_release(data, 3); - return 0; - case WM_MOUSEMOVE: - { - RECT rect; - Ecore_Win32_Window *w = NULL; - - INF("moue move message"); - - w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA); - - if (w->drag.dragging) - { - POINT pt; - - pt.x = GET_X_LPARAM(data_param); - pt.y = GET_Y_LPARAM(data_param); - if (ClientToScreen(window, &pt)) - { - if (w->drag.type == HTCAPTION) - { - int dx; - int dy; - - dx = pt.x - w->drag.px; - dy = pt.y - w->drag.py; - ecore_win32_window_move(w, w->drag.x + dx, w->drag.y + dy); - w->drag.x += dx; - w->drag.y += dy; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - if (w->drag.type == HTLEFT) - { - int dw; - - dw = pt.x - w->drag.px; - ecore_win32_window_move_resize(w, w->drag.x + dw, w->drag.y, w->drag.w - dw, w->drag.h); - w->drag.x += dw; - w->drag.w -= dw; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - if (w->drag.type == HTRIGHT) - { - int dw; - - dw = pt.x - w->drag.px; - ecore_win32_window_resize(w, w->drag.w + dw, w->drag.h); - w->drag.w += dw; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - if (w->drag.type == HTTOP) - { - int dh; - - dh = pt.y - w->drag.py; - ecore_win32_window_move_resize(w, w->drag.x, w->drag.y + dh, w->drag.w, w->drag.h - dh); - w->drag.y += dh; - w->drag.h -= dh; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - if (w->drag.type == HTBOTTOM) - { - int dh; - - dh = pt.y - w->drag.py; - ecore_win32_window_resize(w, w->drag.w, w->drag.h + dh); - w->drag.h += dh; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - if (w->drag.type == HTTOPLEFT) - { - int dx; - int dy; - int dh; - int dw; - - dw = pt.x - w->drag.px; - dh = pt.y - w->drag.py; - dx = dw; - dy = dh; - _ecore_win32_size_check(w, - w->drag.w - dw, w->drag.h - dh, - &dx, &dy); - - ecore_win32_window_move_resize(w, w->drag.x + dx, w->drag.y + dy, w->drag.w - dw, w->drag.h - dh); - w->drag.x += dx; - w->drag.y += dy; - w->drag.w -= dw; - w->drag.h -= dh; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - if (w->drag.type == HTTOPRIGHT) - { - int dx; - int dy; - int dh; - int dw; - - dw = pt.x - w->drag.px; - dh = pt.y - w->drag.py; - dx = dw; - dy = dh; - _ecore_win32_size_check(w, - w->drag.w, w->drag.h - dh, - &dx, &dy); - ecore_win32_window_move_resize(w, w->drag.x, w->drag.y + dy, w->drag.w, w->drag.h - dh); - w->drag.y += dy; - w->drag.w += dw; - w->drag.h -= dh; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - if (w->drag.type == HTBOTTOMLEFT) - { - int dx; - int dy; - int dh; - int dw; - - dw = pt.x - w->drag.px; - dh = pt.y - w->drag.py; - dx = dw; - dy = dh; - _ecore_win32_size_check(w, - w->drag.w - dw, w->drag.h + dh, - &dx, &dy); - ecore_win32_window_move_resize(w, w->drag.x + dx, w->drag.y, w->drag.w - dw, w->drag.h + dh); - w->drag.x += dx; - w->drag.w -= dw; - w->drag.h += dh; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - if (w->drag.type == HTBOTTOMRIGHT) - { - int dh; - int dw; - - dw = pt.x - w->drag.px; - dh = pt.y - w->drag.py; - ecore_win32_window_resize(w, w->drag.w + dw, w->drag.h + dh); - w->drag.w += dw; - w->drag.h += dh; - w->drag.px = pt.x; - w->drag.py = pt.y; - return 0; - } - } - } - - 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: - INF("mouse wheel message"); - _ecore_win32_event_handle_button_press(data, 4); - return 0; - /* Window notifications */ - case WM_CREATE: - INF("create window message"); - _ecore_win32_event_handle_create_notify(data); - return 0; - case WM_DESTROY: - INF("destroy window message"); - _ecore_win32_event_handle_destroy_notify(data); - return 0; - case WM_SHOWWINDOW: - INF("show window message"); - if ((data->data_param == SW_OTHERUNZOOM) || - (data->data_param == SW_OTHERZOOM)) - 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: - INF("close window message"); - _ecore_win32_event_handle_delete_request(data); - return 0; - case WM_GETMINMAXINFO: - INF("get min max info window message"); - return TRUE; - case WM_MOVING: - INF("moving window message"); - _ecore_win32_event_handle_configure_notify(data); - return TRUE; - case WM_MOVE: - INF("move window message"); - return 0; - case WM_SIZING: - INF("sizing window message"); - _ecore_win32_event_handle_resize(data); - _ecore_win32_event_handle_configure_notify(data); - return TRUE; - case WM_SIZE: - INF("size window message"); - 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: - INF("position changed window message"); - _ecore_win32_event_handle_configure_notify(data); - _ecore_win32_event_handle_expose(data); - return 0; - case WM_ENTERSIZEMOVE: - INF("enter size move window message"); - return 0; - case WM_EXITSIZEMOVE: - INF("exit size move window message"); - return 0; - case WM_NCLBUTTONDOWN: - INF("non client left button down window message"); - - if (((DWORD)window_param == HTCAPTION) || - ((DWORD)window_param == HTBOTTOM) || - ((DWORD)window_param == HTBOTTOMLEFT) || - ((DWORD)window_param == HTBOTTOMRIGHT) || - ((DWORD)window_param == HTLEFT) || - ((DWORD)window_param == HTRIGHT) || - ((DWORD)window_param == HTTOP) || - ((DWORD)window_param == HTTOPLEFT) || - ((DWORD)window_param == HTTOPRIGHT)) - { - Ecore_Win32_Window *w; - - w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA); - ecore_win32_window_geometry_get(w, - NULL, NULL, - &w->drag.w, &w->drag.h); - SetCapture(window); - w->drag.type = (DWORD)window_param; - w->drag.px = GET_X_LPARAM(data_param); - w->drag.py = GET_Y_LPARAM(data_param); - w->drag.dragging = 1; - return 0; - } - return DefWindowProc(window, message, window_param, data_param); - case WM_SYSCOMMAND: - INF("sys command window message %d", (int)window_param); - - if ((((DWORD)window_param & 0xfff0) == SC_MOVE) || - (((DWORD)window_param & 0xfff0) == SC_SIZE)) - { - Ecore_Win32_Window *w; - - INF("sys command MOVE or SIZE window message : %dx%d", GET_X_LPARAM(data_param), GET_Y_LPARAM(data_param)); - - w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA); - w->drag.dragging = 1; - return 0; - } - return DefWindowProc(window, message, window_param, data_param); - /* GDI notifications */ - case WM_ERASEBKGND: - return 1; - case WM_PAINT: - { - RECT rect; - - INF("paint message"); - - 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: - INF("set redraw message"); - return 0; - case WM_SYNCPAINT: - INF("sync paint message"); - return 0; - default: - return DefWindowProc(window, message, window_param, data_param); - } -} - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - - -HINSTANCE _ecore_win32_instance = NULL; -double _ecore_win32_double_click_time = 0.25; -unsigned 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; - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Ecore_Win32_Group Ecore_Win32 library - * - * Ecore_Win32 is a library that wraps Windows graphic functions - * and integrate them nicely into the Ecore main loop. - * - * @section Ecore_Win32_Sec_Init Initialisation / Shutdown - * - * To fill... - * - * @section Ecore_Win32_Sec_Icons How to set icons to an application - * - * It is possible to also sets the icon of the application easily: - * - * @li Create an icon with your favorite image creator. The Gimp is a - * good choice. Create several images of size 16, 32 and 48. You can - * also create images of size 24, 64, 128 and 256. Paste all of them - * in the image of size 16 as a layer. Save the image of size 16 with - * the name my_icon.ico. Put it where the source code of the - * application is located. - * @li Create my_icon_rc.rc file with your code editor and add in it: - * @code - * 101 ICON DISCARDABLE "my_icon.ico" - * @endcode - * @li With Visual Studio, put that file in the 'Resource file' part - * of the project. - * @li With MinGW, you have to compile it with windres: - * @code - * windres my_icon_rc.rc my_icon_rc.o - * @endcode - * and add my_icon_rc.o to the object files of the application. - * - * @note The value 101 must not be changed, it's the ID used - * internally by Ecore_Win32 to get the icons. - * - * @{ - */ - -/** - * @brief Initialize the Ecore_Win32 library. - * - * @return 1 or greater on success, 0 on error. - * - * This function sets up the Windows graphic system. It returns 0 on - * failure, otherwise it returns the number of times it has already been - * called. - * - * When Ecore_Win32 is not used anymore, call ecore_win32_shutdown() - * to shut down the Ecore_Win32 library. - */ -EAPI int -ecore_win32_init() -{ - WNDCLASSEX wc; - HICON icon; - HICON icon_sm; - - if (++_ecore_win32_init_count != 1) - return _ecore_win32_init_count; - - if (!eina_init()) - return --_ecore_win32_init_count; - - _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; - } - - icon = LoadImage(_ecore_win32_instance, - MAKEINTRESOURCE(IDI_ICON), - IMAGE_ICON, - GetSystemMetrics(SM_CXICON), - GetSystemMetrics(SM_CYICON), - LR_DEFAULTCOLOR); - icon_sm = LoadImage(_ecore_win32_instance, - MAKEINTRESOURCE(IDI_ICON), - IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - LR_DEFAULTCOLOR); - if (!icon) - icon = LoadIcon (NULL, IDI_APPLICATION); - if (!icon_sm) - icon_sm = LoadIcon (NULL, IDI_APPLICATION); - - memset (&wc, 0, sizeof (WNDCLASSEX)); - wc.cbSize = sizeof (WNDCLASSEX); - 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 = icon; - wc.hCursor = LoadCursor (NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); - wc.lpszMenuName = NULL; - wc.lpszClassName = ECORE_WIN32_WINDOW_CLASS; - wc.hIconSm = icon_sm; - - if(!RegisterClassEx(&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; -} - -/** - * @brief Shut down the Ecore_Win32 library. - * - * @return 0 when the library is completely shut down, 1 or - * greater otherwise. - * - * This function shuts down the Ecore_Win32 library. It returns 0 when it has - * been called the same number of times than ecore_win32_init(). In that case - * it shuts down all the Windows graphic system. - */ -EAPI 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; -} - -/** - * @brief Retrieve the depth of the screen. - * - * @return The depth of the screen. - * - * This function returns the depth of the screen. If an error occurs, - * it returns 0. - */ -EAPI 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; -} - -/** - * @brief Sets the timeout for a double and triple clicks to be flagged. - * - * @param t The time in seconds. - * - * This function sets the time @p t 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. - */ -EAPI void -ecore_win32_double_click_time_set(double t) -{ - if (t < 0.0) t = 0.0; - _ecore_win32_double_click_time = t; -} - -/** - * @brief Retrieve the double and triple click flag timeout. - * - * @return The timeout for double clicks in seconds. - * - * This function returns the double clicks in seconds. If - * ecore_win32_double_click_time_set() has not been called, the - * default value is returned. See ecore_win32_double_click_time_set() - * for more informations. - */ -EAPI double -ecore_win32_double_click_time_get(void) -{ - return _ecore_win32_double_click_time; -} - -/** - * @brief Return the last event time. - * - * @return The last envent time. - * - * This function returns the last event time. - */ -EAPI unsigned long -ecore_win32_current_time_get(void) -{ - return _ecore_win32_event_last_time; -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_cursor.c b/legacy/ecore/src/lib/ecore_win32/ecore_win32_cursor.c deleted file mode 100644 index 9b58c95160..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_cursor.c +++ /dev/null @@ -1,305 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN - -#include - -#include "Ecore_Win32.h" -#include "ecore_win32_private.h" - -/*============================================================================* - * Local * - *============================================================================*/ - - -/*============================================================================* - * Global * - *============================================================================*/ - - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Ecore_Win32_Group Ecore_Win32 library - * - * @{ - */ - -/** - * @brief Create a new cursor. - * - * @param pixels_and The array of bytes containing the bit values for - * the AND mask of the cursor. - * @param pixels_xor The array of bytes containing the bit values for - * the XOR mask of the cursor. - * @param width The width of the cursor. - * @param height The height of the cursor. - * @param hot_x The horizontal position of the cursor's hot spot. - * @param hot_y The vertical position of the cursor's hot spot. - * @return A newly user-defined cursor. - * - * This function creates a new cursor of size @p width and @p - * height. They must be valid size. To determine the valid size of a - * cursor, use ecore_win32_cursor_size_get(). @p pixels_and is an array - * of bytes (unsigned char) containing the bits of the cursor that - * will be visible. @p pixels_xor is similar but will allow the cursor - * to have a shape. Here is the truth table for the masks: - * - * - * - * - * - * - * - *
AND maskXOR maskDisplay
0 0 Black
0 1 White
1 0 Screen
1 1 Reverse screen
- * - * @p hot_x and @p hot_y are the position of the hot spot of the - * cursor. If @p pixels_and or @p pixels_xor are @c NULL, the function - * returns NULL. If @p width or @p height does not match the valid - * size of a cursor, the function returns @c NULL. On success, the - * function creates a user-defined cursor, otherwise it returns - * @c NULL. - * - * Once the cursor is not used anymore, use ecore_win32_cursor_free() - * to free the ressources. - * - * Example of use: - * - * @code - * unsigned char pixels_and[] ={ - * 0xFF, 0xFC, 0x3F, 0xFF, // line 1 - * 0xFF, 0xC0, 0x1F, 0xFF, // line 2 - * 0xFF, 0x00, 0x3F, 0xFF, // line 3 - * 0xFE, 0x00, 0xFF, 0xFF, // line 4 - * - * 0xF7, 0x01, 0xFF, 0xFF, // line 5 - * 0xF0, 0x03, 0xFF, 0xFF, // line 6 - * 0xF0, 0x03, 0xFF, 0xFF, // line 7 - * 0xE0, 0x07, 0xFF, 0xFF, // line 8 - * - * 0xC0, 0x07, 0xFF, 0xFF, // line 9 - * 0xC0, 0x0F, 0xFF, 0xFF, // line 10 - * 0x80, 0x0F, 0xFF, 0xFF, // line 11 - * 0x80, 0x0F, 0xFF, 0xFF, // line 12 - * - * 0x80, 0x07, 0xFF, 0xFF, // line 13 - * 0x00, 0x07, 0xFF, 0xFF, // line 14 - * 0x00, 0x03, 0xFF, 0xFF, // line 15 - * 0x00, 0x00, 0xFF, 0xFF, // line 16 - * - * 0x00, 0x00, 0x7F, 0xFF, // line 17 - * 0x00, 0x00, 0x1F, 0xFF, // line 18 - * 0x00, 0x00, 0x0F, 0xFF, // line 19 - * 0x80, 0x00, 0x0F, 0xFF, // line 20 - * - * 0x80, 0x00, 0x07, 0xFF, // line 21 - * 0x80, 0x00, 0x07, 0xFF, // line 22 - * 0xC0, 0x00, 0x07, 0xFF, // line 23 - * 0xC0, 0x00, 0x0F, 0xFF, // line 24 - * - * 0xE0, 0x00, 0x0F, 0xFF, // line 25 - * 0xF0, 0x00, 0x1F, 0xFF, // line 26 - * 0xF0, 0x00, 0x1F, 0xFF, // line 27 - * 0xF8, 0x00, 0x3F, 0xFF, // line 28 - * - * 0xFE, 0x00, 0x7F, 0xFF, // line 29 - * 0xFF, 0x00, 0xFF, 0xFF, // line 30 - * 0xFF, 0xC3, 0xFF, 0xFF, // line 31 - * 0xFF, 0xFF, 0xFF, 0xFF // line 32 - * }; - * - * unsigned char pixels_xor[] = { - * 0x00, 0x00, 0x00, 0x00, // line 1 - * 0x00, 0x03, 0xC0, 0x00, // line 2 - * 0x00, 0x3F, 0x00, 0x00, // line 3 - * 0x00, 0xFE, 0x00, 0x00, // line 4 - * - * 0x0E, 0xFC, 0x00, 0x00, // line 5 - * 0x07, 0xF8, 0x00, 0x00, // line 6 - * 0x07, 0xF8, 0x00, 0x00, // line 7 - * 0x0F, 0xF0, 0x00, 0x00, // line 8 - * - * 0x1F, 0xF0, 0x00, 0x00, // line 9 - * 0x1F, 0xE0, 0x00, 0x00, // line 10 - * 0x3F, 0xE0, 0x00, 0x00, // line 11 - * 0x3F, 0xE0, 0x00, 0x00, // line 12 - * - * 0x3F, 0xF0, 0x00, 0x00, // line 13 - * 0x7F, 0xF0, 0x00, 0x00, // line 14 - * 0x7F, 0xF8, 0x00, 0x00, // line 15 - * 0x7F, 0xFC, 0x00, 0x00, // line 16 - * - * 0x7F, 0xFF, 0x00, 0x00, // line 17 - * 0x7F, 0xFF, 0x80, 0x00, // line 18 - * 0x7F, 0xFF, 0xE0, 0x00, // line 19 - * 0x3F, 0xFF, 0xE0, 0x00, // line 20 - * - * 0x3F, 0xC7, 0xF0, 0x00, // line 21 - * 0x3F, 0x83, 0xF0, 0x00, // line 22 - * 0x1F, 0x83, 0xF0, 0x00, // line 23 - * 0x1F, 0x83, 0xE0, 0x00, // line 24 - * - * 0x0F, 0xC7, 0xE0, 0x00, // line 25 - * 0x07, 0xFF, 0xC0, 0x00, // line 26 - * 0x07, 0xFF, 0xC0, 0x00, // line 27 - * 0x01, 0xFF, 0x80, 0x00, // line 28 - * - * 0x00, 0xFF, 0x00, 0x00, // line 29 - * 0x00, 0x3C, 0x00, 0x00, // line 30 - * 0x00, 0x00, 0x00, 0x00, // line 31 - * 0x00, 0x00, 0x00, 0x00 // line 32 - * }; - * - * Ecore_Win32_Cursor *cursor = ecore_win32_cursor_new(pixels_and, pixels_xor, 32, 32, 19, 2); - * @endcode - */ -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) -{ - Ecore_Win32_Cursor *cursor = NULL; - int cursor_width; - int cursor_height; - - INF("creating cursor"); - - if (!pixels_and || !pixels_xor) - return NULL; - - 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; -} - -/** - * @brief Free the given cursor. - * - * @param cursor The cursor to free. - * - * This function free @p cursor. @p cursor must have been obtained - * with ecore_win32_cursor_new(). - */ -EAPI void -ecore_win32_cursor_free(Ecore_Win32_Cursor *cursor) -{ - INF("destroying cursor"); - - DestroyCursor(cursor); -} - -/** - * @brief Create a cursor from a Windows ressource. - * - * @param shape The pre-defined shape of the cursor. - * @return The new cursor. - * - * This function returns a pre-defined cursor with a specified - * @p shape. This cursor does not need to be freed, as it is loaded - * from an existing resource. - */ -EAPI Ecore_Win32_Cursor * -ecore_win32_cursor_shaped_new(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; -} - -/** - * @brief Retrieve the size of a valid cursor. - * - * @param width The width of a valid cursor. - * @param height The height of a valid cursor. - * - * This function returns the size of a cursor that must be passed to - * ecore_win32_cursor_new(). @p width and @p height are buffers that - * will be filled with the correct size. They can be @c NULL. - */ -EAPI void -ecore_win32_cursor_size_get(int *width, int *height) -{ - INF("geting size cursor"); - - if (*width) *width = GetSystemMetrics(SM_CXCURSOR); - if (*height) *height = GetSystemMetrics(SM_CYCURSOR); -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd.c b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd.c deleted file mode 100755 index 6c5253ae20..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd.c +++ /dev/null @@ -1,221 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "Ecore_Win32.h" -#include "ecore_win32_private.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - - -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; -} - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Ecore_Win32_Group Ecore_Win32 library - * - * @{ - */ - -/** - * @brief Initialize the Ecore_Win32 Drag and Drop module. - * - * @return 1 or greater on success, 0 on error. - * - * This function initialize the Drag and Drop module. It returns 0 on - * failure, otherwise it returns the number of times it has already - * been called. - * - * When the Drag and Drop module is not used anymore, call - * ecore_win32_dnd_shutdown() to shut down the module. - */ -EAPI 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; -} - -/** - * @brief Shut down the Ecore_Win32 Drag and Drop module. - * - * @return 0 when the module is completely shut down, 1 or - * greater otherwise. - * - * This function shuts down the Drag and Drop module. It returns 0 when it has - * been called the same number of times than ecore_win32_dnd_init(). In that case - * it shut down the module. - */ -EAPI 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; -} - -/** - * @brief Begin a DnD operation. - * - * @param data The name pf the Drag operation. - * @param size The size of the name. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function start a Drag operation with the name @p data. If - * @p data is @c NULL, @c EINA_FALSE is returned. if @p size is less than - * @c 0, it is set to the length (as strlen()) of @p data. On success the - * function returns @c EINA_TRUE, otherwise it returns @c EINA_FALSE. - */ -EAPI Eina_Bool -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 }; - Eina_Bool res = EINA_FALSE; - - if (!data) - return EINA_FALSE; - - 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 = EINA_TRUE; - } - - _ecore_win32_dnd_data_object_free(pDataObject); - _ecore_win32_dnd_drop_source_free(pDropSource); - - // cleanup - ReleaseStgMedium(&stgmed); - - return res; -} - -/** - * @brief Register a Drop operation. - * - * @param window The destination of the Drop operation. - * @param callback The callback called when the Drop operation - * finishes. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * - * This function register a Drop operation on @p window. Once the Drop - * operation finishes, @p callback is called. If @p window is @c NULL, - * the function returns @c EINA_FALSE. On success, it returns @c EINA_TRUE, - * otherwise it returns @c EINA_FALSE. - */ -EAPI Eina_Bool -ecore_win32_dnd_register_drop_target(Ecore_Win32_Window *window, - Ecore_Win32_Dnd_DropTarget_Callback callback) -{ - Ecore_Win32_Window *wnd = (Ecore_Win32_Window *)window; - - if (!window) - return EINA_FALSE; - - wnd->dnd_drop_target = _ecore_win32_dnd_register_drop_window(wnd->window, - callback, - (void *)wnd); - return wnd->dnd_drop_target ? EINA_TRUE : EINA_FALSE; -} - -/** - * @brief Unregister a Drop operation. - * - * @param window The destination of the Drop operation. - * - * This function unregister a Drop operation on @p window. If - * @p window is @c NULL, the function does nothing. - */ -EAPI void -ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window) -{ - Ecore_Win32_Window *wnd = (Ecore_Win32_Window *)window; - - if (!window) - return; - - if (wnd->dnd_drop_target) - _ecore_win32_dnd_unregister_drop_window(wnd->window, wnd->dnd_drop_target); -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp deleted file mode 100644 index 213197780b..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include - -#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 EINA_UNUSED, STGMEDIUM *pmedium EINA_UNUSED) -{ - 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 EINA_UNUSED, 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 EINA_UNUSED, STGMEDIUM *pMedium EINA_UNUSED, BOOL fRelease EINA_UNUSED) -{ - 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 EINA_UNUSED, DWORD advf EINA_UNUSED, IAdviseSink *, DWORD *) -{ - return OLE_E_ADVISENOTSUPPORTED; -} - -HRESULT DataObject::DUnadvise(DWORD dwConnection EINA_UNUSED) -{ - return OLE_E_ADVISENOTSUPPORTED; -} - -HRESULT DataObject::EnumDAdvise(IEnumSTATDATA **ppEnumAdvise EINA_UNUSED) -{ - 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(); -} diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_data_object.h b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_data_object.h deleted file mode 100644 index 3d289cf7f5..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_data_object.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __ECORE_WIN32_DND_DATA_OBJECT_H__ -#define __ECORE_WIN32_DND_DATA_OBJECT_H__ - - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include - - -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__ */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp deleted file mode 100644 index a3a8bb1865..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#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 EINA_UNUSED) -{ - 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(); -} diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h deleted file mode 100644 index 9081f46a15..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __ECORE_WIN32_DND_DROP_SOURCE_H__ -#define __ECORE_WIN32_DND_DROP_SOURCE_H__ - - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include - -#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__ */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp deleted file mode 100644 index 2f2da1af65..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ - -#ifdef HAVE_CONFIG_H -# include -#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 EINA_UNUSED, 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(); -} diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h deleted file mode 100644 index 24c3de3e1a..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __ECORE_WIN32_DND_DROP_TARGET_H__ -#define __ECORE_WIN32_DND_DROP_TARGET_H__ - - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include - -#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__ */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp deleted file mode 100644 index a3858bcdd8..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp +++ /dev/null @@ -1,157 +0,0 @@ - -#include - -#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; -} diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h b/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h deleted file mode 100644 index 9f17f5684e..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __ECORE_WIN32_DND_ENUMFORMATETC_H__ -#define __ECORE_WIN32_DND_ENUMFORMATETC_H__ - - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include - - -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__ */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_event.c b/legacy/ecore/src/lib/ecore_win32/ecore_win32_event.c deleted file mode 100644 index fc285995fc..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_event.c +++ /dev/null @@ -1,1307 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include /* for printf */ - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include - -#include -#include -#include - -#include "Ecore_Win32.h" -#include "ecore_win32_private.h" - - -typedef enum -{ - ECORE_WIN32_KEY_MASK_LSHIFT = 1 << 0, - ECORE_WIN32_KEY_MASK_RSHIFT = 1 << 1, - ECORE_WIN32_KEY_MASK_LCONTROL = 1 << 2, - ECORE_WIN32_KEY_MASK_RCONTROL = 1 << 3, - ECORE_WIN32_KEY_MASK_LMENU = 1 << 4, - ECORE_WIN32_KEY_MASK_RMENU = 1 << 5 -} Ecore_Win32_Key_Mask; - -/***** 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 Ecore_Win32_Key_Mask _ecore_win32_key_mask = 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(Ecore_Win32_Callback_Data *msg, - Eina_Bool is_down, - char **keyname, - char **keysymbol, - char **keycompose, - unsigned int *modifiers); - -static int _ecore_win32_event_char_get(int key, - char **keyname, - char **keysymbol, - char **keycompose, - unsigned int *modifiers); - - -/***** 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 *)calloc(1, sizeof(Ecore_Event_Key)); - if (!e) return; - - if (is_keystroke) - { - if (!_ecore_win32_event_keystroke_get(msg, - EINA_TRUE, - (char **)&e->keyname, - (char **)&e->key, - (char **)&e->string, - &e->modifiers)) - { - free(e); - return; - } - } - else - { - if (!_ecore_win32_event_char_get(LOWORD(msg->window_param), - (char **)&e->keyname, - (char **)&e->key, - (char **)&e->string, - &e->modifiers)) - { - free(e); - return; - } - } - - e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA); - if (!e->window) - { - free(e); - return; - } - e->event_window = e->window; - e->timestamp = msg->timestamp; - - _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) -{ - Ecore_Event_Key *e; - - INF("key released"); - - e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key)); - if (!e) return; - - if (!_ecore_win32_event_keystroke_get(msg, - EINA_FALSE, - (char **)&e->keyname, - (char **)&e->key, - (char **)&e->string, - &e->modifiers)) - { - if (msg->discard_ctrl || - !_ecore_win32_event_char_get(LOWORD(msg->window_param), - (char **)&e->keyname, - (char **)&e->key, - (char **)&e->string, - &e->modifiers)) - { - free(e); - return; - } - } - - e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA); - if (!e->window) - { - free(e); - return; - } - e->event_window = e->window; - e->timestamp = msg->timestamp; - - _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 *)GetWindowLongPtr(msg->window, GWLP_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->event_window = e->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->timestamp; - - _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->event_window = e->window; - e->x = GET_X_LPARAM(msg->data_param); - e->y = GET_Y_LPARAM(msg->data_param); - e->timestamp = msg->timestamp; - - _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->event_window = e->window; - e->buttons = button; - e->x = GET_X_LPARAM(msg->data_param); - e->y = GET_Y_LPARAM(msg->data_param); - e->timestamp = msg->timestamp; - - if (((e->timestamp - _ecore_win32_mouse_down_last_time) <= (unsigned 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) <= (unsigned 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 *)GetWindowLongPtr(msg->window, GWLP_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->event_window = e->window; - e->x = GET_X_LPARAM(msg->data_param); - e->y = GET_Y_LPARAM(msg->data_param); - e->timestamp = msg->timestamp; - - _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->event_window = e->window; - e->buttons = button; - e->x = GET_X_LPARAM(msg->data_param); - e->y = GET_Y_LPARAM(msg->data_param); - e->timestamp = msg->timestamp; - - _ecore_win32_mouse_up_count++; - - if ((_ecore_win32_mouse_up_count >= 2) && - ((e->timestamp - _ecore_win32_mouse_down_last_time) <= (unsigned 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) <= (unsigned 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)GetWindowLongPtr(msg->window, GWLP_USERDATA); - e->event_window = e->window; - e->x = GET_X_LPARAM(msg->data_param); - e->y = GET_Y_LPARAM(msg->data_param); - e->timestamp = msg->timestamp; - - 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)GetWindowLongPtr(msg->window, GWLP_USERDATA); - e->event_window = e->window; - e->x = msg->x; - e->y = msg->y; - e->timestamp = msg->timestamp; - - _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - e->x = msg->x; - e->y = msg->y; - e->timestamp = msg->timestamp ; - - _ecore_win32_event_last_time = e->timestamp; - - 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)GetWindowLongPtr(msg->window, GWLP_USERDATA); - e->event_window = e->window; - e->x = msg->x; - e->y = msg->y; - e->timestamp = msg->timestamp; - - _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - e->x = msg->x; - e->y = msg->y; - e->timestamp = msg->timestamp; - - _ecore_win32_event_last_time = e->timestamp; - - 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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - - e->timestamp = _ecore_win32_event_last_time; - _ecore_win32_event_last_time = e->timestamp; - - 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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - - e->timestamp = _ecore_win32_event_last_time; - _ecore_win32_event_last_time = e->timestamp; - - 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 *)GetWindowLongPtr(msg->window, GWLP_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->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - - e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - - e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - - e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - - e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - e->abovewin = (void *)GetWindowLongPtr(window_pos->hwndInsertAfter, GWLP_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->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - e->width = rect.right - rect.left; - e->height = rect.bottom - rect.top; - e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); - e->timestamp = _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 EINA_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 EINA_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(Ecore_Win32_Callback_Data *msg, - Eina_Bool is_down, - char **keyname, - char **keysymbol, - char **keycompose, - unsigned int *modifiers) -{ - WCHAR buf[3]; - char delete_string[2] = { 0x7f, 0 }; - char *kn = NULL; - char *ks = NULL; - char *kc = NULL; - int key; - int is_extended; - int previous_key_state; - - key = msg->window_param; - is_extended = msg->data_param & 0x01000000; - previous_key_state = msg->data_param & 0x40000000; - - *keyname = NULL; - *keysymbol = NULL; - *keycompose = NULL; - - switch (key) - { - /* Keystroke */ - case VK_PRIOR: - if (is_extended) - { - kn = "Prior"; - ks = "Prior"; - kc = NULL; - } - else - { - kn = "KP_Prior"; - ks = "KP_9"; - kc = "KP_Prior"; - } - break; - case VK_NEXT: - if (is_extended) - { - kn = "Next"; - ks = "Next"; - kc = NULL; - } - else - { - kn = "KP_Next"; - ks = "KP_3"; - kc = "KP_Next"; - } - break; - case VK_END: - if (is_extended) - { - kn = "End"; - ks = "End"; - kc = NULL; - } - else - { - kn = "KP_End"; - ks = "KP_1"; - kc = "KP_End"; - } - break; - case VK_HOME: - if (is_extended) - { - kn = "Home"; - ks = "Home"; - kc = NULL; - } - else - { - kn = "KP_Home"; - ks = "KP_7"; - kc = "KP_Home"; - } - break; - case VK_LEFT: - if (is_extended) - { - kn = "Left"; - ks = "Left"; - kc = NULL; - } - else - { - kn = "KP_Left"; - ks = "KP_4"; - kc = "KP_Left"; - } - break; - case VK_UP: - if (is_extended) - { - kn = "Up"; - ks = "Up"; - kc = NULL; - } - else - { - kn = "KP_Up"; - ks = "KP_8"; - kc = "KP_Up"; - } - break; - case VK_RIGHT: - if (is_extended) - { - kn = "Right"; - ks = "Right"; - kc = NULL; - } - else - { - kn = "KP_Right"; - ks = "KP_6"; - kc = "KP_Right"; - } - break; - case VK_DOWN: - if (is_extended) - { - kn = "Down"; - ks = "Down"; - kc = NULL; - } - else - { - kn = "KP_Down"; - ks = "KP_2"; - kc = "KP_Down"; - } - break; - case VK_INSERT: - if (is_extended) - { - kn = "Insert"; - ks = "Insert"; - kc = NULL; - } - else - { - kn = "KP_Insert"; - ks = "KP_0"; - kc = "KP_Insert"; - } - break; - case VK_DELETE: - if (is_extended) - { - kn = "Delete"; - ks = "Delete"; - kc = delete_string; - } - else - { - kn = "KP_Delete"; - ks = "KP_Decimal"; - kc = "KP_Delete"; - } - break; - case VK_SHIFT: - { - SHORT res; - - if (is_down) - { - if (previous_key_state) return 0; - res = GetKeyState(VK_LSHIFT); - if (res & 0x8000) - { - _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LSHIFT; - kn = "Shift_L"; - ks = "Shift_L"; - kc = ""; - } - res = GetKeyState(VK_RSHIFT); - if (res & 0x8000) - { - _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RSHIFT; - kn = "Shift_R"; - ks = "Shift_R"; - kc = ""; - } - *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT; - } - else /* is_up */ - { - res = GetKeyState(VK_LSHIFT); - if (!(res & 0x8000) && - (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LSHIFT)) - { - kn = "Shift_L"; - ks = "Shift_L"; - kc = ""; - _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LSHIFT; - } - res = GetKeyState(VK_RSHIFT); - if (!(res & 0x8000) && - (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RSHIFT)) - { - kn = "Shift_R"; - ks = "Shift_R"; - kc = ""; - _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RSHIFT; - } - *modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - } - break; - } - case VK_CONTROL: - { - SHORT res; - - if (msg->discard_ctrl) - return 0; - - if (is_down) - { - if (previous_key_state) return 0; - res = GetKeyState(VK_LCONTROL); - if (res & 0x8000) - { - _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LCONTROL; - kn = "Control_L"; - ks = "Control_L"; - kc = ""; - break; - } - res = GetKeyState(VK_RCONTROL); - if (res & 0x8000) - { - _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RCONTROL; - kn = "Control_R"; - ks = "Control_R"; - kc = ""; - break; - } - *modifiers |= ECORE_EVENT_MODIFIER_CTRL; - } - else /* is_up */ - { - res = GetKeyState(VK_LCONTROL); - if (!(res & 0x8000) && - (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LCONTROL)) - { - kn = "Control_L"; - ks = "Control_L"; - kc = ""; - _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LCONTROL; - break; - } - res = GetKeyState(VK_RCONTROL); - if (!(res & 0x8000) && - (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RCONTROL)) - { - kn = "Control_R"; - ks = "Control_R"; - kc = ""; - _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RCONTROL; - break; - } - *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL; - } - break; - } - case VK_MENU: - { - SHORT res; - - if (is_down) - { - if (previous_key_state) return 0; - res = GetKeyState(VK_LMENU); - if (res & 0x8000) - { - _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LMENU; - kn = "Alt_L"; - ks = "Alt_L"; - kc = ""; - } - res = GetKeyState(VK_RMENU); - if (res & 0x8000) - { - _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RMENU; - kn = "Alt_R"; - ks = "Alt_R"; - kc = ""; - } - *modifiers |= ECORE_EVENT_MODIFIER_ALT; - } - else /* is_up */ - { - res = GetKeyState(VK_LMENU); - if (!(res & 0x8000) && - (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LMENU)) - { - kn = "Alt_L"; - ks = "Alt_L"; - kc = ""; - _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LMENU; - } - res = GetKeyState(VK_RMENU); - if (!(res & 0x8000) && - (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RMENU)) - { - kn = "Alt_R"; - ks = "Alt_R"; - kc = ""; - _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RMENU; - } - *modifiers &= ~ECORE_EVENT_MODIFIER_ALT; - } - break; - } - case VK_LWIN: - { - if (is_down) - { - if (previous_key_state) return 0; - kn = "Super_L"; - ks = "Super_L"; - kc = ""; - *modifiers |= ECORE_EVENT_MODIFIER_WIN; - } - else /* is_up */ - { - kn = "Super_L"; - ks = "Super_L"; - kc = ""; - *modifiers &= ~ECORE_EVENT_MODIFIER_WIN; - } - break; - } - case VK_RWIN: - { - if (is_down) - { - if (previous_key_state) return 0; - kn = "Super_R"; - ks = "Super_R"; - kc = ""; - *modifiers |= ECORE_EVENT_MODIFIER_WIN; - } - else /* is_up */ - { - kn = "Super_R"; - ks = "Super_R"; - kc = ""; - *modifiers &= ~ECORE_EVENT_MODIFIER_WIN; - } - 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 */ - BYTE kbd_state[256]; - int res; - - if (is_down) - return 0; - - if (!GetKeyboardState(kbd_state)) - return 0; - - res = ToUnicode(msg->window_param, - MapVirtualKey(msg->window_param, 2), - kbd_state, buf, 3, 0); - if (res == 1) - { - /* FIXME: might be troublesome for non european languages */ - /* in that case, UNICODE should be used, I guess */ - buf[1] = '\0'; - kn = (char *)buf; - ks = (char *)buf; - kc = (char *)buf; - - res = GetAsyncKeyState(VK_SHIFT); - if (res & 0x8000) - *modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - else - *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT; - - res = GetKeyState(VK_CONTROL); - if (res & 0x8000) - *modifiers |= ECORE_EVENT_MODIFIER_CTRL; - else - *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL; - - res = GetKeyState(VK_MENU); - if (res & 0x8000) - *modifiers |= ECORE_EVENT_MODIFIER_ALT; - else - *modifiers &= ~ECORE_EVENT_MODIFIER_ALT; - - break; - } - return 0; - } - } - - *keyname = strdup(kn); - if (!*keyname) return 0; - *keysymbol = strdup(ks); - if (!*keysymbol) - { - free(*keyname); - *keyname = NULL; - return 0; - } - if (!kc) - *keycompose = NULL; - else - { - *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, - unsigned int *modifiers) -{ - char *kn = NULL; - char *ks = NULL; - char *kc = NULL; - char buf[2]; - SHORT res; - - *keyname = NULL; - *keysymbol = NULL; - *keycompose = NULL; - - /* check control charaters such as ^a(key:1), ^z(key:26) */ - if ((key > 0) && (key < 27) && - ((GetKeyState(VK_CONTROL) & 0x8000) || - (GetKeyState(VK_CONTROL) & 0x8000))) key += 96; - - switch (key) - { - case VK_PROCESSKEY: - break; - case VK_BACK: - kn = "BackSpace"; - ks = "BackSpace"; - kc = "\b"; - break; - case VK_TAB: - kn = "Tab"; - ks = "Tab"; - kc = "\t"; - break; - case 0x0a: - /* Line feed (Shift + Enter) */ - kn = "LineFeed"; - ks = "LineFeed"; - kc = "LineFeed"; - break; - case VK_RETURN: - kn = "Return"; - ks = "Return"; - kc = "\n"; - break; - case VK_ESCAPE: - kn = "Escape"; - ks = "Escape"; - kc = "\e"; - break; - case VK_SPACE: - kn = "space"; - ks = "space"; - kc = " "; - break; - default: - /* displayable characters */ - buf[0] = key; - buf[1] = '\0'; - kn = buf; - ks = buf; - kc = buf; - 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; - } - - res = GetAsyncKeyState(VK_SHIFT); - if (res & 0x8000) - *modifiers |= ECORE_EVENT_MODIFIER_SHIFT; - else - *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT; - - res = GetKeyState(VK_CONTROL); - if (res & 0x8000) - *modifiers |= ECORE_EVENT_MODIFIER_CTRL; - else - *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL; - - res = GetKeyState(VK_MENU); - if (res & 0x8000) - *modifiers |= ECORE_EVENT_MODIFIER_ALT; - else - *modifiers &= ~ECORE_EVENT_MODIFIER_ALT; - - return 1; -} diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_private.h b/legacy/ecore/src/lib/ecore_win32/ecore_win32_private.h deleted file mode 100644 index e3e44264cc..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_private.h +++ /dev/null @@ -1,170 +0,0 @@ -#ifndef __ECORE_WIN32_PRIVATE_H__ -#define __ECORE_WIN32_PRIVATE_H__ - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef MIN -# undef MIN -#endif -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) - -#ifdef MAX -# undef MAX -#endif -#define MAX(a,b) (((a) < (b)) ? (b) : (a)) - -/* 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__) - -#ifdef WRN -# undef WRN -#endif -#define WRN(...) EINA_LOG_DOM_WARN(_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; - unsigned long timestamp; - int x; - int y; - Eina_Bool discard_ctrl; -}; - -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; - int base_width; - 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; - - struct { - DWORD type; - int x; - int y; - int w; - int h; - int px; - int py; - unsigned int dragging : 1; - } drag; - - void *dnd_drop_target; -}; - - -extern HINSTANCE _ecore_win32_instance; -extern double _ecore_win32_double_click_time; -extern unsigned 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); -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__ */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_window.c b/legacy/ecore/src/lib/ecore_win32/ecore_win32_window.c deleted file mode 100644 index 36f8a86047..0000000000 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_window.c +++ /dev/null @@ -1,1418 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include /* for printf */ - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN - -#include - -#include "Ecore_Win32.h" -#include "ecore_win32_private.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - - -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) -{ - RECT rect; - Ecore_Win32_Window *w; - int minimal_width; - int minimal_height; - - w = (Ecore_Win32_Window *)calloc(1, sizeof(Ecore_Win32_Window)); - if (!w) - { - ERR("malloc() failed"); - return NULL; - } - - rect.left = 0; - rect.top = 0; - rect.right = width; - rect.bottom = height; - if (!AdjustWindowRectEx(&rect, style, FALSE, 0)) - { - 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 ? parent->window : NULL, - NULL, _ecore_win32_instance, NULL); - if (!w->window) - { - ERR("CreateWindowEx() failed"); - free(w); - return NULL; - } - - SetLastError(0); - if (!SetWindowLongPtr(w->window, GWLP_USERDATA, (LONG_PTR)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; -} - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Ecore_Win32_Group Ecore_Win32 library - * - * @{ - */ - -/** - * @brief Creates a new window. - * - * @param parent The parent window. - * @param x The x coordinate of the top-left corner of the window. - * @param y The y coordinate of the top-left corner of the window. - * @param width The width of the window. - * @param height The height of hte window. - * @return A newly allocated window. - * - * This function creates a new window which parent is @p parent. @p width and - * @p height are the size of the window content (the client part), - * without the border and title bar. @p x and @p y are the system - * coordinates of the top left cerner of the window (that is, of the - * title bar). This function returns a newly created window on - * success, and @c NULL on failure. - */ -EAPI 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); -} - -/** - * @brief Creates a new borderless window. - * - * @param parent The parent window. - * @param x The x coordinate of the top-left corner of the window. - * @param y The y coordinate of the top-left corner of the window. - * @param width The width of the window. - * @param height The height of hte window. - * @return A newly allocated window. - * - * This function is the same than ecore_win32_window_override_new() - * but the returned window is borderless. - */ -EAPI 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 & ~(WS_CAPTION | WS_THICKFRAME)); -} - -/** - * @brief Free the given window. - * - * @param window The window to free. - * - * This function frees @p window. If @p window is @c NULL, this - * function does nothing. - */ -EAPI void -ecore_win32_window_free(Ecore_Win32_Window *window) -{ - if (!window) return; - - INF("destroying window"); - - if (window->shape.mask) - free(window->shape.mask); - - DestroyWindow(window->window); - free(window); -} - -/** - * @brief Return the window HANDLE associated to the given window. - * - * @param window The window to retrieve the HANDLE from. - * - * This function returns the window HANDLE associated to @p window. If - * @p window is @c NULL, this function returns @c NULL. - * - * @note The returned value is of type HWND. - */ -EAPI void * -ecore_win32_window_hwnd_get(Ecore_Win32_Window *window) -{ - if (!window) return NULL; - - return 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((Ecore_Win32_Window *)window->window, w, x, y, width, height, ???); -} -*/ - -/** - * @brief Move the given window to a given position. - * - * @param window The window to move. - * @param x The x coordinate of the destination position. - * @param y The y coordinate of the destination position. - * - * This function move @p window to the new position of coordinates @p x - * and @p y. If @p window is @c NULL, or if it is fullscreen, or on - * error, this function does nothing. - */ -EAPI void -ecore_win32_window_move(Ecore_Win32_Window *window, - int x, - int y) -{ - RECT rect; - - /* FIXME: on fullscreen, should not move it */ - if (!window) return; - - INF("moving window (%dx%d)", x, y); - - if (!GetWindowRect(window->window, &rect)) - { - ERR("GetWindowRect() failed"); - return; - } - - if (!MoveWindow(window->window, x, y, - rect.right - rect.left, - rect.bottom - rect.top, - TRUE)) - { - ERR("MoveWindow() failed"); - } -} - -/** - * @brief Resize the given window to a given size. - * - * @param window The window to resize. - * @param width The new width. - * @param height The new height. - * - * This function resize @p window to the new @p width and @p height. - * If @p window is @c NULL, or if it is fullscreen, or on error, this - * function does nothing. - */ -EAPI void -ecore_win32_window_resize(Ecore_Win32_Window *window, - int width, - int height) -{ - RECT rect; - DWORD style; - int x; - int y; - int minimal_width; - int minimal_height; - - /* FIXME: on fullscreen, should not resize it */ - if (!window) return; - - INF("resizing window (%dx%d)", width, height); - - minimal_width = MAX(GetSystemMetrics(SM_CXMIN), (int)window->min_width); - minimal_height = MAX(GetSystemMetrics(SM_CYMIN), (int)window->min_height); - - if (!GetWindowRect(window->window, &rect)) - { - ERR("GetWindowRect() failed"); - return; - } - - x = rect.left; - y = rect.top; - rect.left = 0; - rect.top = 0; - if (width < minimal_width) width = minimal_width; - if (width > (int)window->max_width) width = window->max_width; - if (height < minimal_height) height = minimal_height; - if (height > (int)window->max_height) height = window->max_height; - rect.right = width; - rect.bottom = height; - if (!(style = GetWindowLong(window->window, GWL_STYLE))) - { - ERR("GetWindowLong() failed"); - return; - } - if (!AdjustWindowRect(&rect, style, FALSE)) - { - ERR("AdjustWindowRect() failed"); - return; - } - - if (!MoveWindow(window->window, x, y, - rect.right - rect.left, - rect.bottom - rect.top, - TRUE)) - { - ERR("MoveWindow() failed"); - } -} - -/** - * @brief Move and resize the given window to a given position and size. - * - * @param window The window to move and resize. - * @param x The x coordinate of the destination position. - * @param y The x coordinate of the destination position. - * @param width The new width. - * @param height The new height. - * - * This function resize @p window to the new position of coordinates @p x - * and @p y and the new @p width and @p height. If @p window is @c NULL, - * or if it is fullscreen, or on error, this function does nothing. - */ -EAPI void -ecore_win32_window_move_resize(Ecore_Win32_Window *window, - int x, - int y, - int width, - int height) -{ - RECT rect; - DWORD style; - int minimal_width; - int minimal_height; - - /* FIXME: on fullscreen, should not move/resize it */ - if (!window) return; - - INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height); - - minimal_width = MAX(GetSystemMetrics(SM_CXMIN), (int)window->min_width); - minimal_height = MAX(GetSystemMetrics(SM_CYMIN), (int)window->min_height); - - rect.left = 0; - rect.top = 0; - if (width < minimal_width) width = minimal_width; - if (width > (int)window->max_width) width = window->max_width; - if (height < minimal_height) height = minimal_height; - if (height > (int)window->max_height) height = window->max_height; - rect.right = width; - rect.bottom = height; - if (!(style = GetWindowLong(window->window, GWL_STYLE))) - { - ERR("GetWindowLong() failed"); - return; - } - if (!AdjustWindowRect(&rect, style, FALSE)) - { - ERR("AdjustWindowRect() failed"); - return; - } - - if (!MoveWindow(window->window, x, y, - rect.right - rect.left, - rect.bottom - rect.top, - TRUE)) - { - ERR("MoveWindow() failed"); - } -} - -/** - * @brief Get the geometry of the given window. - * - * @param window The window to retrieve the geometry from. - * @param x The x coordinate of the position. - * @param y The x coordinate of the position. - * @param width The width. - * @param height The height. - * - * This function retrieves the position and size of @p window. @p x, - * @p y, @p width and @p height can be buffers that will be filled with - * the corresponding values. If one of them is @c NULL, nothing will - * be done for that parameter. If @p window is @c NULL, and if the - * buffers are not @c NULL, they will be filled with respectively 0, - * 0, the size of the screen and the height of the screen. - */ -EAPI 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(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(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; -} - -/** - * @brief Get the size of the given window. - * - * @param window The window to retrieve the size from. - * @param width The width. - * @param height The height. - * - * This function retrieves the size of @p window. @p width and - * @p height can be buffers that will be filled with the corresponding - * values. If one of them is @c NULL, nothing will be done for that - * parameter. If @p window is @c NULL, and if the buffers are not - * @c NULL, they will be filled with respectively the size of the screen - * and the height of the screen. - */ -EAPI 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(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; -} - -/** - * @brief Set the minimum size of the given window. - * - * @param window The window. - * @param min_width The minimal width. - * @param min_height The minimal height. - * - * This function sets the minimum size of @p window to @p min_width - * and *p min_height. If @p window is @c NULL, this functions does - * nothing. - */ -EAPI void -ecore_win32_window_size_min_set(Ecore_Win32_Window *window, - unsigned int min_width, - unsigned int min_height) -{ - if (!window) return; - - printf ("ecore_win32_window_size_min_set : %p %d %d\n", window, min_width, min_height); - window->min_width = min_width; - window->min_height = min_height; -} - -/** - * @brief Get the minimum size of the given window. - * - * @param window The window. - * @param min_width The minimal width. - * @param min_height The minimal height. - * - * This function fills the minimum size of @p window in the buffers - * @p min_width and *p min_height. They both can be @c NULL. If - * @p window is @c NULL, this functions does nothing. - */ -EAPI void -ecore_win32_window_size_min_get(Ecore_Win32_Window *window, - unsigned int *min_width, - unsigned int *min_height) -{ - if (!window) return; - - printf ("ecore_win32_window_size_min_get : %p %d %d\n", window, window->min_width, window->min_height); - if (min_width) *min_width = window->min_width; - if (min_height) *min_height = window->min_height; -} - -/** - * @brief Set the maximum size of the given window. - * - * @param window The window. - * @param max_width The maximal width. - * @param max_height The maximal height. - * - * This function sets the maximum size of @p window to @p max_width - * and *p max_height. If @p window is @c NULL, this functions does - * nothing. - */ -EAPI void -ecore_win32_window_size_max_set(Ecore_Win32_Window *window, - unsigned int max_width, - unsigned int max_height) -{ - if (!window) return; - - printf ("ecore_win32_window_size_max_set : %p %d %d\n", window, max_width, max_height); - window->max_width = max_width; - window->max_height = max_height; -} - -/** - * @brief Get the maximum size of the given window. - * - * @param window The window. - * @param max_width The maximal width. - * @param max_height The maximal height. - * - * This function fills the maximum size of @p window in the buffers - * @p max_width and *p max_height. They both can be @c NULL. If - * @p window is @c NULL, this functions does nothing. - */ -EAPI void -ecore_win32_window_size_max_get(Ecore_Win32_Window *window, - unsigned int *max_width, - unsigned int *max_height) -{ - if (!window) return; - - printf ("ecore_win32_window_size_max_get : %p %d %d\n", window, window->max_width, window->max_height); - if (max_width) *max_width = window->max_width; - if (max_height) *max_height = window->max_height; -} - -/** - * @brief Set the base size of the given window. - * - * @param window The window. - * @param base_width The base width. - * @param base_height The base height. - * - * This function sets the base size of @p window to @p base_width - * and *p base_height. If @p window is @c NULL, this functions does - * nothing. - */ -EAPI void -ecore_win32_window_size_base_set(Ecore_Win32_Window *window, - unsigned int base_width, - unsigned int base_height) -{ - printf ("ecore_win32_window_size_base_set : %p %d %d\n", window, base_width, base_height); - if (!window) return; - - window->base_width = base_width; - window->base_height = base_height; -} - -/** - * @brief Get the base size of the given window. - * - * @param window The window. - * @param base_width The base width. - * @param base_height The bas height. - * - * This function fills the base size of @p window in the buffers - * @p base_width and *p base_height. They both can be @c NULL. If - * @p window is @c NULL, this functions does nothing. - */ -EAPI void -ecore_win32_window_size_base_get(Ecore_Win32_Window *window, - unsigned int *base_width, - unsigned int *base_height) -{ - if (!window) return; - - printf ("ecore_win32_window_size_base_get : %p %d %d\n", window, window->base_width, window->base_height); - if (base_width) *base_width = window->base_width; - if (base_height) *base_height = window->base_height; -} - -/** - * @brief Set the step size of the given window. - * - * @param window The window. - * @param step_width The step width. - * @param step_height The step height. - * - * This function sets the step size of @p window to @p step_width - * and *p step_height. If @p window is @c NULL, this functions does - * nothing. - */ -EAPI void -ecore_win32_window_size_step_set(Ecore_Win32_Window *window, - unsigned int step_width, - unsigned int step_height) -{ - printf ("ecore_win32_window_size_step_set : %p %d %d\n", window, step_width, step_height); - if (!window) return; - - window->step_width = step_width; - window->step_height = step_height; -} - -/** - * @brief Get the step size of the given window. - * - * @param window The window. - * @param step_width The step width. - * @param step_height The bas height. - * - * This function fills the step size of @p window in the buffers - * @p step_width and *p step_height. They both can be @c NULL. If - * @p window is @c NULL, this functions does nothing. - */ -EAPI void -ecore_win32_window_size_step_get(Ecore_Win32_Window *window, - unsigned int *step_width, - unsigned int *step_height) -{ - if (!window) return; - - printf ("ecore_win32_window_size_step_get : %p %d %d\n", window, window->step_width, window->step_height); - if (step_width) *step_width = window->step_width; - if (step_height) *step_height = window->step_height; -} - -/** - * @brief Show the given window. - * - * @param window The window to show. - * - * This function shows @p window. If @p window is @c NULL, or on - * error, this function does nothing. - */ -EAPI void -ecore_win32_window_show(Ecore_Win32_Window *window) -{ - if (!window) return; - - INF("showing window"); - - ShowWindow(window->window, SW_SHOWNORMAL); - if (!UpdateWindow(window->window)) - { - ERR("UpdateWindow() failed"); - } -} - -/* FIXME: seems to block the taskbar */ -/** - * @brief Hide the given window. - * - * @param window The window to show. - * - * This function hides @p window. If @p window is @c NULL, or on - * error, this function does nothing. - */ -EAPI void -ecore_win32_window_hide(Ecore_Win32_Window *window) -{ - if (!window) return; - - INF("hiding window"); - - ShowWindow(window->window, SW_HIDE); -} - -/** - * @brief Place the given window at the top of the Z order. - * - * @param window The window to place at the top. - * - * This function places @p window at the top of the Z order. If - * @p window is @c NULL, this function does nothing. - */ -EAPI void -ecore_win32_window_raise(Ecore_Win32_Window *window) -{ - if (!window) return; - - INF("raising window"); - - if (!SetWindowPos(window->window, - HWND_TOP, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE)) - { - ERR("SetWindowPos() failed"); - } -} - -/** - * @brief Place the given window at the bottom of the Z order. - * - * @param window The window to place at the bottom. - * - * This function places @p window at the bottom of the Z order. If - * @p window is @c NULL, this function does nothing. - */ -EAPI void -ecore_win32_window_lower(Ecore_Win32_Window *window) -{ - if (!window) return; - - INF("lowering window"); - - if (!SetWindowPos(window->window, - HWND_BOTTOM, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE)) - { - ERR("SetWindowPos() failed"); - } -} - -/** - * @brief Set the title of the given window. - * - * @param window The window to set the title. - * @param title The new title. - * - * This function sets the title of @p window to @p title. If @p window - * is @c NULL, or if @p title is @c NULL or empty, or on error, this - * function does nothing. - */ -EAPI 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(window->window, title)) - { - ERR("SetWindowText() failed"); - } -} - -/** - * @brief Set the focus to the given window. - * - * @param window The window to give focus to. - * - * This function gives the focus to @p window. If @p window is - * @c NULL, this function does nothing. - */ -EAPI void -ecore_win32_window_focus(Ecore_Win32_Window *window) -{ - if (!window) return; - - INF("focusing window"); - - if (!SetFocus(window->window)) - { - ERR("SetFocus() failed"); - } -} - -/** - * @brief Get the current focused window. - * - * @return The window that has focus. - * - * This function returns the window that has focus. If the calling - * thread's message queue does not have an associated window with the - * keyboard focus, the return value is @c NULL. - * - * @note Even if the returned value is @c NULL, another thread's queue - * may be associated with a window that has the keyboard focus. - * - * @note The returned value is of type HWND. - */ -EAPI void * -ecore_win32_window_focus_get(void) -{ - HWND focused; - - INF("getting focused window"); - - focused = GetFocus(); - if (!focused) - { - ERR("GetFocus() failed"); - return NULL; - } - - return focused; -} - -/** - * @brief Iconify or restore the given window. - * - * @param window The window. - * @param on @c EINA_TRUE to iconify the window, @c EINA_FALSE to restore it. - * - * This function iconify or restore @p window. If @p on is set to @c EINA_TRUE, - * the window will be iconified, if it is set to @c EINA_FALSE, it will be - * restored. If @p window is @c NULL or if the state does not change (like - * iconifying the window while it is already iconified), this function does - * nothing. - */ -EAPI void -ecore_win32_window_iconified_set(Ecore_Win32_Window *window, - Eina_Bool on) -{ - if (!window) return; - - if (((window->iconified) && (on)) || - ((!window->iconified) && (!on))) - return; - - INF("iconifying window: %s", on ? "yes" : "no"); - - ShowWindow(window->window, on ? SW_MINIMIZE : SW_RESTORE); - window->iconified = on; -} - -/** - * @brief Remove or restore the border of the given window. - * - * @param window The window. - * @param on @c EINA_TRUE to remove the border, @c EINA_FALSE to restore it. - * - * This function remove or restore the border of @p window. If @p on is set to - * @c EINA_TRUE, the window will have no border, if it is set to @c EINA_FALSE, - * it will have a border. If @p window is @c NULL or if the state does not - * change (like setting to borderless while the window has no border), this - * function does nothing. - */ -EAPI void -ecore_win32_window_borderless_set(Ecore_Win32_Window *window, - Eina_Bool on) -{ - RECT rect; - DWORD style; - - if (!window) return; - - if (((window->borderless) && (on)) || - ((!window->borderless) && (!on))) - return; - - INF("setting window without border: %s", on ? "yes" : "no"); - - style = GetWindowLong(window->window, GWL_STYLE); - if (on) - { - if (!GetClientRect(window->window, &rect)) - { - ERR("GetClientRect() failed"); - return; - } - SetLastError(0); - if (!SetWindowLongPtr(window->window, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME)) && - (GetLastError() != 0)) - { - ERR("SetWindowLongPtr() failed"); - return; - } - } - else - { - if (!GetWindowRect(window->window, &rect)) - { - ERR("GetWindowRect() failed"); - return; - } - style |= WS_CAPTION | WS_THICKFRAME; - if (!AdjustWindowRect (&rect, style, FALSE)) - { - ERR("AdjustWindowRect() failed"); - return; - } - SetLastError(0); - if (!SetWindowLongPtr(window->window, GWL_STYLE, style) && - (GetLastError() != 0)) - { - ERR("SetWindowLongPtr() failed"); - return; - } - } - if (!SetWindowPos(window->window, HWND_TOPMOST, - rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, - SWP_NOMOVE | SWP_FRAMECHANGED)) - { - ERR("SetWindowPos() failed"); - return; - } - - window->borderless = on; -} - -/** - * @brief Set the given window to fullscreen. - * - * @param window The window. - * @param on @c EINA_TRUE for fullscreen mode, @c EINA_FALSE for windowed mode. - * - * This function set @p window to fullscreen or windowed mode. If @p on is set - * to @c EINA_TRUE, the window will be fullscreen, if it is set to - * @c EINA_FALSE, it will be windowed. If @p window is @c NULL or if the state - * does not change (like setting to fullscreen while the window is already - * fullscreen), this function does nothing. - */ -EAPI void -ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window, - Eina_Bool on) -{ - if (!window) return; - - if (((window->fullscreen) && (on)) || - ((!window->fullscreen) && (!on))) - return; - - INF("setting fullscreen: %s", on ? "yes" : "no"); - - window->fullscreen = !!on; - - if (on) - { - DWORD style; - - if (!GetWindowRect(window->window, &window->rect)) - { - ERR("GetWindowRect() failed"); - return; - } - if (!(window->style = GetWindowLong(window->window, GWL_STYLE))) - { - ERR("GetWindowLong() failed"); - return; - } - style = window->style & ~WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX; - style |= WS_VISIBLE | WS_POPUP; - SetLastError(0); - if (!SetWindowLongPtr(window->window, GWL_STYLE, style) && - (GetLastError() != 0)) - { - ERR("SetWindowLongPtr() failed"); - return; - } - SetLastError(0); - if (!SetWindowLongPtr(window->window, GWL_EXSTYLE, WS_EX_TOPMOST) && - (GetLastError() != 0)) - { - ERR("SetWindowLongPtr() failed"); - return; - } - if (!SetWindowPos(window->window, HWND_TOPMOST, 0, 0, - GetSystemMetrics (SM_CXSCREEN), - GetSystemMetrics (SM_CYSCREEN), - SWP_NOCOPYBITS | SWP_SHOWWINDOW)) - { - ERR("SetWindowPos() failed"); - return; - } - } - else - { - SetLastError(0); - if (!SetWindowLongPtr(window->window, GWL_STYLE, window->style) && - (GetLastError() != 0)) - { - ERR("SetWindowLongPtr() failed"); - return; - } - SetLastError(0); - if (!SetWindowLongPtr(window->window, GWL_EXSTYLE, 0) && - (GetLastError() != 0)) - { - ERR("SetWindowLongPtr() failed"); - return; - } - if (!SetWindowPos(window->window, HWND_NOTOPMOST, - window->rect.left, - window->rect.top, - window->rect.right - window->rect.left, - window->rect.bottom - window->rect.top, - SWP_NOCOPYBITS | SWP_SHOWWINDOW)) - { - ERR("SetWindowPos() failed"); - return; - } - } -} - -/** - * @brief Set the given cursor to the given window. - * - * @param window The window to modify the cursor. - * @param cursor The new cursor. - * - * This function sets @p cursor to @p window. @p cursor must have been - * obtained by ecore_win32_cursor_new() or - * ecore_win32_cursor_shaped_new(). If @p window or @p cursor is - * @c NULL, the function does nothing. - */ -EAPI void -ecore_win32_window_cursor_set(Ecore_Win32_Window *window, - Ecore_Win32_Cursor *cursor) -{ - INF("setting cursor"); - - if (!window || !cursor) - return; - - if (!SetClassLongPtr(window->window, - GCLP_HCURSOR, (LONG_PTR)cursor)) - { - ERR("SetClassLong() failed"); - } -} - -/** - * @brief Set the state of the given window. - * - * @param window The window to modify the state. - * @param state An array of the new states. - * @param num The number of states in the array. - * - * This function set the state of @p window. @p state is an array of - * states of size @p num. If @p window or @p state are @c NULL, or if - * @p num is less or equal than 0, the function does nothing. - */ -EAPI 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 <= 0)) - return; - - INF("setting cursor state"); - - for (i = 0; i < num; i++) - { - switch (state[i]) - { - case ECORE_WIN32_WINDOW_STATE_ICONIFIED: - window->state.iconified = 1; - break; - case ECORE_WIN32_WINDOW_STATE_MODAL: - window->state.modal = 1; - break; - case ECORE_WIN32_WINDOW_STATE_STICKY: - window->state.sticky = 1; - break; - case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT: - window->state.maximized_vert = 1; - break; - case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ: - window->state.maximized_horz = 1; - break; - case ECORE_WIN32_WINDOW_STATE_MAXIMIZED: - window->state.maximized_horz = 1; - window->state.maximized_vert = 1; - break; - case ECORE_WIN32_WINDOW_STATE_SHADED: - window->state.shaded = 1; - break; - case ECORE_WIN32_WINDOW_STATE_HIDDEN: - window->state.hidden = 1; - break; - case ECORE_WIN32_WINDOW_STATE_FULLSCREEN: - window->state.fullscreen = 1; - break; - case ECORE_WIN32_WINDOW_STATE_ABOVE: - window->state.above = 1; - break; - case ECORE_WIN32_WINDOW_STATE_BELOW: - window->state.below = 1; - break; - case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION: - window->state.demands_attention = 1; - break; - case ECORE_WIN32_WINDOW_STATE_UNKNOWN: - /* nothing to be done */ - break; - } - } -} - -/** - * @brief Apply the modification of the state to the given window. - * - * @param window The window. - * @param state The state to apply changes. - * @param set The value of the state change. - * - * This function applies the modification of the state @p state of - * @p window. @p set is used only for - * #ECORE_WIN32_WINDOW_STATE_ICONIFIED and - * #ECORE_WIN32_WINDOW_STATE_FULLSCREEN. If @p window is @c NULL, the - * function does nothing. - */ -EAPI void -ecore_win32_window_state_request_send(Ecore_Win32_Window *window, - Ecore_Win32_Window_State state, - unsigned int set) -{ - if (!window) return; - - INF("sending cursor state"); - - switch (state) - { - case ECORE_WIN32_WINDOW_STATE_ICONIFIED: - if (window->state.iconified) - ecore_win32_window_iconified_set(window, set); - break; - case ECORE_WIN32_WINDOW_STATE_MODAL: - window->state.modal = 1; - break; - case ECORE_WIN32_WINDOW_STATE_STICKY: - window->state.sticky = 1; - break; - case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT: - if (window->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(window->window, &rect)) - { - ERR("GetClientRect() failed"); - break; - } - - if (!MoveWindow(window->window, rect.left, y, - rect.right - rect.left, - height, - TRUE)) - { - ERR("MoveWindow() failed"); - } - } - break; - case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ: - if (window->state.maximized_horz) - { - RECT rect; - - if (!GetClientRect(window->window, &rect)) - { - ERR("GetClientRect() failed"); - break; - } - - if (!MoveWindow(window->window, 0, rect.top, - GetSystemMetrics(SM_CXSCREEN), - rect.bottom - rect.top, - TRUE)) - { - ERR("MoveWindow() failed"); - } - } - break; - case ECORE_WIN32_WINDOW_STATE_MAXIMIZED: - if (window->state.maximized_vert && window->state.maximized_horz) - { - RECT rect; - - if (!SystemParametersInfo(SPI_GETWORKAREA, 0, - &rect, 0)) - { - ERR("SystemParametersInfo() failed"); - break; - } - - if (!MoveWindow(window->window, 0, 0, - GetSystemMetrics(SM_CXSCREEN), - rect.bottom - rect.top, - TRUE)) - { - ERR("MoveWindow() failed"); - } - } - break; - case ECORE_WIN32_WINDOW_STATE_SHADED: - window->state.shaded = 1; - break; - case ECORE_WIN32_WINDOW_STATE_HIDDEN: - window->state.hidden = 1; - break; - case ECORE_WIN32_WINDOW_STATE_FULLSCREEN: - if (window->state.fullscreen) - ecore_win32_window_fullscreen_set(window, set); - break; - case ECORE_WIN32_WINDOW_STATE_ABOVE: - if (window->state.above) - if (!SetWindowPos(window->window, HWND_TOP, - 0, 0, - 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW)) - { - ERR("SetWindowPos() failed"); - } - break; - case ECORE_WIN32_WINDOW_STATE_BELOW: - if (window->state.below) - if (!SetWindowPos(window->window, HWND_BOTTOM, - 0, 0, - 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW)) - { - ERR("SetWindowPos() failed"); - } - break; - case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION: - window->state.demands_attention = 1; - break; - case ECORE_WIN32_WINDOW_STATE_UNKNOWN: - /* nothing to be done */ - break; - } -} - -/** - * @brief Set the type of the given window. - * - * @param window The window to modify the type. - * @param type The nwindow types. - * - * This function set the type of @p window to @p type. If - * @p window is @c NULL, the function does nothing. - */ -EAPI 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: - window->type.desktop = 1; - break; - case ECORE_WIN32_WINDOW_TYPE_DOCK: - window->type.dock = 1; - break; - case ECORE_WIN32_WINDOW_TYPE_TOOLBAR: - window->type.toolbar = 1; - break; - case ECORE_WIN32_WINDOW_TYPE_MENU: - window->type.menu = 1; - break; - case ECORE_WIN32_WINDOW_TYPE_UTILITY: - window->type.utility = 1; - break; - case ECORE_WIN32_WINDOW_TYPE_SPLASH: - window->type.splash = 1; - break; - case ECORE_WIN32_WINDOW_TYPE_DIALOG: - window->type.dialog = 1; - break; - case ECORE_WIN32_WINDOW_TYPE_NORMAL: - window->type.normal = 1; - break; - case ECORE_WIN32_WINDOW_TYPE_UNKNOWN: - window->type.normal = 1; - break; - } -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_wince/Ecore_WinCE.h b/legacy/ecore/src/lib/ecore_wince/Ecore_WinCE.h deleted file mode 100644 index 20c197575a..0000000000 --- a/legacy/ecore/src/lib/ecore_wince/Ecore_WinCE.h +++ /dev/null @@ -1,314 +0,0 @@ -#ifndef __ECORE_WINCE_H__ -#define __ECORE_WINCE_H__ - -/* - * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND - * THE API MAY CHANGE. - */ - -#ifndef ECORE_WINCE_WIP_OSXCKQSD -# warning "You are using a work in progress API. This API is not stable" -# warning "and is subject to change. You use this at your own risk." -#endif - -#include - -#ifdef EAPI -# undef EAPI -#endif - -#ifdef _WIN32 -# 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 - -/** - * @defgroup Ecore_WinCE_Group Ecore_WinCE library - * - * @{ - */ - - -/** - * @typedef Ecore_WinCE_Window - * Abstract type for a window. - */ -typedef struct _Ecore_WinCE_Window Ecore_WinCE_Window; - - -/** - * @typedef Ecore_WinCE_Event_Mouse_In - * Event sent when the mouse enters the window. - */ -typedef struct _Ecore_WinCE_Event_Mouse_In Ecore_WinCE_Event_Mouse_In; - -/** - * @typedef Ecore_WinCE_Event_Mouse_Out - * Event sent when the mouse leaves the window. - */ -typedef struct _Ecore_WinCE_Event_Mouse_Out Ecore_WinCE_Event_Mouse_Out; - -/** - * @typedef Ecore_WinCE_Event_Window_Focus_In - * Event sent when the window gets the focus. - */ -typedef struct _Ecore_WinCE_Event_Window_Focus_In Ecore_WinCE_Event_Window_Focus_In; - -/** - * @typedef Ecore_WinCE_Event_Window_Focus_Out - * Event sent when the window looses the focus. - */ -typedef struct _Ecore_WinCE_Event_Window_Focus_Out Ecore_WinCE_Event_Window_Focus_Out; - -/** - * @typedef Ecore_WinCE_Event_Window_Damage - * Event sent when the window is damaged. - */ -typedef struct _Ecore_WinCE_Event_Window_Damage Ecore_WinCE_Event_Window_Damage; - -/** - * @typedef Ecore_WinCE_Event_Window_Create - * Event sent when the window is created. - */ -typedef struct _Ecore_WinCE_Event_Window_Create Ecore_WinCE_Event_Window_Create; - -/** - * @typedef Ecore_WinCE_Event_Window_Destroy - * Event sent when the window is destroyed. - */ -typedef struct _Ecore_WinCE_Event_Window_Destroy Ecore_WinCE_Event_Window_Destroy; - -/** - * @typedef Ecore_WinCE_Event_Window_Hide - * Event sent when the window is hidden. - */ -typedef struct _Ecore_WinCE_Event_Window_Hide Ecore_WinCE_Event_Window_Hide; - -/** - * @typedef Ecore_WinCE_Event_Window_Show - * Event sent when the window is shown. - */ -typedef struct _Ecore_WinCE_Event_Window_Show Ecore_WinCE_Event_Window_Show; - -/** - * @typedef Ecore_WinCE_Event_Window_Delete_Request - * Event sent when the window is deleted. - */ -typedef struct _Ecore_WinCE_Event_Window_Delete_Request Ecore_WinCE_Event_Window_Delete_Request; - - -/** - * @struct _Ecore_WinCE_Event_Mouse_In - * Event sent when the mouse enters the window. - */ -struct _Ecore_WinCE_Event_Mouse_In -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate where the mouse entered */ - int y; /**< The y coordinate where the mouse entered */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Mouse_Out - * Event sent when the mouse leaves the window. - */ -struct _Ecore_WinCE_Event_Mouse_Out -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate where the mouse leaved */ - int y; /**< The y coordinate where the mouse leaved */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Window_Focus_In - * Event sent when the window gets the focus. - */ -struct _Ecore_WinCE_Event_Window_Focus_In -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Window_Focus_Out - * Event sent when the window looses the focus. - */ -struct _Ecore_WinCE_Event_Window_Focus_Out -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Window_Damage - * Event sent when the window is damaged. - */ -struct _Ecore_WinCE_Event_Window_Damage -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - int x; /**< The x coordinate of the top left corner of the damaged region */ - int y; /**< The y coordinate of the top left corner of the damaged region */ - int width; /**< The width of the damaged region */ - int height; /**< The height of the damaged region */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Window_Create - * Event sent when the window is created. - */ -struct _Ecore_WinCE_Event_Window_Create -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Window_Destroy - * Event sent when the window is destroyed. - */ -struct _Ecore_WinCE_Event_Window_Destroy -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Window_Hide - * Event sent when the window is hidden. - */ -struct _Ecore_WinCE_Event_Window_Hide -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Window_Show - * Event sent when the window is shown. - */ -struct _Ecore_WinCE_Event_Window_Show -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ -}; - -/** - * @struct _Ecore_WinCE_Event_Window_Delete_Request - * Event sent when the window is deleted. - */ -struct _Ecore_WinCE_Event_Window_Delete_Request -{ - Ecore_WinCE_Window *window; /**< The window that received the event */ - long time; /**< The time the event occurred */ -}; - - -EAPI extern int ECORE_WINCE_EVENT_MOUSE_IN; /**< Ecore_Event for the #Ecore_WinCE_Event_Mouse_In event */ -EAPI extern int ECORE_WINCE_EVENT_MOUSE_OUT; /**< Ecore_Event for the #Ecore_WinCE_Event_Mouse_Out event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_FOCUS_IN; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Focus_In event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Focus_Out event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the Ecore_WinCE_Event_Damage event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_CREATE; /**< Ecore_Event for the Ecore_WinCE_Event_Create event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the Ecore_WinCE_Event_Destroy event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_HIDE; /**< Ecore_Event for the Ecore_WinCE_Event_Hide event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_SHOW; /**< Ecore_Event for the Ecore_WinCE_Event_Show event */ -EAPI extern int ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Delete_Request event */ - - -/* Core */ - -EAPI int ecore_wince_init(); -EAPI int ecore_wince_shutdown(); -EAPI void ecore_wince_double_click_time_set(double t); -EAPI double ecore_wince_double_click_time_get(void); -EAPI long ecore_wince_current_time_get(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_focus(Ecore_WinCE_Window *window); - -EAPI void *ecore_wince_window_focus_get(void); - -EAPI void ecore_wince_window_backend_set(Ecore_WinCE_Window *window, int backend); - -EAPI void ecore_wince_window_suspend_cb_set(Ecore_WinCE_Window *window, int (*suspend_cb)(int)); - -EAPI void ecore_wince_window_resume_cb_set(Ecore_WinCE_Window *window, int (*resume_cb)(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, - Eina_Bool on); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ECORE_WINCE_H__ */ diff --git a/legacy/ecore/src/lib/ecore_wince/ecore_wince.c b/legacy/ecore/src/lib/ecore_wince/ecore_wince.c deleted file mode 100644 index 15da44c5e3..0000000000 --- a/legacy/ecore/src/lib/ecore_wince/ecore_wince.c +++ /dev/null @@ -1,400 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include /* for printf */ - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN - -#include -#include -#include - -#include "Ecore_WinCE.h" -#include "ecore_wince_private.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - -static int _ecore_wince_init_count = 0; - -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; - Ecore_WinCE_Window *w = NULL; - - w = (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_OTHERZOOM)) - 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_ERASEBKGND: - return 1; - 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 EINA_UNUSED, - Eina_Log_Level level EINA_UNUSED, - const char *file EINA_UNUSED, - const char *fnc, - int line, - const char *fmt, - void *data EINA_UNUSED, - va_list args) -{ - fprintf(stderr, "[%s:%d] ", fnc, line); - vfprintf(stderr, fmt, args); -} - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - - -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; - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Ecore_WinCE_Group Ecore_WinCE library - * - * Ecore_WinCE is a library that wraps Windows CE graphic functions - * and integrate them nicely into the Ecore main loop. - * - * @{ - */ - -/** - * @brief Initialize the Ecore_WinCE library. - * - * @return 1 or greater on success, 0 on error. - * - * This function sets up the Windows CE graphic system. It returns 0 on - * failure, otherwise it returns the number of times it has already been - * called. - * - * When Ecore_WinCE is not used anymore, call ecore_wince_shutdown() - * to shut down the Ecore_WinCE library. - */ -EAPI 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; -} - -/** - * @brief Shut down the Ecore_WinCE library. - * - * @return 0 when the library is completely shut down, 1 or - * greater otherwise. - * - * This function shuts down the Ecore_WinCE library. It returns 0 when it has - * been called the same number of times than ecore_wince_init(). In that case - * it shuts down all the Windows CE graphic system. - */ -EAPI 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; -} - -/** - * @brief Set the timeout for a double and triple clicks to be flagged. - * - * @param t The time in seconds. - * - * This function sets the time @p t 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. - */ -EAPI void -ecore_wince_double_click_time_set(double t) -{ - if (t < 0.0) t = 0.0; - _ecore_wince_double_click_time = t; -} - -/** - * @brief Retrieve the double and triple click flag timeout. - * - * @return The timeout for double clicks in seconds. - * - * This function returns the double clicks in seconds. If - * ecore_wince_double_click_time_set() has not been called, the - * default value is returned. See ecore_wince_double_click_time_set() - * for more informations. - */ -EAPI double -ecore_wince_double_click_time_get(void) -{ - return _ecore_wince_double_click_time; -} - -/** - * @brief Return the last event time. - * - * @return The last envent time. - * - * This function returns the last event time. - */ -EAPI long -ecore_wince_current_time_get(void) -{ - return _ecore_wince_event_last_time; -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_wince/ecore_wince_event.c b/legacy/ecore/src/lib/ecore_wince/ecore_wince_event.c deleted file mode 100644 index 39430343e3..0000000000 --- a/legacy/ecore/src/lib/ecore_wince/ecore_wince_event.c +++ /dev/null @@ -1,1123 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN - -#include -#include -#include - -#include "Ecore_WinCE.h" -#include "ecore_wince_private.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - -typedef enum -{ - ECORE_WINCE_KEY_MASK_LSHIFT = 1 << 0, - ECORE_WINCE_KEY_MASK_RSHIFT = 1 << 1, - ECORE_WINCE_KEY_MASK_LCONTROL = 1 << 2, - ECORE_WINCE_KEY_MASK_RCONTROL = 1 << 3, - ECORE_WINCE_KEY_MASK_LMENU = 1 << 4, - ECORE_WINCE_KEY_MASK_RMENU = 1 << 5 -} Ecore_Wince_Key_Mask; - -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 Ecore_Wince_Key_Mask _ecore_wince_key_mask = 0; - -static void -_ecore_wince_event_free_key_down(void *data EINA_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 EINA_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, - Eina_Bool is_down, - char **keyname, - char **keysymbol, - char **keycompose) -{ - char *kn; - char *ks; - char *kc; - int previous_key_state; - - previous_key_state = msg->data_param & 0x40000000; - - *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_SHIFT: - { - SHORT res; - - if (is_down) - { - if (previous_key_state) return 0; - res = GetKeyState(VK_LSHIFT); - if (res & 0x8000) - { - _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_LSHIFT; - kn = "Shift_L"; - ks = "Shift_L"; - kc = ""; - } - res = GetKeyState(VK_RSHIFT); - if (res & 0x8000) - { - _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_RSHIFT; - kn = "Shift_R"; - ks = "Shift_R"; - kc = ""; - } - } - else /* is_up */ - { - res = GetKeyState(VK_LSHIFT); - if (!(res & 0x8000) && - (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_LSHIFT)) - { - kn = "Shift_L"; - ks = "Shift_L"; - kc = ""; - _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_LSHIFT; - } - res = GetKeyState(VK_RSHIFT); - if (!(res & 0x8000) && - (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_RSHIFT)) - { - kn = "Shift_R"; - ks = "Shift_R"; - kc = ""; - _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_RSHIFT; - } - } - break; - } - case VK_CONTROL: - { - SHORT res; - - if (is_down) - { - if (previous_key_state) return 0; - res = GetKeyState(VK_LCONTROL); - if (res & 0x8000) - { - _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_LCONTROL; - kn = "Control_L"; - ks = "Control_L"; - kc = ""; - break; - } - res = GetKeyState(VK_RCONTROL); - if (res & 0x8000) - { - _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_RCONTROL; - kn = "Control_R"; - ks = "Control_R"; - kc = ""; - break; - } - } - else /* is_up */ - { - res = GetKeyState(VK_LCONTROL); - if (!(res & 0x8000) && - (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_LCONTROL)) - { - kn = "Control_L"; - ks = "Control_L"; - kc = ""; - _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_LCONTROL; - break; - } - res = GetKeyState(VK_RCONTROL); - if (!(res & 0x8000) && - (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_RCONTROL)) - { - kn = "Control_R"; - ks = "Control_R"; - kc = ""; - _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_RCONTROL; - break; - } - } - break; - } - case VK_MENU: - { - SHORT res; - - if (is_down) - { - if (previous_key_state) return 0; - res = GetKeyState(VK_LMENU); - if (res & 0x8000) - { - _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_LMENU; - kn = "Alt_L"; - ks = "Alt_L"; - kc = ""; - } - res = GetKeyState(VK_RMENU); - if (res & 0x8000) - { - _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_RMENU; - kn = "Alt_R"; - ks = "Alt_R"; - kc = ""; - } - } - else /* is_up */ - { - res = GetKeyState(VK_LMENU); - if (!(res & 0x8000) && - (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_LMENU)) - { - kn = "Alt_L"; - ks = "Alt_L"; - kc = ""; - _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_LMENU; - } - res = GetKeyState(VK_RMENU); - if (!(res & 0x8000) && - (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_RMENU)) - { - kn = "Alt_R"; - ks = "Alt_R"; - kc = ""; - _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_RMENU; - } - } - break; - } - case VK_LWIN: - { - if (is_down) - { - if (previous_key_state) return 0; - kn = "Super_L"; - ks = "Super_L"; - kc = ""; - *modifiers |= ECORE_EVENT_MODIFIER_WIN; - } - else /* is_up */ - { - kn = "Super_L"; - ks = "Super_L"; - kc = ""; - *modifiers &= ~ECORE_EVENT_MODIFIER_WIN; - } - break; - } - case VK_RWIN: - { - if (is_down) - { - if (previous_key_state) return 0; - kn = "Super_R"; - ks = "Super_R"; - kc = ""; - *modifiers |= ECORE_EVENT_MODIFIER_WIN; - } - else /* is_up */ - { - kn = "Super_R"; - ks = "Super_R"; - kc = ""; - *modifiers &= ~ECORE_EVENT_MODIFIER_WIN; - } - 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; - - /* check control charaters such as ^a(key:1), ^z(key:26) */ - if ((key > 0) && (key < 27) && - ((GetKeyState(VK_CONTROL) & 0x8000) || - (GetKeyState(VK_CONTROL) & 0x8000))) key += 96; - - 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; - case VK_SPACE: - strncpy(kn, "space", 32); - strncpy(ks, "space", 32); - strncpy(kc, " ", 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; -} - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - -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), - EINA_TRUE, - (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); - e->event_window = e->window; - 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), - EINA_FALSE, - (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); - e->event_window = e->window; - 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->event_window = e->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->event_window = e->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->event_window = e->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->event_window = e->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->event_window = e->window; - 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->event_window = e->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->event_window = e->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; - 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_cb) - window->resume_cb(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; - 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_cb) - window->suspend_cb(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); -} - -/*============================================================================* - * API * - *============================================================================*/ - diff --git a/legacy/ecore/src/lib/ecore_wince/ecore_wince_private.h b/legacy/ecore/src/lib/ecore_wince/ecore_wince_private.h deleted file mode 100644 index b506312f99..0000000000 --- a/legacy/ecore/src/lib/ecore_wince/ecore_wince_private.h +++ /dev/null @@ -1,85 +0,0 @@ -#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_cb) (int); -typedef int (*ecore_wince_resume_cb) (int); - - -struct _Ecore_WinCE_Window -{ - HWND window; - - int backend; - ecore_wince_suspend_cb suspend_cb; - ecore_wince_resume_cb resume_cb; - - 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__ */ diff --git a/legacy/ecore/src/lib/ecore_wince/ecore_wince_window.c b/legacy/ecore/src/lib/ecore_wince/ecore_wince_window.c deleted file mode 100644 index 49a6312da3..0000000000 --- a/legacy/ecore/src/lib/ecore_wince/ecore_wince_window.c +++ /dev/null @@ -1,827 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN - -#include -#include - -#include "Ecore_WinCE.h" -#include "ecore_wince_private.h" - -/*============================================================================* - * Local * - *============================================================================*/ - -/** - * @cond LOCAL - */ - - -typedef BOOL (__stdcall *UnregisterFunc1Proc)(UINT, UINT); - -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; -} - -/** - * @endcond - */ - - -/*============================================================================* - * Global * - *============================================================================*/ - -/*============================================================================* - * API * - *============================================================================*/ - -/** - * @addtogroup Ecore_WinCE_Group Ecore_WinCE library - * - * @{ - */ - -/** - * @brief Creates a new window. - * - * @param parent The parent window. - * @param x The x coordinate of the top-left corner of the window. - * @param y The y coordinate of the top-left corner of the window. - * @param width The width of the window. - * @param height The height of hte window. - * @return A newly allocated window. - * - * This function creates a new window which parent is @p parent. @p width and - * @p height are the size of the window content (the client part), - * without the border and title bar. @p x and @p y are the system - * coordinates of the top left cerner of the window (that is, of the - * title bar). This function returns a newly created window on - * success, and @c NULL on failure. - */ -EAPI Ecore_WinCE_Window * -ecore_wince_window_new(Ecore_WinCE_Window *parent, - int x, - int y, - int width, - int height) -{ - Ecore_WinCE_Window *w; - HWND window; - RECT rect; - - INF("creating window"); - - w = (Ecore_WinCE_Window *)calloc(1, sizeof(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 ? ((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; -} - -/** - * @brief Free the given window. - * - * @param window The window to free. - * - * This function frees @p window. If @p window is @c NULL, this - * function does nothing. - */ -EAPI void -ecore_wince_window_free(Ecore_WinCE_Window *window) -{ - if (!window) return; - - INF("destroying window"); - - DestroyWindow(window->window); - free(window); -} - -/** - * @brief Return the window HANDLE associated to the given window. - * - * @param window The window to retrieve the HANDLE from. - * - * This function returns the window HANDLE associated to @p window. If - * @p window is @c NULL, this function returns @c NULL. - */ -EAPI void * -ecore_wince_window_hwnd_get(Ecore_WinCE_Window *window) -{ - if (!window) - return NULL; - - return window->window; -} - -/** - * @brief Move the given window to a given position. - * - * @param window The window to move. - * @param x The x coordinate of the destination position. - * @param y The y coordinate of the destination position. - * - * This function move @p window to the new position of coordinates @p x - * and @p y. If @p window is @c NULL, or if it is fullscreen, or on - * error, this function does nothing. - */ -EAPI void -ecore_wince_window_move(Ecore_WinCE_Window *window, - int x, - int y) -{ - RECT rect; - - if (!window || window->fullscreen) - return; - - INF("moving window (%dx%d)", x, y); - - if (!GetWindowRect(window->window, &rect)) - { - ERR("GetWindowRect() failed"); - return; - } - - if (!MoveWindow(window->window, x, y, - rect.right - rect.left, - rect.bottom - rect.top, - TRUE)) - { - ERR("MoveWindow() failed"); - } -} - -/** - * @brief Resize the given window to a given size. - * - * @param window The window to resize. - * @param width The new width. - * @param height The new height. - * - * This function resize @p window to the new @p width and @p height. - * If @p window is @c NULL, or if it is fullscreen, or on error, this - * function does nothing. - */ -EAPI void -ecore_wince_window_resize(Ecore_WinCE_Window *window, - int width, - int height) -{ - RECT rect; - DWORD style; - DWORD exstyle; - int x; - int y; - - if (!window || window->fullscreen) - return; - - INF("resizing window (%dx%d)", width, height); - - if (!GetWindowRect(window->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(window->window, GWL_STYLE))) - { - ERR("GetWindowLong() failed"); - return; - } - if (!(exstyle = GetWindowLong(window->window, GWL_EXSTYLE))) - { - ERR("GetWindowLong() failed"); - return; - } - if (!AdjustWindowRectEx(&rect, style, FALSE, exstyle)) - { - ERR("AdjustWindowRectEx() failed"); - return; - } - - if (!MoveWindow(window->window, x, y, - rect.right - rect.left, - rect.bottom - rect.top, - FALSE)) - { - ERR("MoveWindow() failed"); - } -} - -/** - * @brief Move and resize the given window to a given position and size. - * - * @param window The window to move and resize. - * @param x The x coordinate of the destination position. - * @param y The x coordinate of the destination position. - * @param width The new width. - * @param height The new height. - * - * This function resize @p window to the new position of coordinates @p x - * and @p y and the new @p width and @p height. If @p window is @c NULL, - * or if it is fullscreen, or on error, this function does nothing. - */ -EAPI void -ecore_wince_window_move_resize(Ecore_WinCE_Window *window, - int x, - int y, - int width, - int height) -{ - RECT rect; - DWORD style; - DWORD exstyle; - - if (!window || window->fullscreen) - return; - - INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height); - - rect.left = 0; - rect.top = 0; - rect.right = width; - rect.bottom = height; - if (!(style = GetWindowLong(window->window, GWL_STYLE))) - { - ERR("GetWindowLong() failed"); - return; - } - if (!(exstyle = GetWindowLong(window->window, GWL_EXSTYLE))) - { - ERR("GetWindowLong() failed"); - return; - } - if (!AdjustWindowRectEx(&rect, style, FALSE, exstyle)) - { - ERR("AdjustWindowRectEx() failed"); - return; - } - - if (!MoveWindow(window->window, x, y, - rect.right - rect.left, - rect.bottom - rect.top, - TRUE)) - { - ERR("MoveWindow() failed"); - } -} - -/** - * @brief Show the given window. - * - * @param window The window to show. - * - * This function shows @p window. If @p window is @c NULL, or on - * error, this function does nothing. - */ -EAPI void -ecore_wince_window_show(Ecore_WinCE_Window *window) -{ - if (!window) return; - - INF("showing window"); - - if (!ShowWindow(window->window, SW_SHOWNORMAL)) - { - ERR("ShowWindow() failed"); - return; - } - if (!UpdateWindow(window->window)) - { - ERR("UpdateWindow() failed"); - } - if (!SendMessage(window->window, WM_SHOWWINDOW, 1, 0)) - { - ERR("SendMessage() failed"); - } -} - -/** - * @brief Hide the given window. - * - * @param window The window to show. - * - * This function hides @p window. If @p window is @c NULL, or on - * error, this function does nothing. - */ -EAPI void -ecore_wince_window_hide(Ecore_WinCE_Window *window) -{ - if (!window) return; - - INF("hiding window"); - - if (!ShowWindow(window->window, SW_HIDE)) - { - ERR("ShowWindow() failed"); - return; - } - if (!SendMessage(window->window, WM_SHOWWINDOW, 0, 0)) - { - ERR("SendMessage() failed"); - } -} - -/** - * @brief Set the title of the given window. - * - * @param window The window to set the title. - * @param title The new title. - * - * This function sets the title of @p window to @p title. If @p window - * is @c NULL, or if @p title is @c NULL or empty, or on error, this - * function does nothing. - */ -EAPI 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(window->window, wtitle)) - { - ERR("SetWindowText() failed"); - } - free(wtitle); -} - -/** - * @brief Set the focus to the given window. - * - * @param window The window to give focus to. - * - * This function gives the focus to @p window. If @p window is - * @c NULL, this function does nothing. - */ -EAPI void -ecore_wince_window_focus(Ecore_WinCE_Window *window) -{ - if (!window) return; - - INF("focusing window"); - - if (!SetFocus(window->window)) - { - ERR("SetFocus() failed"); - } -} - -/** - * @brief Get the current focused window. - * - * @return The window that has focus. - * - * This function returns the window that has focus. If the calling - * thread's message queue does not have an associated window with the - * keyboard focus, the return value is @c NULL. - * - * @note Even if the returned value is @c NULL, another thread's queue - * may be associated with a window that has the keyboard focus. - * - * @note The returned value is of type HWND. - */ -EAPI void * -ecore_wince_window_focus_get(void) -{ - HWND focused; - - INF("getting focused window"); - - focused = GetFocus(); - if (!focused) - { - ERR("GetFocus() failed"); - return NULL; - } - - return focused; -} - -/** - * @brief Set the graphic backend used for the given window. - * - * @param window The window. - * @param backend The backend. - * - * This function sets the graphic backend to use with @p window to - * @p backend. If @p window if @c NULL, this function does nothing. - * - * The valid values for @p backend are - * - * @li 0: automatic choice of the backend. - * @li 1: the framebuffer (fast but could be not well suported). - * @li 2: GAPI (less fast but almost always supported). - * @li 3: DirectDraw (less fast than GAPI but almost always - * supported). - * @li 4: GDI (the slowest but always supported). - * - * The @p backend is used only in Evas and Ecore_Evas. So this - * function should not be called if Ecore_Evas is used. - */ -EAPI void -ecore_wince_window_backend_set(Ecore_WinCE_Window *window, - int backend) -{ - if (!window) - return; - - INF("setting backend"); - - window->backend = backend; -} - -/** - * @brief Set the suspend callback used for the given window. - * - * @param window The window. - * @param suspend_cb The suspend callback. - * - * This function sets the suspend callback to use with @p window to - * @p suspend_cb. If @p window if @c NULL, this function does nothing. - * - * The @p suspend_cb is used only in Evas and Ecore_Evas. So this - * function should not be called if Ecore_Evas is used. - */ -EAPI void -ecore_wince_window_suspend_cb_set(Ecore_WinCE_Window *window, int (*suspend_cb)(int)) -{ - if (!window) - return; - - INF("setting suspend callback"); - - window->suspend_cb = suspend_cb; -} - -/** - * @brief Set the resume callback used for the given window. - * - * @param window The window. - * @param resume_cb The resume callback. - * - * This function sets the resume callback to use with @p window to - * @p resume_cb. If @p window if @c NULL, this function does nothing. - * - * The @p resume_cb is used only in Evas and Ecore_Evas. So this - * function should not be called if Ecore_Evas is used. - */ -EAPI void -ecore_wince_window_resume_cb_set(Ecore_WinCE_Window *window, int (*resume_cb)(int)) -{ - if (!window) - return; - - INF("setting resume callback"); - - window->resume_cb = resume_cb; -} - -/** - * @brief Get the geometry of the given window. - * - * @param window The window to retrieve the geometry from. - * @param x The x coordinate of the position. - * @param y The x coordinate of the position. - * @param width The width. - * @param height The height. - * - * This function retrieves the position and size of @p window. @p x, - * @p y, @p width and @p height can be buffers that will be filled with - * the corresponding values. If one of them is @c NULL, nothing will - * be done for that parameter. If @p window is @c NULL, and if the - * buffers are not @c NULL, they will be filled with respectively 0, - * 0, the size of the screen and the height of the screen. - */ -EAPI 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(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(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; -} - -/** - * @brief Get the size of the given window. - * - * @param window The window to retrieve the size from. - * @param width The width. - * @param height The height. - * - * This function retrieves the size of @p window. @p width and - * @p height can be buffers that will be filled with the corresponding - * values. If one of them is @c NULL, nothing will be done for that - * parameter. If @p window is @c NULL, and if the buffers are not - * @c NULL, they will be filled with respectively the size of the screen - * and the height of the screen. - */ -EAPI 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(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; -} - -/** - * @brief Set the given window to fullscreen. - * - * @param window The window. - * @param on @c EINA_TRUE for fullscreen mode, @c EINA_FALSE for windowed mode. - * - * This function set @p window to fullscreen or windowed mode. If @p on is set - * to @c EINA_TRUE, the window will be fullscreen, if it is set to - * @c EINA_FALSE, it will be windowed. If @p window is @c NULL or if the state - * does not change (like setting to fullscreen while the window is already - * fullscreen), this function does nothing. - */ -EAPI void -ecore_wince_window_fullscreen_set(Ecore_WinCE_Window *window, - Eina_Bool on) -{ - HWND task_bar; - - if (!window) return; - - if (((window->fullscreen) && (on)) || - ((!window->fullscreen) && (!on))) - return; - - INF("setting fullscreen: %s", on ? "yes" : "no"); - - window->fullscreen = !!on; - - if (on) - { - /* save the position and size of the window */ - if (!GetWindowRect(window->window, &window->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(window->window, GWL_STYLE, WS_POPUP | WS_VISIBLE)) - { - INF("SetWindowLong() failed"); - } - - /* resize window to fit the entire screen */ - if (!SetWindowPos(window->window, 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(window->window, - 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(window->window, GWL_STYLE, WS_CAPTION | WS_SYSMENU | WS_VISIBLE)) - { - INF("SetWindowLong() failed"); - } - /* restaure the position and size of the window */ - if (!SetWindowPos(window->window, HWND_TOPMOST, - window->rect.left, - window->rect.top, - window->rect.right - window->rect.left, - window->rect.bottom - window->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(window->window, - window->rect.left, - window->rect.top, - window->rect.right - window->rect.left, - window->rect.bottom - window->rect.top, - TRUE)) - { - INF("MoveWindow() failed"); - } - } -} - -/** - * @} - */ diff --git a/legacy/ecore/src/lib/ecore_x/Ecore_X.h b/legacy/ecore/src/lib/ecore_x/Ecore_X.h deleted file mode 100644 index b3fc0fabab..0000000000 --- a/legacy/ecore/src/lib/ecore_x/Ecore_X.h +++ /dev/null @@ -1,2407 +0,0 @@ -#ifndef _ECORE_X_H -#define _ECORE_X_H - -#include - -#ifdef EAPI -# undef EAPI -#endif // ifdef EAPI - -#ifdef _MSC_VER -# ifdef BUILDING_DLL -# define EAPI __declspec(dllexport) -# else // ifdef BUILDING_DLL -# define EAPI __declspec(dllimport) -# endif // ifdef BUILDING_DLL -#else // ifdef _MSC_VER -# ifdef __GNUC__ -# if __GNUC__ >= 4 -# define EAPI __attribute__ ((visibility("default"))) -# else // if __GNUC__ >= 4 -# define EAPI -# endif // if __GNUC__ >= 4 -# else // ifdef __GNUC__ -# define EAPI -# endif // ifdef __GNUC__ -#endif // ifdef _MSC_VER - -#include - -/** - * @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 // ifndef _ECORE_X_WINDOW_PREDEF -typedef void *Ecore_X_Visual; -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 // ifdef HAVE_ECORE_X_XCB -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 int Ecore_X_Randr_Screen; - -typedef Ecore_X_ID Ecore_X_Device; - -#ifdef __cplusplus -extern "C" { -#endif // ifdef __cplusplus - -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 _Ecore_X_Window_State - * Defines the different states of the window of Ecore_X. - */ -typedef enum _Ecore_X_Window_State -{ - ECORE_X_WINDOW_STATE_UNKNOWN = 0, - ECORE_X_WINDOW_STATE_ICONIFIED, /** The window is iconified. */ - ECORE_X_WINDOW_STATE_MODAL, /** The window is a modal dialog box. */ - ECORE_X_WINDOW_STATE_STICKY, /** The window manager should keep the window's position fixed - * even if the virtual desktop scrolls. */ - ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, /** The window has the maximum vertical size. */ - ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, /** The window has the maximum horizontal size. */ - ECORE_X_WINDOW_STATE_SHADED, /** The window is shaded. */ - ECORE_X_WINDOW_STATE_SKIP_TASKBAR, /** The window should not be included in the taskbar. */ - ECORE_X_WINDOW_STATE_SKIP_PAGER, /** The window should not be included in the pager. */ - ECORE_X_WINDOW_STATE_HIDDEN, /** The window is invisible (i.e. minimized/iconified) */ - ECORE_X_WINDOW_STATE_FULLSCREEN, /** The window should fill the entire screen and have no - * window border/decorations */ - ECORE_X_WINDOW_STATE_ABOVE, - ECORE_X_WINDOW_STATE_BELOW, - 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_Orientation -{ - ECORE_X_RANDR_ORIENTATION_ROT_0 = (1 << 0), - ECORE_X_RANDR_ORIENTATION_ROT_90 = (1 << 1), - ECORE_X_RANDR_ORIENTATION_ROT_180 = (1 << 2), - ECORE_X_RANDR_ORIENTATION_ROT_270 = (1 << 3), - ECORE_X_RANDR_ORIENTATION_FLIP_X = (1 << 4), - ECORE_X_RANDR_ORIENTATION_FLIP_Y = (1 << 5) -} Ecore_X_Randr_Orientation; - -typedef enum _Ecore_X_Randr_Connection_Status -{ - ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED = 0, - ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED = 1, - ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN = 2 -} Ecore_X_Randr_Connection_Status; - -typedef enum _Ecore_X_Randr_Output_Policy -{ - ECORE_X_RANDR_OUTPUT_POLICY_ABOVE = 1, - ECORE_X_RANDR_OUTPUT_POLICY_RIGHT = 2, - ECORE_X_RANDR_OUTPUT_POLICY_BELOW = 3, - ECORE_X_RANDR_OUTPUT_POLICY_LEFT = 4, - ECORE_X_RANDR_OUTPUT_POLICY_CLONE = 5, - ECORE_X_RANDR_OUTPUT_POLICY_NONE = 6, - ECORE_X_RANDR_OUTPUT_POLICY_ASK = 7 -} Ecore_X_Randr_Output_Policy; - -typedef enum _Ecore_X_Randr_Relative_Alignment -{ - ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE = 0, - ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL = 1, - ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR = 2 -} Ecore_X_Randr_Relative_Alignment; - -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; - -typedef enum _Ecore_X_Randr_Edid_Display_Interface_Type -{ - ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_UNDEFINED, - ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DVI, - ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_HDMI_A, - ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_HDMI_B, - ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_MDDI, - ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT -} Ecore_X_Randr_Edid_Display_Interface_Type; - -typedef enum _Ecore_X_Randr_Edid_Display_Colorscheme -{ - ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_MONOCHROME_GRAYSCALE = 0x00, - ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB = 0x08, - ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_NON_RGB = 0x10, - ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_UNDEFINED = 0x18, - ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4 = 0x444000, - ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4 = 0x444, - ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2 = 0x422 -} Ecore_X_Randr_Edid_Display_Colorscheme; - -typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio -{ - ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3 = 0x0, - ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9 = 0x1, - ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10 = 0x2, - ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4 = 0x4, - ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9 = 0x8 -} Ecore_X_Randr_Edid_Aspect_Ratio; - -#define ECORE_X_RANDR_EDID_UNKNOWN_VALUE -1 - -#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 - -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_INPUT -} Ecore_X_Shape_Type; - -typedef enum _Ecore_X_Mapping_Type -{ - ECORE_X_MAPPING_MODIFIER, - ECORE_X_MAPPING_KEYBOARD, - ECORE_X_MAPPING_MOUSE -} Ecore_X_Mapping_Type; - -typedef enum _Ecore_X_Randr_Property_Change -{ - ECORE_X_RANDR_PROPERTY_CHANGE_ADD, - ECORE_X_RANDR_PROPERTY_CHANGE_DEL -} Ecore_X_Randr_Property_Change; - -typedef enum _Ecore_X_Netwm_Direction -{ - ECORE_X_NETWM_DIRECTION_SIZE_TL = 0, - ECORE_X_NETWM_DIRECTION_SIZE_T = 1, - ECORE_X_NETWM_DIRECTION_SIZE_TR = 2, - ECORE_X_NETWM_DIRECTION_SIZE_R = 3, - ECORE_X_NETWM_DIRECTION_SIZE_BR = 4, - ECORE_X_NETWM_DIRECTION_SIZE_B = 5, - ECORE_X_NETWM_DIRECTION_SIZE_BL = 6, - ECORE_X_NETWM_DIRECTION_SIZE_L = 7, - ECORE_X_NETWM_DIRECTION_MOVE = 8, - ECORE_X_NETWM_DIRECTION_CANCEL = 11, -} Ecore_X_Netwm_Direction; - -/** - * @typedef _Ecore_X_Error_Code - * Defines the error codes of Ecore_X which wraps the X Window Systems - * protocol's errors. - * - * @since 1.7.0 - */ -typedef enum _Ecore_X_Error_Code -{ - /** Everything is okay. */ - ECORE_X_ERROR_CODE_SUCCESS = 0, /** Bad request code */ - ECORE_X_ERROR_CODE_BAD_REQUEST = 1, /** Int parameter out of range */ - ECORE_X_ERROR_CODE_BAD_VALUE = 2, /** Parameter not a Window */ - ECORE_X_ERROR_CODE_BAD_WINDOW = 3, /** Parameter not a Pixmap */ - ECORE_X_ERROR_CODE_BAD_PIXMAP = 4, /** Parameter not an Atom */ - ECORE_X_ERROR_CODE_BAD_ATOM = 5, /** Parameter not a Cursor */ - ECORE_X_ERROR_CODE_BAD_CURSOR = 6, /** Parameter not a Font */ - ECORE_X_ERROR_CODE_BAD_FONT = 7, /** Parameter mismatch */ - ECORE_X_ERROR_CODE_BAD_MATCH = 8, /** Parameter not a Pixmap or Window */ - ECORE_X_ERROR_CODE_BAD_DRAWABLE = 9, /** Bad access */ - ECORE_X_ERROR_CODE_BAD_ACCESS = 10, /** Insufficient resources */ - ECORE_X_ERROR_CODE_BAD_ALLOC = 11, /** No such colormap */ - ECORE_X_ERROR_CODE_BAD_COLOR = 12, /** Parameter not a GC */ - ECORE_X_ERROR_CODE_BAD_GC = 13, /** Choice not in range or already used */ - ECORE_X_ERROR_CODE_BAD_ID_CHOICE = 14, /** Font or color name doesn't exist */ - ECORE_X_ERROR_CODE_BAD_NAME = 15, /** Request length incorrect */ - ECORE_X_ERROR_CODE_BAD_LENGTH = 16, /** Server is defective */ - ECORE_X_ERROR_CODE_BAD_IMPLEMENTATION = 17, -} Ecore_X_Error_Code; - -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_Mapping_Change Ecore_X_Event_Mapping_Change; -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_Event_Fixes_Selection_Notify Ecore_X_Event_Fixes_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_Gesture_Notify_Flick Ecore_X_Event_Gesture_Notify_Flick; -typedef struct _Ecore_X_Event_Gesture_Notify_Pan Ecore_X_Event_Gesture_Notify_Pan; -typedef struct _Ecore_X_Event_Gesture_Notify_PinchRotation Ecore_X_Event_Gesture_Notify_PinchRotation; -typedef struct _Ecore_X_Event_Gesture_Notify_Tap Ecore_X_Event_Gesture_Notify_Tap; -typedef struct _Ecore_X_Event_Gesture_Notify_TapNHold Ecore_X_Event_Gesture_Notify_TapNHold; -typedef struct _Ecore_X_Event_Gesture_Notify_Hold Ecore_X_Event_Gesture_Notify_Hold; -typedef struct _Ecore_X_Event_Gesture_Notify_Group Ecore_X_Event_Gesture_Notify_Group; -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_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; - -typedef struct _Ecore_X_Randr_Screen_Size Ecore_X_Randr_Screen_Size; -typedef struct _Ecore_X_Randr_Screen_Size_MM Ecore_X_Randr_Screen_Size_MM; - -typedef struct _Ecore_X_Xdnd_Position Ecore_X_Xdnd_Position; - -struct _Ecore_X_Event_Mouse_In -{ - int modifiers; - int x, y; - Eina_Bool same_screen : 1; - 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; - Eina_Bool override : 1; - Eina_Bool 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; - Eina_Bool installed : 1; - Ecore_X_Time time; -}; - -struct _Ecore_X_Event_Mapping_Change -{ - Ecore_X_Mapping_Type type; - int keycode; - int num; -}; - -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; -}; - -typedef enum -{ - ECORE_X_OWNER_CHANGE_REASON_NEW_OWNER, - ECORE_X_OWNER_CHANGE_REASON_DESTROY, - ECORE_X_OWNER_CHANGE_REASON_CLOSE -} Ecore_X_Owner_Change_Reason; - -struct _Ecore_X_Event_Fixes_Selection_Notify -{ - Ecore_X_Window win; - Ecore_X_Window owner; - Ecore_X_Time time; - Ecore_X_Time selection_time; - Ecore_X_Selection selection; - Ecore_X_Atom atom; - Ecore_X_Owner_Change_Reason reason; -}; - -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_Xdnd_Position -{ - Ecore_X_Window win, prev; - struct - { - int x, y; - } position; -}; - -struct _Ecore_X_Event_Xdnd_Status -{ - Ecore_X_Window win, target; - Eina_Bool will_accept : 1; - 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; - Eina_Bool completed : 1; - 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; - Ecore_X_Shape_Type type; - int x, y, w, h; - Eina_Bool shaped : 1; -}; - -struct _Ecore_X_Event_Screensaver_Notify -{ - Ecore_X_Window win; - Eina_Bool on : 1; - 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_Randr_Screen_Size -{ - int width, height; -}; - -struct _Ecore_X_Randr_Screen_Size_MM -{ - int width, height, width_mm, height_mm; -}; - -struct _Ecore_X_Event_Screen_Change -{ - Ecore_X_Window win; - Ecore_X_Window root; - Ecore_X_Randr_Screen_Size_MM size; /* in pixel and millimeters */ - Ecore_X_Time time; - Ecore_X_Time config_time; - Ecore_X_Randr_Orientation orientation; - 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_Orientation orientation; - Eina_Rectangle geo; -}; - -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_Orientation orientation; - Ecore_X_Randr_Connection_Status 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; - Ecore_X_Randr_Property_Change state; -}; - -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_MAPPING_CHANGE; -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_FIXES_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_GESTURE_NOTIFY_FLICK; -EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_PAN; -EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION; -EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_TAP; -EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD; -EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD; -EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP; -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_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_XKB_STATE_NOTIFY; /** @since 1.7 */ -EAPI extern int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY; /** @since 1.7 */ - -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_MODIFIER_SHIFT; /**< @since 1.7 */ -EAPI extern int ECORE_X_MODIFIER_CTRL; /**< @since 1.7 */ -EAPI extern int ECORE_X_MODIFIER_ALT; /**< @since 1.7 */ -EAPI extern int ECORE_X_MODIFIER_WIN; /**< @since 1.7 */ -EAPI extern int ECORE_X_MODIFIER_ALTGR; /**< @since 1.7 */ - -EAPI extern int ECORE_X_LOCK_SCROLL; -EAPI extern int ECORE_X_LOCK_NUM; -EAPI extern int ECORE_X_LOCK_CAPS; -EAPI extern int ECORE_X_LOCK_SHIFT; - -EAPI extern int ECORE_X_RAW_BUTTON_PRESS; /**< @since 1.8 */ -EAPI extern int ECORE_X_RAW_BUTTON_RELEASE; /**< @since 1.8 */ -EAPI extern int ECORE_X_RAW_MOTION; /**< @since 1.8 */ - -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 _Ecore_X_Window_State_Hint - * Defines the different state hint of the window of Ecore_X. - */ -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; - -typedef enum _Ecore_X_Illume_Indicator_State -{ - ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN = 0, - ECORE_X_ILLUME_INDICATOR_STATE_OFF, - ECORE_X_ILLUME_INDICATOR_STATE_ON -} Ecore_X_Illume_Indicator_State; - -typedef enum _Ecore_X_Illume_Clipboard_State -{ - ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN = 0, - ECORE_X_ILLUME_CLIPBOARD_STATE_OFF, - ECORE_X_ILLUME_CLIPBOARD_STATE_ON -} Ecore_X_Illume_Clipboard_State; - -typedef enum _Ecore_X_Illume_Indicator_Opacity_Mode -{ - ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN = 0, - ECORE_X_ILLUME_INDICATOR_OPAQUE, - ECORE_X_ILLUME_INDICATOR_TRANSLUCENT, - ECORE_X_ILLUME_INDICATOR_TRANSPARENT -} Ecore_X_Illume_Indicator_Opacity_Mode; - -typedef enum _Ecore_X_Illume_Window_State -{ - ECORE_X_ILLUME_WINDOW_STATE_NORMAL = 0, - ECORE_X_ILLUME_WINDOW_STATE_FLOATING -} Ecore_X_Illume_Window_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_screen_size_get(const Ecore_X_Screen *screen, int *w, int *h); -EAPI int ecore_x_screen_count_get(void); -EAPI int ecore_x_screen_index_get(const Ecore_X_Screen *screen); -EAPI Ecore_X_Screen *ecore_x_screen_get(int index); - -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 Eina_Bool ecore_x_bell(int percent); -EAPI unsigned int ecore_x_visual_id_get(Ecore_X_Visual visual); - -EAPI Ecore_X_Visual ecore_x_default_visual_get(Ecore_X_Display *disp, Ecore_X_Screen *screen); -EAPI Ecore_X_Colormap ecore_x_default_colormap_get(Ecore_X_Display *disp, Ecore_X_Screen *screen); -EAPI int ecore_x_default_depth_get(Ecore_X_Display *disp, Ecore_X_Screen *screen); - -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 Ecore_X_ID ecore_x_error_resource_id_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 Eina_Bool 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 Eina_Bool ecore_x_selection_primary_set(Ecore_X_Window w, const void *data, int size); -EAPI Eina_Bool ecore_x_selection_primary_clear(void); -EAPI Eina_Bool ecore_x_selection_secondary_set(Ecore_X_Window w, const void *data, int size); -EAPI Eina_Bool ecore_x_selection_secondary_clear(void); -EAPI Eina_Bool ecore_x_selection_xdnd_set(Ecore_X_Window w, const void *data, int size); -EAPI Eina_Bool ecore_x_selection_xdnd_clear(void); -EAPI Eina_Bool ecore_x_selection_clipboard_set(Ecore_X_Window w, const void *data, int size); -EAPI Eina_Bool 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 Eina_Bool ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret, int *len, Ecore_X_Atom *targprop, int *targsize); -EAPI void ecore_x_selection_converter_add(char *target, Eina_Bool (*func)(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *, int *)); -EAPI void ecore_x_selection_converter_atom_add(Ecore_X_Atom target, Eina_Bool (*func)(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *tprop, int *tsize)); -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_selection_owner_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Time tm); -EAPI Ecore_X_Window ecore_x_selection_owner_get(Ecore_X_Atom atom); -EAPI Eina_Bool ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *targprop, int *s); /** @since 1.8 */ - -EAPI void ecore_x_dnd_aware_set(Ecore_X_Window win, Eina_Bool on); -EAPI int ecore_x_dnd_version_get(Ecore_X_Window win); -EAPI Eina_Bool 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, Eina_Bool 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 Eina_Bool ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size); -EAPI Eina_Bool ecore_x_dnd_drop(void); -EAPI void ecore_x_dnd_send_status(Eina_Bool will_accept, Eina_Bool 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 void ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *data), const void *data); - -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 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, Eina_Bool 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 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, Eina_Bool override); - -EAPI void ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int *val, unsigned int num); -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 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 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 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 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 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 char *ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type); -EAPI Eina_Bool 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_input_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h); -EAPI void ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num); -EAPI void ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h); -EAPI void ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win, int x, int y, int w, int h); -EAPI void ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win, int x, int y, int w, int h); -EAPI void ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y); -EAPI void ecore_x_window_shape_input_window_set(Ecore_X_Window win, Ecore_X_Window shape_win); -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_input_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_input_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_input_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num); -EAPI Ecore_X_Rectangle *ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret); -EAPI Ecore_X_Rectangle *ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win, int *num_ret); -EAPI void ecore_x_window_shape_events_select(Ecore_X_Window win, Eina_Bool 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 void ecore_x_gc_foreground_set(Ecore_X_GC gc, unsigned long foreground); -EAPI void ecore_x_gc_background_set(Ecore_X_GC gc, unsigned long background); - -EAPI Eina_Bool 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 Eina_Bool ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, const void *data, int len); -EAPI Eina_Bool ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y); -EAPI Eina_Bool ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b); -EAPI Eina_Bool ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b); -EAPI Eina_Bool ecore_x_mouse_in_send(Ecore_X_Window win, int x, int y); -EAPI Eina_Bool ecore_x_mouse_out_send(Ecore_X_Window win, int x, int y); - -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 Eina_Bool 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 Eina_Bool 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 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 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, Eina_Bool 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, Eina_Bool is_urgent); -EAPI Eina_Bool ecore_x_icccm_hints_get(Ecore_X_Window win, Eina_Bool *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, Eina_Bool *is_urgent); -EAPI void ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, Eina_Bool 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 Eina_Bool ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, Eina_Bool *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, Eina_Bool on); -EAPI Eina_Bool 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 Eina_Bool 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, Eina_Bool 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 Eina_Bool 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 unsigned int *ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, 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, Eina_Bool 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 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 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 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 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 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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_set(Ecore_X_Window win, Ecore_X_Icon *icon, int num); - -EAPI Eina_Bool 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 Eina_Bool 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 Eina_Bool ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid); -EAPI void ecore_x_netwm_handled_icons_set(Ecore_X_Window win); -EAPI Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb); -EAPI Eina_Bool 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, Eina_Bool set); -EAPI void ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop); -EAPI void ecore_x_netwm_moveresize_request_send(Ecore_X_Window win, int x, int y, Ecore_X_Netwm_Direction direction, unsigned int button); - -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 Eina_Bool 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 Eina_Bool 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_access_action_next_send(Ecore_X_Window win); -EAPI void ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win); -EAPI void ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win); -EAPI void ecore_x_e_illume_access_action_read_send(Ecore_X_Window win); -EAPI void ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win); -EAPI void ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win); -EAPI void ecore_x_e_illume_access_action_up_send(Ecore_X_Window win); -EAPI void ecore_x_e_illume_access_action_down_send(Ecore_X_Window win); - -EAPI void ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag); -EAPI Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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_illume_clipboard_state_set(Ecore_X_Window win, Ecore_X_Illume_Clipboard_State state); - -EAPI Ecore_X_Illume_Clipboard_State ecore_x_e_illume_clipboard_state_get(Ecore_X_Window win); - -EAPI void ecore_x_e_illume_clipboard_geometry_set(Ecore_X_Window win, int x, int y, int w, int h); -EAPI Eina_Bool ecore_x_e_illume_clipboard_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h); -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_draw_size_done_send(Ecore_X_Window root, Ecore_X_Window win, int w, int h); -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 void ecore_x_e_comp_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pixmap); -EAPI Ecore_X_Pixmap ecore_x_e_comp_pixmap_get(Ecore_X_Window win); - -EAPI char *ecore_x_e_window_profile_get(Ecore_X_Window win); -EAPI void ecore_x_e_window_profile_set(Ecore_X_Window win, const char *profile); -EAPI void ecore_x_e_window_profile_list_set(Ecore_X_Window win, const char **profiles, unsigned int num_profiles); -EAPI Eina_Bool ecore_x_e_window_profile_list_get(Ecore_X_Window win, const char ***profiles, int *ret_num); - -EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter); -EAPI Eina_Bool ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm); -EAPI Eina_Bool 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_sync_counter_set(Ecore_X_Sync_Counter counter, int val); -EAPI void ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter, int val_hi, unsigned int val_lo); -EAPI Eina_Bool ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter, int *val_hi, unsigned int *val_lo); - -EAPI int ecore_x_xinerama_screen_count_get(void); -EAPI Eina_Bool ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h); - -EAPI Eina_Bool ecore_x_screensaver_event_available_get(void); -EAPI int ecore_x_screensaver_idle_time_get(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(Eina_Bool on); -EAPI Eina_Bool ecore_x_screensaver_custom_blanking_enable(void); /** @since 1.7 */ -EAPI Eina_Bool ecore_x_screensaver_custom_blanking_disable(void); /** @since 1.7 */ - -/* FIXME: these funcs need categorising */ - -typedef struct _Ecore_X_Window_Attributes -{ - Ecore_X_Window root; - int x, y, w, h; - int border; - int depth; - Eina_Bool visible : 1; - Eina_Bool viewable : 1; - Eina_Bool override : 1; - Eina_Bool input_only : 1; - Eina_Bool 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 Eina_Bool 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 Eina_Bool ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold); -EAPI Eina_Bool ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold); -EAPI Eina_Bool ecore_x_pointer_mapping_set(unsigned char *map, int nmap); -EAPI Eina_Bool ecore_x_pointer_mapping_get(unsigned char *map, int nmap); -EAPI Eina_Bool ecore_x_pointer_grab(Ecore_X_Window win); -EAPI Eina_Bool ecore_x_pointer_confine_grab(Ecore_X_Window win); -EAPI void ecore_x_pointer_ungrab(void); -EAPI Eina_Bool ecore_x_pointer_warp(Ecore_X_Window win, int x, int y); -EAPI Eina_Bool 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(Eina_Bool (*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(Ecore_X_Window win, int *x, int *y); - -/* ecore_x_region.c */ -EAPI Ecore_X_XRegion *ecore_x_xregion_new(void); -EAPI void ecore_x_xregion_free(Ecore_X_XRegion *region); -EAPI Eina_Bool 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 Eina_Bool ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); -EAPI Eina_Bool ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); -EAPI Eina_Bool ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect); -EAPI Eina_Bool ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); -EAPI Eina_Bool ecore_x_xregion_is_empty(Ecore_X_XRegion *region); -EAPI Eina_Bool ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); -EAPI Eina_Bool ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y); -EAPI Eina_Bool ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect); - -/* ecore_x_randr.c */ - -/* The usage of 'Ecore_X_Randr_None' or 'Ecore_X_Randr_Unset' - * depends on the context. In most cases 'Ecore_X_Randr_Unset' - * can be used, but in some cases -1 is a special value to - * functions, thus 'Ecore_X_Randr_None' (=0) must be used. - */ - -typedef short Ecore_X_Randr_Refresh_Rate; -typedef int Ecore_X_Randr_Crtc_Gamma; -typedef int Ecore_X_Randr_Signal_Format; -typedef int Ecore_X_Randr_Signal_Property; -typedef int Ecore_X_Randr_Connector_Type; - -typedef struct _Ecore_X_Randr_Mode_Info -{ - Ecore_X_ID xid; - unsigned int width; - unsigned int height; - unsigned long dotClock; - unsigned int hSyncStart; - unsigned int hSyncEnd; - unsigned int hTotal; - unsigned int hSkew; - unsigned int vSyncStart; - unsigned int vSyncEnd; - unsigned int vTotal; - char *name; - unsigned int nameLength; - unsigned long modeFlags; -} Ecore_X_Randr_Mode_Info; - -EAPI int ecore_x_randr_version_get(void); -EAPI Eina_Bool ecore_x_randr_query(void); - -/* ecore_x_randr_11.c */ -EAPI Ecore_X_Randr_Orientation ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root); -EAPI Ecore_X_Randr_Orientation ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root); -EAPI Eina_Bool ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Orientation orientation); -EAPI Ecore_X_Randr_Screen_Size_MM *ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, int *num); - -/** - * @brief get the current set size of a given screen's primary output - * @param root window which's primary output will be queried - * @param w the current size's width - * @param h the current size's height - * @param w_mm the current size's width in mm - * @param h_mm the current size's height in mm - * @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set() - */ -EAPI void ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm, int *size_index); -EAPI Eina_Bool ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, int size_index); -EAPI Ecore_X_Randr_Refresh_Rate ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root); -EAPI Ecore_X_Randr_Refresh_Rate *ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, int size_index, int *num); -EAPI Eina_Bool ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root, int size_index, Ecore_X_Randr_Refresh_Rate rate); - -/* ecore_x_randr_12.c */ -EAPI void ecore_x_randr_events_select(Ecore_X_Window win, Eina_Bool on); - -EAPI void ecore_x_randr_screen_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm); -EAPI void ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *wmin, int *hmin, int *wmax, int *hmax); -EAPI void ecore_x_randr_screen_reset(Ecore_X_Window root); -EAPI Eina_Bool ecore_x_randr_screen_current_size_set(Ecore_X_Window root, int w, int h, int w_mm, int h_mm); -EAPI Ecore_X_Randr_Mode_Info **ecore_x_randr_modes_info_get(Ecore_X_Window root, int *num); -EAPI Ecore_X_Randr_Mode ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info); -EAPI void ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode); -EAPI Ecore_X_Randr_Mode_Info *ecore_x_randr_mode_info_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode); -EAPI void ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info); -EAPI Ecore_X_Randr_Crtc *ecore_x_randr_crtcs_get(Ecore_X_Window root, int *num); -EAPI Ecore_X_Randr_Output *ecore_x_randr_outputs_get(Ecore_X_Window root, int *num); -EAPI Ecore_X_Randr_Output *ecore_x_randr_window_outputs_get(Ecore_X_Window window, int *num); -EAPI Ecore_X_Randr_Output *ecore_x_randr_current_output_get(Ecore_X_Window window, int *num); -EAPI Ecore_X_Randr_Crtc *ecore_x_randr_window_crtcs_get(Ecore_X_Window window, int *num); -EAPI Ecore_X_Randr_Crtc *ecore_x_randr_current_crtc_get(Ecore_X_Window window, int *num); -EAPI Ecore_X_Randr_Output *ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num); -EAPI Ecore_X_Randr_Output *ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num); -EAPI void ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h); -EAPI void ecore_x_randr_crtc_pos_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y); -EAPI Eina_Bool ecore_x_randr_crtc_pos_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, int y); -EAPI Ecore_X_Randr_Mode ecore_x_randr_crtc_mode_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); -EAPI Eina_Bool ecore_x_randr_crtc_mode_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int noutputs, Ecore_X_Randr_Mode mode); -EAPI void ecore_x_randr_crtc_size_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *w, int *h); -EAPI Ecore_X_Randr_Refresh_Rate ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Mode mode); -EAPI Ecore_X_Randr_Orientation ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); -EAPI Ecore_X_Randr_Orientation ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); -EAPI Eina_Bool ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Orientation orientation); -EAPI Eina_Bool ecore_x_randr_crtc_clone_set(Ecore_X_Window root, Ecore_X_Randr_Crtc original, Ecore_X_Randr_Crtc clone); -EAPI Eina_Bool ecore_x_randr_crtc_settings_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int noutputs, int x, int y, Ecore_X_Randr_Mode mode, Ecore_X_Randr_Orientation orientation); -EAPI Eina_Bool ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc_r1, Ecore_X_Randr_Crtc crtc_r2, Ecore_X_Randr_Output_Policy policy, Ecore_X_Randr_Relative_Alignment alignment); -EAPI Eina_Bool ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode); -EAPI void ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode); -EAPI Ecore_X_Randr_Mode *ecore_x_randr_output_modes_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num, int *npreferred); -EAPI Ecore_X_Randr_Output *ecore_x_randr_output_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); -EAPI Ecore_X_Randr_Crtc *ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); -EAPI Ecore_X_Randr_Crtc ecore_x_randr_output_crtc_get(Ecore_X_Window root, Ecore_X_Randr_Output output); -EAPI char *ecore_x_randr_output_name_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *len); -EAPI int ecore_x_randr_crtc_gamma_ramp_size_get(Ecore_X_Randr_Crtc crtc); -EAPI Ecore_X_Randr_Crtc_Gamma **ecore_x_randr_crtc_gamma_ramps_get(Ecore_X_Randr_Crtc crtc); -EAPI Eina_Bool ecore_x_randr_crtc_gamma_ramps_set(Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Crtc_Gamma *red, const Ecore_X_Randr_Crtc_Gamma *green, const Ecore_X_Randr_Crtc_Gamma *blue); -EAPI Eina_Bool ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, const Ecore_X_Randr_Crtc *not_moved, int nnot_moved, int dx, int dy); -EAPI Eina_Bool ecore_x_randr_move_crtcs(Ecore_X_Window root, const Ecore_X_Randr_Crtc *crtcs, int ncrtc, int dx, int dy); -EAPI void ecore_x_randr_mode_size_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode, int *w, int *h); -EAPI Ecore_X_Randr_Connection_Status ecore_x_randr_output_connection_status_get(Ecore_X_Window root, Ecore_X_Randr_Output output); -EAPI void ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w, int *h); -EAPI Eina_Bool ecore_x_randr_output_crtc_set(Ecore_X_Window root, Ecore_X_Randr_Output output, const Ecore_X_Randr_Crtc crtc); - -/* ecore_x_randr_12_edid.c */ - -/** - * @brief Validates the header from raw EDID data. - * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if the header is valid, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Checks whether a display's EDID has a valid checksum. - * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if the checksum is valid, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the encoded version from raw EDID data. - * - * The return value has the minor version in the lowest 8 bits, and the major - * version in all the rest of the bits. i.e. - * - * minor = (version & 0x000000ff); - * major = (version & 0xffffff00) >> 8; - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded major and minor version encasuplated an int. - */ -EAPI int ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the encoded manufacturer from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded manufacturer identifier. - */ -EAPI char *ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the encoded name from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded manufacturer identifier. - */ -EAPI char *ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the encoded ASCII from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded ASCII display identifier. - */ -EAPI char *ecore_x_randr_edid_display_ascii_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the encoded serial identifier from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded serial identifier. - */ -EAPI char *ecore_x_randr_edid_display_serial_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the encoded model number from raw EDID data. - * - * The manufacturer ID table is necessary for a useful description. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded model number. - */ -EAPI int ecore_x_randr_edid_model_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the manufacturer serial number from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The encoded serial manufacturer serial number. - */ -EAPI int ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the manufacturer model number from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The manufacturer's model number. - */ -EAPI int ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Looks up the DPMS support from raw EDID data. - * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if DPMS is supported in some way, @c EINA_FALSE - * otherwise. - */ -EAPI Eina_Bool ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Looks up the DPMS Standby support from raw EDID data. - * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if DPMS Standby is supported, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Looks up the DPMS Suspend support from raw EDID data. - * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if DPMS Suspend is supported, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Looks up the DPMS Off support from raw EDID data. - * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if DPMS Off is supported, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the preferred aspect ratio from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The preferred aspect ratio. - */ -EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the supported aspect ratios from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The supported aspect ratios. - */ -EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the supported colorschemes from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The supported colorschemes. - */ -EAPI Ecore_X_Randr_Edid_Display_Colorscheme ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the display type from raw EDID data. - * - * @param edid The edid structure. - * @param edid_length Length of the edid structure. - * @return @c EINA_TRUE, if the display is a digital one, @c EINA_FALSE - * otherwise. - */ -EAPI Eina_Bool ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length); - -/** - * @brief Get the display interface type from raw EDID data. - * - * @param edid the edid structure - * @param edid_length length of the edid structure - * @return The interface type. - */ -EAPI Ecore_X_Randr_Edid_Display_Interface_Type ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, unsigned long edid_length); - -/* ecore_x_randr_12.c */ - -EAPI Eina_Bool ecore_x_randr_output_backlight_available(void); -EAPI void ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, double level); -EAPI double ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, Ecore_X_Randr_Output output); -EAPI Eina_Bool ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, Ecore_X_Randr_Output output, double level); -EAPI Ecore_X_Randr_Output ecore_x_randr_primary_output_get(Ecore_X_Window root); -EAPI void ecore_x_randr_primary_output_set(Ecore_X_Window root, Ecore_X_Randr_Output output); -EAPI Ecore_X_Render_Subpixel_Order ecore_x_randr_output_subpixel_order_get(Ecore_X_Window root, Ecore_X_Randr_Output output); -EAPI unsigned char *ecore_x_randr_output_edid_get(Ecore_X_Window root, Ecore_X_Randr_Output output, unsigned long *length); -EAPI Ecore_X_Randr_Output *ecore_x_randr_output_wired_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); -EAPI Ecore_X_Randr_Output **ecore_x_randr_output_compatibility_list_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); -EAPI Ecore_X_Randr_Signal_Format *ecore_x_randr_output_signal_formats_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); -EAPI Eina_Bool ecore_x_randr_output_signal_format_set(Ecore_X_Window root, Ecore_X_Randr_Output output, Ecore_X_Randr_Signal_Format *signal); -EAPI Ecore_X_Randr_Signal_Property *ecore_x_randr_output_signal_properties_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); -EAPI int ecore_x_randr_output_connector_number_get(Ecore_X_Window root, Ecore_X_Randr_Output output); -EAPI Ecore_X_Randr_Connector_Type ecore_x_randr_output_connector_type_get(Ecore_X_Window root, Ecore_X_Randr_Output output); -/* WTF - these dont exist in ecore-x!!!! -EAPI Eina_Rectangle *ecore_x_randr_crtc_panning_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h); -EAPI Eina_Bool ecore_x_randr_crtc_panning_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, const int y, const int w, const int h); -EAPI Eina_Rectangle *ecore_x_randr_crtc_tracking_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h); -EAPI Eina_Bool ecore_x_randr_crtc_tracking_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, const int y, const int w, const int h); -EAPI Eina_Rectangle *ecore_x_randr_crtc_border_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); -EAPI Eina_Bool ecore_x_randr_crtc_border_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int left, const int top, const int right, const int bottom); -*/ - -/* 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 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); - -/** - * xfixes selection notification request. - * - * This lets you choose which selections you want to get notifications for. - * @param selection The selection atom. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - * @since 1.1.0 - */ -EAPI Eina_Bool ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection); - -/* XComposite Extension Support */ -EAPI Eina_Bool 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 void ecore_x_composite_window_events_disable(Ecore_X_Window win); -EAPI void ecore_x_composite_window_events_enable(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; - -struct _Ecore_X_Event_Xkb -{ - int group; -}; -typedef struct _Ecore_X_Event_Xkb Ecore_X_Event_Xkb; /** @since 1.7 */ - -EAPI Eina_Bool 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 Eina_Bool ecore_x_screen_is_composited(int screen); -EAPI void ecore_x_screen_is_composited_set(int screen, Ecore_X_Window win); - -EAPI Eina_Bool ecore_x_dpms_query(void); -EAPI Eina_Bool ecore_x_dpms_capable_get(void); -EAPI Eina_Bool ecore_x_dpms_enabled_get(void); -EAPI void ecore_x_dpms_enabled_set(int enabled); -EAPI void ecore_x_dpms_timeouts_get(unsigned int *standby, unsigned int *suspend, unsigned int *off); -EAPI Eina_Bool 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 Eina_Bool ecore_x_test_fake_key_down(const char *key); -EAPI Eina_Bool ecore_x_test_fake_key_up(const char *key); -EAPI Eina_Bool ecore_x_test_fake_key_press(const char *key); -EAPI const char *ecore_x_keysym_string_get(int keysym); - -/** - * Given a keyname, return the keycode representing that key - * @param keyname The key from which to get the keycode. - * @return The keycode of the key. - * - * @since 1.2.0 - */ -EAPI int ecore_x_keysym_keycode_get(const char *keyname); - -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, Ecore_X_GC gc, 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_image_is_argb32_get(Ecore_X_Image *im); - -EAPI Eina_Bool ecore_x_image_to_argb_convert(void *src, int sbpp, int sbpl, Ecore_X_Colormap c, Ecore_X_Visual v, int x, int y, int w, int h, unsigned int *dst, int dbpl, int dx, int dy); - -EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win); -EAPI Eina_Bool ecore_x_input_raw_select(Ecore_X_Window win); /**< @since 1.8 */ - -EAPI Eina_Bool ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win); - -typedef enum _Ecore_X_Gesture_Event_Mask -{ - ECORE_X_GESTURE_EVENT_MASK_NONE = 0L, - ECORE_X_GESTURE_EVENT_MASK_FLICK = (1L << 0), - ECORE_X_GESTURE_EVENT_MASK_PAN = (1L << 1), - ECORE_X_GESTURE_EVENT_MASK_PINCHROTATION = (1L << 2), - ECORE_X_GESTURE_EVENT_MASK_TAP = (1L << 3), - ECORE_X_GESTURE_EVENT_MASK_TAPNHOLD = (1L << 4), - ECORE_X_GESTURE_EVENT_MASK_HOLD = (1L << 5), - ECORE_X_GESTURE_EVENT_MASK_GROUP = (1L << 6) -} Ecore_X_Gesture_Event_Mask; - -typedef enum _Ecore_X_Gesture_Event_Type -{ - ECORE_X_GESTURE_EVENT_FLICK, - ECORE_X_GESTURE_EVENT_PAN, - ECORE_X_GESTURE_EVENT_PINCHROTATION, - ECORE_X_GESTURE_EVENT_TAP, - ECORE_X_GESTURE_EVENT_TAPNHOLD, - ECORE_X_GESTURE_EVENT_HOLD, - ECORE_X_GESTURE_EVENT_GROUP -} Ecore_X_Gesture_Event_Type; - -typedef enum _Ecore_X_Gesture_Event_Subtype -{ - ECORE_X_GESTURE_END, - ECORE_X_GESTURE_BEGIN, - ECORE_X_GESTURE_UPDATE, - ECORE_X_GESTURE_DONE -} Ecore_X_Gesture_Event_Subtype; - -typedef enum _Ecore_X_Gesture_Group_Subtype -{ - ECORE_X_GESTURE_GROUP_REMOVED, - ECORE_X_GESTURE_GROUP_ADDED, - ECORE_X_GESTURE_GROUP_CURRENT -} Ecore_X_Gesture_Group_Subtype; - -typedef enum _Ecore_X_Gesture_Direction -{ - ECORE_X_GESTURE_NORTHWARD, - ECORE_X_GESTURE_NORTHEASTWARD, - ECORE_X_GESTURE_EASTWARD, - ECORE_X_GESTURE_SOUTHEASTWARD, - ECORE_X_GESTURE_SOUTHWARD, - ECORE_X_GESTURE_SOUTHWESTWARD, - ECORE_X_GESTURE_WESTWARD, - ECORE_X_GESTURE_NORTHWESTWARD -} Ecore_X_Gesture_Direction; - -struct _Ecore_X_Event_Gesture_Notify_Flick -{ - Ecore_X_Window win; - Ecore_X_Time time; - Ecore_X_Gesture_Event_Subtype subtype; - int num_fingers; - int distance; - Ecore_X_Time duration; - Ecore_X_Gesture_Direction direction; - double angle; -}; - -struct _Ecore_X_Event_Gesture_Notify_Pan -{ - Ecore_X_Window win; - Ecore_X_Time time; - Ecore_X_Gesture_Event_Subtype subtype; - int num_fingers; - int dx; - int dy; - int distance; - Ecore_X_Time duration; - Ecore_X_Gesture_Direction direction; -}; - -struct _Ecore_X_Event_Gesture_Notify_PinchRotation -{ - Ecore_X_Window win; - Ecore_X_Time time; - Ecore_X_Gesture_Event_Subtype subtype; - int num_fingers; - int distance; - int cx; - int cy; - double zoom; - double angle; -}; - -struct _Ecore_X_Event_Gesture_Notify_Tap -{ - Ecore_X_Window win; - Ecore_X_Time time; - Ecore_X_Gesture_Event_Subtype subtype; - int num_fingers; - int cx; - int cy; - int tap_repeat; - Ecore_X_Time interval; -}; - -struct _Ecore_X_Event_Gesture_Notify_TapNHold -{ - Ecore_X_Window win; - Ecore_X_Time time; - Ecore_X_Gesture_Event_Subtype subtype; - int num_fingers; - int cx; - int cy; - Ecore_X_Time interval; - Ecore_X_Time hold_time; -}; - -struct _Ecore_X_Event_Gesture_Notify_Hold -{ - Ecore_X_Window win; - Ecore_X_Time time; - Ecore_X_Gesture_Event_Subtype subtype; - int num_fingers; - int cx; - int cy; - Ecore_X_Time hold_time; -}; - -struct _Ecore_X_Event_Gesture_Notify_Group -{ - Ecore_X_Window win; - Ecore_X_Time time; - Ecore_X_Gesture_Group_Subtype subtype; - int num_groups; - int group_id; -}; - -EAPI Eina_Bool ecore_x_gesture_supported(void); - -EAPI Eina_Bool ecore_x_gesture_events_select(Ecore_X_Window win, Ecore_X_Gesture_Event_Mask mask); - -EAPI Ecore_X_Gesture_Event_Mask ecore_x_gesture_events_selected_get(Ecore_X_Window win); - -EAPI Eina_Bool ecore_x_gesture_event_grab(Ecore_X_Window win, Ecore_X_Gesture_Event_Type type, int num_fingers); - -EAPI Eina_Bool ecore_x_gesture_event_ungrab(Ecore_X_Window win, Ecore_X_Gesture_Event_Type type, int num_fingers); - -EAPI void ecore_x_e_illume_indicator_state_set(Ecore_X_Window win, Ecore_X_Illume_Indicator_State state); -EAPI Ecore_X_Illume_Indicator_State ecore_x_e_illume_indicator_state_get(Ecore_X_Window win); -EAPI void ecore_x_e_illume_indicator_state_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_State state); - -EAPI void ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win, Ecore_X_Illume_Indicator_Opacity_Mode mode); - -EAPI Ecore_X_Illume_Indicator_Opacity_Mode ecore_x_e_illume_indicator_opacity_get(Ecore_X_Window win); - -EAPI void ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_Opacity_Mode mode); - -EAPI void -ecore_x_e_illume_window_state_set(Ecore_X_Window win, - Ecore_X_Illume_Window_State state); - -EAPI Ecore_X_Illume_Window_State ecore_x_e_illume_window_state_get(Ecore_X_Window win); -EAPI void ecore_x_xkb_select_group(int group); /* @since 1.7 */ - -#ifdef __cplusplus -} -#endif // ifdef __cplusplus - -#include -#include - -#endif // ifndef _ECORE_X_H diff --git a/legacy/ecore/src/lib/ecore_x/Ecore_X_Atoms.h b/legacy/ecore/src/lib/ecore_x/Ecore_X_Atoms.h deleted file mode 100644 index ca6351d839..0000000000 --- a/legacy/ecore/src/lib/ecore_x/Ecore_X_Atoms.h +++ /dev/null @@ -1,292 +0,0 @@ -#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; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_PIXMAP; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_VISUALID; - -/* 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; - -/* currently 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_ILLUME_INDICATOR_STATE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_ON; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN; - -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; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_PIXMAP; - -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION; - -/* currently elementary and E specific extension */ -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST; - -/* for sliding window */ -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY; - -/* for SDB(Samsung Debug Bridge) */ -EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT; -EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT; -#endif /* _ECORE_X_ATOMS_H */ diff --git a/legacy/ecore/src/lib/ecore_x/Ecore_X_Cursor.h b/legacy/ecore/src/lib/ecore_x/Ecore_X_Cursor.h deleted file mode 100644 index 807541e596..0000000000 --- a/legacy/ecore/src/lib/ecore_x/Ecore_X_Cursor.h +++ /dev/null @@ -1,87 +0,0 @@ -#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_BOGOSITY 10 -#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 // ifndef _ECORE_X_CURSOR_H diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x_atoms_decl.h b/legacy/ecore/src/lib/ecore_x/ecore_x_atoms_decl.h deleted file mode 100644 index 155283efe6..0000000000 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_atoms_decl.h +++ /dev/null @@ -1,602 +0,0 @@ -/* 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; -EAPI Ecore_X_Atom ECORE_X_ATOM_PIXMAP = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_VISUALID = 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_ILLUME_INDICATOR_STATE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_ON = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE= 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN = 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; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_PIXMAP = 0; - -/* currently Emotion and E17 specific extension */ -EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION = 0; - -/* for sliding window */ -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY = 0; - -/* for SDB(Samsung Debug Bridge) */ -EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT = 0; - -/* currently elementary and E specific extension */ -EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE = 0; -EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST = 0; - -typedef struct _Atom_Item Atom_Item; - -struct _Atom_Item -{ - const char *name; - Ecore_X_Atom *atom; -}; - -const Atom_Item atom_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 }, - { "PIXMAP", &ECORE_X_ATOM_PIXMAP }, - { "VISUALID", &ECORE_X_ATOM_VISUALID }, - - { "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_ILLUME_INDICATOR_STATE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE }, - { "_E_ILLUME_INDICATOR_ON", &ECORE_X_ATOM_E_ILLUME_INDICATOR_ON }, - { "_E_ILLUME_INDICATOR_OFF", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF }, - { "_E_ILLUME_INDICATOR_OPACITY_MODE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE }, - { "_E_ILLUME_INDICATOR_OPAQUE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE }, - { "_E_ILLUME_INDICATOR_TRANSLUCENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT }, - { "_E_ILLUME_INDICATOR_TRANSPARENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT }, - { "_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLES", &ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE }, - { "_E_ILLUME_ROTATE_WINDOW_ANGLE", &ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE }, - { "_E_ILLUME_ROTATE_ROOT_ANGLE", &ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE }, - { "_E_ILLUME_CLIPBOARD_STATE", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE }, - { "_E_ILLUME_CLIPBOARD_ON", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON }, - { "_E_ILLUME_CLIPBOARD_OFF", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF }, - { "_E_ILLUME_CLIPBOARD_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY }, - { "_E_ILLUME_WINDOW_STATE", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE }, - { "_E_ILLUME_WINDOW_STATE_NORMAL", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL }, - { "_E_ILLUME_WINDOW_STATE_FLOATING", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING }, - { "_E_ILLUME_ACCESS_CONTROL", &ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL }, - { "_E_ILLUME_ACCESS_ACTION_NEXT", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT }, - { "_E_ILLUME_ACCESS_ACTION_PREV", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV }, - { "_E_ILLUME_ACCESS_ACTION_ACTIVATE", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE }, - { "_E_ILLUME_ACCESS_ACTION_READ", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ }, - { "_E_ILLUME_ACCESS_ACTION_READ_NEXT", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT }, - { "_E_ILLUME_ACCESS_ACTION_READ_PREV", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV }, - { "_E_ILLUME_ACCESS_ACTION_UP", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP }, - { "_E_ILLUME_ACCESS_ACTION_DOWN", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN }, - { "_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 }, - { "_E_COMP_PIXMAP", &ECORE_X_ATOM_E_COMP_PIXMAP }, - { "_E_VIDEO_PARENT", &ECORE_X_ATOM_E_VIDEO_PARENT }, - { "_E_VIDEO_POSITION", &ECORE_X_ATOM_E_VIDEO_POSITION } -}; - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb.c deleted file mode 100644 index 2f1e1a2601..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb.c +++ /dev/null @@ -1,1583 +0,0 @@ -#include "ecore_xcb_private.h" -#include -#include - -/* local function prototypes */ -static int _ecore_xcb_shutdown(Eina_Bool close_display); -static Eina_Bool _ecore_xcb_fd_handle(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED); -static Eina_Bool _ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED); -static Eina_Bool _ecore_xcb_idle_enter(void *data EINA_UNUSED); - -/* local variables */ -static int _ecore_xcb_init_count = 0; -static int _ecore_xcb_grab_count = 0; -static Ecore_Fd_Handler *_ecore_xcb_fd_handler = NULL; -static xcb_generic_event_t *_ecore_xcb_event_buffered = NULL; -static Ecore_Idle_Enterer *_ecore_xcb_idle_enterer = NULL; - -/* external variables */ -int _ecore_xcb_log_dom = -1; -Ecore_X_Display *_ecore_xcb_display = NULL; -Ecore_X_Connection *_ecore_xcb_conn = NULL; -Ecore_X_Screen *_ecore_xcb_screen = NULL; -Ecore_X_Atom _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_NUM]; -double _ecore_xcb_double_click_time = 0.25; - -/** - * @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) -{ - char *gl = NULL; - uint32_t mask, list[1]; - - /* check if we have initialized already */ - if (++_ecore_xcb_init_count != 1) - return _ecore_xcb_init_count; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* try to initialize eina */ - if (!eina_init()) return --_ecore_xcb_init_count; - - /* setup ecore_xcb log domain */ - _ecore_xcb_log_dom = - eina_log_domain_register("ecore_x", ECORE_XCB_DEFAULT_LOG_COLOR); - if (_ecore_xcb_log_dom < 0) - { - EINA_LOG_ERR("Cannot create Ecore Xcb log domain"); - eina_shutdown(); - return --_ecore_xcb_init_count; - } - - /* try to initialize ecore */ - if (!ecore_init()) - { - /* unregister log domain */ - eina_log_domain_unregister(_ecore_xcb_log_dom); - _ecore_xcb_log_dom = -1; - eina_shutdown(); - return --_ecore_xcb_init_count; - } - - /* try to initialize ecore_event */ - if (!ecore_event_init()) - { - /* unregister log domain */ - eina_log_domain_unregister(_ecore_xcb_log_dom); - _ecore_xcb_log_dom = -1; - ecore_shutdown(); - eina_shutdown(); - return --_ecore_xcb_init_count; - } - - /* NB: XLib has XInitThreads */ - - /* check for env var which says we are not going to use GL @ all - * - * NB: This is done because if someone wants a 'pure' xcb implementation - * of ecore_x, all they need do is export this variable in the environment - * and ecore_x will not use xlib stuff at all. - * - * The upside is you can get pure xcb-based ecore_x (w/ all the speed), but - * there is a down-side here in that you cannot get OpenGL without XLib :( - */ - if ((gl = getenv("ECORE_X_NO_XLIB"))) - { - /* we found the env var that says 'Yes, we are not ever gonna try - * OpenGL so it is safe to not use XLib at all' */ - - /* try to connect to the display server */ - _ecore_xcb_conn = xcb_connect(name, NULL); - } - else - { - /* env var was not specified, so we will assume that the user - * may want opengl @ some point. connect this way for opengl to work */ - void *libxcb, *libxlib; - Display *(*_real_display)(const char *display); - xcb_connection_t *(*_real_connection)(Display * dpy); - void (*_real_queue)(Display *dpy, enum XEventQueueOwner owner); - int (*_real_close)(Display *dpy); -#ifdef EVAS_FRAME_QUEUING - Status (*_real_threads)(void); -#endif - - /* want to dlopen here to avoid actual library linkage */ - libxlib = dlopen("libX11.so", (RTLD_LAZY | RTLD_GLOBAL)); - if (!libxlib) - libxlib = dlopen("libX11.so.6", (RTLD_LAZY | RTLD_GLOBAL)); - if (!libxlib) - libxlib = dlopen("libX11.so.6.3.0", (RTLD_LAZY | RTLD_GLOBAL)); - if (!libxlib) - { - ERR("Could not dlsym to libX11"); - /* unregister log domain */ - eina_log_domain_unregister(_ecore_xcb_log_dom); - _ecore_xcb_log_dom = -1; - ecore_event_shutdown(); - ecore_shutdown(); - eina_shutdown(); - return --_ecore_xcb_init_count; - } - - libxcb = dlopen("libX11-xcb.so", (RTLD_LAZY | RTLD_GLOBAL)); - if (!libxcb) - libxcb = dlopen("libX11-xcb.so.1", (RTLD_LAZY | RTLD_GLOBAL)); - if (!libxcb) - libxcb = dlopen("libX11-xcb.so.1.0.0", (RTLD_LAZY | RTLD_GLOBAL)); - if (!libxcb) - { - ERR("Could not dlsym to libX11-xcb"); - /* unregister log domain */ - eina_log_domain_unregister(_ecore_xcb_log_dom); - _ecore_xcb_log_dom = -1; - ecore_event_shutdown(); - ecore_shutdown(); - eina_shutdown(); - return --_ecore_xcb_init_count; - } - - _real_display = dlsym(libxlib, "XOpenDisplay"); - _real_close = dlsym(libxlib, "XCloseDisplay"); - _real_connection = dlsym(libxcb, "XGetXCBConnection"); - _real_queue = dlsym(libxcb, "XSetEventQueueOwner"); -#ifdef EVAS_FRAME_QUEUING - _real_threads = dlsym(libxlib, "XInitThreads"); -#endif - - if (_real_display) - { -#ifdef EVAS_FRAME_QUEUING - if (_real_threads) _real_threads(); -#endif - _ecore_xcb_display = _real_display(name); - if (!_ecore_xcb_display) - { - ERR("Could not open Display via XLib"); - /* unregister log domain */ - eina_log_domain_unregister(_ecore_xcb_log_dom); - _ecore_xcb_log_dom = -1; - ecore_event_shutdown(); - ecore_shutdown(); - eina_shutdown(); - return --_ecore_xcb_init_count; - } - if (_real_connection) - _ecore_xcb_conn = _real_connection(_ecore_xcb_display); - if (!_ecore_xcb_conn) - { - ERR("Could not get XCB Connection from XLib"); - - if (_real_close) _real_close(_ecore_xcb_display); - - /* unregister log domain */ - eina_log_domain_unregister(_ecore_xcb_log_dom); - _ecore_xcb_log_dom = -1; - ecore_event_shutdown(); - ecore_shutdown(); - eina_shutdown(); - return --_ecore_xcb_init_count; - } - if (_real_queue) - _real_queue(_ecore_xcb_display, XCBOwnsEventQueue); - } - } - - if (xcb_connection_has_error(_ecore_xcb_conn)) - { - CRIT("XCB Connection has error"); - eina_log_domain_unregister(_ecore_xcb_log_dom); - _ecore_xcb_log_dom = -1; - ecore_event_shutdown(); - ecore_shutdown(); - eina_shutdown(); - return --_ecore_xcb_init_count; - } - - /* grab the default screen */ - _ecore_xcb_screen = - xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; - - /* NB: This method of init/finalize extensions first, then atoms - * Does end up being 2 round trips to X, BUT if we do extensions init then - * atoms init first, and call the 'finalize' functions later, we end up - * being slower, so it's a trade-off. This current method clocks in - * around 0.003 for fetching atoms VS 0.010 for init both then finalize */ - - /* prefetch extension data */ - _ecore_xcb_extensions_init(); - - /* finalize extensions */ - _ecore_xcb_extensions_finalize(); - - /* set keyboard autorepeat */ - mask = XCB_KB_AUTO_REPEAT_MODE; - list[0] = XCB_AUTO_REPEAT_MODE_ON; - xcb_change_keyboard_control(_ecore_xcb_conn, mask, list); - - /* setup xcb events */ - _ecore_xcb_events_init(); - - /* setup xcb keymasks */ - _ecore_xcb_keymap_init(); - - /* finalize xcb keymasks */ - _ecore_xcb_keymap_finalize(); - - /* setup ecore fd handler */ - _ecore_xcb_fd_handler = - ecore_main_fd_handler_add(xcb_get_file_descriptor(_ecore_xcb_conn), - ECORE_FD_READ, _ecore_xcb_fd_handle, - _ecore_xcb_conn, _ecore_xcb_fd_handle_buff, - _ecore_xcb_conn); - - if (!_ecore_xcb_fd_handler) - return _ecore_xcb_shutdown(EINA_TRUE); - - /* prefetch atoms */ - _ecore_xcb_atoms_init(); - - /* finalize atoms */ - _ecore_xcb_atoms_finalize(); - - /* icccm_init: dummy function */ - ecore_x_icccm_init(); - - /* setup netwm */ - ecore_x_netwm_init(); - - /* old e hints init: dummy function */ - ecore_x_e_init(); - - _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = - ECORE_X_ATOM_WM_DELETE_WINDOW; - _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = - ECORE_X_ATOM_WM_TAKE_FOCUS; - _ecore_xcb_atoms_wm_protocol[ECORE_X_NET_WM_PROTOCOL_PING] = - ECORE_X_ATOM_NET_WM_PING; - _ecore_xcb_atoms_wm_protocol[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = - ECORE_X_ATOM_NET_WM_SYNC_REQUEST; - - /* setup selection */ - _ecore_xcb_selection_init(); - - /* setup dnd */ - _ecore_xcb_dnd_init(); - - _ecore_xcb_idle_enterer = - ecore_idle_enterer_add(_ecore_xcb_idle_enter, NULL); - - 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_X_Init_Group - */ -EAPI int -ecore_x_shutdown(void) -{ - return _ecore_xcb_shutdown(EINA_TRUE); -} - -/** - * Shuts down the Ecore X library. - * - * As ecore_x_shutdown, except do not close Display, only connection. - * - * @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_disconnect(void) -{ - return _ecore_xcb_shutdown(EINA_FALSE); -} - -/** - * @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__); - - CHECK_XCB_CONN; - xcb_flush(_ecore_xcb_conn); -} - -/** - * Retrieves the Ecore_X_Screen handle used for the current X connection. - * @return The current default screen. - * @ingroup Ecore_X_Display_Attr_Group - */ -EAPI Ecore_X_Screen * -ecore_x_default_screen_get(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return (Ecore_X_Screen *)_ecore_xcb_screen; -} - -EAPI Ecore_X_Connection * -ecore_x_connection_get(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - CHECK_XCB_CONN; - return (Ecore_X_Connection *)_ecore_xcb_conn; -} - -/** - * Return the last event time - */ -EAPI Ecore_X_Time -ecore_x_current_time_get(void) -{ - return _ecore_xcb_events_last_time_get(); -} - -/** - * 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__); - - CHECK_XCB_CONN; - free(xcb_get_input_focus_reply(_ecore_xcb_conn, - xcb_get_input_focus_unchecked(_ecore_xcb_conn), - NULL)); -} - -EAPI void -ecore_x_grab(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - CHECK_XCB_CONN; - _ecore_xcb_grab_count++; - if (_ecore_xcb_grab_count == 1) - xcb_grab_server(_ecore_xcb_conn); -} - -EAPI void -ecore_x_ungrab(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - CHECK_XCB_CONN; - _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); -} - -/** - * 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 mask The mask of the message to be sent. - * @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 @c EINA_TRUE on success @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -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) -{ - xcb_client_message_event_t ev; - xcb_void_cookie_t cookie; - xcb_generic_error_t *err; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = type; - ev.data.data32[0] = (uint32_t)d0; - ev.data.data32[1] = (uint32_t)d1; - ev.data.data32[2] = (uint32_t)d2; - ev.data.data32[3] = (uint32_t)d3; - ev.data.data32[4] = (uint32_t)d4; - - cookie = xcb_send_event(_ecore_xcb_conn, 0, win, mask, (const char *)&ev); - - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - DBG("Problem Sending Event"); - DBG("\tType: %d", type); - DBG("\tWin: %d", win); - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -/** - * 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 @c 20. - * - * @return @c EINA_TRUE on success @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, - const void *data, int len) -{ - xcb_client_message_event_t ev; - xcb_void_cookie_t cookie; - xcb_generic_error_t *err; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 8; - ev.window = win; - ev.type = type; - if (len > 20) len = 20; - memcpy(ev.data.data8, data, len); - memset(ev.data.data8 + len, 0, 20 - len); - - cookie = xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); - - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - DBG("Problem Sending Event"); - DBG("\tType: %d", type); - DBG("\tWin: %d", win); - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b) -{ - xcb_translate_coordinates_cookie_t cookie; - xcb_translate_coordinates_reply_t *reply; - xcb_button_press_event_t ev; - xcb_void_cookie_t vcookie; - xcb_generic_error_t *err; - Ecore_X_Window root = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - root = ecore_x_window_root_get(win); - cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); - reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - memset(&ev, 0, sizeof(xcb_button_press_event_t)); - - ev.response_type = XCB_BUTTON_PRESS; - ev.event = win; - ev.child = win; - ev.root = root; - ev.event_x = x; - ev.event_y = y; - ev.same_screen = 1; - ev.state = 1 << b; - ev.detail = b; // xcb uses detail for button - ev.root_x = reply->dst_x; - ev.root_y = reply->dst_y; - ev.time = ecore_x_current_time_get(); - free(reply); - - vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, - XCB_EVENT_MASK_BUTTON_PRESS, (const char *)&ev); - - err = xcb_request_check(_ecore_xcb_conn, vcookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b) -{ - xcb_translate_coordinates_cookie_t cookie; - xcb_translate_coordinates_reply_t *reply; - xcb_button_release_event_t ev; - xcb_void_cookie_t vcookie; - xcb_generic_error_t *err; - Ecore_X_Window root = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - root = ecore_x_window_root_get(win); - cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); - reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - memset(&ev, 0, sizeof(xcb_button_release_event_t)); - - ev.response_type = XCB_BUTTON_RELEASE; - ev.event = win; - ev.child = win; - ev.root = root; - ev.event_x = x; - ev.event_y = y; - ev.same_screen = 1; - ev.state = 0; - ev.root_x = reply->dst_x; - ev.root_y = reply->dst_y; - ev.detail = b; // xcb uses detail for button - ev.time = ecore_x_current_time_get(); - free(reply); - - vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, - XCB_EVENT_MASK_BUTTON_RELEASE, (const char *)&ev); - - err = xcb_request_check(_ecore_xcb_conn, vcookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y) -{ - xcb_translate_coordinates_cookie_t cookie; - xcb_translate_coordinates_reply_t *reply; - xcb_motion_notify_event_t ev; - xcb_void_cookie_t vcookie; - xcb_generic_error_t *err; - Ecore_X_Window root = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - root = ecore_x_window_root_get(win); - cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); - reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - memset(&ev, 0, sizeof(xcb_motion_notify_event_t)); - - ev.response_type = XCB_MOTION_NOTIFY; - ev.event = win; - ev.child = win; - ev.root = root; - ev.event_x = x; - ev.event_y = y; - ev.same_screen = 1; - ev.state = 0; - ev.detail = 0; // xcb uses 'detail' for is_hint - ev.root_x = reply->dst_x; - ev.root_y = reply->dst_y; - ev.time = ecore_x_current_time_get(); - free(reply); - - vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, - XCB_EVENT_MASK_POINTER_MOTION, (const char *)&ev); - - err = xcb_request_check(_ecore_xcb_conn, vcookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_mouse_in_send(Ecore_X_Window win, int x, int y) -{ - xcb_translate_coordinates_cookie_t cookie; - xcb_translate_coordinates_reply_t *reply; - xcb_enter_notify_event_t ev; - xcb_void_cookie_t vcookie; - xcb_generic_error_t *err; - Ecore_X_Window root = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - root = ecore_x_window_root_get(win); - cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); - reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - memset(&ev, 0, sizeof(xcb_enter_notify_event_t)); - - ev.response_type = XCB_ENTER_NOTIFY; - ev.event = win; - ev.child = win; - ev.root = root; - ev.event_x = x; - ev.event_y = y; - ev.same_screen_focus = 1; - ev.mode = XCB_NOTIFY_MODE_NORMAL; - ev.detail = XCB_NOTIFY_DETAIL_NONLINEAR; - /* ev.focus = 0; */ - ev.state = 0; - ev.root_x = reply->dst_x; - ev.root_y = reply->dst_y; - ev.time = ecore_x_current_time_get(); - free(reply); - - vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, - XCB_EVENT_MASK_ENTER_WINDOW, (const char *)&ev); - - err = xcb_request_check(_ecore_xcb_conn, vcookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_mouse_out_send(Ecore_X_Window win, int x, int y) -{ - xcb_translate_coordinates_cookie_t cookie; - xcb_translate_coordinates_reply_t *reply; - xcb_leave_notify_event_t ev; - xcb_void_cookie_t vcookie; - xcb_generic_error_t *err; - Ecore_X_Window root = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - root = ecore_x_window_root_get(win); - cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); - reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - memset(&ev, 0, sizeof(xcb_leave_notify_event_t)); - - ev.response_type = XCB_LEAVE_NOTIFY; - ev.event = win; - ev.child = win; - ev.root = root; - ev.event_x = x; - ev.event_y = y; - ev.same_screen_focus = 1; - ev.mode = XCB_NOTIFY_MODE_NORMAL; - ev.detail = XCB_NOTIFY_DETAIL_NONLINEAR; - /* ev.focus = 0; */ - ev.state = 0; - ev.root_x = reply->dst_x; - ev.root_y = reply->dst_y; - ev.time = ecore_x_current_time_get(); - free(reply); - - vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, - XCB_EVENT_MASK_LEAVE_WINDOW, (const char *)&ev); - - err = xcb_request_check(_ecore_xcb_conn, vcookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_keyboard_grab(Ecore_X_Window win) -{ - xcb_grab_keyboard_cookie_t cookie; - xcb_grab_keyboard_reply_t *reply; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = - xcb_grab_keyboard_unchecked(_ecore_xcb_conn, 0, win, XCB_CURRENT_TIME, - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); - reply = xcb_grab_keyboard_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - free(reply); - return EINA_TRUE; -} - -EAPI void -ecore_x_keyboard_ungrab(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_ungrab_keyboard(_ecore_xcb_conn, XCB_CURRENT_TIME); -} - -EAPI void -ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y) -{ - xcb_query_pointer_cookie_t cookie; - xcb_query_pointer_reply_t *reply; - -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -// if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - if (x) *x = -1; - if (y) *y = -1; - - cookie = xcb_query_pointer_unchecked(_ecore_xcb_conn, win); - reply = xcb_query_pointer_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - if (x) *x = reply->win_x; - if (y) *y = reply->win_y; - free(reply); -} - -EAPI Eina_Bool -ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold) -{ - xcb_void_cookie_t vcookie; - xcb_generic_error_t *err; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - vcookie = - xcb_change_pointer_control_checked(_ecore_xcb_conn, - accel_num, accel_denom, threshold, - 1, 1); - err = xcb_request_check(_ecore_xcb_conn, vcookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold) -{ - xcb_get_pointer_control_cookie_t cookie; - xcb_get_pointer_control_reply_t *reply; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (accel_num) *accel_num = 0; - if (accel_denom) *accel_denom = 0; - if (threshold) *threshold = 0; - - cookie = xcb_get_pointer_control_unchecked(_ecore_xcb_conn); - reply = xcb_get_pointer_control_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - if (accel_num) *accel_num = reply->acceleration_numerator; - if (accel_denom) *accel_denom = reply->acceleration_denominator; - if (threshold) *threshold = reply->threshold; - free(reply); - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_pointer_mapping_set(unsigned char *map, int nmap) -{ - xcb_set_pointer_mapping_cookie_t cookie; - xcb_set_pointer_mapping_reply_t *reply; - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_set_pointer_mapping_unchecked(_ecore_xcb_conn, nmap, map); - reply = xcb_set_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - if (reply->status == XCB_MAPPING_STATUS_SUCCESS) - ret = EINA_TRUE; - - free(reply); - return ret; -} - -EAPI Eina_Bool -ecore_x_pointer_mapping_get(unsigned char *map, int nmap) -{ - xcb_get_pointer_mapping_cookie_t cookie; - xcb_get_pointer_mapping_reply_t *reply; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (map) *map = 0; - nmap = 0; - - cookie = xcb_get_pointer_mapping_unchecked(_ecore_xcb_conn); - reply = xcb_get_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - nmap = xcb_get_pointer_mapping_map_length(reply); - if (nmap <= 0) - { - free(reply); - return EINA_FALSE; - } - - if (map) - { - uint8_t *tmp; - int i = 0; - - tmp = xcb_get_pointer_mapping_map(reply); - for (i = 0; i < nmap; i++) - map[i] = tmp[i]; - } - - free(reply); - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_pointer_grab(Ecore_X_Window win) -{ - xcb_grab_pointer_cookie_t cookie; - xcb_grab_pointer_reply_t *reply; - uint16_t mask; - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - mask = (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); - - cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, win, mask, - 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 EINA_FALSE; - - ret = (reply->status == XCB_GRAB_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE; - - free(reply); - return ret; -} - -EAPI Eina_Bool -ecore_x_pointer_confine_grab(Ecore_X_Window win) -{ - xcb_grab_pointer_cookie_t cookie; - xcb_grab_pointer_reply_t *reply; - uint16_t mask; - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - mask = (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); - - cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, win, mask, - XCB_GRAB_MODE_ASYNC, - XCB_GRAB_MODE_ASYNC, - win, XCB_NONE, XCB_CURRENT_TIME); - reply = xcb_grab_pointer_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - ret = (reply->status == XCB_GRAB_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE; - - free(reply); - return ret; -} - -EAPI void -ecore_x_pointer_ungrab(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_ungrab_pointer(_ecore_xcb_conn, XCB_CURRENT_TIME); -} - -EAPI Eina_Bool -ecore_x_pointer_warp(Ecore_X_Window win, int x, int y) -{ - xcb_void_cookie_t vcookie; - xcb_generic_error_t *err; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - vcookie = - xcb_warp_pointer_checked(_ecore_xcb_conn, XCB_NONE, win, 0, 0, 0, 0, x, y); - err = xcb_request_check(_ecore_xcb_conn, vcookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -/** - * Invoke the standard system beep to alert users - * - * @param percent The volume at which the bell rings. Must be in the range - * [-100,+100]. If percent >= 0, the final volume will be: - * base - [(base * percent) / 100] + percent - * Otherwise, it's calculated as: - * base + [(base * percent) / 100] - * where @c base is the bell's base volume as set by XChangeKeyboardControl(3). - * - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_bell(int percent) -{ - xcb_void_cookie_t cookie; - xcb_generic_error_t *err; - - CHECK_XCB_CONN; - - // FIXME: Use unchecked version after development is ironed out - cookie = xcb_bell_checked(_ecore_xcb_conn, percent); - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI void -ecore_x_display_size_get(Ecore_X_Display *dsp EINA_UNUSED, int *w, int *h) -{ - xcb_screen_t *screen; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - /* grab the default screen */ - screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; - if (w) *w = screen->width_in_pixels; - if (h) *h = screen->height_in_pixels; -} - -EAPI unsigned long -ecore_x_display_black_pixel_get(Ecore_X_Display *dsp EINA_UNUSED) -{ - xcb_screen_t *screen; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - /* grab the default screen */ - screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; - return screen->black_pixel; -} - -EAPI unsigned long -ecore_x_display_white_pixel_get(Ecore_X_Display *dsp EINA_UNUSED) -{ - xcb_screen_t *screen; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - /* grab the default screen */ - screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; - return screen->white_pixel; -} - -EAPI void -ecore_x_pointer_last_xy_get(int *x, int *y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (x) *x = _ecore_xcb_event_last_root_x; - if (y) *y = _ecore_xcb_event_last_root_y; -} - -EAPI void -ecore_x_focus_reset(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_POINTER_ROOT, - ((xcb_screen_t *)_ecore_xcb_screen)->root, - XCB_CURRENT_TIME); -// ecore_x_flush(); -} - -EAPI void -ecore_x_events_allow_all(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_allow_events(_ecore_xcb_conn, XCB_ALLOW_ASYNC_BOTH, XCB_CURRENT_TIME); -// ecore_x_flush(); -} - -/** - * 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__); - CHECK_XCB_CONN; - - xcb_kill_client(_ecore_xcb_conn, win); -// ecore_x_flush(); -} - -/** - * 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 = 0, i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - ecore_x_grab(); - - screens = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem; - - /* Traverse 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_t *wins = NULL; - int tree_c_len, j = 0; - - wins = xcb_query_tree_children(reply); - tree_c_len = xcb_query_tree_children_length(reply); - for (j = 0; j < tree_c_len; j++) - xcb_kill_client(_ecore_xcb_conn, wins[j]); - free(reply); - } - } - - ecore_x_ungrab(); - ecore_x_sync(); // needed -} - -/** - * 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 account 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) -{ - uint16_t mw = 0, w = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - mw = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_millimeters; - if (mw <= 0) return 75; - w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; - return (((w * 254) / mw) + 5) / 10; -} - -/** - * @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) -{ - char *gl = NULL; - - CHECK_XCB_CONN; - - /* if we have the 'dont use xlib' env var, then we are not using - * XLib and thus cannot return a real XDisplay. - * - * NB: This may break EFL in some places and needs lots of testing !!! */ - if ((gl = getenv("ECORE_X_NO_XLIB"))) - return (Ecore_X_Display *)_ecore_xcb_conn; - else /* we can safely return an XDisplay var */ - return (Ecore_X_Display *)_ecore_xcb_display; -} - -/** - * 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__); - CHECK_XCB_CONN; - return xcb_get_file_descriptor(_ecore_xcb_conn); -} - -EAPI void -ecore_x_passive_grab_replay_func_set(Eina_Bool (*func)(void *data, int type, void *event), - void *data) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_window_grab_replay_func = func; - _ecore_xcb_window_grab_replay_data = data; -} - -/** - * Retrieves the size of an Ecore_X_Screen. - * @param screen the handle to the screen to query. - * @param w where to return the width. May be NULL. Returns 0 on errors. - * @param h where to return the height. May be NULL. Returns 0 on errors. - * @ingroup Ecore_X_Display_Attr_Group - * @see ecore_x_default_screen_get() - * - * @since 1.1 - */ -EAPI void -ecore_x_screen_size_get(const Ecore_X_Screen *screen, int *w, int *h) -{ - xcb_screen_t *s; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (w) *w = 0; - if (h) *h = 0; - if (!(s = (xcb_screen_t *)screen)) return; - if (w) *w = s->width_in_pixels; - if (h) *h = s->height_in_pixels; -} - -/** - * Retrieves the count of screens. - * - * @return The count of screens. - * @ingroup Ecore_X_Display_Attr_Group - * - * @since 1.1 - */ -EAPI int -ecore_x_screen_count_get(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - return xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); -} - -/** - * Retrieves the index number of the given screen. - * - * @param screen The screen for which index will be gotten. - * @return The index number of the screen. - * @ingroup Ecore_X_Display_Attr_Group - * - * @since 1.1 - */ -EAPI int -ecore_x_screen_index_get(const Ecore_X_Screen *screen) -{ - xcb_screen_iterator_t iter; - int i = 0; - - CHECK_XCB_CONN; - - iter = - xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - for (; iter.rem; xcb_screen_next(&iter)) - { - if (iter.data == (xcb_screen_t *)screen) - return i; - i++; - } - - return 0; -} - -/** - * Retrieves the screen based on index number. - * - * @param idx The index that will be used to retrieve the screen. - * @return The Ecore_X_Screen at this index. - * @ingroup Ecore_X_Display_Attr_Group - * - * @since 1.1 - */ -EAPI Ecore_X_Screen * -ecore_x_screen_get(int idx) -{ - xcb_screen_iterator_t iter; - int i = 0; - - CHECK_XCB_CONN; - - iter = - xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - for (i = 0; iter.rem; xcb_screen_next(&iter), i++) - if (i == idx) return iter.data; - - return NULL; -} - -EAPI unsigned int -ecore_x_visual_id_get(Ecore_X_Visual visual) -{ - return ((xcb_visualtype_t *)visual)->visual_id; -} - -/** - * Retrieve the default Visual. - * - * @param disp The Display to get the Default Visual from - * @param screen The Screen. - * - * @return The default visual. - * @since 1.1.0 - */ -EAPI Ecore_X_Visual -ecore_x_default_visual_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen) -{ - xcb_screen_t *s; - xcb_depth_iterator_t diter; - xcb_visualtype_iterator_t viter; - - CHECK_XCB_CONN; - - s = (xcb_screen_t *)screen; - diter = xcb_screen_allowed_depths_iterator(s); - for (; diter.rem; xcb_depth_next(&diter)) - { - viter = xcb_depth_visuals_iterator(diter.data); - for (; viter.rem; xcb_visualtype_next(&viter)) - { - if (viter.data->visual_id == s->root_visual) - return viter.data; - } - } - return 0; -} - -/** - * Retrieve the default Colormap. - * - * @param disp The Display to get the Default Colormap from - * @param screen The Screen. - * - * @return The default colormap. - * @since 1.1.0 - */ -EAPI Ecore_X_Colormap -ecore_x_default_colormap_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen) -{ - xcb_screen_t *s; - - s = (xcb_screen_t *)screen; - return s->default_colormap; -} - -/** - * Retrieve the default depth. - * - * @param disp The Display to get the Default Depth from - * @param screen The Screen. - * - * @return The default depth. - * @since 1.1.0 - */ -EAPI int -ecore_x_default_depth_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen) -{ - xcb_screen_t *s; - - s = (xcb_screen_t *)screen; - return s->root_depth; -} - -EAPI void -ecore_x_xkb_select_group(int group) -{ - // XXX: implement me */ -} - -/** - * 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_xcb_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_xcb_double_click_time; -} - -/* local function prototypes */ -static int -_ecore_xcb_shutdown(Eina_Bool close_display) -{ - if (--_ecore_xcb_init_count != 0) - return _ecore_xcb_init_count; - - if (!_ecore_xcb_conn) - return _ecore_xcb_init_count; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - ecore_idle_enterer_del(_ecore_xcb_idle_enterer); - _ecore_xcb_idle_enterer = NULL; - - if (_ecore_xcb_fd_handler) - ecore_main_fd_handler_del(_ecore_xcb_fd_handler); - - /* disconnect from display server */ - if (close_display) - xcb_disconnect(_ecore_xcb_conn); - else - { - close(xcb_get_file_descriptor(_ecore_xcb_conn)); - _ecore_xcb_conn = NULL; - } - - /* shutdown events */ - _ecore_xcb_events_shutdown(); - - /* shutdown input extension */ - _ecore_xcb_input_shutdown(); - - /* shutdown gesture extension */ - _ecore_xcb_gesture_shutdown(); - - /* shutdown selection */ - _ecore_xcb_selection_shutdown(); - - /* shutdown dnd */ - _ecore_xcb_dnd_shutdown(); - - /* shutdown netwm */ - ecore_x_netwm_shutdown(); - - /* shutdown keymap */ - _ecore_xcb_keymap_shutdown(); - - /* shutdown ecore_event */ - ecore_event_shutdown(); - - /* shutdown ecore */ - ecore_shutdown(); - - /* unregister log domain */ - eina_log_domain_unregister(_ecore_xcb_log_dom); - _ecore_xcb_log_dom = -1; - - /* shutdown eina */ - eina_shutdown(); - - return _ecore_xcb_init_count; -} - -static Eina_Bool -_ecore_xcb_fd_handle(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) -{ - xcb_connection_t *conn; - xcb_generic_event_t *ev = NULL; - - conn = (xcb_connection_t *)data; - - if (_ecore_xcb_event_buffered) - { - _ecore_xcb_events_handle(_ecore_xcb_event_buffered); - free(_ecore_xcb_event_buffered); - _ecore_xcb_event_buffered = NULL; - } - -// xcb_flush(conn); - - while ((ev = xcb_poll_for_event(conn))) - { - /* NB: Ecore Xlib uses filterevent for xim, but xcb does not support - * xim, so no need for it here */ - - /* check for errors first */ - if (xcb_connection_has_error(conn)) - { - xcb_generic_error_t *err; - - err = (xcb_generic_error_t *)ev; - _ecore_xcb_io_error_handle(err); - } - else - { - /* FIXME: Filter event for XIM */ - _ecore_xcb_events_handle(ev); - free(ev); - } - } - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) -{ - xcb_connection_t *conn; - xcb_generic_event_t *ev = NULL; - - conn = (xcb_connection_t *)data; - ev = xcb_poll_for_event(conn); - if (ev) - { - /* check for errors first */ - if (xcb_connection_has_error(conn)) - { - xcb_generic_error_t *err; - - err = (xcb_generic_error_t *)ev; - _ecore_xcb_io_error_handle(err); - return ECORE_CALLBACK_CANCEL; - } - _ecore_xcb_event_buffered = ev; - return ECORE_CALLBACK_RENEW; - } - return ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_ecore_xcb_idle_enter(void *data EINA_UNUSED) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_flush(_ecore_xcb_conn); - return ECORE_CALLBACK_RENEW; -} diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_atoms.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_atoms.c deleted file mode 100644 index c8c217eec7..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_atoms.c +++ /dev/null @@ -1,149 +0,0 @@ -#include "ecore_xcb_private.h" -#include "ecore_x_atoms_decl.h" - -/* NB: Increment if you add new atoms */ -#define ECORE_X_ATOMS_COUNT 199 - -/* local function prototypes */ - -/* local variables */ -static xcb_intern_atom_cookie_t cookies[ECORE_X_ATOMS_COUNT]; - -void -_ecore_xcb_atoms_init(void) -{ - int i = 0, num = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - num = (sizeof(atom_items) / sizeof(Atom_Item)); - for (i = 0; i < num; i++) - { - cookies[i] = - xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, - strlen(atom_items[i].name), atom_items[i].name); - } -} - -void -_ecore_xcb_atoms_finalize(void) -{ - int i = 0, num = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - num = (sizeof(atom_items) / sizeof(Atom_Item)); - for (i = 0; i < num; i++) - { - xcb_intern_atom_reply_t *reply = NULL; - - if (!(reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], 0))) - continue; - *(atom_items[i].atom) = reply->atom; - free(reply); - } -} - -/** - * @defgroup Ecore_X_Atom_Group XCB Atom Functions - * - * Functions that operate on atoms - */ - -/** - * 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. - * - * @ingroup Ecore_X_Atom_Group - */ -EAPI Ecore_X_Atom -ecore_x_atom_get(const char *name) -{ - xcb_intern_atom_cookie_t cookie; - xcb_intern_atom_reply_t *reply; - Ecore_X_Atom a; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(name), name); - reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return XCB_ATOM_NONE; - a = reply->atom; - free(reply); - return a; -} - -/** - * Retrieves the name of the given atom. - * - * @param atom - * @return The name of the atom. - * - * @ingroup Ecore_X_Atom_Group - */ -EAPI char * -ecore_x_atom_name_get(Ecore_X_Atom atom) -{ - xcb_get_atom_name_cookie_t cookie; - xcb_get_atom_name_reply_t *reply; - char *name; - int len = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, atom); - reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return NULL; - len = xcb_get_atom_name_name_length(reply); - name = (char *)malloc(sizeof(char) * (len + 1)); - if (!name) - { - free(reply); - return NULL; - } - memcpy(name, xcb_get_atom_name_name(reply), len); - name[len] = '\0'; - - free(reply); - return name; -} - -EAPI void -ecore_x_atoms_get(const char **names, - int num, - Ecore_X_Atom *atoms) -{ - xcb_intern_atom_cookie_t cookies[num]; - int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - for (i = 0; i < num; i++) - { - cookies[i] = - xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, - strlen(names[i]), names[i]); - } - for (i = 0; i < num; i++) - { - xcb_intern_atom_reply_t *reply = NULL; - - if (!(reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], 0))) - continue; - atoms[i] = reply->atom; - free(reply); - } -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_composite.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_composite.c deleted file mode 100644 index 0d3b44e4aa..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_composite.c +++ /dev/null @@ -1,290 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_COMPOSITE -# include -#endif - -/* local variables */ -static Eina_Bool _composite_avail = EINA_FALSE; - -void -_ecore_xcb_composite_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_COMPOSITE - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_composite_id); -#endif -} - -void -_ecore_xcb_composite_finalize(void) -{ -#ifdef ECORE_XCB_COMPOSITE - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_COMPOSITE - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_composite_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_composite_query_version_cookie_t cookie; - xcb_composite_query_version_reply_t *reply; - - cookie = - xcb_composite_query_version_unchecked(_ecore_xcb_conn, - XCB_COMPOSITE_MAJOR_VERSION, - XCB_COMPOSITE_MINOR_VERSION); - reply = - xcb_composite_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { -// if ((reply->major_version >= XCB_COMPOSITE_MAJOR_VERSION) && - if (reply->minor_version >= XCB_COMPOSITE_MINOR_VERSION) - { -# ifdef ECORE_XCB_RENDER - if (_ecore_xcb_render_avail_get()) - { -# ifdef ECORE_XCB_XFIXES - if (_ecore_xcb_xfixes_avail_get()) - _composite_avail = EINA_TRUE; -# endif - } -# endif - } - - free(reply); - } - } -#endif -} - -/** - * @defgroup Ecore_X_Composite_Group X Composite Extension Functions - * - * Functions related to the X Composite Extension - */ - -/** - * Return whether the Composite Extension is available - * - * @return @c EINA_TRUE is the Composite Extension is available, @c EINA_FALSE - * if not. - * - * @ingroup Ecore_X_Composite_Group - */ -EAPI Eina_Bool -ecore_x_composite_query(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return _composite_avail; -} - -EAPI void -ecore_x_composite_redirect_window(Ecore_X_Window win, - Ecore_X_Composite_Update_Type type) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return; - -#ifdef ECORE_XCB_COMPOSITE - uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - - switch (type) - { - case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: - update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - break; - - case ECORE_X_COMPOSITE_UPDATE_MANUAL: - update = XCB_COMPOSITE_REDIRECT_MANUAL; - break; - } - xcb_composite_redirect_window(_ecore_xcb_conn, win, update); -// ecore_x_flush(); -#endif -} - -EAPI void -ecore_x_composite_redirect_subwindows(Ecore_X_Window win, - Ecore_X_Composite_Update_Type type) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return; - -#ifdef ECORE_XCB_COMPOSITE - uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - - switch (type) - { - case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: - update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - break; - - case ECORE_X_COMPOSITE_UPDATE_MANUAL: - update = XCB_COMPOSITE_REDIRECT_MANUAL; - break; - } - xcb_composite_redirect_subwindows(_ecore_xcb_conn, win, update); -// ecore_x_flush(); -#endif -} - -EAPI void -ecore_x_composite_unredirect_window(Ecore_X_Window win, - Ecore_X_Composite_Update_Type type) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return; - -#ifdef ECORE_XCB_COMPOSITE - uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - - switch (type) - { - case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: - update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - break; - - case ECORE_X_COMPOSITE_UPDATE_MANUAL: - update = XCB_COMPOSITE_REDIRECT_MANUAL; - break; - } - xcb_composite_unredirect_window(_ecore_xcb_conn, win, update); -// ecore_x_flush(); -#endif -} - -EAPI void -ecore_x_composite_unredirect_subwindows(Ecore_X_Window win, - Ecore_X_Composite_Update_Type type) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return; - -#ifdef ECORE_XCB_COMPOSITE - uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - - switch (type) - { - case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: - update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; - break; - - case ECORE_X_COMPOSITE_UPDATE_MANUAL: - update = XCB_COMPOSITE_REDIRECT_MANUAL; - break; - } - xcb_composite_unredirect_subwindows(_ecore_xcb_conn, win, update); -// ecore_x_flush(); -#endif -} - -EAPI Ecore_X_Pixmap -ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win) -{ -#ifdef ECORE_XCB_COMPOSITE - Ecore_X_Pixmap pmap = XCB_NONE; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return XCB_NONE; - -#ifdef ECORE_XCB_COMPOSITE - pmap = xcb_generate_id(_ecore_xcb_conn); - xcb_composite_name_window_pixmap(_ecore_xcb_conn, win, pmap); -// ecore_x_flush(); -#endif - - return pmap; -} - -EAPI void -ecore_x_composite_window_events_disable(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return; - -#ifdef ECORE_XCB_SHAPE - ecore_x_window_shape_input_rectangle_set(win, -1, -1, 1, 1); -// ecore_x_flush(); -#else - return; - win = 0; -#endif -} - -EAPI void -ecore_x_composite_window_events_enable(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return; - -#ifdef ECORE_XCB_SHAPE - ecore_x_window_shape_input_rectangle_set(win, 0, 0, 65535, 65535); -// ecore_x_flush(); -#else - return; - win = 0; -#endif -} - -EAPI Ecore_X_Window -ecore_x_composite_render_window_enable(Ecore_X_Window root) -{ - Ecore_X_Window win = 0; -#ifdef ECORE_XCB_COMPOSITE - xcb_composite_get_overlay_window_cookie_t cookie; - xcb_composite_get_overlay_window_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return 0; - -#ifdef ECORE_XCB_COMPOSITE - cookie = xcb_composite_get_overlay_window_unchecked(_ecore_xcb_conn, root); - reply = - xcb_composite_get_overlay_window_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return win; - - win = reply->overlay_win; - free(reply); - - ecore_x_composite_window_events_disable(win); -// ecore_x_flush(); -#endif - - return win; -} - -EAPI void -ecore_x_composite_render_window_disable(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_composite_avail) return; - -#ifdef ECORE_XCB_COMPOSITE - xcb_composite_release_overlay_window(_ecore_xcb_conn, win); -// ecore_x_flush(); -#endif -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_cursor.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_cursor.c deleted file mode 100644 index 755df04e4f..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_cursor.c +++ /dev/null @@ -1,400 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_CURSOR -# include -# include -#endif - -/* local function prototypes */ -#ifdef ECORE_XCB_CURSOR -static xcb_render_pictforminfo_t *_ecore_xcb_cursor_format_get(void); -#endif -static void _ecore_xcb_cursor_default_size_get(void); -static void _ecore_xcb_cursor_dpi_size_get(void); -static void _ecore_xcb_cursor_guess_size(void); -#ifdef ECORE_XCB_CURSOR -static Ecore_X_Cursor _ecore_xcb_cursor_image_load_cursor(xcb_image_t *img, - int hot_x, - int hot_y); -#endif -static void _ecore_xcb_cursor_image_destroy(xcb_image_t *img); - -/* local variables */ -static int _ecore_xcb_cursor_size = 0; -static Eina_Bool _ecore_xcb_cursor = EINA_FALSE; -#ifdef ECORE_XCB_CURSOR -static uint32_t _ecore_xcb_cursor_format_id = 0; -// static xcb_render_pictforminfo_t *_ecore_xcb_cursor_format = NULL; -#endif - -void -_ecore_xcb_cursor_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - /* NB: No-op */ -} - -void -_ecore_xcb_cursor_finalize(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_CURSOR - _ecore_xcb_cursor = _ecore_xcb_render_argb_get(); - - /* find render pict format */ - if (_ecore_xcb_cursor_format_id <= 0) - _ecore_xcb_cursor_format_id = _ecore_xcb_cursor_format_get()->id; -#endif - - /* try to grab cursor size from XDefaults */ - _ecore_xcb_cursor_default_size_get(); - - /* if that failed, try to get it from Xft Dpi setting */ - if (_ecore_xcb_cursor_size == 0) - _ecore_xcb_cursor_dpi_size_get(); - - /* if that failed, try to guess from display size */ - if (_ecore_xcb_cursor_size == 0) - _ecore_xcb_cursor_guess_size(); - - /* NB: Would normally add theme stuff here, but E cursor does not support - * xcursor themes. Delay parsing that stuff out until such time if/when the - * user selects to use X Cursor, rather than E cursor */ -} - -EAPI Eina_Bool -ecore_x_cursor_color_supported_get(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_cursor; -} - -EAPI Ecore_X_Cursor -ecore_x_cursor_new(Ecore_X_Window win, - int *pixels, - int w, - int h, - int hot_x, - int hot_y) -{ - Ecore_X_Cursor cursor = 0; - xcb_image_t *img; - -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_CURSOR - if (_ecore_xcb_cursor) - { - img = _ecore_xcb_image_create_native(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, - 32, NULL, (w * h * sizeof(int)), - (uint8_t *)pixels); - cursor = _ecore_xcb_cursor_image_load_cursor(img, hot_x, hot_y); - _ecore_xcb_cursor_image_destroy(img); - return cursor; - } - else -#endif - { - Ecore_X_GC gc; - xcb_pixmap_t pmap, mask; - uint32_t *pix; - uint8_t fr = 0x00, fg = 0x00, fb = 0x00; - uint8_t br = 0xff, bg = 0xff, bb = 0xff; - uint32_t brightest = 0, darkest = 255 * 3; - uint16_t x, y; - const uint32_t dither[2][2] = - { - {0, 2}, - {3, 1} - }; - - img = _ecore_xcb_image_create_native(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, - 1, NULL, ~0, NULL); - if (img->data) free(img->data); - img->data = malloc(img->size); - - pmap = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, 1, pmap, win, w, h); - mask = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, 1, mask, win, w, h); - - 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(img, x, y, v); - pix++; - } - } - - gc = ecore_x_gc_new(pmap, 0, NULL); - xcb_put_image(_ecore_xcb_conn, img->format, pmap, gc, w, h, - 0, 0, 0, img->depth, img->size, img->data); - ecore_x_gc_free(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(img, x, y, v); - pix++; - } - } - - gc = ecore_x_gc_new(mask, 0, NULL); - xcb_put_image(_ecore_xcb_conn, img->format, mask, gc, w, h, - 0, 0, 0, img->depth, img->size, img->data); - ecore_x_gc_free(gc); - - if (img->data) free(img->data); - _ecore_xcb_cursor_image_destroy(img); - - cursor = xcb_generate_id(_ecore_xcb_conn); - xcb_create_cursor(_ecore_xcb_conn, cursor, pmap, 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, pmap); - xcb_free_pixmap(_ecore_xcb_conn, mask); - - return cursor; - } - - return 0; -} - -EAPI void -ecore_x_cursor_free(Ecore_X_Cursor c) -{ -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_free_cursor(_ecore_xcb_conn, 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) -{ - Ecore_X_Cursor cursor = 0; - xcb_font_t font; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - font = xcb_generate_id(_ecore_xcb_conn); - xcb_open_font(_ecore_xcb_conn, font, strlen("cursor"), "cursor"); - - cursor = xcb_generate_id(_ecore_xcb_conn); - /* FIXME: Add request check ?? */ - 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_cursor_size = size; - /* NB: May need to adjust size of current cursors here */ -} - -EAPI int -ecore_x_cursor_size_get(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_cursor_size; -} - -/* local functions */ -#ifdef ECORE_XCB_CURSOR -static xcb_render_pictforminfo_t * -_ecore_xcb_cursor_format_get(void) -{ - const xcb_render_query_pict_formats_reply_t *reply; - xcb_render_pictforminfo_t *ret = NULL; - - CHECK_XCB_CONN; - - reply = xcb_render_util_query_formats(_ecore_xcb_conn); - if (reply) - ret = xcb_render_util_find_standard_format(reply, - XCB_PICT_STANDARD_ARGB_32); - - return ret; -} - -#endif - -static void -_ecore_xcb_cursor_default_size_get(void) -{ - char *s = NULL; - int v = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - s = getenv("XCURSOR_SIZE"); - if (!s) - { - _ecore_xcb_xdefaults_init(); - v = _ecore_xcb_xdefaults_int_get("Xcursor", "size"); - _ecore_xcb_xdefaults_shutdown(); - } - else - v = atoi(s); - if (v) _ecore_xcb_cursor_size = ((v * 16) / 72); -} - -static void -_ecore_xcb_cursor_dpi_size_get(void) -{ - int v = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_xdefaults_init(); - v = _ecore_xcb_xdefaults_int_get("Xft", "dpi"); - if (v) _ecore_xcb_cursor_size = ((v * 16) / 72); - _ecore_xcb_xdefaults_shutdown(); -} - -static void -_ecore_xcb_cursor_guess_size(void) -{ - int w = 0, h = 0, s = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_screen_size_get(_ecore_xcb_screen, &w, &h); - if (h < w) s = h; - else s = w; - _ecore_xcb_cursor_size = (s / 48); -} - -#ifdef ECORE_XCB_CURSOR -static Ecore_X_Cursor -_ecore_xcb_cursor_image_load_cursor(xcb_image_t *img, - int hot_x, - int hot_y) -{ - Ecore_X_Cursor cursor = 0; - Ecore_X_GC gc; - xcb_pixmap_t pmap; - xcb_render_picture_t pict; - - CHECK_XCB_CONN; - - pmap = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, img->depth, pmap, - ((xcb_screen_t *)_ecore_xcb_screen)->root, - img->width, img->height); - - gc = ecore_x_gc_new(pmap, 0, NULL); - xcb_put_image(_ecore_xcb_conn, img->format, pmap, gc, - img->width, img->height, 0, 0, 0, img->depth, - img->size, img->data); - ecore_x_gc_free(gc); - - pict = xcb_generate_id(_ecore_xcb_conn); - xcb_render_create_picture(_ecore_xcb_conn, pict, pmap, - _ecore_xcb_cursor_format_id, 0, NULL); - xcb_free_pixmap(_ecore_xcb_conn, pmap); - - cursor = xcb_generate_id(_ecore_xcb_conn); - xcb_render_create_cursor(_ecore_xcb_conn, cursor, pict, hot_x, hot_y); - xcb_render_free_picture(_ecore_xcb_conn, pict); - - return cursor; -} - -#endif - -static void -_ecore_xcb_cursor_image_destroy(xcb_image_t *img) -{ - CHECK_XCB_CONN; - if (img) xcb_image_destroy(img); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_damage.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_damage.c deleted file mode 100644 index deb3b9cb49..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_damage.c +++ /dev/null @@ -1,155 +0,0 @@ -#include "ecore_xcb_private.h" -# ifdef ECORE_XCB_DAMAGE -# include -# endif - -/* local variables */ -static Eina_Bool _damage_avail = EINA_FALSE; - -/* external variables */ -int _ecore_xcb_event_damage = -1; - -void -_ecore_xcb_damage_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_DAMAGE - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_damage_id); -#endif -} - -void -_ecore_xcb_damage_finalize(void) -{ -#ifdef ECORE_XCB_DAMAGE - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_DAMAGE - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_damage_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_damage_query_version_cookie_t cookie; - xcb_damage_query_version_reply_t *reply; - - cookie = - xcb_damage_query_version_unchecked(_ecore_xcb_conn, - XCB_DAMAGE_MAJOR_VERSION, - XCB_DAMAGE_MINOR_VERSION); - reply = xcb_damage_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - _damage_avail = EINA_TRUE; - free(reply); - } - - if (_damage_avail) - _ecore_xcb_event_damage = ext_reply->first_event; - } -#endif -} - -/** - * @defgroup Ecore_X_Damage_Group X Damage Extension Functions - * - * Functions related to the X Damage Extension. - */ - -EAPI Eina_Bool -ecore_x_damage_query(void) -{ - return _damage_avail; -} - -/** - * Create a damage object - * - * @param drawable The drawable to monitor - * @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; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_damage_avail) return 0; - -#ifdef ECORE_XCB_DAMAGE - damage = xcb_generate_id(_ecore_xcb_conn); - xcb_damage_create(_ecore_xcb_conn, damage, drawable, level); -// ecore_x_flush(); -#endif - - return damage; -} - -/** - * Destroy 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_damage_avail) return; - -#ifdef ECORE_XCB_DAMAGE - xcb_damage_destroy(_ecore_xcb_conn, damage); -// ecore_x_flush(); -#endif -} - -/** - * 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 = \ - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_damage_avail) return; - -#ifdef ECORE_XCB_DAMAGE - xcb_damage_subtract(_ecore_xcb_conn, damage, repair, parts); -// ecore_x_flush(); -#endif -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_dnd.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_dnd.c deleted file mode 100644 index 80ae6b4c5d..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_dnd.c +++ /dev/null @@ -1,688 +0,0 @@ -#include "ecore_xcb_private.h" - -#ifndef MIN -# define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -/* local structures */ -typedef struct _Version_Cache_Item -{ - Ecore_X_Window win; - int ver; -} Version_Cache_Item; - -/* local function prototypes */ -static Eina_Bool _ecore_xcb_dnd_converter_copy(char *target EINA_UNUSED, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *tprop EINA_UNUSED, - int *count EINA_UNUSED); - -/* local variables */ -static int _ecore_xcb_dnd_init_count = 0; -static Ecore_X_DND_Source *_source = NULL; -static Ecore_X_DND_Target *_target = NULL; -static Version_Cache_Item *_version_cache = NULL; -static int _version_cache_num = 0, _version_cache_alloc = 0; -static void (*_posupdatecb)(void *, - Ecore_X_Xdnd_Position *); -static void *_posupdatedata; - -/* external variables */ -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; - -void -_ecore_xcb_dnd_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!_ecore_xcb_dnd_init_count) - { - _source = calloc(1, sizeof(Ecore_X_DND_Source)); - if (!_source) return; - _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)); - if (!_target) - { - free(_source); - _source = NULL; - return; - } - _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_xcb_dnd_init_count++; -} - -void -_ecore_xcb_dnd_shutdown(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_dnd_init_count--; - if (_ecore_xcb_dnd_init_count > 0) return; - if (_source) free(_source); - _source = NULL; - if (_target) free(_target); - _target = NULL; - _ecore_xcb_dnd_init_count = 0; -} - -EAPI void -ecore_x_dnd_send_status(Eina_Bool will_accept, - Eina_Bool suppress, - Ecore_X_Rectangle rect, - Ecore_X_Atom action) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (_target->state == ECORE_X_DND_TARGET_IDLE) return; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - _target->will_accept = will_accept; - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.type = ECORE_X_ATOM_XDND_STATUS; - ev.format = 32; - ev.window = _target->source; - 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; - - ev.data.data32[2] = rect.x; - ev.data.data32[2] <<= 16; - ev.data.data32[2] |= rect.y; - ev.data.data32[3] = rect.width; - ev.data.data32[3] <<= 16; - ev.data.data32[3] |= rect.height; - - if (will_accept) - ev.data.data32[4] = action; - else - ev.data.data32[4] = XCB_NONE; - _target->accepted_action = action; - - xcb_send_event(_ecore_xcb_conn, 0, _target->source, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); -} - -EAPI Eina_Bool -ecore_x_dnd_drop(void) -{ - xcb_client_message_event_t ev; - Eina_Bool status = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - if (_source->dest) - { - 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, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - _source->state = ECORE_X_DND_SOURCE_DROPPED; - status = EINA_TRUE; - } - 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, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - _source->state = ECORE_X_DND_SOURCE_IDLE; - } - } - else - { - 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_aware_set(Ecore_X_Window win, - Eina_Bool 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, - ECORE_X_ATOM_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 *data; - int num = 0; - Version_Cache_Item *t; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (_source->state == ECORE_X_DND_SOURCE_DRAGGING) - { - if (_version_cache) - { - int i = 0; - - 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, - ECORE_X_ATOM_ATOM, 32, &data, &num)) - { - int version = 0; - - version = (int)*data; - free(data); - if (_source->state == ECORE_X_DND_SOURCE_DRAGGING) - { - _version_cache_num++; - if (_version_cache_num > _version_cache_alloc) - _version_cache_alloc += 16; - t = realloc(_version_cache, - _version_cache_alloc * sizeof(Version_Cache_Item)); - if (!t) return 0; - _version_cache = t; - _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; - t = realloc(_version_cache, - _version_cache_alloc * sizeof(Version_Cache_Item)); - if (!t) return 0; - _version_cache = t; - _version_cache[_version_cache_num - 1].win = win; - _version_cache[_version_cache_num - 1].ver = 0; - } - - return 0; -} - -EAPI Eina_Bool -ecore_x_dnd_type_isset(Ecore_X_Window win, - const char *type) -{ - int num = 0, i = 0; - Eina_Bool ret = EINA_FALSE; - unsigned char *data; - Ecore_X_Atom *atoms, atom; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_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 = EINA_TRUE; - break; - } - } - - free(data); - return ret; -} - -EAPI void -ecore_x_dnd_type_set(Ecore_X_Window win, - const char *type, - Eina_Bool on) -{ - Ecore_X_Atom atom, *oldset = NULL, *newset = NULL; - int i = 0, j = 0, num = 0; - unsigned char *data = NULL, *old_data = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - atom = ecore_x_atom_get(type); - ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, 32, &old_data, &num); - oldset = (Ecore_X_Atom *)old_data; - if (on) - { - if (ecore_x_dnd_type_isset(win, type)) - { - free(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]; - newset[0] = atom; - ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, 32, data, num + 1); - } - else - { - if (!ecore_x_dnd_type_isset(win, 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(win, ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, 32, data, num - 1); - } - free(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__); - CHECK_XCB_CONN; - - 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_xcb_dnd_converter_copy); - } - ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_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__); - CHECK_XCB_CONN; - - 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_xcb_dnd_converter_copy); - ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_ACTION_LIST, - ECORE_X_ATOM_ATOM, 32, data, - num_actions); - } -} - -/** - * The DND position update cb is called Ecore_X sends a DND position to a - * client. - * - * It essentially mirrors some of the data sent in the position message. - * Generally this cb should be set just before position update is called. - * Please note well you need to look after your own data pointer if someone - * trashes you position update cb set. - * - * It is considered good form to clear this when the dnd event finishes. - * - * @param cb Callback to updated each time ecore_x sends a position update. - * @param data User data. - */ -EAPI void -ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *data), - const void *data) -{ - _posupdatecb = cb; - _posupdatedata = (void *)data; -} - -EAPI Eina_Bool -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 EINA_FALSE; - - /* Take ownership of XdndSelection */ - if (!ecore_x_selection_xdnd_set(source, data, size)) return EINA_FALSE; - - 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_xcb_events_last_time_get(); - _source->prev.window = 0; - - /* Default Accepted Action: move */ - _source->action = ECORE_X_ATOM_XDND_ACTION_MOVE; - _source->accepted_action = XCB_NONE; - _source->dest = XCB_NONE; - - return EINA_TRUE; -} - -EAPI void -ecore_x_dnd_send_finished(void) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (_target->state == ECORE_X_DND_TARGET_IDLE) return; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.type = ECORE_X_ATOM_XDND_FINISHED; - ev.window = _target->source; - 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, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - _target->state = ECORE_X_DND_TARGET_IDLE; -} - -EAPI void -ecore_x_dnd_source_action_set(Ecore_X_Atom action) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _source->action = action; - if (_source->prev.window) - _ecore_xcb_dnd_drag(_source->prev.window, - _source->prev.x, _source->prev.y); -} - -Ecore_X_DND_Source * -_ecore_xcb_dnd_source_get(void) -{ - return _source; -} - -Ecore_X_DND_Target * -_ecore_xcb_dnd_target_get(void) -{ - return _target; -} - -void -_ecore_xcb_dnd_drag(Ecore_X_Window root, - int x, - int y) -{ - xcb_client_message_event_t ev; - Ecore_X_Window win, *skip; - Ecore_X_Xdnd_Position pos; - int num = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) return; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - - skip = ecore_x_window_ignore_list(&num); - win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num); - while ((win) && !(ecore_x_dnd_version_get(win))) - win = ecore_x_window_shadow_parent_get(root, win); - - 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, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - _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 = 0; - unsigned char *data; - Ecore_X_Atom *types; - - ecore_x_window_prop_property_get(_source->win, - ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, 32, - &data, &num); - types = (Ecore_X_Atom *)data; - 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, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - _source->await_status = 0; - _source->will_accept = 0; - } - - 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; - ev.data.data32[2] = ((x << 16) & 0xffff0000) | (y & 0xffff); - ev.data.data32[3] = _source->time; - ev.data.data32[4] = _source->action; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - _source->await_status = 1; - } - } - - if (_posupdatecb) - { - pos.position.x = x; - pos.position.y = y; - pos.win = win; - pos.prev = _source->dest; - _posupdatecb(_posupdatedata, &pos); - } - - _source->prev.x = x; - _source->prev.y = y; - _source->prev.window = root; - _source->dest = win; -} - -EAPI Ecore_X_Atom -ecore_x_dnd_source_action_get(void) -{ - return _source->action; -} - -/* local functions */ -static Eina_Bool -_ecore_xcb_dnd_converter_copy(char *target EINA_UNUSED, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *tprop EINA_UNUSED, - int *count EINA_UNUSED) -{ - Ecore_Xcb_Textproperty text_prop; - Ecore_Xcb_Encoding_Style style = XcbTextStyle; - char *mystr; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!data) || (!size)) return EINA_FALSE; - - mystr = calloc(1, size + 1); - if (!mystr) return EINA_FALSE; - - memcpy(mystr, data, size); - if (_ecore_xcb_mb_textlist_to_textproperty(&mystr, 1, style, &text_prop)) - { - int len; - - len = strlen((char *)text_prop.value) + 1; - if (!(*data_ret = malloc(len))) - { - free(mystr); - return EINA_FALSE; - } - memcpy(*data_ret, text_prop.value, len); - *size_ret = len; - free(text_prop.value); - free(mystr); - return EINA_TRUE; - } - else - { - free(mystr); - return EINA_FALSE; - } -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_dpms.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_dpms.c deleted file mode 100644 index 39ef589dd1..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_dpms.c +++ /dev/null @@ -1,320 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_DAMAGE -# include -#endif - -/* local variables */ -static Eina_Bool _dpms_avail = EINA_FALSE; - -void -_ecore_xcb_dpms_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_DPMS - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_dpms_id); -#endif -} - -void -_ecore_xcb_dpms_finalize(void) -{ -#ifdef ECORE_XCB_DPMS - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_DPMS - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dpms_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_dpms_get_version_cookie_t cookie; - xcb_dpms_get_version_reply_t *reply; - - cookie = - xcb_dpms_get_version_unchecked(_ecore_xcb_conn, - XCB_DPMS_MAJOR_VERSION, - XCB_DPMS_MINOR_VERSION); - reply = xcb_dpms_get_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - if (reply->server_major_version >= 1) - _dpms_avail = EINA_TRUE; - free(reply); - } - } -#endif -} - -/** - * @defgroup Ecore_X_DPMS_Group X DPMS Extension Functions - * - * Functions related to the X DPMS Extension - */ - -/** - * Checks if the DPMS extension is available or not. - * - * @return @c EINA_TRUE if the DPMS extension is available, - * @c EINA_FALSE otherwise. - * - * Return @c EINA_TRUE if the X server supports the DPMS Extension version 1.0, - * @c EINA_FALSE otherwise. - * - * @ingroup Ecore_X_DPMS_Group - */ -EAPI Eina_Bool -ecore_x_dpms_query(void) -{ -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _dpms_avail; -} - -/** - * 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 Eina_Bool -ecore_x_dpms_capable_get(void) -{ - Eina_Bool ret = EINA_FALSE; -#ifdef ECORE_XCB_DPMS - xcb_dpms_capable_cookie_t cookie; - xcb_dpms_capable_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_dpms_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_DPMS - cookie = xcb_dpms_capable_unchecked(_ecore_xcb_conn); - reply = xcb_dpms_capable_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - ret = reply->capable; - free(reply); - } -#endif - - return ret; -} - -/** - * Checks the DPMS state of the display. - * @return @c EINA_TRUE if DPMS is enabled, @c EINA_FALSE otherwise. - * @ingroup Ecore_X_DPMS_Group - */ -EAPI Eina_Bool -ecore_x_dpms_enabled_get(void) -{ - Eina_Bool ret = EINA_FALSE; -#ifdef ECORE_XCB_DPMS - xcb_dpms_info_cookie_t cookie; - xcb_dpms_info_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_dpms_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_DPMS - cookie = xcb_dpms_info_unchecked(_ecore_xcb_conn); - reply = xcb_dpms_info_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - if (reply->state) ret = EINA_TRUE; - free(reply); -#endif - - return ret; -} - -/** - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_dpms_avail) return; - -#ifdef ECORE_XCB_DPMS - if (enabled) - xcb_dpms_enable(_ecore_xcb_conn); - else - xcb_dpms_disable(_ecore_xcb_conn); -#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_XCB_DPMS - xcb_dpms_get_timeouts_cookie_t cookie; - xcb_dpms_get_timeouts_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (standby) *standby = 0; - if (suspend) *suspend = 0; - if (off) *off = 0; - - if (!_dpms_avail) return; - -#ifdef ECORE_XCB_DPMS - cookie = xcb_dpms_get_timeouts_unchecked(_ecore_xcb_conn); - reply = xcb_dpms_get_timeouts_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - if (standby) *standby = reply->standby_timeout; - if (suspend) *suspend = reply->suspend_timeout; - if (off) *off = reply->off_timeout; - free(reply); -#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. - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. - * @ingroup Ecore_X_DPMS_Group - */ -EAPI Eina_Bool -ecore_x_dpms_timeouts_set(unsigned int standby, - unsigned int suspend, - unsigned int off) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_dpms_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_DPMS - // FIXME: Add request check - xcb_dpms_set_timeouts(_ecore_xcb_conn, standby, suspend, off); - return EINA_TRUE; -#endif - - return EINA_FALSE; -} - -/** - * 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(void) -{ - unsigned int standby = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_dpms_timeouts_get(&standby, NULL, NULL); - return standby; -} - -/** - * 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(void) -{ - unsigned int suspend = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_dpms_timeouts_get(NULL, &suspend, NULL); - 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. - * @ingroup Ecore_X_DPMS_Group - */ -EAPI unsigned int -ecore_x_dpms_timeout_off_get(void) -{ - unsigned int off = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_dpms_timeouts_get(NULL, NULL, &off); - return off; -} - -/** - * Sets the standby timeout (in unit of seconds). - * @param new_timeout 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) -{ - unsigned int standby = 0, suspend = 0, off = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_dpms_timeouts_get(&standby, &suspend, &off); - ecore_x_dpms_timeouts_set(new_timeout, suspend, off); -} - -/** - * Sets the suspend timeout (in unit of seconds). - * @param new_timeout 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) -{ - unsigned int standby = 0, suspend = 0, off = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_dpms_timeouts_get(&standby, &suspend, &off); - ecore_x_dpms_timeouts_set(standby, new_timeout, off); -} - -/** - * Sets the off timeout (in unit of seconds). - * @param new_timeout 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) -{ - unsigned int standby = 0, suspend = 0, off = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_dpms_timeouts_get(&standby, &suspend, &off); - ecore_x_dpms_timeouts_set(standby, suspend, new_timeout); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_drawable.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_drawable.c deleted file mode 100644 index 4e9a3564ce..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_drawable.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "ecore_xcb_private.h" - -/** - * @defgroup Ecore_X_Drawable_Group X Drawable Functions - * - * Functions that operate on drawables. - */ - -/** - * 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 draw, - Ecore_X_GC gc, - int x, - int y, - int w, - int h) -{ - xcb_rectangle_t rect; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_poly_fill_rectangle(_ecore_xcb_conn, draw, gc, 1, - (const xcb_rectangle_t *)&rect); -// ecore_x_flush(); -} - -/** - * 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 draw, - int *x, - int *y, - int *w, - int *h) -{ - xcb_get_geometry_cookie_t cookie; - xcb_get_geometry_reply_t *reply; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = 0; - if (h) *h = 0; - cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, draw); - reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - if (x) *x = reply->x; - if (y) *y = reply->y; - if (w) *w = (int)reply->width; - if (h) *h = (int)reply->height; - free(reply); -} - -/** - * 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) -{ - xcb_get_geometry_cookie_t cookie; - xcb_get_geometry_reply_t *reply; - int ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, d); - reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - ret = (int)reply->border_width; - free(reply); - return 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) -{ - xcb_get_geometry_cookie_t cookie; - xcb_get_geometry_reply_t *reply; - int ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, d); - reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - ret = (int)reply->depth; - free(reply); - return ret; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_e.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_e.c deleted file mode 100644 index 82d94b634f..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_e.c +++ /dev/null @@ -1,1576 +0,0 @@ -#include "ecore_xcb_private.h" - -/* local function prototypes */ -static Ecore_X_Atom _ecore_xcb_e_vkbd_atom_get(Ecore_X_Virtual_Keyboard_State state); -static Ecore_X_Virtual_Keyboard_State _ecore_xcb_e_vkbd_state_get(Ecore_X_Atom atom); -static Ecore_X_Atom _ecore_xcb_e_quickpanel_atom_get(Ecore_X_Illume_Quickpanel_State state); -static Ecore_X_Illume_Quickpanel_State _ecore_xcb_e_quickpanel_state_get(Ecore_X_Atom atom); -static Ecore_X_Atom _ecore_xcb_e_illume_atom_get(Ecore_X_Illume_Mode mode); -static Ecore_X_Illume_Mode _ecore_xcb_e_illume_mode_get(Ecore_X_Atom atom); -static Ecore_X_Atom _ecore_xcb_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state); -static Ecore_X_Illume_Indicator_State _ecore_xcb_e_indicator_state_get(Ecore_X_Atom atom); - -EAPI void -ecore_x_e_init(void) -{ -} - -EAPI void -ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root, - Ecore_X_Window win) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE; - ev.data.data32[0] = win; - ev.data.data32[1] = 0; - ev.data.data32[2] = 0; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, root, - (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); -// ecore_x_flush(); -} - -EAPI void -ecore_x_e_comp_sync_draw_size_done_send(Ecore_X_Window root, - Ecore_X_Window win, - int w, - int h) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE; - ev.data.data32[0] = win; - ev.data.data32[1] = 1; - ev.data.data32[2] = w; - ev.data.data32[3] = h; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, root, - (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); -// ecore_x_flush(); -} - -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) -{ - Ecore_X_Sync_Counter counter = 0; - int ret = 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 Eina_Bool -ecore_x_e_comp_sync_supported_get(Ecore_X_Window root) -{ - Ecore_X_Window win, win2; - int ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - 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 EINA_TRUE; - } - return EINA_FALSE; -} - -EAPI void -ecore_x_e_window_profile_list_set(Ecore_X_Window win, - const char **profiles, - unsigned int num_profiles) -{ - Ecore_X_Atom *atoms; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!win) - return; - - if (!num_profiles) - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE_LIST); - else - { - atoms = alloca(num_profiles * sizeof(Ecore_X_Atom)); - ecore_x_atoms_get(profiles, num_profiles, atoms); - ecore_x_window_prop_property_set(win, - ECORE_X_ATOM_E_PROFILE_LIST, - ECORE_X_ATOM_ATOM, 32, (void *)atoms, - num_profiles); - } -} - -EAPI Eina_Bool -ecore_x_e_window_profile_list_get(Ecore_X_Window win, - const char ***profiles, - int *ret_num) -{ - unsigned char *data = NULL; - Ecore_X_Atom *atoms; - int num, i; - - if (ret_num) - *ret_num = 0; - - if (profiles) - *profiles = NULL; - - if (!win) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ecore_x_window_prop_property_get(win, - ECORE_X_ATOM_E_PROFILE_LIST, - ECORE_X_ATOM_ATOM, 32, &data, &num)) - return EINA_FALSE; - - if (ret_num) - *ret_num = num; - - if (profiles) - { - (*profiles) = calloc(num, sizeof(char *)); - if (!(*profiles)) - { - if (ret_num) - *ret_num = 0; - - if (data) - free(data); - - return EINA_FALSE; - } - - atoms = (Ecore_X_Atom *)data; - for (i = 0; i < num; i++) - (*profiles)[i] = ecore_x_atom_name_get(atoms[i]); - } - - if (data) - free(data); - - return EINA_TRUE; -} - -EAPI void -ecore_x_e_window_profile_set(Ecore_X_Window win, - const char *profile) -{ - Ecore_X_Atom atom; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!win) - return; - - if (!profile) - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE); - else - { - atom = ecore_x_atom_get(profile); - ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_PROFILE, - ECORE_X_ATOM_ATOM, 32, (void *)&atom, 1); - } -} - -EAPI char * -ecore_x_e_window_profile_get(Ecore_X_Window win) -{ - Ecore_X_Atom *atom = NULL; - unsigned char *data; - char *profile = NULL; - int num; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_PROFILE, - ECORE_X_ATOM_ATOM, 32, &data, &num)) - return NULL; - - if (data) - atom = (Ecore_X_Atom *)data; - - if (atom) - profile = ecore_x_atom_name_get(atom[0]); - - return profile; -} - -EAPI void -ecore_x_e_comp_sync_supported_set(Ecore_X_Window root, - Eina_Bool enabled) -{ - Ecore_X_Window win; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - 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 = 0; - - 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 void -ecore_x_e_comp_sync_begin_send(Ecore_X_Window win) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_E_COMP_SYNC_BEGIN; - ev.data.data32[0] = win; - ev.data.data32[1] = 0; - ev.data.data32[2] = 0; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); -} - -EAPI void -ecore_x_e_comp_sync_end_send(Ecore_X_Window win) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_E_COMP_SYNC_END; - ev.data.data32[0] = win; - ev.data.data32[1] = 0; - ev.data.data32[2] = 0; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); -} - -EAPI void -ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_E_COMP_SYNC_CANCEL; - ev.data.data32[0] = win; - ev.data.data32[1] = 0; - ev.data.data32[2] = 0; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); -} - -EAPI void -ecore_x_e_comp_flush_send(Ecore_X_Window win) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_E_COMP_FLUSH; - ev.data.data32[0] = win; - ev.data.data32[1] = 0; - ev.data.data32[2] = 0; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); -} - -EAPI void -ecore_x_e_comp_dump_send(Ecore_X_Window win) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_E_COMP_DUMP; - ev.data.data32[0] = win; - ev.data.data32[1] = 0; - ev.data.data32[2] = 0; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); -} - -EAPI void -ecore_x_e_comp_pixmap_set(Ecore_X_Window win, - Ecore_X_Pixmap pixmap) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (pixmap) - ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_PIXMAP, - ECORE_X_ATOM_PIXMAP, &pixmap, 1); - else - ecore_x_window_prop_property_del(win, pixmap); -} - -EAPI Ecore_X_Pixmap -ecore_x_e_comp_pixmap_get(Ecore_X_Window win) -{ - Ecore_X_Pixmap pixmap = 0; - int ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ret = ecore_x_window_prop_xid_get(win, ECORE_X_ATOM_E_COMP_PIXMAP, - ECORE_X_ATOM_PIXMAP, &pixmap, 1); - if (ret != 1) return 0; - return pixmap; -} - -EAPI void -ecore_x_e_frame_size_set(Ecore_X_Window win, - int fl, - int fr, - int ft, - int fb) -{ - uint32_t 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 Ecore_X_Virtual_Keyboard_State -ecore_x_e_virtual_keyboard_state_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_VIRTUAL_KEYBOARD_STATE, - &atom, 1)) - return ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN; - - return _ecore_xcb_e_vkbd_state_get(atom); -} - -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_xcb_e_vkbd_atom_get(state); - ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE, - &atom, 1); -} - -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_xcb_e_vkbd_atom_get(state), - 0, 0, 0, 0); -} - -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 Eina_Bool -ecore_x_e_virtual_keyboard_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_VIRTUAL_KEYBOARD, - &val, 1)) - return EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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_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_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_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 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 Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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 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 Eina_Bool -ecore_x_e_illume_softkey_geometry_get(Ecore_X_Window win, - int *x, - int *y, - int *w, - int *h) -{ - unsigned int geom[4]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = 0; - if (h) *h = 0; - - if (ecore_x_window_prop_card32_get(win, - ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY, - geom, 4) != 4) - return EINA_FALSE; - - if (x) *x = geom[0]; - if (y) *y = geom[1]; - if (w) *w = geom[2]; - if (h) *h = geom[3]; - - return EINA_TRUE; -} - -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 Eina_Bool -ecore_x_e_illume_indicator_geometry_get(Ecore_X_Window win, - int *x, - int *y, - int *w, - int *h) -{ - unsigned int geom[4]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = 0; - if (h) *h = 0; - - if (ecore_x_window_prop_card32_get(win, - ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY, - geom, 4) != 4) - return EINA_FALSE; - - if (x) *x = geom[0]; - if (y) *y = geom[1]; - if (w) *w = geom[2]; - if (h) *h = geom[3]; - - return EINA_TRUE; -} - -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 Eina_Bool -ecore_x_e_illume_keyboard_geometry_get(Ecore_X_Window win, - int *x, - int *y, - int *w, - int *h) -{ - unsigned int geom[4]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = 0; - if (h) *h = 0; - - if (ecore_x_window_prop_card32_get(win, - ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY, - geom, 4) != 4) - return EINA_FALSE; - - if (x) *x = geom[0]; - if (y) *y = geom[1]; - if (w) *w = geom[2]; - if (h) *h = geom[3]; - - return EINA_TRUE; -} - -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 Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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_xcb_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 = 0; - - 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_xcb_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_xcb_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); -} - -static Ecore_X_Atom -_ecore_xcb_e_clipboard_atom_get(Ecore_X_Illume_Clipboard_State state) -{ - switch (state) - { - case ECORE_X_ILLUME_CLIPBOARD_STATE_ON: - return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON; - case ECORE_X_ILLUME_CLIPBOARD_STATE_OFF: - return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF; - default: - break; - } - return 0; -} - -static Ecore_X_Illume_Clipboard_State -_ecore_xcb_e_clipboard_state_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON) - return ECORE_X_ILLUME_CLIPBOARD_STATE_ON; - - if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF) - return ECORE_X_ILLUME_CLIPBOARD_STATE_OFF; - - return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; -} - -EAPI void -ecore_x_e_illume_clipboard_state_set(Ecore_X_Window win, - Ecore_X_Illume_Clipboard_State state) -{ - Ecore_X_Atom atom = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - atom = _ecore_xcb_e_clipboard_atom_get(state); - - ecore_x_window_prop_atom_set(win, - ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE, - &atom, 1); -} - -EAPI Ecore_X_Illume_Clipboard_State -ecore_x_e_illume_clipboard_state_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_CLIPBOARD_STATE, - &atom, 1)) - return ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN; - return _ecore_xcb_e_clipboard_state_get(atom); -} - -EAPI void -ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY, - geom, 4); -} - -EAPI Eina_Bool -ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY, - geom, 4); - if (ret != 4) return EINA_FALSE; - - if (x) *x = geom[0]; - if (y) *y = geom[1]; - if (w) *w = geom[2]; - if (h) *h = geom[3]; - - return EINA_TRUE; -} - -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_xcb_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_xcb_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_xcb_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_access_action_next_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_read_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_up_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_down_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN, - 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 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 Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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_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 num) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_window_prop_window_set(win, ECORE_X_ATOM_E_ILLUME_ZONE_LIST, - zones, num); -} - -/* local functions */ -static Ecore_X_Atom -_ecore_xcb_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: - break; - } - return 0; -} - -static Ecore_X_Virtual_Keyboard_State -_ecore_xcb_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_xcb_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: - break; - } - return 0; -} - -static Ecore_X_Illume_Quickpanel_State -_ecore_xcb_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; -} - -static Ecore_X_Atom -_ecore_xcb_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: - break; - } - return ECORE_X_ILLUME_MODE_UNKNOWN; -} - -static Ecore_X_Illume_Mode -_ecore_xcb_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; -} - -static Ecore_X_Atom -_ecore_xcb_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state) -{ - switch (state) - { - case ECORE_X_ILLUME_INDICATOR_STATE_ON: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_ON; - - case ECORE_X_ILLUME_INDICATOR_STATE_OFF: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF; - - default: - break; - } - return 0; -} - -static Ecore_X_Illume_Indicator_State -_ecore_xcb_e_indicator_state_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_ON) - return ECORE_X_ILLUME_INDICATOR_STATE_ON; - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF) - return ECORE_X_ILLUME_INDICATOR_STATE_OFF; - - return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; -} - -EAPI void -ecore_x_e_illume_indicator_state_set(Ecore_X_Window win, - Ecore_X_Illume_Indicator_State state) -{ - Ecore_X_Atom atom = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - atom = _ecore_xcb_e_indicator_atom_get(state); - ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE, - &atom, 1); -} - -EAPI Ecore_X_Illume_Indicator_State -ecore_x_e_illume_indicator_state_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_INDICATOR_STATE, - &atom, 1)) - return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; - - return _ecore_xcb_e_indicator_state_get(atom); -} - -EAPI void -ecore_x_e_illume_indicator_state_send(Ecore_X_Window win, - Ecore_X_Illume_Indicator_State state) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - _ecore_xcb_e_indicator_atom_get(state), - 0, 0, 0, 0); -} - -static Ecore_X_Atom -_ecore_x_e_indicator_opacity_atom_get(Ecore_X_Illume_Indicator_Opacity_Mode mode) -{ - switch (mode) - { - case ECORE_X_ILLUME_INDICATOR_OPAQUE: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE; - - case ECORE_X_ILLUME_INDICATOR_TRANSLUCENT: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT; - - case ECORE_X_ILLUME_INDICATOR_TRANSPARENT: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; - - default: - break; - } - return 0; -} - -static Ecore_X_Illume_Indicator_Opacity_Mode -_ecore_x_e_indicator_opacity_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE) - return ECORE_X_ILLUME_INDICATOR_OPAQUE; - - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT) - return ECORE_X_ILLUME_INDICATOR_TRANSLUCENT; - - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT) - return ECORE_X_ILLUME_INDICATOR_TRANSPARENT; - - return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; -} - -EAPI void -ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win, - Ecore_X_Illume_Indicator_Opacity_Mode mode) -{ - Ecore_X_Atom atom = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - atom = _ecore_x_e_indicator_opacity_atom_get(mode); - ecore_x_window_prop_atom_set(win, - ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE, - &atom, 1); -} - -EAPI Ecore_X_Illume_Indicator_Opacity_Mode -ecore_x_e_illume_indicator_opacity_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_INDICATOR_OPACITY_MODE, - &atom, 1)) - return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; - - return _ecore_x_e_indicator_opacity_get(atom); -} - -EAPI void -ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, - Ecore_X_Illume_Indicator_Opacity_Mode mode) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, - ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - _ecore_x_e_indicator_opacity_atom_get(mode), - 0, 0, 0, 0); -} - -static Ecore_X_Atom -_ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state) -{ - switch (state) - { - case ECORE_X_ILLUME_WINDOW_STATE_NORMAL: - return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL; - - case ECORE_X_ILLUME_WINDOW_STATE_FLOATING: - return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; - - default: - break; - } - return 0; -} - -static Ecore_X_Illume_Window_State -_ecore_x_e_illume_window_state_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL) - return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; - - if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING) - return ECORE_X_ILLUME_WINDOW_STATE_FLOATING; - - return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; -} - -EAPI void -ecore_x_e_illume_window_state_set(Ecore_X_Window win, - Ecore_X_Illume_Window_State state) -{ - Ecore_X_Atom atom = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - atom = _ecore_x_e_illume_window_state_atom_get(state); - ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_WINDOW_STATE, - &atom, 1); -} - -EAPI Ecore_X_Illume_Window_State -ecore_x_e_illume_window_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_WINDOW_STATE, - &atom, 1)) - return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; - - return _ecore_x_e_illume_window_state_get(atom); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_error.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_error.c deleted file mode 100644 index fc329265d5..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_error.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "ecore_xcb_private.h" -#include - -/* local variables */ -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; -static Ecore_X_ID _error_resource_id = 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; -} - -/** - * Get the resource id that caused the error. - * @return The resource id causing the X error - * - * Return the X resource id that caused the last X error - */ -EAPI Ecore_X_ID -ecore_x_error_resource_id_get(void) -{ - return _error_resource_id; -} - -int -_ecore_xcb_error_handle(xcb_generic_error_t *err) -{ - WRN("Got Error:"); - WRN("\tEvent: %s", xcb_event_get_request_label(err->major_code)); - WRN("\tError: %s", xcb_event_get_error_label(err->error_code)); - -#ifdef OLD_XCB_VERSION - if (err->error_code == XCB_EVENT_ERROR_BAD_VALUE) - WRN("\tBad Value: %d", ((xcb_value_error_t *)err)->bad_value); - else if (err->error_code == XCB_EVENT_ERROR_BAD_WINDOW) - WRN("\tBad Window: %d", ((xcb_window_error_t *)err)->bad_value); -#else - if (err->error_code == XCB_VALUE) - WRN("\tBad Value: %d", ((xcb_value_error_t *)err)->bad_value); - else if (err->error_code == XCB_WINDOW) - WRN("\tBad Window: %d", ((xcb_window_error_t *)err)->bad_value); -#endif - - _error_request_code = err->sequence; - _error_code = err->error_code; - _error_resource_id = err->resource_id; - if (_error_func) - _error_func(_error_data); - - return 0; -} - -int -_ecore_xcb_io_error_handle(xcb_generic_error_t *err) -{ - CRIT("IO Error:"); - if (err) - { - CRIT("\tRequest: %d", err->sequence); - CRIT("\tCode: %d", err->error_code); - } - if (_io_error_func) - _io_error_func(_io_error_data); - else - exit(-1); - - return 0; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_events.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_events.c deleted file mode 100644 index 9cc86f62a8..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_events.c +++ /dev/null @@ -1,2824 +0,0 @@ -#include "ecore_xcb_private.h" -//#include "Ecore_X_Atoms.h" -#include -#include -#include -# ifdef ECORE_XCB_DAMAGE -# include -# endif -# ifdef ECORE_XCB_RANDR -# include -# endif -# ifdef ECORE_XCB_SCREENSAVER -# include -# endif -# ifdef ECORE_XCB_SYNC -# include -# endif -# ifdef ECORE_XCB_XFIXES -# include -# endif -# ifdef ECORE_XCB_XGESTURE -# include -# endif - -#ifndef CODESET -# define CODESET "INVALID" -#endif - -typedef struct _Ecore_X_Mouse_Down_Info -{ - EINA_INLIST; - int dev; - Ecore_X_Time last_time; - Ecore_X_Time last_last_time; - Ecore_X_Window last_win; - Ecore_X_Window last_last_win; - Ecore_X_Window last_event_win; - Ecore_X_Window last_last_event_win; - Eina_Bool did_double : 1; - Eina_Bool did_triple : 1; -} Ecore_X_Mouse_Down_Info; - -/* local function prototypes */ -static void _ecore_xcb_event_handle_any_event(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_key_press(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_key_release(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_button_press(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_button_release(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_motion_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_expose(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_map_request(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_client_message(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event); -#ifdef ECORE_XCB_XGESTURE -static void _ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event); -#endif -#ifdef ECORE_XCB_SHAPE -static void _ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event); -#endif -static void _ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event EINA_UNUSED); -static void _ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event); -static void _ecore_xcb_event_handle_input_event(xcb_generic_event_t *event); - -static void _ecore_xcb_event_key_press(xcb_generic_event_t *event); -static void _ecore_xcb_event_key_release(xcb_generic_event_t *event); -static void _ecore_xcb_event_mouse_move_free(void *data EINA_UNUSED, - void *event); -static Ecore_X_Event_Mode _ecore_xcb_event_mode_get(uint8_t mode); -static Ecore_X_Event_Detail _ecore_xcb_event_detail_get(uint8_t detail); -static void _ecore_xcb_event_xdnd_enter_free(void *data EINA_UNUSED, - void *event); -static void _ecore_xcb_event_selection_notify_free(void *data EINA_UNUSED, - void *event); -static void _ecore_xcb_event_generic_event_free(void *data, - void *event); -static void _ecore_xcb_event_mouse_down_info_clear(void); -static Ecore_X_Mouse_Down_Info *_ecore_xcb_event_mouse_down_info_get(int dev); - -/* local variables */ -static Eina_Bool _ecore_xcb_event_last_mouse_move = EINA_FALSE; -//static Ecore_Event *_ecore_xcb_event_last_mouse_move_event = NULL; -static Eina_Inlist *_ecore_xcb_mouse_down_info_list = NULL; -static Ecore_X_Time _ecore_xcb_event_last_time; -static Ecore_X_Window _ecore_xcb_event_last_window = 0; - -/* public variables */ -int16_t _ecore_xcb_event_last_root_x = 0; -int16_t _ecore_xcb_event_last_root_y = 0; - -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_MAPPING_CHANGE = 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_FIXES_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_GESTURE_NOTIFY_FLICK = 0; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN = 0; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = 0; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP = 0; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = 0; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = 0; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_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_XKB_STATE_NOTIFY = 0; -EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0; -EAPI int ECORE_X_EVENT_GENERIC = 0; - -EAPI int ECORE_X_RAW_BUTTON_PRESS = 0; -EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0; -EAPI int ECORE_X_RAW_MOTION = 0; - -void -_ecore_xcb_events_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - 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_MAPPING_CHANGE = 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_FIXES_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_GESTURE_NOTIFY_FLICK = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_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_XKB_STATE_NOTIFY = ecore_event_type_new(); - ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new(); - ECORE_X_EVENT_GENERIC = ecore_event_type_new(); - - ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new(); - ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new(); - ECORE_X_RAW_MOTION = ecore_event_type_new(); - } -} - -void -_ecore_xcb_events_shutdown(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_event_mouse_down_info_clear(); - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; -// if (_ecore_xcb_event_last_mouse_move_event) -// { -// ecore_event_del(_ecore_xcb_event_last_mouse_move_event); -// _ecore_xcb_event_last_mouse_move_event = NULL; -// } -} - -void -_ecore_xcb_events_handle(xcb_generic_event_t *ev) -{ - uint8_t response = 0; - -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - /* strip highest bit (set if event is generated) */ - response = (ev->response_type & ~0x80); - if (response == 0) - { - xcb_generic_error_t *err; - - err = (xcb_generic_error_t *)ev; - - /* NB: There is no way to check access of destroyed windows, - * so trap those cases and ignore. We also ignore BadValue from - * xcb_grab/ungrab_button (happens when we are using any_mod) - * and a few others */ -#ifdef OLD_XCB_VERSION - if (err->error_code == XCB_EVENT_ERROR_BAD_WINDOW) return; - else if (err->error_code == XCB_EVENT_ERROR_BAD_MATCH) - { - if ((err->major_code == XCB_SET_INPUT_FOCUS) || - (err->major_code == XCB_CONFIGURE_WINDOW)) - return; - } - else if (err->error_code == XCB_EVENT_ERROR_BAD_VALUE) - { - if ((err->major_code == XCB_KILL_CLIENT) || - (err->major_code == XCB_GRAB_BUTTON) || - (err->major_code == XCB_UNGRAB_BUTTON)) - return; - } -#else - if (err->error_code == XCB_WINDOW) return; - else if (err->error_code == XCB_MATCH) - { - if ((err->major_code == XCB_SET_INPUT_FOCUS) || - (err->major_code == XCB_CONFIGURE_WINDOW)) - return; - } - else if (err->error_code == XCB_VALUE) - { - if ((err->major_code == XCB_KILL_CLIENT) || - (err->major_code == XCB_GRAB_BUTTON) || - (err->major_code == XCB_UNGRAB_BUTTON)) - return; - } -#endif - WRN("Got Event Error:"); - WRN("\tMajor Code: %d", err->major_code); - WRN("\tMinor Code: %d", err->minor_code); - WRN("\tRequest: %s", xcb_event_get_request_label(err->major_code)); - WRN("\tError: %s", xcb_event_get_error_label(err->error_code)); - if (err->error_code == 2) // bad value - WRN("\tValue: %d", ((xcb_value_error_t *)err)->bad_value); - else if (err->error_code == 8) // bad match - WRN("\tMatch: %d", ((xcb_match_error_t *)err)->bad_value); - - if (err->major_code == XCB_SEND_EVENT) - { - WRN("\tSend Event Error"); - WRN("\t\tSeq: %d", ev->sequence); - WRN("\t\tFull Seq: %d", ev->full_sequence); - WRN("\t\tType: %d", ev->response_type); - } - /* if (err->major_code == 148) */ - /* { */ - /* printf("GOT 148 Error\n"); */ - /* } */ - return; - } - - /* FIXME: Filter event for xim when xcb supports xim */ - - _ecore_xcb_event_handle_any_event(ev); - - if (response == XCB_KEY_PRESS) - _ecore_xcb_event_handle_key_press(ev); - else if (response == XCB_KEY_RELEASE) - _ecore_xcb_event_handle_key_release(ev); - else if (response == XCB_BUTTON_PRESS) - _ecore_xcb_event_handle_button_press(ev); - else if (response == XCB_BUTTON_RELEASE) - _ecore_xcb_event_handle_button_release(ev); - else if (response == XCB_MOTION_NOTIFY) - _ecore_xcb_event_handle_motion_notify(ev); - else if (response == XCB_ENTER_NOTIFY) - _ecore_xcb_event_handle_enter_notify(ev); - else if (response == XCB_LEAVE_NOTIFY) - _ecore_xcb_event_handle_leave_notify(ev); - else if (response == XCB_KEYMAP_NOTIFY) - _ecore_xcb_event_handle_keymap_notify(ev); - else if (response == XCB_FOCUS_IN) - _ecore_xcb_event_handle_focus_in(ev); - else if (response == XCB_FOCUS_OUT) - _ecore_xcb_event_handle_focus_out(ev); - else if (response == XCB_EXPOSE) - _ecore_xcb_event_handle_expose(ev); - else if (response == XCB_GRAPHICS_EXPOSURE) - _ecore_xcb_event_handle_graphics_exposure(ev); - else if (response == XCB_VISIBILITY_NOTIFY) - _ecore_xcb_event_handle_visibility_notify(ev); - else if (response == XCB_CREATE_NOTIFY) - _ecore_xcb_event_handle_create_notify(ev); - else if (response == XCB_DESTROY_NOTIFY) - _ecore_xcb_event_handle_destroy_notify(ev); - else if (response == XCB_MAP_NOTIFY) - _ecore_xcb_event_handle_map_notify(ev); - else if (response == XCB_UNMAP_NOTIFY) - _ecore_xcb_event_handle_unmap_notify(ev); - else if (response == XCB_MAP_REQUEST) - _ecore_xcb_event_handle_map_request(ev); - else if (response == XCB_REPARENT_NOTIFY) - _ecore_xcb_event_handle_reparent_notify(ev); - else if (response == XCB_CONFIGURE_NOTIFY) - _ecore_xcb_event_handle_configure_notify(ev); - else if (response == XCB_CONFIGURE_REQUEST) - _ecore_xcb_event_handle_configure_request(ev); - else if (response == XCB_GRAVITY_NOTIFY) - _ecore_xcb_event_handle_gravity_notify(ev); - else if (response == XCB_RESIZE_REQUEST) - _ecore_xcb_event_handle_resize_request(ev); - else if (response == XCB_CIRCULATE_NOTIFY) - _ecore_xcb_event_handle_circulate_notify(ev); - else if (response == XCB_CIRCULATE_REQUEST) - _ecore_xcb_event_handle_circulate_request(ev); - else if (response == XCB_PROPERTY_NOTIFY) - _ecore_xcb_event_handle_property_notify(ev); - else if (response == XCB_SELECTION_CLEAR) - _ecore_xcb_event_handle_selection_clear(ev); - else if (response == XCB_SELECTION_REQUEST) - _ecore_xcb_event_handle_selection_request(ev); - else if (response == XCB_SELECTION_NOTIFY) - _ecore_xcb_event_handle_selection_notify(ev); - else if (response == XCB_COLORMAP_NOTIFY) - _ecore_xcb_event_handle_colormap_notify(ev); - else if (response == XCB_CLIENT_MESSAGE) - _ecore_xcb_event_handle_client_message(ev); - else if (response == XCB_MAPPING_NOTIFY) - _ecore_xcb_event_handle_mapping_notify(ev); - else if (response == 35) /* GenericEvent == 35 */ - _ecore_xcb_event_handle_generic_event(ev); -#ifdef ECORE_XCB_DAMAGE - else if ((_ecore_xcb_event_damage >= 0) && - (response == (_ecore_xcb_event_damage + XCB_DAMAGE_NOTIFY))) - _ecore_xcb_event_handle_damage_notify(ev); -#endif -#ifdef ECORE_XCB_RANDR - else if ((_ecore_xcb_event_randr >= 0) && - (response == - _ecore_xcb_event_randr + XCB_RANDR_SCREEN_CHANGE_NOTIFY)) - _ecore_xcb_event_handle_randr_change(ev); - else if ((_ecore_xcb_event_randr >= 0) && - (response == (_ecore_xcb_event_randr + XCB_RANDR_NOTIFY))) - _ecore_xcb_event_handle_randr_notify(ev); -#endif -#ifdef ECORE_XCB_SCREENSAVER - else if ((_ecore_xcb_event_screensaver >= 0) && - (response == - _ecore_xcb_event_screensaver + XCB_SCREENSAVER_NOTIFY)) - _ecore_xcb_event_handle_screensaver_notify(ev); -#endif -#ifdef ECORE_XCB_XGESTURE - else if ((_ecore_xcb_event_gesture >= 0) && - (response == - _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_FLICK)) - _ecore_xcb_event_handle_gesture_notify_flick(ev); - else if ((_ecore_xcb_event_gesture >= 0) && - (response == - _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_PAN)) - _ecore_xcb_event_handle_gesture_notify_pan(ev); - else if ((_ecore_xcb_event_gesture >= 0) && - (response == - _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_PINCH_ROTATION)) - _ecore_xcb_event_handle_gesture_notify_pinchrotation(ev); - else if ((_ecore_xcb_event_gesture >= 0) && - (response == - _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_TAP)) - _ecore_xcb_event_handle_gesture_notify_tap(ev); - else if ((_ecore_xcb_event_gesture >= 0) && - (response == - _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_TAP_N_HOLD)) - _ecore_xcb_event_handle_gesture_notify_tapnhold(ev); - else if ((_ecore_xcb_event_gesture >= 0) && - (response == - _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_HOLD)) - _ecore_xcb_event_handle_gesture_notify_hold(ev); - else if ((_ecore_xcb_event_gesture >= 0) && - (response == - _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_GROUP)) - _ecore_xcb_event_handle_gesture_notify_group(ev); -#endif -#ifdef ECORE_XCB_SHAPE - else if ((_ecore_xcb_event_shape >= 0) && - (response == (_ecore_xcb_event_shape + XCB_SHAPE_NOTIFY))) - _ecore_xcb_event_handle_shape_change(ev); -#endif -#ifdef ECORE_XCB_SYNC - else if ((_ecore_xcb_event_sync >= 0) && - (response == (_ecore_xcb_event_sync + XCB_SYNC_COUNTER_NOTIFY))) - _ecore_xcb_event_handle_sync_counter(ev); - else if ((_ecore_xcb_event_sync >= 0) && - (response == (_ecore_xcb_event_sync + XCB_SYNC_ALARM_NOTIFY))) - _ecore_xcb_event_handle_sync_alarm(ev); -#endif -#ifdef ECORE_XCB_XFIXES - else if ((_ecore_xcb_event_xfixes >= 0) && - (response == - _ecore_xcb_event_xfixes + XCB_XFIXES_SELECTION_NOTIFY)) - _ecore_xcb_event_handle_xfixes_selection_notify(ev); - else if ((_ecore_xcb_event_xfixes >= 0) && - (response == (_ecore_xcb_event_xfixes + XCB_XFIXES_CURSOR_NOTIFY))) - _ecore_xcb_event_handle_xfixes_cursor_notify(ev); -#endif -} - -Ecore_X_Time -_ecore_xcb_events_last_time_get(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_event_last_time; -} - -EAPI void -ecore_x_event_mask_set(Ecore_X_Window win, - Ecore_X_Event_Mask mask) -{ - xcb_get_window_attributes_cookie_t cookie; - xcb_get_window_attributes_reply_t *reply; - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); - reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - - list = (mask | reply->your_event_mask); - free(reply); - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_EVENT_MASK, &list); -// ecore_x_flush(); -} - -EAPI void -ecore_x_event_mask_unset(Ecore_X_Window win, - Ecore_X_Event_Mask mask) -{ - xcb_get_window_attributes_cookie_t cookie; - xcb_get_window_attributes_reply_t *reply; - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); - reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - - list = (reply->your_event_mask & ~mask); - free(reply); - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_EVENT_MASK, &list); -// ecore_x_flush(); -} - -unsigned int -_ecore_xcb_events_modifiers_get(unsigned int state) -{ - unsigned int modifiers = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - 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_MODIFIER_ALTGR) - modifiers |= ECORE_EVENT_MODIFIER_ALTGR; - if (state & ECORE_X_LOCK_SCROLL) - modifiers |= ECORE_EVENT_LOCK_SCROLL; - if (state & ECORE_X_LOCK_CAPS) - modifiers |= ECORE_EVENT_LOCK_CAPS; - if (state & ECORE_X_LOCK_NUM) - modifiers |= ECORE_EVENT_LOCK_NUM; - if (state & ECORE_X_LOCK_SHIFT) - modifiers |= ECORE_EVENT_LOCK_SHIFT; - - return modifiers; -} - -/* local functions */ -static void -_ecore_xcb_event_handle_any_event(xcb_generic_event_t *event) -{ - xcb_generic_event_t *ev; - -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ev = malloc(sizeof(xcb_generic_event_t)); - if (!ev) return; - - memcpy(ev, event, sizeof(xcb_generic_event_t)); - ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_key_press(xcb_generic_event_t *event) -{ - _ecore_xcb_event_key_press(event); -} - -static void -_ecore_xcb_event_handle_key_release(xcb_generic_event_t *event) -{ - _ecore_xcb_event_key_release(event); -} - -static void -_ecore_xcb_event_handle_button_press(xcb_generic_event_t *event) -{ - xcb_button_press_event_t *ev; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - - ev = (xcb_button_press_event_t *)event; - if ((ev->detail > 3) && (ev->detail < 8)) - { - Ecore_Event_Mouse_Wheel *e; - - if (!(e = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return; - - e->timestamp = ev->time; - e->modifiers = _ecore_xcb_events_modifiers_get(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); - - _ecore_xcb_window_grab_allow_events(ev->event, ev->child, - ECORE_EVENT_MOUSE_WHEEL, - e, ev->time); - } - else - { - Ecore_Event_Mouse_Button *e; - unsigned int child_win = 0; - - child_win = (ev->child ? ev->child : ev->event); - - _ecore_xcb_event_mouse_move(ev->time, ev->state, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y, - ev->event, child_win, - ev->root, ev->same_screen, - 0, 1, 1, 1.0, 0.0, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y); - - e = _ecore_xcb_event_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, ev->event, - child_win, - ev->root, ev->same_screen, - 0, 1, 1, 1.0, 0.0, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y); - if (e) - _ecore_xcb_window_grab_allow_events(ev->event, ev->child, - ECORE_EVENT_MOUSE_BUTTON_DOWN, - e, ev->time); - } -} - -static void -_ecore_xcb_event_handle_button_release(xcb_generic_event_t *event) -{ - xcb_button_release_event_t *ev; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_button_release_event_t *)event; - if ((ev->detail <= 3) || (ev->detail > 7)) - { - _ecore_xcb_event_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, - 0, 1, 1, 1.0, 0.0, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y); - - _ecore_xcb_event_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, - 0, 1, 1, 1.0, 0.0, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y); - } -} - -static void -_ecore_xcb_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_event_last_mouse_move_event) */ - /* { */ - /* ecore_event_del(_ecore_xcb_event_last_mouse_move_event); */ - /* _ecore_xcb_event_last_mouse_move = EINA_FALSE; */ - /* _ecore_xcb_event_last_mouse_move_event = NULL; */ - /* } */ - - _ecore_xcb_event_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, - 0, 1, 1, 1.0, 0.0, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y); - _ecore_xcb_event_last_mouse_move = EINA_TRUE; - - _ecore_xcb_dnd_drag(ev->root, ev->root_x, ev->root_y); -} - -static void -_ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event) -{ - xcb_enter_notify_event_t *ev; - Ecore_X_Event_Mouse_In *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_enter_notify_event_t *)event; - - _ecore_xcb_event_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, - 0, 1, 1, 1.0, 0.0, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y); - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Mouse_In)))) return; - - e->modifiers = _ecore_xcb_events_modifiers_get(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->event_win = ev->event; - e->same_screen = ev->same_screen_focus; - e->root_win = ev->root; - e->mode = _ecore_xcb_event_mode_get(ev->mode); - e->detail = _ecore_xcb_event_detail_get(ev->detail); - e->time = ev->time; - _ecore_xcb_event_last_time = e->time; - - ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event) -{ - xcb_leave_notify_event_t *ev; - Ecore_X_Event_Mouse_Out *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_enter_notify_event_t *)event; - - _ecore_xcb_event_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, - 0, 1, 1, 1.0, 0.0, - ev->event_x, ev->event_y, - ev->root_x, ev->root_y); - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out)))) return; - - e->modifiers = _ecore_xcb_events_modifiers_get(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->event_win = ev->event; - e->same_screen = ev->same_screen_focus; - e->root_win = ev->root; - e->mode = _ecore_xcb_event_mode_get(ev->mode); - e->detail = _ecore_xcb_event_detail_get(ev->detail); - - 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); -} - -static void -_ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event EINA_UNUSED) -{ -// LOGFN(__FILE__, __LINE__, __FUNCTION__); - - // FIXME: handle this event type - _ecore_xcb_event_last_mouse_move = EINA_FALSE; -} - -static void -_ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event) -{ - xcb_focus_in_event_t *ev; - Ecore_X_Event_Window_Focus_In *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_focus_in_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In)))) return; - - e->win = ev->event; - e->mode = _ecore_xcb_event_mode_get(ev->mode); - e->detail = _ecore_xcb_event_detail_get(ev->detail); - - 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); -} - -static void -_ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event) -{ - xcb_focus_out_event_t *ev; - Ecore_X_Event_Window_Focus_Out *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_focus_out_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out)))) return; - - e->win = ev->event; - e->mode = _ecore_xcb_event_mode_get(ev->mode); - e->detail = _ecore_xcb_event_detail_get(ev->detail); - - 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); -} - -static void -_ecore_xcb_event_handle_expose(xcb_generic_event_t *event) -{ - xcb_expose_event_t *ev; - Ecore_X_Event_Window_Damage *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_expose_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) 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); -} - -static void -_ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event) -{ - xcb_graphics_exposure_event_t *ev; - Ecore_X_Event_Window_Damage *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_graphics_exposure_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) return; - - e->win = ev->drawable; - e->x = ev->x; - e->y = ev->y; - e->w = ev->width; - e->h = ev->height; - e->count = ev->count; - e->time = _ecore_xcb_event_last_time; - - ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event) -{ - xcb_visibility_notify_event_t *ev; - Ecore_X_Event_Window_Visibility_Change *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_visibility_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change)))) - 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); -} - -static void -_ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event) -{ - xcb_create_notify_event_t *ev; - Ecore_X_Event_Window_Create *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_create_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Create)))) return; - - e->win = ev->window; - e->parent = ev->parent; - if (ev->override_redirect) - e->override = 1; - else - e->override = 0; - e->x = ev->x; - e->y = ev->y; - e->w = ev->width; - e->h = ev->height; - e->border = ev->border_width; - e->time = _ecore_xcb_event_last_time; - - ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event) -{ - xcb_destroy_notify_event_t *ev; - Ecore_X_Event_Window_Destroy *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_destroy_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy)))) return; - - e->win = ev->window; - e->event_win = ev->event; - if (e->win == _ecore_xcb_event_last_window) - _ecore_xcb_event_last_window = 0; - e->time = _ecore_xcb_event_last_time; - - ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event) -{ - xcb_map_notify_event_t *ev; - Ecore_X_Event_Window_Show *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_map_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show)))) return; - - e->win = ev->window; - e->event_win = ev->event; - e->time = _ecore_xcb_event_last_time; - - ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event) -{ - xcb_unmap_notify_event_t *ev; - Ecore_X_Event_Window_Hide *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_unmap_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Hide)))) return; - - e->win = ev->window; - e->event_win = ev->event; - e->time = _ecore_xcb_event_last_time; - - ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_map_request(xcb_generic_event_t *event) -{ - xcb_map_request_event_t *ev; - Ecore_X_Event_Window_Show_Request *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_map_request_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request)))) 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); -} - -static void -_ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event) -{ - xcb_reparent_notify_event_t *ev; - Ecore_X_Event_Window_Reparent *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_reparent_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent)))) return; - - e->win = ev->window; - e->event_win = ev->event; - e->parent = ev->parent; - e->time = _ecore_xcb_event_last_time; - - ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event) -{ - xcb_configure_notify_event_t *ev; - Ecore_X_Event_Window_Configure *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_configure_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure)))) return; - - e->win = ev->window; - e->event_win = ev->event; - 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); -} - -static void -_ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event) -{ - xcb_configure_request_event_t *ev; - Ecore_X_Event_Window_Configure_Request *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_configure_request_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request)))) - return; - - e->win = ev->window; - e->parent_win = ev->parent; - 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); -} - -static void -_ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event EINA_UNUSED) -{ -/* - xcb_gravity_notify_event_t *ev; - Ecore_X_Event_Window_Gravity *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_gravity_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Gravity)))) return; - - e->win = ev->window; - e->event_win = ev->event; - e->time = _ecore_xcb_event_last_time; - - ecore_event_add(ECORE_X_EVENT_WINDOW_GRAVITY, e, NULL, NULL); - */ -} - -static void -_ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event) -{ - xcb_resize_request_event_t *ev; - Ecore_X_Event_Window_Resize_Request *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_resize_request_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request)))) 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); -} - -static void -_ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event) -{ - xcb_circulate_notify_event_t *ev; - Ecore_X_Event_Window_Stack *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_circulate_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack)))) 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); -} - -static void -_ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event) -{ - xcb_circulate_request_event_t *ev; - Ecore_X_Event_Window_Stack_Request *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_circulate_request_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request)))) 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); -} - -static void -_ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event) -{ - xcb_property_notify_event_t *ev; - Ecore_X_Event_Window_Property *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_property_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Property)))) 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); -} - -static void -_ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event) -{ - xcb_selection_clear_event_t *ev; - Ecore_X_Event_Selection_Clear *e; - Ecore_X_Atom sel; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_selection_clear_event_t *)event; - if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Clear)))) return; - - e->win = ev->owner; - 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; - e->time = ev->time; - - ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event) -{ - xcb_selection_request_event_t *ev; - Ecore_X_Event_Selection_Request *e; - Ecore_X_Selection_Intern *sd; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_selection_request_event_t *)event; - if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Request)))) return; - - e->owner = ev->owner; - e->requestor = ev->requestor; - e->selection = ev->selection; - e->target = ev->target; - e->property = ev->property; - e->time = ev->time; - - ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL); - - if ((sd = _ecore_xcb_selection_get(ev->selection)) && - (sd->win == ev->owner)) - { - Ecore_X_Selection_Intern *si; - - si = _ecore_xcb_selection_get(ev->selection); - if (si->data) - { - Ecore_X_Atom property = XCB_NONE, type; - void *data = NULL; - int len = 0, typesize = 0; - - type = ev->target; - typesize = 8; - len = sd->length; - - if (!ecore_x_selection_convert(ev->selection, ev->target, - &data, &len, &type, &typesize)) - property = XCB_NONE; - else if (data) - { - ecore_x_window_prop_property_set(ev->requestor, ev->property, - type, typesize, data, len); - property = ev->property; - free(data); - } - ecore_x_selection_notify_send(ev->requestor, ev->selection, - ev->target, property, ev->time); - } - } -} - -static void -_ecore_xcb_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 = 0, format = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_selection_notify_event_t *)event; - selection = ev->selection; - if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS) - { - format = - ecore_x_window_prop_property_get(ev->requestor, ev->property, - XCB_ATOM_ATOM, 32, &data, &num); - if (!format) - { - /* fallback if targets handling is not working and try get the - * selection directly */ - xcb_convert_selection(_ecore_xcb_conn, ev->requestor, - selection, selection, - ECORE_X_ATOM_UTF8_STRING, XCB_CURRENT_TIME); - return; - } - } - else - format = ecore_x_window_prop_property_get(ev->requestor, ev->property, - XCB_GET_PROPERTY_TYPE_ANY, 8, - &data, &num); - - 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_xcb_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_xcb_selection_parse(e->target, data, num, format); - - ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, - _ecore_xcb_event_selection_notify_free, NULL); -} - -static void -_ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event) -{ - xcb_colormap_notify_event_t *ev; - Ecore_X_Event_Window_Colormap *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_colormap_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap)))) 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); -} - -static void -_ecore_xcb_event_handle_client_message(xcb_generic_event_t *event) -{ - xcb_client_message_event_t *ev; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_client_message_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 */ - - if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) && (ev->format == 32) && - (ev->data.data32[0] == ECORE_X_ATOM_WM_DELETE_WINDOW)) - { - Ecore_X_Event_Window_Delete_Request *e; - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request)))) - 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) && (ev->data.data32[2] < 9)) - { - Ecore_X_Event_Window_Move_Resize_Request *e; - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request)))) - 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); - } - else if (ev->type == ECORE_X_ATOM_XDND_ENTER) - { - Ecore_X_Event_Xdnd_Enter *e; - Ecore_X_DND_Target *target; - - DBG("Got Xdnd Enter Event"); - if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)))) return; - target = _ecore_xcb_dnd_target_get(); - target->state = ECORE_X_DND_TARGET_ENTERED; - target->source = ev->data.data32[0]; - target->win = ev->window; - target->version = (int)(ev->data.data32[1] >> 24); - if (target->version > ECORE_X_DND_VERSION) - { - WRN("DND: Requested version %d but we only support up to %d", - target->version, ECORE_X_DND_VERSION); - free(e); - return; - } - if (ev->data.data32[1] & 0x1UL) - { - unsigned char *data; - Ecore_X_Atom *types; - int num_ret = 0; - - if (!ecore_x_window_prop_property_get(target->source, - ECORE_X_ATOM_XDND_TYPE_LIST, - ECORE_X_ATOM_ATOM, 32, - &data, &num_ret)) - { - WRN("DND: Could not fetch data type list from source window"); - free(e); - return; - } - types = (Ecore_X_Atom *)data; - e->types = calloc(num_ret, sizeof(char *)); - if (e->types) - { - int i = 0; - - for (i = 0; i < num_ret; i++) - e->types[i] = ecore_x_atom_name_get(types[i]); - } - e->num_types = num_ret; - } - else - { - int i = 0; - - e->types = calloc(3, sizeof(char *)); - if (e->types) - { - while ((i < 3) && (ev->data.data32[i + 2])) - { - e->types[i] = - ecore_x_atom_name_get(ev->data.data32[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_xcb_event_xdnd_enter_free, NULL); - } - else if (ev->type == ECORE_X_ATOM_XDND_POSITION) - { - Ecore_X_Event_Xdnd_Position *e; - Ecore_X_DND_Target *target; - - DBG("Got Xdnd Position Event"); - target = _ecore_xcb_dnd_target_get(); - if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || - (target->win != ev->window)) return; - target->pos.x = ev->data.data32[2] >> 16; - target->pos.y = ev->data.data32[2] & 0xFFFFUL; - target->action = ev->data.data32[4]; - target->time = (target->version >= 1) ? - (Ecore_X_Time)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); - } - else if (ev->type == ECORE_X_ATOM_XDND_STATUS) - { - Ecore_X_Event_Xdnd_Status *e; - Ecore_X_DND_Source *source; - - DBG("Got Xdnd Status Event"); - source = _ecore_xcb_dnd_source_get(); - if ((source->win != ev->window) || - (source->dest != (Ecore_X_Window)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 = ev->data.data32[2] >> 16; - source->rectangle.y = ev->data.data32[2] & 0xFFFFUL; - source->rectangle.width = ev->data.data32[3] >> 16; - source->rectangle.height = 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); - } - else if (ev->type == ECORE_X_ATOM_XDND_LEAVE) - { - Ecore_X_Event_Xdnd_Leave *e; - Ecore_X_DND_Target *target; - - DBG("Got Xdnd Leave Event"); - target = _ecore_xcb_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 = (Ecore_X_Window)ev->data.data32[0]; - ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL); - } - else if (ev->type == ECORE_X_ATOM_XDND_DROP) - { - Ecore_X_Event_Xdnd_Drop *e; - Ecore_X_DND_Target *target; - - DBG("Got Xdnd Drop Event"); - target = _ecore_xcb_dnd_target_get(); - if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || - (target->win != ev->window)) - return; - target->time = (target->version >= 1) ? - (Ecore_X_Time)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); - } - else if (ev->type == ECORE_X_ATOM_XDND_FINISHED) - { - Ecore_X_Event_Xdnd_Finished *e; - Ecore_X_DND_Source *source; - Eina_Bool completed = EINA_TRUE; - - DBG("Got Xdnd Finished Event"); - source = _ecore_xcb_dnd_source_get(); - if ((source->win != ev->window) || - (source->dest != (Ecore_X_Window)ev->data.data32[0])) - return; - if ((source->version < 5) || (ev->data.data32[1] & 0x1UL)) - { - ecore_x_selection_xdnd_clear(); - source->state = ECORE_X_DND_SOURCE_IDLE; - } - else if (source->version >= 5) - { - completed = EINA_FALSE; - source->state = ECORE_X_DND_SOURCE_CONVERTING; - /* FIXME: Probably need to add a timer to switch back to idle - * and discard the selection data */ - } - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished)))) - 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; - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)))) - 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_xcb_netwm_window_state_get(ev->data.data32[1]); - if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN) - { - /* FIXME */ - } - e->state[1] = _ecore_xcb_netwm_window_state_get(ev->data.data32[2]); - if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN) - { - /* FIXME */ - } - e->source = ev->data.data32[3]; - ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL); - } -#ifdef OLD_XCB_VERSION - else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) && - (ev->format == 32) && (ev->data.data32[0] == XCB_WM_STATE_ICONIC)) -#else - else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) && (ev->format == 32) && - (ev->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC)) -#endif - { - Ecore_X_Event_Window_State_Request *e; - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)))) - 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; - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change)))) - 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; - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request)))) - 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; - Ecore_X_Window root = 0; - int count = 0; - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Ping)))) 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); - - CHECK_XCB_CONN; - - count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); - if (count > 1) - root = ecore_x_window_root_get(e->win); - else - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - if (ev->window != root) - { - ev->window = root; - xcb_send_event(_ecore_xcb_conn, 0, root, - (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), - (const char *)&ev); -// ecore_x_flush(); - } - } - else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) && - (ev->format == 8)) - { - _ecore_xcb_netwm_startup_info_begin(ev->window, ev->data.data8[0]); - } - else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) && (ev->format == 8)) - { - _ecore_xcb_netwm_startup_info(ev->window, ev->data.data8[0]); - } - else if ((ev->type == 27777) && (ev->data.data32[0] == 0x7162534) && - (ev->format == 32)) // && (ev->window = _private_window)) - { - if (ev->data.data32[1] == 0x10000001) - _ecore_xcb_window_button_grab_remove(ev->data.data32[2]); - else if (ev->data.data32[1] == 0x10000002) - _ecore_xcb_window_key_grab_remove(ev->data.data32[2]); - } - else - { - Ecore_X_Event_Client_Message *e; - int i = 0; - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Client_Message)))) - 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); - } -} - -static void -_ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event) -{ - xcb_mapping_notify_event_t *ev; - Ecore_X_Event_Mapping_Change *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - - ev = (xcb_mapping_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change)))) return; - - _ecore_xcb_keymap_refresh(ev); - _ecore_xcb_modifiers_get(); - - switch (ev->request) - { - case XCB_MAPPING_MODIFIER: - e->type = ECORE_X_MAPPING_MODIFIER; - break; - - case XCB_MAPPING_KEYBOARD: - e->type = ECORE_X_MAPPING_KEYBOARD; - break; - - case XCB_MAPPING_POINTER: - default: - e->type = ECORE_X_MAPPING_MOUSE; - break; - } - e->keycode = ev->first_keycode; - e->num = ev->count; - - ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_DAMAGE - xcb_damage_notify_event_t *ev; - Ecore_X_Event_Damage *e; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; -#ifdef ECORE_XCB_DAMAGE - ev = (xcb_damage_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Damage)))) return; - - e->level = ev->level; - e->drawable = ev->drawable; - e->damage = ev->damage; - 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 -} - -static void -_ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_screen_change_notify_event_t *ev; - Ecore_X_Event_Screen_Change *e; -#endif - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; -#ifdef ECORE_XCB_RANDR - ev = (xcb_randr_screen_change_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Screen_Change)))) return; - - e->win = ev->request_window; - e->root = ev->root; - e->size.width = ev->width; - e->size.height = ev->height; - e->time = ev->timestamp; - e->config_time = ev->config_timestamp; - e->size.width_mm = ev->mwidth; - e->size.height_mm = ev->mheight; - e->orientation = ev->rotation; - e->subpixel_order = ev->subpixel_order; - - ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL); -#endif -} - -static void -_ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_notify_event_t *ev; -#endif - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; -#ifdef ECORE_XCB_RANDR - ev = (xcb_randr_notify_event_t *)event; - switch (ev->subCode) - { - case XCB_RANDR_NOTIFY_CRTC_CHANGE: - _ecore_xcb_event_handle_randr_crtc_change(event); - break; - - case XCB_RANDR_NOTIFY_OUTPUT_CHANGE: - _ecore_xcb_event_handle_randr_output_change(event); - break; - - case XCB_RANDR_NOTIFY_OUTPUT_PROPERTY: - _ecore_xcb_event_handle_randr_output_property_change(event); - break; - - default: - break; - } -#endif -} - -static void -_ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_notify_event_t *ev; - Ecore_X_Event_Randr_Crtc_Change *e; -#endif - -#ifdef ECORE_XCB_RANDR - ev = (xcb_randr_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change)))) - return; - - e->win = ev->u.cc.window; - e->crtc = ev->u.cc.crtc; - e->mode = ev->u.cc.mode; - e->orientation = ev->u.cc.rotation; - e->geo.x = ev->u.cc.x; - e->geo.y = ev->u.cc.y; - e->geo.w = ev->u.cc.width; - e->geo.h = ev->u.cc.height; - - ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL); -#endif -} - -static void -_ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_notify_event_t *ev; - Ecore_X_Event_Randr_Output_Change *e; -#endif - -#ifdef ECORE_XCB_RANDR - ev = (xcb_randr_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change)))) - return; - - e->win = ev->u.oc.window; - e->output = ev->u.oc.output; - e->crtc = ev->u.oc.crtc; - e->mode = ev->u.oc.mode; - e->orientation = ev->u.oc.rotation; - e->connection = ev->u.oc.connection; - e->subpixel_order = ev->u.oc.subpixel_order; - - ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL); -#endif -} - -static void -_ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_notify_event_t *ev; - Ecore_X_Event_Randr_Output_Property_Notify *e; -#endif - -#ifdef ECORE_XCB_RANDR - ev = (xcb_randr_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify)))) - return; - - e->win = ev->u.op.window; - e->output = ev->u.op.output; - e->property = ev->u.op.atom; - e->time = ev->u.op.timestamp; - if (ev->u.op.status == XCB_PROPERTY_NEW_VALUE) - e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD; - else - e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL; - - ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, e, NULL, NULL); -#endif -} - -static void -_ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_SCREENSAVER - xcb_screensaver_notify_event_t *ev; - Ecore_X_Event_Screensaver_Notify *e; -#endif - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; -#ifdef ECORE_XCB_SCREENSAVER - ev = (xcb_screensaver_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify)))) return; - - e->win = ev->window; - e->on = EINA_FALSE; - if ((ev->state == XCB_SCREENSAVER_STATE_ON) || - (ev->state == XCB_SCREENSAVER_STATE_CYCLE)) e->on = EINA_TRUE; - e->time = ev->time; - - ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL); -#endif -} - -#ifdef ECORE_XCB_XGESTURE -static void -_ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event) -{ - xcb_gesture_notify_flick_event_t *ev; - Ecore_X_Event_Gesture_Notify_Flick *e; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); - - ev = (xcb_gesture_notify_flick_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick)))) return; - - e->win = ev->window; - e->time = ev->time; - e->subtype = ev->kind; - e->num_fingers = ev->num_finger; - e->distance = ev->distance; - e->duration = ev->duration; - e->direction = ev->direction; - e->angle = XFixedToDouble(ev->angle); - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event) -{ - xcb_gesture_notify_pan_event_t *ev; - Ecore_X_Event_Gesture_Notify_Pan *e; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); - - ev = (xcb_gesture_notify_pan_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan)))) return; - - e->win = ev->window; - e->time = ev->time; - e->subtype = ev->kind; - e->num_fingers = ev->num_finger; - e->dx = ev->dx; - e->dy = ev->dy; - e->distance = ev->distance; - e->duration = ev->duration; - e->direction = ev->direction; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event) -{ - xcb_gesture_notify_pinch_rotation_event_t *ev; - Ecore_X_Event_Gesture_Notify_PinchRotation *e; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); - - ev = (xcb_gesture_notify_pinch_rotation_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation)))) return; - - e->win = ev->window; - e->time = ev->time; - e->subtype = ev->kind; - e->num_fingers = ev->num_finger; - e->distance = ev->distance; - e->cx = ev->cx; - e->cy = ev->cy; - e->zoom = XFixedToDouble(ev->zoom); - e->angle = XFixedToDouble(ev->angle); - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event) -{ - xcb_gesture_notify_tap_event_t *ev; - Ecore_X_Event_Gesture_Notify_Tap *e; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); - - ev = (xcb_gesture_notify_tap_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap)))) return; - - e->win = ev->window; - e->time = ev->time; - e->subtype = ev->kind; - e->num_fingers = ev->num_finger; - e->cx = ev->cx; - e->cy = ev->cy; - e->tap_repeat = ev->tap_repeat; - e->interval = ev->interval; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL); -} - -static void -_ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event) -{ - xcb_gesture_notify_tap_n_hold_event_t *ev; - Ecore_X_Event_Gesture_Notify_TapNHold *e; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); - - ev = (xcb_gesture_notify_tap_n_hold_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold)))) return; - - e->win = ev->window; - e->time = ev->time; - e->subtype = ev->kind; - e->num_fingers = ev->num_finger; - e->cx = ev->cx; - e->cy = ev->cy; - e->interval = ev->interval; - e->hold_time = ev->holdtime; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL); -} - -static void - _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event) -{ - xcb_gesture_notify_hold_event_t *ev; - Ecore_X_Event_Gesture_Notify_Hold *e; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); - - ev = (xcb_gesture_notify_hold_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold)))) return; - - e->win = ev->window; - e->time = ev->time; - e->subtype = ev->kind; - e->num_fingers = ev->num_finger; - e->cx = ev->cx; - e->cy = ev->cy; - e->hold_time = ev->holdtime; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL); -} - -static void - _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event) -{ - xcb_gesture_notify_group_event_t *ev; - Ecore_X_Event_Gesture_Notify_Group *e; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); - - ev = (xcb_gesture_notify_group_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group)))) return; - - e->win = ev->window; - e->time = ev->time; - e->subtype = ev->kind; - e->num_groups = ev->num_group; - e->group_id = ev->groupid; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL); -} -#endif - -#ifdef ECORE_XCB_SHAPE -static void -_ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event) -{ - xcb_shape_notify_event_t *ev; - Ecore_X_Event_Window_Shape *e; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - ev = (xcb_shape_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Shape)))) return; - - e->win = ev->affected_window; - e->time = ev->server_time; - switch (ev->shape_kind) - { - case XCB_SHAPE_SK_BOUNDING: - e->type = ECORE_X_SHAPE_BOUNDING; - break; - - case XCB_SHAPE_SK_CLIP: - e->type = ECORE_X_SHAPE_CLIP; - break; - - case XCB_SHAPE_SK_INPUT: - e->type = ECORE_X_SHAPE_INPUT; - break; - - default: - break; - } - e->x = ev->extents_x; - e->y = ev->extents_y; - e->w = ev->extents_width; - e->h = ev->extents_height; - e->shaped = ev->shaped; - - ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL); -} - -#endif - -static void -_ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_counter_notify_event_t *ev; - Ecore_X_Event_Sync_Counter *e; -#endif - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - -#ifdef ECORE_XCB_SYNC - ev = (xcb_sync_counter_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter)))) return; - - e->time = ev->timestamp; - - ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL); -#endif -} - -static void -_ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_alarm_notify_event_t *ev; - Ecore_X_Event_Sync_Alarm *e; -#endif - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; -#ifdef ECORE_XCB_SYNC - ev = (xcb_sync_alarm_notify_event_t *)event; - if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm)))) return; - - e->time = ev->timestamp; - e->alarm = ev->alarm; - - ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL); -#endif -} - -static void -_ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event) -{ -#ifdef ECORE_XCB_XFIXES - Ecore_X_Event_Fixes_Selection_Notify *e; - Ecore_X_Atom sel; - xcb_xfixes_selection_notify_event_t *ev; -#endif - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; -#ifdef ECORE_XCB_XFIXES - ev = (xcb_xfixes_selection_notify_event_t *)event; - - if (!(e = calloc(1, sizeof(*e)))) return; - - e->win = ev->window; - e->owner = ev->owner; - e->time = ev->timestamp; - e->selection_time = ev->selection_timestamp; - 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; - e->reason = ev->subtype; - - ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL); -#endif -} - -static void -_ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event EINA_UNUSED) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); -// FIXME: TBD -} - -static void -_ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event) -{ - xcb_ge_event_t *ev; - Ecore_X_Event_Generic *e; - - ev = (xcb_ge_event_t *)event; - - /* pad0 *IS* extension - bug in xcb */ - if (ev->pad0 == _ecore_xcb_event_input) - { - _ecore_xcb_event_handle_input_event(event); -// FIXME: should we generate generic events as WELL as input events? -// return; - } - - if (!(e = calloc(1, sizeof(Ecore_X_Event_Generic)))) - return; - - DBG("Handle Generic Event: %d", ev->event_type); - - e->cookie = ev->sequence; - /* NB: These are bugs in xcb ge_event structure. The struct should have a - * field for extension & data, but does not. - * - * XCB people have been notified of this issue */ - e->extension = ev->pad0; - /* e->data = ev->pad1; */ - if (ev->length > 0) - { - int len = ev->length * sizeof(int); - e->data = malloc(len); - if (e->data) memcpy(e->data, &(event[1]), len); - } - - e->evtype = ev->event_type; - - ecore_event_add(ECORE_X_EVENT_GENERIC, e, - _ecore_xcb_event_generic_event_free, e->data); -} - -static void -_ecore_xcb_event_handle_input_event(xcb_generic_event_t *event) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_input_handle_event(event); -} - -static void -_ecore_xcb_event_key_press(xcb_generic_event_t *event) -{ - Ecore_Event_Key *e; - xcb_keysym_t sym = XCB_NO_SYMBOL; - xcb_keycode_t keycode = 0; - xcb_key_press_event_t *xevent; - char *keyname = NULL, *key = NULL; - char *compose = NULL; - char compose_buffer[256]; - int val = 0; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - - xevent = (xcb_key_press_event_t *)event; - keycode = xevent->detail; - - sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state); - keyname = _ecore_xcb_keymap_keysym_to_string(sym); - if (!keyname) - { - char buff[256]; - - snprintf(buff, sizeof(buff), "Keycode-%i", keycode); - keyname = buff; - } - - val = - _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer, - sizeof(compose_buffer), &sym); - if (val > 0) - { - compose_buffer[val] = 0; - compose = - eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); - if (!compose) - ERR("Ecore_X cannot convert input key string '%s' to UTF-8. " - "Is Eina built with iconv support?", compose_buffer); - } - - key = _ecore_xcb_keymap_keysym_to_string(sym); - if (!key) key = keyname; - - e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + - (compose ? strlen(compose) : 0) + 3); - if (e) - { - e->keyname = (char *)(e + 1); - e->key = e->keyname + strlen(keyname) + 1; - - e->compose = NULL; - if (compose) e->compose = (e->key + strlen(key) + 1); - e->string = e->compose; - - strcpy((char *)e->keyname, keyname); - strcpy((char *)e->key, key); - if (compose) strcpy((char *)e->compose, compose); - - e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state); - e->timestamp = xevent->time; - e->window = xevent->child ? xevent->child : xevent->event; - e->event_window = xevent->event; - e->same_screen = xevent->same_screen; - e->root_window = xevent->root; - - DBG("Sending Key Down Event: %s", e->keyname); - ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); - } - _ecore_xcb_event_last_time = xevent->time; -} - -static void -_ecore_xcb_event_key_release(xcb_generic_event_t *event) -{ - Ecore_Event_Key *e; - xcb_keysym_t sym = XCB_NO_SYMBOL; - xcb_keycode_t keycode = 0; - xcb_key_release_event_t *xevent; - char *keyname = NULL, *key = NULL; - char *compose = NULL; - char compose_buffer[256]; - int val = 0; - - _ecore_xcb_event_last_mouse_move = EINA_FALSE; - - xevent = (xcb_key_release_event_t *)event; - keycode = xevent->detail; - - sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state); - keyname = _ecore_xcb_keymap_keysym_to_string(sym); - if (!keyname) - { - char buff[256]; - - snprintf(buff, sizeof(buff), "Keycode-%i", keycode); - keyname = buff; - } - - val = - _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer, - sizeof(compose_buffer), &sym); - if (val > 0) - { - compose_buffer[val] = 0; - compose = - eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); -// tmp = compose; - } - - key = _ecore_xcb_keymap_keysym_to_string(sym); - if (!key) key = keyname; - - e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + - (compose ? strlen(compose) : 0) + 3); - if (e) - { - e->keyname = (char *)(e + 1); - e->key = e->keyname + strlen(keyname) + 1; - - e->compose = NULL; - if (compose) e->compose = (e->key + strlen(key) + 1); - e->string = e->compose; - - strcpy((char *)e->keyname, keyname); - strcpy((char *)e->key, key); - if (compose) strcpy((char *)e->compose, compose); - - e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state); - e->timestamp = xevent->time; - e->window = xevent->child ? xevent->child : xevent->event; - e->event_window = xevent->event; - e->same_screen = xevent->same_screen; - e->root_window = xevent->root; - - ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); - } - _ecore_xcb_event_last_time = xevent->time; -} - -void -_ecore_xcb_event_mouse_move(uint16_t timestamp, - uint16_t modifiers, - int16_t x, - int16_t y, - int16_t root_x, - int16_t root_y, - xcb_window_t event_win, - xcb_window_t win, - xcb_window_t root_win, - uint8_t same_screen, - int dev, - double radx, - double rady, - double pressure, - double angle, - int16_t mx, - int16_t my, - int16_t mrx, - int16_t mry) -{ - Ecore_Event_Mouse_Move *e; - Ecore_Event *event; - - if (!(e = malloc(sizeof(Ecore_Event_Mouse_Move)))) return; - - e->window = win; - e->root_window = root_win; - e->timestamp = timestamp; - e->same_screen = same_screen; - e->event_window = event_win; - e->modifiers = _ecore_xcb_events_modifiers_get(modifiers); - e->x = x; - e->y = y; - e->root.x = root_x; - e->root.y = root_y; - 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_xcb_event_mouse_move_free, NULL); - - _ecore_xcb_event_last_time = e->timestamp; - _ecore_xcb_event_last_window = e->window; - _ecore_xcb_event_last_root_x = root_x; - _ecore_xcb_event_last_root_y = root_y; -// _ecore_xcb_event_last_mouse_move_event = event; -} - -static void -_ecore_xcb_event_mouse_move_free(void *data EINA_UNUSED, - void *event) -{ - Ecore_Event_Mouse_Move *ev; - - ev = event; -// if (_ecore_xcb_event_last_mouse_move_event) -// { -// _ecore_xcb_event_last_mouse_move = EINA_FALSE; -// _ecore_xcb_event_last_mouse_move_event = NULL; -// } - if (ev) free(ev); -} - -Ecore_Event_Mouse_Button * -_ecore_xcb_event_mouse_button(int event, - uint16_t timestamp, - uint16_t modifiers, - xcb_button_t buttons, - int16_t x, - int16_t y, - int16_t root_x, - int16_t root_y, - xcb_window_t event_win, - xcb_window_t win, - xcb_window_t root_win, - uint8_t same_screen, - int dev, - double radx, - double rady, - double pressure, - double angle, - int16_t mx, - int16_t my, - int16_t mrx, - int16_t mry) -{ - Ecore_Event_Mouse_Button *e; - Ecore_X_Mouse_Down_Info *info = NULL; - - if (!(e = malloc(sizeof(Ecore_Event_Mouse_Button)))) return NULL; - - e->window = win; - e->root_window = root_win; - e->timestamp = timestamp; - e->same_screen = same_screen; - e->event_window = event_win; - e->buttons = buttons; - e->modifiers = _ecore_xcb_events_modifiers_get(modifiers); - e->double_click = 0; - e->triple_click = 0; - e->x = x; - e->y = y; - e->root.x = root_x; - e->root.y = root_y; - - if ((info = _ecore_xcb_event_mouse_down_info_get(dev))) - { - if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && - (info->did_triple)) - { - info->last_win = 0; - info->last_last_win = 0; - info->last_event_win = 0; - info->last_time = 0; - info->last_last_time = 0; - } - if (event_win == win) - { - if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) - { - if (((int)(timestamp - info->last_time) <= - (int)(1000 * _ecore_xcb_double_click_time)) && - (win == info->last_win) && - (event_win == info->last_event_win)) - { - e->double_click = 1; - info->did_double = EINA_TRUE; - } - else - { - info->did_double = EINA_FALSE; - info->did_triple = EINA_FALSE; - } - if (((int)(timestamp - info->last_last_time) <= - (int)(2 * 1000 * _ecore_xcb_double_click_time)) && - (win == info->last_win) && - (win == info->last_last_win) && - (event_win == info->last_event_win) && - (event_win == info->last_last_event_win)) - { - e->triple_click = 1; - info->did_triple = EINA_TRUE; - } - else - info->did_triple = EINA_FALSE; - } - else - { - if (info->did_double) e->double_click = 1; - if (info->did_triple) e->triple_click = 1; - } - } - } - - /* NB: Comment out right now because _ecore_xcb_mouse_up_count is - * only used here...nowhere else in the code */ - - /* if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && */ - /* (!e->double_click) && (!e->triple_click)) */ - /* _ecore_xcb_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_xcb_event_last_time = e->timestamp; - _ecore_xcb_event_last_window = e->window; - _ecore_xcb_event_last_root_x = root_x; - _ecore_xcb_event_last_root_y = root_y; - - ecore_event_add(event, e, NULL, NULL); - - if ((info) && (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && - (win == event_win) && (!info->did_triple)) - { - info->last_last_win = info->last_win; - info->last_win = win; - info->last_last_event_win = info->last_event_win; - info->last_event_win = event_win; - info->last_last_time = info->last_time; - info->last_time = timestamp; - } - - return e; -} - -static Ecore_X_Event_Mode -_ecore_xcb_event_mode_get(uint8_t mode) -{ - switch (mode) - { - case XCB_NOTIFY_MODE_NORMAL: - return ECORE_X_EVENT_MODE_NORMAL; - - case XCB_NOTIFY_MODE_WHILE_GRABBED: - return ECORE_X_EVENT_MODE_WHILE_GRABBED; - - case XCB_NOTIFY_MODE_GRAB: - return ECORE_X_EVENT_MODE_GRAB; - - case XCB_NOTIFY_MODE_UNGRAB: - return ECORE_X_EVENT_MODE_UNGRAB; - - default: - return ECORE_X_EVENT_MODE_NORMAL; - } -} - -static Ecore_X_Event_Detail -_ecore_xcb_event_detail_get(uint8_t detail) -{ - switch (detail) - { - case XCB_NOTIFY_DETAIL_ANCESTOR: - return ECORE_X_EVENT_DETAIL_ANCESTOR; - - case XCB_NOTIFY_DETAIL_VIRTUAL: - return ECORE_X_EVENT_DETAIL_VIRTUAL; - - case XCB_NOTIFY_DETAIL_INFERIOR: - return ECORE_X_EVENT_DETAIL_INFERIOR; - - case XCB_NOTIFY_DETAIL_NONLINEAR: - return ECORE_X_EVENT_DETAIL_NON_LINEAR; - - case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: - return ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; - - case XCB_NOTIFY_DETAIL_POINTER: - return ECORE_X_EVENT_DETAIL_POINTER; - - case XCB_NOTIFY_DETAIL_POINTER_ROOT: - return ECORE_X_EVENT_DETAIL_POINTER_ROOT; - - case XCB_NOTIFY_DETAIL_NONE: - default: - return ECORE_X_EVENT_DETAIL_ANCESTOR; - } -} - -static void -_ecore_xcb_event_xdnd_enter_free(void *data EINA_UNUSED, - void *event) -{ - Ecore_X_Event_Xdnd_Enter *e; - int i = 0; - - e = event; - for (i = 0; i < e->num_types; i++) - free(e->types[i]); - free(e->types); - free(e); -} - -static void -_ecore_xcb_event_selection_notify_free(void *data EINA_UNUSED, - void *event) -{ - Ecore_X_Event_Selection_Notify *e; - Ecore_X_Selection_Data *sel; - - e = event; - if (!(sel = e->data)) return; - if (sel->free) sel->free(sel); - free(e->target); - free(e); -} - -static void -_ecore_xcb_event_generic_event_free(void *data, - void *event) -{ - Ecore_X_Event_Generic *e; - - e = (Ecore_X_Event_Generic *)event; - if (e->data) free(data); - free(e); -} - -static void -_ecore_xcb_event_mouse_down_info_clear(void) -{ - Eina_Inlist *l; - Ecore_X_Mouse_Down_Info *info = NULL; - - l = _ecore_xcb_mouse_down_info_list; - while (l) - { - info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info); - l = eina_inlist_remove(l, l); - free(info); - } - _ecore_xcb_mouse_down_info_list = NULL; -} - -static Ecore_X_Mouse_Down_Info * -_ecore_xcb_event_mouse_down_info_get(int dev) -{ - Eina_Inlist *l; - Ecore_X_Mouse_Down_Info *info = NULL; - - l = _ecore_xcb_mouse_down_info_list; - EINA_INLIST_FOREACH(l, info) - if (info->dev == dev) return info; - - if (!(info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info)))) return NULL; - - info->dev = dev; - l = eina_inlist_append(l, (Eina_Inlist *)info); - _ecore_xcb_mouse_down_info_list = l; - - return info; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_extensions.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_extensions.c deleted file mode 100644 index 40c10ac05b..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_extensions.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "ecore_xcb_private.h" - -void -_ecore_xcb_extensions_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shm_id); - -#ifdef ECORE_XCB_SHAPE - _ecore_xcb_shape_init(); -#endif - -#ifdef ECORE_XCB_SCREENSAVER - _ecore_xcb_screensaver_init(); -#endif - -#ifdef ECORE_XCB_SYNC - _ecore_xcb_sync_init(); -#endif - -#ifdef ECORE_XCB_RANDR - _ecore_xcb_randr_init(); -#endif - -#ifdef ECORE_XCB_XFIXES - _ecore_xcb_xfixes_init(); -#endif - -#ifdef ECORE_XCB_DAMAGE - _ecore_xcb_damage_init(); -#endif - -#ifdef ECORE_XCB_RENDER - _ecore_xcb_render_init(); -#endif - -#ifdef ECORE_XCB_COMPOSITE - _ecore_xcb_composite_init(); -#endif - -#ifdef ECORE_XCB_DPMS - _ecore_xcb_dpms_init(); -#endif - -#ifdef ECORE_XCB_DPMS - _ecore_xcb_dpms_init(); -#endif - -#ifdef ECORE_XCB_CURSOR - _ecore_xcb_cursor_init(); -#endif - -#ifdef ECORE_XCB_XINERAMA - _ecore_xcb_xinerama_init(); -#endif - -#ifdef ECORE_XCB_XINPUT - _ecore_xcb_input_init(); -#endif - -#ifdef ECORE_XCB_GESTURE - _ecore_xcb_gesture_init(); -#endif - -/* #ifdef ECORE_XCB_DRI */ -/* _ecore_xcb_dri_init(); */ -/* #endif */ - -#ifdef ECORE_XCB_XTEST - _ecore_xcb_xtest_init(); -#endif - - xcb_prefetch_maximum_request_length(_ecore_xcb_conn); -} - -void -_ecore_xcb_extensions_finalize(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xcb_get_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); - xcb_get_extension_data(_ecore_xcb_conn, &xcb_shm_id); - -#ifdef ECORE_XCB_SHAPE - _ecore_xcb_shape_finalize(); -#endif - -#ifdef ECORE_XCB_SCREENSAVER - _ecore_xcb_screensaver_finalize(); -#endif - -#ifdef ECORE_XCB_SYNC - _ecore_xcb_sync_finalize(); -#endif - -#ifdef ECORE_XCB_RANDR - _ecore_xcb_randr_finalize(); -#endif - -#ifdef ECORE_XCB_XFIXES - _ecore_xcb_xfixes_finalize(); -#endif - -#ifdef ECORE_XCB_DAMAGE - _ecore_xcb_damage_finalize(); -#endif - -#ifdef ECORE_XCB_RENDER - _ecore_xcb_render_finalize(); -#endif - -#ifdef ECORE_XCB_COMPOSITE - _ecore_xcb_composite_finalize(); -#endif - -#ifdef ECORE_XCB_DPMS - _ecore_xcb_dpms_finalize(); -#endif - -#ifdef ECORE_XCB_CURSOR - _ecore_xcb_cursor_finalize(); -#endif - -#ifdef ECORE_XCB_XINERAMA - _ecore_xcb_xinerama_finalize(); -#endif - -#ifdef ECORE_XCB_XINPUT - _ecore_xcb_input_finalize(); -#endif - -#ifdef ECORE_XCB_GESTURE - _ecore_xcb_gesture_finalize(); -#endif - -/* #ifdef ECORE_XCB_DRI */ -/* _ecore_xcb_dri_finalize(); */ -/* #endif */ - -#ifdef ECORE_XCB_XTEST - _ecore_xcb_xtest_finalize(); -#endif - - xcb_get_maximum_request_length(_ecore_xcb_conn); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_gc.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_gc.c deleted file mode 100644 index d811b54594..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_gc.c +++ /dev/null @@ -1,173 +0,0 @@ -#include "ecore_xcb_private.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 drawable, - Ecore_X_GC_Value_Mask value_mask, - const unsigned int *value_list) -{ - xcb_gcontext_t gc; - uint32_t vmask = 0; - int i = 0, mask = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!drawable) drawable = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - for (i = 0, mask = 1; i <= 22; i++, mask <<= 1) - { - switch (mask & value_mask) - { - case ECORE_X_GC_VALUE_MASK_FUNCTION: - vmask |= XCB_GC_FUNCTION; - break; - - case ECORE_X_GC_VALUE_MASK_PLANE_MASK: - vmask |= XCB_GC_PLANE_MASK; - break; - - case ECORE_X_GC_VALUE_MASK_FOREGROUND: - vmask |= XCB_GC_FOREGROUND; - break; - - case ECORE_X_GC_VALUE_MASK_BACKGROUND: - vmask |= XCB_GC_BACKGROUND; - break; - - case ECORE_X_GC_VALUE_MASK_LINE_WIDTH: - vmask |= XCB_GC_LINE_WIDTH; - break; - - case ECORE_X_GC_VALUE_MASK_LINE_STYLE: - vmask |= XCB_GC_LINE_STYLE; - break; - - case ECORE_X_GC_VALUE_MASK_CAP_STYLE: - vmask |= XCB_GC_CAP_STYLE; - break; - - case ECORE_X_GC_VALUE_MASK_JOIN_STYLE: - vmask |= XCB_GC_JOIN_STYLE; - break; - - case ECORE_X_GC_VALUE_MASK_FILL_STYLE: - vmask |= XCB_GC_FILL_STYLE; - break; - - case ECORE_X_GC_VALUE_MASK_FILL_RULE: - vmask |= XCB_GC_FILL_RULE; - break; - - case ECORE_X_GC_VALUE_MASK_TILE: - vmask |= XCB_GC_TILE; - break; - - case ECORE_X_GC_VALUE_MASK_STIPPLE: - vmask |= XCB_GC_STIPPLE; - break; - - case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X: - vmask |= XCB_GC_TILE_STIPPLE_ORIGIN_X; - break; - - case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y: - vmask |= XCB_GC_TILE_STIPPLE_ORIGIN_Y; - break; - - case ECORE_X_GC_VALUE_MASK_FONT: - vmask |= XCB_GC_FONT; - break; - - case ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE: - vmask |= XCB_GC_SUBWINDOW_MODE; - break; - - case ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES: - vmask |= XCB_GC_GRAPHICS_EXPOSURES; - break; - - case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X: - vmask |= XCB_GC_CLIP_ORIGIN_X; - break; - - case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y: - vmask |= XCB_GC_CLIP_ORIGIN_Y; - break; - - case ECORE_X_GC_VALUE_MASK_CLIP_MASK: - vmask |= XCB_GC_CLIP_MASK; - break; - - case ECORE_X_GC_VALUE_MASK_DASH_OFFSET: - vmask |= XCB_GC_DASH_OFFSET; - break; - - case ECORE_X_GC_VALUE_MASK_DASH_LIST: - vmask |= XCB_GC_DASH_LIST; - break; - - case ECORE_X_GC_VALUE_MASK_ARC_MODE: - vmask |= XCB_GC_ARC_MODE; - break; - } - } - - gc = xcb_generate_id(_ecore_xcb_conn); - xcb_create_gc(_ecore_xcb_conn, gc, drawable, vmask, value_list); - -// ecore_x_flush(); - return gc; -} - -/** - * 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__); - CHECK_XCB_CONN; - - xcb_free_gc(_ecore_xcb_conn, gc); -// ecore_x_flush(); -} - -EAPI void -ecore_x_gc_foreground_set(Ecore_X_GC gc, - unsigned long foreground) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = foreground; - xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list); -// ecore_x_flush(); -} - -EAPI void -ecore_x_gc_background_set(Ecore_X_GC gc, - unsigned long background) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = background; - xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_BACKGROUND, &list); -// ecore_x_flush(); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_gesture.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_gesture.c deleted file mode 100644 index 27c13167af..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_gesture.c +++ /dev/null @@ -1,203 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_XGESTURE -# include -# include -#endif - -/* local variables */ -static Eina_Bool _gesture_available = EINA_FALSE; - -/* external variables */ -int _ecore_xcb_event_gesture = -1; - -void -_ecore_xcb_gesture_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XGESTURE - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_gesture_id); -#endif -} - -void -_ecore_xcb_gesture_finalize(void) -{ -#ifdef ECORE_XCB_XGESTURE - xcb_gesture_query_version_cookie_t cookie; - xcb_gesture_query_version_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XGESTURE - cookie = - xcb_gesture_query_version_unchecked(_ecore_xcb_conn); - reply = - xcb_gesture_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - _gesture_available = EINA_TRUE; - free(reply); - } - - if (_gesture_available) - { - const xcb_query_extension_reply_t *ext_reply; - - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_gesture_id); - if (ext_reply) - _ecore_xcb_event_gesture = ext_reply->first_event; - } -#endif -} - -void -_ecore_xcb_gesture_shutdown(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); -} - -EAPI Eina_Bool -ecore_x_gesture_supported(void) -{ - return _gesture_available; -} - -#ifdef ECORE_XCB_XGESTURE -EAPI Eina_Bool -ecore_x_gesture_events_select(Ecore_X_Window win, - Ecore_X_Gesture_Event_Mask mask) -#else -EAPI Eina_Bool -ecore_x_gesture_events_select(Ecore_X_Window win EINA_UNUSED, - Ecore_X_Gesture_Event_Mask mask EINA_UNUSED) -#endif - -{ -#ifdef ECORE_XCB_XGESTURE - if (!_gesture_available) return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN - - xcb_gesture_select_events(_ecore_xcb_conn, win, mask); - - return EINA_TRUE; -#else - return EINA_FALSE; -#endif -} - -#ifdef ECORE_XCB_XGESTURE -EAPI Ecore_X_Gesture_Event_Mask -ecore_x_gesture_events_selected_get(Ecore_X_Window win) -#else -EAPI Ecore_X_Gesture_Event_Mask -ecore_x_gesture_events_selected_get(Ecore_X_Window win EINA_UNUSED) -#endif -{ -#ifdef ECORE_XCB_XGESTURE - xcb_gesture_get_selected_events_cookie_t ecookie; - xcb_gesture_get_selected_events_reply_t *ereply; - Ecore_X_Gesture_Event_Mask mask = ECORE_X_GESTURE_EVENT_MASK_NONE; - - if (!_gesture_available) return mask; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN - - ecookie = xcb_gesture_get_selected_events(_ecore_xcb_conn, win); - ereply = - xcb_gesture_get_selected_events_reply(_ecore_xcb_conn, ecookie, NULL); - if (ereply) - { - mask = ereply->mask; - free(ereply); - } - - return mask; -#else - return ECORE_X_GESTURE_EVENT_MASK_NONE; -#endif -} - -#ifdef ECORE_XCB_XGESTURE -EAPI Eina_Bool -ecore_x_gesture_event_grab(Ecore_X_Window win, - Ecore_X_Gesture_Event_Type type, - int num_fingers) -#else -EAPI Eina_Bool -ecore_x_gesture_event_grab(Ecore_X_Window win EINA_UNUSED, - Ecore_X_Gesture_Event_Type type EINA_UNUSED, - int num_fingers EINA_UNUSED) -#endif -{ -#ifdef ECORE_XCB_XGESTURE - Eina_Bool status = EINA_TRUE; - xcb_gesture_grab_event_cookie_t ecookie; - xcb_gesture_grab_event_reply_t *ereply; - - if (!_gesture_available) return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN - - ecookie = - xcb_gesture_grab_event(_ecore_xcb_conn, win, type, num_fingers, 0L); - ereply = xcb_gesture_grab_event_reply(_ecore_xcb_conn, ecookie, NULL); - - if (ereply) - { - if (ereply->status) status = EINA_FALSE; - free(ereply); - } - else - status = EINA_FALSE; - - return status; -#else - return EINA_FALSE; -#endif -} - -#ifdef ECORE_XCB_XGESTURE -EAPI Eina_Bool -ecore_x_gesture_event_ungrab(Ecore_X_Window win, - Ecore_X_Gesture_Event_Type type, - int num_fingers) -#else -EAPI Eina_Bool -ecore_x_gesture_event_ungrab(Ecore_X_Window win EINA_UNUSED, - Ecore_X_Gesture_Event_Type type EINA_UNUSED, - int num_fingers EINA_UNUSED) -#endif -{ -#ifdef ECORE_XCB_XGESTURE - Eina_Bool status = EINA_TRUE; - xcb_gesture_ungrab_event_cookie_t ecookie; - xcb_gesture_ungrab_event_reply_t *ereply; - - if (!_gesture_available) return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN - - ecookie = - xcb_gesture_ungrab_event(_ecore_xcb_conn, win, type, num_fingers, 0L); - ereply = xcb_gesture_ungrab_event_reply(_ecore_xcb_conn, ecookie, NULL); - - if (ereply) - { - if (ereply->status) status = EINA_FALSE; - free(ereply); - } - else - status = EINA_FALSE; - - return status; -#else - return EINA_FALSE; -#endif -} diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_icccm.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_icccm.c deleted file mode 100644 index 8dea8617d1..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_icccm.c +++ /dev/null @@ -1,1569 +0,0 @@ -#include "ecore_xcb_private.h" -#include - -EAPI void -ecore_x_icccm_init(void) -{ -} - -/** - * 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) -{ - void *buf; - char *b; - int nbytes, i; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - for (i = 0, nbytes = 0; i < argc; i++) - if (argv[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, win, - ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8, - nbytes, buf); - free(buf); -} - -/** - * 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) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - int len = 0; - char **v, *data, *cp, *start; - int c = 0, i = 0, j = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (argc) *argc = 0; - if (argv) *argv = NULL; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, - ECORE_X_ATOM_WM_COMMAND, - XCB_GET_PROPERTY_TYPE_ANY, - 0, 1000000L); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - - if ((reply->type != ECORE_X_ATOM_STRING) || (reply->format != 8)) - { - free(reply); - return; - } - - len = reply->value_len; - if (len < 1) - { - free(reply); - return; - } - - data = (char *)xcb_get_property_value(reply); - if (len && (data[len - 1] == '\0')) - len--; - - c = 1; - for (cp = (char *)data, i = len; i > 0; cp++, i--) - if (*cp == '\0') c++; - - v = (char **)malloc((c + 1) * sizeof(char *)); - if (!v) - { - free(reply); - return; - } - - start = (char *)malloc((len + 1) * sizeof(char)); - if (!start) - { - free(reply); - free(v); - return; - } - - memcpy(start, (char *)data, len); - start[len] = '\0'; - for (cp = start, i = len + 1, j = 0; i > 0; cp++, i--) - { - if (*cp == '\0') - { - v[j] = start; - start = (cp + 1); - j++; - } - } - - if (c < 1) - { - free(reply); - free(v); - return; - } - - if (argc) *argc = c; - - if (argv) - { - (*argv) = malloc(c * sizeof(char *)); - if (!*argv) - { - free(reply); - 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(reply); - free(v); -} - -EAPI char * -ecore_x_icccm_title_get(Ecore_X_Window win) -{ - xcb_get_property_cookie_t cookie; -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_t prop; -#else - xcb_icccm_get_text_property_reply_t prop; -#endif - uint8_t ret = 0; - char *title = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return NULL; -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_name_unchecked(_ecore_xcb_conn, win); - ret = xcb_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); -#else - cookie = xcb_icccm_get_wm_name_unchecked(_ecore_xcb_conn, win); - ret = xcb_icccm_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); -#endif - if (ret == 0) return NULL; - if (prop.name_len < 1) - { -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_wipe(&prop); -#else - xcb_icccm_get_text_property_reply_wipe(&prop); -#endif - return NULL; - } - - if (!(title = malloc((prop.name_len + 1) * sizeof(char *)))) - { -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_wipe(&prop); -#else - xcb_icccm_get_text_property_reply_wipe(&prop); -#endif - return NULL; - } - memcpy(title, prop.name, sizeof(char *) * prop.name_len); - title[prop.name_len] = '\0'; - - if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) - { - Ecore_Xcb_Textproperty tp; - int count = 0; - char **list = NULL; - Eina_Bool ret = EINA_FALSE; - - tp.value = strdup(title); - tp.nitems = prop.name_len; - tp.encoding = prop.encoding; -#ifdef HAVE_ICONV - ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); -#else - ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); -#endif - if (ret) - { - if (count > 0) - title = strdup(list[0]); - - if (list) free(list); - } - } - -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_wipe(&prop); -#else - xcb_icccm_get_text_property_reply_wipe(&prop); -#endif - return title; -} - -EAPI void -ecore_x_icccm_title_set(Ecore_X_Window win, - const char *title) -{ - Ecore_Xcb_Textproperty prop; - char *list[1]; - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!title) return; - - prop.value = NULL; - list[0] = strdup(title); - -#ifdef HAVE_ICONV - ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle, - &prop); -#else - ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle, - &prop); -#endif - - if (ret) - { -#ifdef OLD_XCB_VERSION - xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, - strlen(prop.value), prop.value); -#else - xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8, - strlen(prop.value), prop.value); -#endif - if (prop.value) free(prop.value); - } - else -#ifdef OLD_XCB_VERSION - xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, - strlen(title), title); -#else - xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8, - strlen(title), title); -#endif - free(list[0]); -} - -/** - * 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 **name, - char **class) -{ - xcb_get_property_cookie_t cookie; -#ifdef OLD_XCB_VERSION - xcb_get_wm_class_reply_t prop; -#else - xcb_icccm_get_wm_class_reply_t prop; -#endif - uint8_t ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (name) *name = NULL; - if (class) *class = NULL; - -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_class_unchecked(_ecore_xcb_conn, win); - ret = xcb_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL); -#else - cookie = xcb_icccm_get_wm_class_unchecked(_ecore_xcb_conn, win); - ret = xcb_icccm_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL); -#endif - if (ret == 0) return; - - if (name) *name = strdup(prop.instance_name); - if (class) *class = strdup(prop.class_name); - -#ifdef OLD_XCB_VERSION - xcb_get_wm_class_reply_wipe(&prop); -#else - xcb_icccm_get_wm_class_reply_wipe(&prop); -#endif -} - -/** - * 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 *name, - const char *class) -{ - char *class_string, *s; - int length_name, length_class; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - 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, win, - ECORE_X_ATOM_WM_CLASS, ECORE_X_ATOM_STRING, 8, - length_name + length_class + 2, (void *)class_string); - free(class_string); -} - -/** - * 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 forwindow) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, - ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32, - 1, (void *)&forwindow); -} - -/** - * Remove the transient_for setting from a window. - * @param win The window - */ -EAPI void -ecore_x_icccm_transient_for_unset(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_window_prop_property_del(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) -{ - Ecore_X_Window forwin = 0; - xcb_get_property_cookie_t cookie; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_transient_for_unchecked(_ecore_xcb_conn, win); - xcb_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL); -#else - cookie = xcb_icccm_get_wm_transient_for_unchecked(_ecore_xcb_conn, win); - xcb_icccm_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL); -#endif - - return forwin; -} - -/** - * 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 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, role); -} - -/** - * 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 leader; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER, - &leader, 1) > 0) - return leader; - - return 0; -} - -/** - * 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 leader) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER, - &leader, 1); -} - -EAPI Ecore_X_Window_State_Hint -ecore_x_icccm_state_get(Ecore_X_Window win) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE; - uint8_t *prop; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = - xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, - ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE, - 0L, 0x7fffffff); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return hint; - if ((reply->type == 0) || (reply->format != 8) || (reply->value_len != 2)) - { - free(reply); - return hint; - } - - prop = (uint8_t *)xcb_get_property_value(reply); -#ifdef OLD_XCB_VERSION - 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: - break; - } -#else - switch (prop[0]) - { - case XCB_ICCCM_WM_STATE_WITHDRAWN: - hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; - break; - - case XCB_ICCCM_WM_STATE_NORMAL: - hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; - break; - - case XCB_ICCCM_WM_STATE_ICONIC: - hint = ECORE_X_WINDOW_STATE_HINT_ICONIC; - break; - - default: - break; - } -#endif - - free(reply); - return hint; -} - -EAPI void -ecore_x_icccm_state_set(Ecore_X_Window win, - Ecore_X_Window_State_Hint state) -{ -#ifdef OLD_XCB_VERSION - xcb_wm_hints_t hints; -#else - xcb_icccm_wm_hints_t hints; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef OLD_XCB_VERSION - xcb_wm_hints_set_none(&hints); - - hints.flags = XCB_WM_HINT_STATE; - - if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) - xcb_wm_hints_set_withdrawn(&hints); - else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) - xcb_wm_hints_set_normal(&hints); - else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) - xcb_wm_hints_set_iconic(&hints); - - xcb_set_wm_hints(_ecore_xcb_conn, win, &hints); -#else - xcb_icccm_wm_hints_set_none(&hints); - - hints.flags = XCB_ICCCM_WM_HINT_STATE; - - if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) - xcb_icccm_wm_hints_set_withdrawn(&hints); - else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) - xcb_icccm_wm_hints_set_normal(&hints); - else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) - xcb_icccm_wm_hints_set_iconic(&hints); - - xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints); -#endif -} - -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_hints_set(Ecore_X_Window win, - Eina_Bool 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, - Eina_Bool is_urgent) -{ -#ifdef OLD_XCB_VERSION - xcb_wm_hints_t hints; -#else - xcb_icccm_wm_hints_t hints; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef OLD_XCB_VERSION - xcb_wm_hints_set_none(&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, win, &hints); -#else - xcb_icccm_wm_hints_set_none(&hints); - xcb_icccm_wm_hints_set_input(&hints, accepts_focus); - - if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) - xcb_icccm_wm_hints_set_withdrawn(&hints); - else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL) - xcb_icccm_wm_hints_set_normal(&hints); - else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC) - xcb_icccm_wm_hints_set_iconic(&hints); - - if (icon_pixmap != 0) - xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap); - if (icon_mask != 0) - xcb_icccm_wm_hints_set_icon_mask(&hints, icon_mask); - if (icon_window != 0) - xcb_icccm_wm_hints_set_icon_window(&hints, icon_window); - if (window_group != 0) - xcb_icccm_wm_hints_set_window_group(&hints, window_group); - if (is_urgent) - xcb_icccm_wm_hints_set_urgency(&hints); - - xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints); -#endif -} - -EAPI Eina_Bool -ecore_x_icccm_hints_get(Ecore_X_Window win, - Eina_Bool *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, - Eina_Bool *is_urgent) -{ - xcb_get_property_cookie_t cookie; -#ifdef OLD_XCB_VERSION - xcb_wm_hints_t hints; -#else - xcb_icccm_wm_hints_t hints; -#endif - uint8_t ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (accepts_focus) *accepts_focus = EINA_TRUE; - 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 = EINA_FALSE; - -#ifdef OLD_XCB_VERSION - xcb_wm_hints_set_none(&hints); - cookie = xcb_get_wm_hints_unchecked(_ecore_xcb_conn, win); - ret = xcb_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); -#else - xcb_icccm_wm_hints_set_none(&hints); - cookie = xcb_icccm_get_wm_hints_unchecked(_ecore_xcb_conn, win); - ret = xcb_icccm_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); -#endif - if (!ret) return EINA_FALSE; - -#ifdef OLD_XCB_VERSION - if ((hints.flags & XCB_WM_HINT_INPUT) && (accepts_focus)) -#else - if ((hints.flags & XCB_ICCCM_WM_HINT_INPUT) && (accepts_focus)) -#endif - { - if (hints.input) - *accepts_focus = EINA_TRUE; - else - *accepts_focus = EINA_FALSE; - } - -#ifdef OLD_XCB_VERSION - if ((hints.flags & XCB_WM_HINT_STATE) && (initial_state)) - { - if (hints.initial_state == XCB_WM_STATE_WITHDRAWN) - *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; - else if (hints.initial_state == XCB_WM_STATE_NORMAL) - *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; - else if (hints.initial_state == XCB_WM_STATE_ICONIC) - *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; - } - - if ((hints.flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap)) - *icon_pixmap = hints.icon_pixmap; - - if ((hints.flags & XCB_WM_HINT_ICON_MASK) && (icon_mask)) - *icon_mask = hints.icon_mask; - - if ((hints.flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window)) - *icon_window = hints.icon_window; - - if ((hints.flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group)) - *window_group = hints.window_group; - - if ((hints.flags & XCB_WM_HINT_X_URGENCY) && (is_urgent)) - *is_urgent = EINA_TRUE; -#else - if ((hints.flags & XCB_ICCCM_WM_HINT_STATE) && (initial_state)) - { - if (hints.initial_state == XCB_ICCCM_WM_STATE_WITHDRAWN) - *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; - else if (hints.initial_state == XCB_ICCCM_WM_STATE_NORMAL) - *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; - else if (hints.initial_state == XCB_ICCCM_WM_STATE_ICONIC) - *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; - } - - if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_PIXMAP) && (icon_pixmap)) - *icon_pixmap = hints.icon_pixmap; - - if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_MASK) && (icon_mask)) - *icon_mask = hints.icon_mask; - - if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_WINDOW) && (icon_window)) - *icon_window = hints.icon_window; - - if ((hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) && (window_group)) - *window_group = hints.window_group; - - if ((hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) && (is_urgent)) - *is_urgent = EINA_TRUE; -#endif - - return EINA_TRUE; -} - -/** - * 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) -{ - xcb_get_property_cookie_t cookie; -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_t prop; -#else - xcb_icccm_get_text_property_reply_t prop; -#endif - uint8_t ret = 0; - char *tmp = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return NULL; - -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_icon_name_unchecked(_ecore_xcb_conn, win); - ret = xcb_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); -#else - cookie = xcb_icccm_get_wm_icon_name_unchecked(_ecore_xcb_conn, win); - ret = xcb_icccm_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); -#endif - if (ret == 0) return NULL; - - if (prop.name_len < 1) - { -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_wipe(&prop); -#else - xcb_icccm_get_text_property_reply_wipe(&prop); -#endif - return NULL; - } - - if (!(tmp = malloc((prop.name_len + 1) * sizeof(char *)))) - { -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_wipe(&prop); -#else - xcb_icccm_get_text_property_reply_wipe(&prop); -#endif - return NULL; - } - memcpy(tmp, prop.name, sizeof(char *) * prop.name_len); - tmp[prop.name_len] = '\0'; - - if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) - { - Ecore_Xcb_Textproperty tp; - int count = 0; - char **list = NULL; - Eina_Bool ret = EINA_FALSE; - - tp.value = strdup(tmp); - tp.nitems = prop.name_len; - tp.encoding = prop.encoding; -#ifdef HAVE_ICONV - ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); -#else - ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); -#endif - if (ret) - { - if (count > 0) - tmp = strdup(list[0]); - - if (list) free(list); - } - } - -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_wipe(&prop); -#else - xcb_icccm_get_text_property_reply_wipe(&prop); -#endif - return tmp; -} - -/** - * 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 *name) -{ - Ecore_Xcb_Textproperty prop; - char *list[1]; - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!win) || (!name)) return; - - prop.value = NULL; - list[0] = strdup(name); - -#ifdef HAVE_ICONV - ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle, - &prop); -#else - ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle, - &prop); -#endif - - if (ret) - { -#ifdef OLD_XCB_VERSION - xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, - strlen(prop.value), prop.value); -#else - xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, - 8, strlen(prop.value), prop.value); -#endif - if (prop.value) free(prop.value); - } - else -#ifdef OLD_XCB_VERSION - xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, - strlen(name), name); -#else - xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, - 8, strlen(name), name); -#endif - - free(list[0]); -} - -EAPI void -ecore_x_icccm_iconic_request_send(Ecore_X_Window win, - Ecore_X_Window root) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_WM_CHANGE_STATE; -#ifdef OLD_XCB_VERSION - ev.data.data32[0] = XCB_WM_STATE_ICONIC; -#else - ev.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC; -#endif - - xcb_send_event(_ecore_xcb_conn, 0, root, - (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT), - (const char *)&ev); -// ecore_x_flush(); -} - -/** - * 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, - Eina_Bool on) -{ - Ecore_X_Atom proto; - xcb_get_property_cookie_t cookie; -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_t protos; -#else - xcb_icccm_get_wm_protocols_reply_t protos; -#endif - int i = 0, count = 0, set = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return; - proto = _ecore_xcb_atoms_wm_protocol[protocol]; -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); - if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL)) -#else - cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); - if (!xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL)) -#endif - count = 0; - else - count = protos.atoms_len; - - for (i = 0; i < count; i++) - { - if (protos.atoms[i] == proto) - { - set = 1; - break; - } - } - - if (on) - { - if (!set) - { - Ecore_X_Atom *atoms = NULL; - - atoms = malloc((count + 1) * sizeof(Ecore_X_Atom)); - if (atoms) - { - for (i = 0; i < count; i++) - atoms[i] = protos.atoms[i]; - atoms[count] = proto; -#ifdef OLD_XCB_VERSION - xcb_set_wm_protocols(_ecore_xcb_conn, - ECORE_X_ATOM_WM_PROTOCOLS, - win, count, atoms); -#else - xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, - ECORE_X_ATOM_WM_PROTOCOLS, - count, atoms); -#endif - free(atoms); - } - } - } - else - { - if (set) - { - for (i = 0; i < count; i++) - { - if (protos.atoms[i] == proto) - { - int j = 0; - - for (j = (i + 1); j < count; j++) - protos.atoms[j - 1] = protos.atoms[j]; - if (count > 1) -#ifdef OLD_XCB_VERSION - xcb_set_wm_protocols(_ecore_xcb_conn, - ECORE_X_ATOM_WM_PROTOCOLS, - win, count - 1, protos.atoms); -#else - xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, - ECORE_X_ATOM_WM_PROTOCOLS, - count - 1, protos.atoms); -#endif - else - ecore_x_window_prop_property_del(win, - ECORE_X_ATOM_WM_PROTOCOLS); - break; - } - } - } - } - -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_wipe(&protos); -#else - xcb_icccm_get_wm_protocols_reply_wipe(&protos); -#endif -} - -/** - * 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 Eina_Bool -ecore_x_icccm_protocol_isset(Ecore_X_Window win, - Ecore_X_WM_Protocol protocol) -{ - Ecore_X_Atom proto; - Eina_Bool ret = EINA_FALSE; - xcb_get_property_cookie_t cookie; -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_t reply; -#else - xcb_icccm_get_wm_protocols_reply_t reply; -#endif - uint8_t val = 0; - unsigned int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE; - - proto = _ecore_xcb_atoms_wm_protocol[protocol]; -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); - val = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL); -#else - cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); - val = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL); -#endif - if (!val) return EINA_FALSE; - - for (i = 0; i < reply.atoms_len; i++) - if (reply.atoms[i] == proto) - { - ret = EINA_TRUE; - break; - } - -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_wipe(&reply); -#else - xcb_icccm_get_wm_protocols_reply_wipe(&reply); -#endif - - return ret; -} - -/** - * 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__); - CHECK_XCB_CONN; - - if (num > 0) -#ifdef OLD_XCB_VERSION - xcb_set_wm_protocols(_ecore_xcb_conn, ECORE_X_ATOM_WM_PROTOCOLS, - win, num, protos); -#else - xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, - ECORE_X_ATOM_WM_PROTOCOLS, num, protos); -#endif - else - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_PROTOCOLS); -} - -EAPI Eina_Bool -ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, - Eina_Bool *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 hints; - xcb_get_property_cookie_t cookie; - uint8_t ret = 0; - int32_t minw = 0, minh = 0; - int32_t maxw = 32767, maxh = 32767; - int32_t basew = -1, baseh = -1; - int32_t stepx = -1, stepy = -1; - double mina = 0.0, maxa = 0.0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (request_pos) *request_pos = EINA_FALSE; - 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; - -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); - ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); -#else - cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); - ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, - &hints, NULL); -#endif - if (!ret) return EINA_FALSE; - -#ifdef OLD_XCB_VERSION - if ((hints.flags & XCB_SIZE_HINT_US_POSITION) || - (hints.flags & XCB_SIZE_HINT_P_POSITION)) -#else - if ((hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION) || - (hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION)) -#endif - { - if (request_pos) *request_pos = EINA_TRUE; - } - -#ifdef OLD_XCB_VERSION - if (hints.flags & XCB_SIZE_HINT_P_WIN_GRAVITY) -#else - if (hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY) -#endif - { - if (gravity) *gravity = hints.win_gravity; - } - -#ifdef OLD_XCB_VERSION - if (hints.flags & XCB_SIZE_HINT_P_MIN_SIZE) -#else - if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE) -#endif - { - minw = hints.min_width; - minh = hints.min_height; - } - -#ifdef OLD_XCB_VERSION - if (hints.flags & XCB_SIZE_HINT_P_MAX_SIZE) -#else - if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE) -#endif - { - maxw = hints.max_width; - maxh = hints.max_height; - if (maxw < minw) maxw = minw; - if (maxh < minh) maxh = minh; - } - -#ifdef OLD_XCB_VERSION - if (hints.flags & XCB_SIZE_HINT_BASE_SIZE) -#else - if (hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE) -#endif - { - basew = hints.base_width; - baseh = hints.base_height; - if (basew > minw) minw = basew; - if (baseh > minh) minh = baseh; - } - -#ifdef OLD_XCB_VERSION - if (hints.flags & XCB_SIZE_HINT_P_RESIZE_INC) -#else - if (hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC) -#endif - { - stepx = hints.width_inc; - stepy = hints.height_inc; - if (stepx < 1) stepx = 1; - if (stepy < 1) stepy = 1; - } - -#ifdef OLD_XCB_VERSION - if (hints.flags & XCB_SIZE_HINT_P_ASPECT) -#else - if (hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT) -#endif - { - if (hints.min_aspect_den > 0) - mina = ((double)hints.min_aspect_num) / ((double)hints.min_aspect_den); - - if (hints.max_aspect_den > 0) - maxa = ((double)hints.max_aspect_num) / ((double)hints.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 EINA_TRUE; -} - -EAPI void -ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, - Eina_Bool 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_get_property_cookie_t cookie; - xcb_size_hints_t hints; - uint8_t ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); - ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); -#else - cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); - ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, - &hints, NULL); -#endif - if (!ret) memset(&hints, 0, sizeof(xcb_size_hints_t)); - - hints.flags = 0; - -#ifdef OLD_XCB_VERSION - if (request_pos) - hints.flags |= XCB_SIZE_HINT_US_POSITION; - - if (gravity != ECORE_X_GRAVITY_NW) - xcb_size_hints_set_win_gravity(&hints, gravity); - if ((min_w > 0) || (min_h > 0)) - xcb_size_hints_set_min_size(&hints, min_w, min_h); - if ((max_w > 0) || (max_h > 0)) - xcb_size_hints_set_max_size(&hints, max_w, max_h); - if ((base_w > 0) || (base_h > 0)) - xcb_size_hints_set_base_size(&hints, base_w, base_h); - if ((step_x > 1) || (step_y > 1)) - xcb_size_hints_set_resize_inc(&hints, step_x, step_y); - if ((min_aspect > 0.0) || (max_aspect > 0.0)) - xcb_size_hints_set_aspect(&hints, - (int32_t)(min_aspect * 10000), 10000, - (int32_t)(max_aspect * 10000), 10000); - - xcb_set_wm_normal_hints(_ecore_xcb_conn, win, &hints); -#else - if (request_pos) - hints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION; - - if (gravity != ECORE_X_GRAVITY_NW) - xcb_icccm_size_hints_set_win_gravity(&hints, gravity); - if ((min_w > 0) || (min_h > 0)) - xcb_icccm_size_hints_set_min_size(&hints, min_w, min_h); - if ((max_w > 0) || (max_h > 0)) - xcb_icccm_size_hints_set_max_size(&hints, max_w, max_h); - if ((base_w > 0) || (base_h > 0)) - xcb_icccm_size_hints_set_base_size(&hints, base_w, base_h); - if ((step_x > 1) || (step_y > 1)) - xcb_icccm_size_hints_set_resize_inc(&hints, step_x, step_y); - if ((min_aspect > 0.0) || (max_aspect > 0.0)) - xcb_icccm_size_hints_set_aspect(&hints, - (int32_t)(min_aspect * 10000), 10000, - (int32_t)(max_aspect * 10000), 10000); - - xcb_icccm_set_wm_normal_hints(_ecore_xcb_conn, win, &hints); -#endif -} - -EAPI void -ecore_x_icccm_move_resize_send(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ - xcb_configure_notify_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - - memset(&ev, 0, sizeof(xcb_configure_notify_event_t)); - - ev.response_type = XCB_CONFIGURE_NOTIFY; - ev.event = win; - ev.window = win; - ev.above_sibling = XCB_NONE; - ev.x = x; - ev.y = y; - ev.width = w; - ev.height = h; - ev.border_width = 0; - ev.override_redirect = 0; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev); -// ecore_x_flush(); -} - -/** - * 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) -{ - xcb_get_property_cookie_t cookie; -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_t prop; -#else - xcb_icccm_get_text_property_reply_t prop; -#endif - uint8_t ret = 0; - char *tmp = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_client_machine_unchecked(_ecore_xcb_conn, win); - ret = xcb_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, &prop, NULL); -#else - cookie = xcb_icccm_get_wm_client_machine_unchecked(_ecore_xcb_conn, win); - ret = xcb_icccm_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, - &prop, NULL); -#endif - if (ret == 0) return NULL; - - tmp = malloc((prop.name_len + 1) * sizeof(char *)); - if (!tmp) - { -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_wipe(&prop); -#else - xcb_icccm_get_text_property_reply_wipe(&prop); -#endif - return NULL; - } - memcpy(tmp, prop.name, sizeof(char *) * prop.name_len); - tmp[prop.name_len] = '\0'; - -#ifdef OLD_XCB_VERSION - xcb_get_text_property_reply_wipe(&prop); -#else - xcb_icccm_get_text_property_reply_wipe(&prop); -#endif - - return tmp; -} - -EAPI void -ecore_x_icccm_take_focus_send(Ecore_X_Window win, - Ecore_X_Time t) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, - XCB_EVENT_MASK_NO_EVENT, - 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, - XCB_EVENT_MASK_NO_EVENT, - ECORE_X_ATOM_WM_SAVE_YOURSELF, t, 0, 0, 0); -} - -/** - * 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 = 0; - unsigned char *odata = NULL, *data = NULL; - Ecore_X_Window *newset = NULL, *oldset = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, - ECORE_X_ATOM_WINDOW, 32, &odata, &num)) - { - if (!(newset = calloc(1, sizeof(Ecore_X_Window)))) return; - newset[0] = subwin; - num = 1; - data = (unsigned char *)newset; - } - else - { - if (!(newset = calloc(num + 1, sizeof(Ecore_X_Window)))) return; - oldset = (Ecore_X_Window *)odata; - for (i = 0; i < num; i++) - { - if (oldset[i] == subwin) - { - if (odata) free(odata); - odata = NULL; - free(newset); - return; - } - newset[i] = oldset[i]; - } - newset[num++] = subwin; - if (odata) free(odata); - data = (unsigned char *)newset; - } - ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, - ECORE_X_ATOM_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 = 0, j = 0, k = 0; - unsigned char *odata = NULL, *data = NULL; - Ecore_X_Window *newset = NULL, *oldset = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, - ECORE_X_ATOM_WINDOW, 32, &odata, &num)) - return; - - oldset = (Ecore_X_Window *)odata; - for (i = 0; i < num; i++) - { - if (oldset[i] == subwin) - { - if (num == 1) - { - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS); - if (odata) free(odata); - odata = NULL; - return; - } - else - { - newset = calloc(num - 1, sizeof(Ecore_X_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, - ECORE_X_ATOM_WINDOW, 32, data, k); - if (odata) free(odata); - odata = NULL; - free(newset); - return; - } - } - } - if (odata) free(odata); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_image.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_image.c deleted file mode 100644 index 8e221101b0..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_image.c +++ /dev/null @@ -1,738 +0,0 @@ -#include "ecore_xcb_private.h" -#include -#include -#include -#include - -struct _Ecore_X_Image -{ - xcb_shm_segment_info_t shminfo; - xcb_image_t *xim; - Ecore_X_Visual vis; - int depth, w, h; - int bpl, bpp, rows; - unsigned char *data; - Eina_Bool shm : 1; -}; - -/* local function prototypes */ -static void _ecore_xcb_image_shm_check(void); -static void _ecore_xcb_image_shm_create(Ecore_X_Image *im); -static xcb_format_t *_ecore_xcb_image_find_format(const xcb_setup_t *setup, - uint8_t depth); - -/* local variables */ -static int _ecore_xcb_image_shm_can = -1; - -EAPI Ecore_X_Image * -ecore_x_image_new(int w, - int h, - Ecore_X_Visual vis, - int depth) -{ - Ecore_X_Image *im; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(im = calloc(1, sizeof(Ecore_X_Image)))) return NULL; - im->w = w; - im->h = h; - im->vis = vis; - im->depth = depth; - _ecore_xcb_image_shm_check(); - im->shm = _ecore_xcb_image_shm_can; - return im; -} - -EAPI void -ecore_x_image_free(Ecore_X_Image *im) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!im) return; - if (im->shm) - { - if (im->xim) - { - xcb_shm_detach(_ecore_xcb_conn, im->shminfo.shmseg); - xcb_image_destroy(im->xim); - shmdt(im->shminfo.shmaddr); - shmctl(im->shminfo.shmid, IPC_RMID, 0); - } - } - else if (im->xim) - { - if (im->xim->data) free(im->xim->data); - im->xim->data = NULL; - xcb_image_destroy(im->xim); - } - - free(im); -// ecore_x_flush(); -} - -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) -{ - Eina_Bool ret = EINA_TRUE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (im->shm) - { - if (!im->xim) _ecore_xcb_image_shm_create(im); - if (!im->xim) return EINA_FALSE; - - if ((sx == 0) && (w == im->w)) - { - im->xim->data = (uint8_t *)im->data + (im->xim->stride * sy) + - (sx * im->bpp); - im->xim->width = w; - im->xim->height = h; - - ecore_x_grab(); - if (!xcb_image_shm_get(_ecore_xcb_conn, draw, im->xim, - im->shminfo, x, y, 0xffffffff)) - { - DBG("\tImage Shm Get Failed"); - ret = EINA_FALSE; - } - ecore_x_ungrab(); - ecore_x_sync(); // needed - } - else - { - Ecore_X_Image *tim; - - 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) - { - unsigned char *spixels, *pixels; - int sbpp = 0, sbpl = 0, srows = 0; - int bpp = 0, bpl = 0, rows = 0; - - spixels = - ecore_x_image_data_get(tim, &sbpl, &srows, &sbpp); - pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp); - if ((spixels) && (pixels)) - { - unsigned char *p, *sp; - int r = 0; - - 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); - } - } - } - else - { - ret = EINA_FALSE; - ecore_x_grab(); - im->xim = - xcb_image_get(_ecore_xcb_conn, draw, x, y, w, h, - 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP); - if (!im->xim) ret = EINA_FALSE; - ecore_x_ungrab(); - ecore_x_sync(); // needed - - if (im->xim) - { - im->data = (unsigned char *)im->xim->data; - im->bpl = im->xim->stride; - im->rows = im->xim->height; - if (im->xim->bpp <= 8) - im->bpp = 1; - else if (im->xim->bpp <= 16) - im->bpp = 2; - else - im->bpp = 4; - } - } - - return ret; -} - -EAPI void * -ecore_x_image_data_get(Ecore_X_Image *im, - int *bpl, - int *rows, - int *bpp) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!im) return NULL; - if (!im->xim) _ecore_xcb_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; -} - -EAPI void -ecore_x_image_put(Ecore_X_Image *im, - Ecore_X_Drawable draw, - Ecore_X_GC gc, - int x, - int y, - int sx, - int sy, - int w, - int h) -{ - Ecore_X_GC tgc = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!gc) - { - uint32_t mask, values[1]; - - tgc = xcb_generate_id(_ecore_xcb_conn); - mask = XCB_GC_SUBWINDOW_MODE; - values[0] = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS; - xcb_create_gc(_ecore_xcb_conn, tgc, draw, mask, values); - gc = tgc; - } - if (!im->xim) _ecore_xcb_image_shm_create(im); - if (im->xim) - { - if (im->shm) - xcb_shm_put_image(_ecore_xcb_conn, draw, gc, im->xim->width, - im->xim->height, sx, sy, w, h, x, y, - im->xim->depth, im->xim->format, 0, - im->shminfo.shmseg, - im->xim->data - im->shminfo.shmaddr); -// xcb_image_shm_put(_ecore_xcb_conn, draw, gc, im->xim, -// im->shminfo, sx, sy, x, y, w, h, 0); - else - xcb_image_put(_ecore_xcb_conn, draw, gc, im->xim, sx, sy, 0); - } - if (tgc) ecore_x_gc_free(tgc); - ecore_x_sync(); -} - -EAPI Eina_Bool -ecore_x_image_is_argb32_get(Ecore_X_Image *im) -{ - xcb_visualtype_t *vis; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - vis = (xcb_visualtype_t *)im->vis; - if (!im->xim) _ecore_xcb_image_shm_create(im); - - if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || - (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && - (im->depth >= 24) && (vis->red_mask == 0xff0000) && - (vis->green_mask == 0x00ff00) && (vis->blue_mask == 0x0000ff)) - { -#ifdef WORDS_BIGENDIAN - if (im->xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST) return EINA_TRUE; -#else - if (im->xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST) return EINA_TRUE; -#endif - } - - return EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_image_to_argb_convert(void *src, - int sbpp, - int sbpl, - Ecore_X_Colormap c, - Ecore_X_Visual v, - int x, - int y, - int w, - int h, - unsigned int *dst, - int dbpl, - int dx, - int dy) -{ - xcb_visualtype_t *vis; - uint32_t *cols; - int n = 0, nret = 0, i, row, mode = 0; - unsigned int pal[256], r, g, b; - enum - { - rgbnone = 0, - rgb565, - bgr565, - rgbx555, - argbx888, - abgrx888, - rgba888x, - bgra888x, - argbx666 - }; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - sbpp *= 8; - - vis = (xcb_visualtype_t *)v; - n = vis->colormap_entries; - if ((n <= 256) && - ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || - (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || - (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || - (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY))) - { - xcb_query_colors_cookie_t cookie; - xcb_query_colors_reply_t *reply; - - if (!c) - { - c = (xcb_colormap_t)((xcb_screen_t *) - _ecore_xcb_screen)->default_colormap; - } - - cols = alloca(n * sizeof(uint32_t)); - for (i = 0; i < n; i++) - cols[i] = i; - - cookie = xcb_query_colors_unchecked(_ecore_xcb_conn, c, n, cols); - reply = xcb_query_colors_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - xcb_rgb_iterator_t iter; - xcb_rgb_t *ret; - - iter = xcb_query_colors_colors_iterator(reply); - ret = xcb_query_colors_colors(reply); - if (ret) - { - for (i = 0; iter.rem; xcb_rgb_next(&iter), i++) - { - pal[i] = 0xff000000 | - ((iter.data->red >> 8) << 16) | - ((iter.data->green >> 8) << 8) | - ((iter.data->blue >> 8)); - } - nret = n; - } - free(reply); - } - } - else if ((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || - (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) - { - if ((vis->red_mask == 0x00ff0000) && - (vis->green_mask == 0x0000ff00) && - (vis->blue_mask == 0x000000ff)) - mode = argbx888; - else if ((vis->red_mask == 0x000000ff) && - (vis->green_mask == 0x0000ff00) && - (vis->blue_mask == 0x00ff0000)) - mode = abgrx888; - else if ((vis->red_mask == 0xff000000) && - (vis->green_mask == 0x00ff0000) && - (vis->blue_mask == 0x0000ff00)) - mode = rgba888x; - else if ((vis->red_mask == 0x0000ff00) && - (vis->green_mask == 0x00ff0000) && - (vis->blue_mask == 0xff000000)) - mode = bgra888x; - else if ((vis->red_mask == 0x0003f000) && - (vis->green_mask == 0x00000fc0) && - (vis->blue_mask == 0x0000003f)) - mode = argbx666; - else if ((vis->red_mask == 0x0000f800) && - (vis->green_mask == 0x000007e0) && - (vis->blue_mask == 0x0000001f)) - mode = rgb565; - else if ((vis->red_mask == 0x0000001f) && - (vis->green_mask == 0x000007e0) && - (vis->blue_mask == 0x0000f800)) - mode = bgr565; - else if ((vis->red_mask == 0x00007c00) && - (vis->green_mask == 0x000003e0) && - (vis->blue_mask == 0x0000001f)) - mode = rgbx555; - else - return EINA_FALSE; - } - for (row = 0; row < h; row++) - { - unsigned char *s8; - unsigned short *s16; - unsigned int *s32, *dp, *de; - - dp = ((unsigned int *)(((unsigned char *)dst) + - ((dy + row) * dbpl))) + dx; - de = dp + w; - switch (sbpp) - { - case 8: - s8 = ((unsigned char *)(((unsigned char *)src) + - ((y + row) * sbpl))) + x; - if (nret > 0) - { - while (dp < de) - { - *dp = pal[*s8]; - s8++; dp++; - } - } - else - return EINA_FALSE; - break; - - case 16: - s16 = ((unsigned short *)(((unsigned char *)src) + - ((y + row) * sbpl))) + x; - switch (mode) - { - case rgb565: - while (dp < de) - { - r = (*s16 & 0xf800) << 8; - g = (*s16 & 0x07e0) << 5; - b = (*s16 & 0x001f) << 3; - r |= (r >> 5) & 0xff0000; - g |= (g >> 6) & 0x00ff00; - b |= (b >> 5); - *dp = 0xff000000 | r | g | b; - s16++; dp++; - } - break; - - case bgr565: - while (dp < de) - { - r = (*s16 & 0x001f) << 19; - g = (*s16 & 0x07e0) << 5; - b = (*s16 & 0xf800) >> 8; - r |= (r >> 5) & 0xff0000; - g |= (g >> 6) & 0x00ff00; - b |= (b >> 5); - *dp = 0xff000000 | r | g | b; - s16++; dp++; - } - break; - - case rgbx555: - while (dp < de) - { - r = (*s16 & 0x7c00) << 9; - g = (*s16 & 0x03e0) << 6; - b = (*s16 & 0x001f) << 3; - r |= (r >> 5) & 0xff0000; - g |= (g >> 5) & 0x00ff00; - b |= (b >> 5); - *dp = 0xff000000 | r | g | b; - s16++; dp++; - } - break; - - default: - return EINA_FALSE; - break; - } - break; - - case 24: - case 32: - s32 = ((unsigned int *)(((unsigned char *)src) + - ((y + row) * sbpl))) + x; - switch (mode) - { - case argbx888: - while (dp < de) - { - *dp = 0xff000000 | *s32; - s32++; dp++; - } - break; - - case abgrx888: - while (dp < de) - { - r = *s32 & 0x000000ff; - g = *s32 & 0x0000ff00; - b = *s32 & 0x00ff0000; - *dp = 0xff000000 | (r << 16) | (g) | (b >> 16); - s32++; dp++; - } - break; - - case rgba888x: - while (dp < de) - { - *dp = 0xff000000 | (*s32 >> 8); - s32++; dp++; - } - break; - - case bgra888x: - while (dp < de) - { - r = *s32 & 0x0000ff00; - g = *s32 & 0x00ff0000; - b = *s32 & 0xff000000; - *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24); - s32++; dp++; - } - break; - - case argbx666: - while (dp < de) - { - r = (*s32 & 0x3f000) << 6; - g = (*s32 & 0x00fc0) << 4; - b = (*s32 & 0x0003f) << 2; - r |= (r >> 6) & 0xff0000; - g |= (g >> 6) & 0x00ff00; - b |= (b >> 6); - *dp = 0xff000000 | r | g | b; - s32++; dp++; - } - break; - - default: - return EINA_FALSE; - break; - } - break; - break; - - default: - return EINA_FALSE; - break; - } - } - return EINA_TRUE; -} - -/* local functions */ -static void -_ecore_xcb_image_shm_check(void) -{ -// xcb_shm_query_version_reply_t *reply; - xcb_shm_segment_info_t shminfo; - xcb_shm_get_image_cookie_t cookie; - xcb_shm_get_image_reply_t *ireply; - xcb_image_t *img = 0; - uint8_t depth = 0; - - if (_ecore_xcb_image_shm_can != -1) return; - CHECK_XCB_CONN; - - /* reply = */ - /* xcb_shm_query_version_reply(_ecore_xcb_conn, */ - /* xcb_shm_query_version(_ecore_xcb_conn), NULL); */ - /* if (!reply) */ - /* { */ - /* _ecore_xcb_image_shm_can = 0; */ - /* return; */ - /* } */ - - /* if ((reply->major_version < 1) || */ - /* ((reply->major_version == 1) && (reply->minor_version == 0))) */ - /* { */ - /* _ecore_xcb_image_shm_can = 0; */ - /* free(reply); */ - /* return; */ - /* } */ - - /* free(reply); */ - - depth = ((xcb_screen_t *)_ecore_xcb_screen)->root_depth; - - ecore_x_sync(); // needed - - img = _ecore_xcb_image_create_native(1, 1, XCB_IMAGE_FORMAT_Z_PIXMAP, - depth, NULL, ~0, NULL); - if (!img) - { - _ecore_xcb_image_shm_can = 0; - return; - } - - shminfo.shmid = - shmget(IPC_PRIVATE, img->stride * img->height, (IPC_CREAT | 0666)); - if (shminfo.shmid == (uint32_t)-1) - { - xcb_image_destroy(img); - _ecore_xcb_image_shm_can = 0; - return; - } - - shminfo.shmaddr = shmat(shminfo.shmid, 0, 0); - img->data = shminfo.shmaddr; - if (img->data == (uint8_t *)-1) - { - xcb_image_destroy(img); - _ecore_xcb_image_shm_can = 0; - return; - } - - shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn); - xcb_shm_attach(_ecore_xcb_conn, shminfo.shmseg, shminfo.shmid, 0); - - cookie = - xcb_shm_get_image(_ecore_xcb_conn, - ((xcb_screen_t *)_ecore_xcb_screen)->root, - 0, 0, img->width, img->height, - 0xffffffff, img->format, - shminfo.shmseg, img->data - shminfo.shmaddr); - - ecore_x_sync(); // needed - - ireply = xcb_shm_get_image_reply(_ecore_xcb_conn, cookie, NULL); - if (ireply) - { - _ecore_xcb_image_shm_can = 1; - free(ireply); - } - else - _ecore_xcb_image_shm_can = 0; - - xcb_shm_detach(_ecore_xcb_conn, shminfo.shmseg); - xcb_image_destroy(img); - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); -} - -static void -_ecore_xcb_image_shm_create(Ecore_X_Image *im) -{ - CHECK_XCB_CONN; - - im->xim = - _ecore_xcb_image_create_native(im->w, im->h, XCB_IMAGE_FORMAT_Z_PIXMAP, - im->depth, NULL, ~0, NULL); - if (!im->xim) return; - - im->shminfo.shmid = shmget(IPC_PRIVATE, im->xim->size, (IPC_CREAT | 0666)); - if (im->shminfo.shmid == (uint32_t)-1) - { - xcb_image_destroy(im->xim); - return; - } - - im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0); - im->xim->data = im->shminfo.shmaddr; - if ((!im->xim->data) || (im->xim->data == (uint8_t *)-1)) - { - DBG("Shm Create No Image Data"); - xcb_image_destroy(im->xim); - shmdt(im->shminfo.shmaddr); - shmctl(im->shminfo.shmid, IPC_RMID, 0); - return; - } - - im->shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn); - xcb_shm_attach(_ecore_xcb_conn, im->shminfo.shmseg, im->shminfo.shmid, 0); - - im->data = (unsigned char *)im->xim->data; - im->bpl = im->xim->stride; - im->rows = im->xim->height; - if (im->xim->bpp <= 8) - im->bpp = 1; - else if (im->xim->bpp <= 16) - im->bpp = 2; - else - im->bpp = 4; -} - -xcb_image_t * -_ecore_xcb_image_create_native(int w, - int h, - xcb_image_format_t format, - uint8_t depth, - void *base, - uint32_t bytes, - uint8_t *data) -{ - static uint8_t dpth = 0; - static xcb_format_t *fmt = NULL; - const xcb_setup_t *setup; - xcb_image_format_t xif; - - CHECK_XCB_CONN; - - /* NB: We cannot use xcb_image_create_native as it only creates images - * using MSB_FIRST, so this routine recreates that function and uses - * the endian-ness of the server setup */ - setup = xcb_get_setup(_ecore_xcb_conn); - xif = format; - - if ((xif == XCB_IMAGE_FORMAT_Z_PIXMAP) && (depth == 1)) - xif = XCB_IMAGE_FORMAT_XY_PIXMAP; - - if (dpth != depth) - { - dpth = depth; - fmt = _ecore_xcb_image_find_format(setup, depth); - if (!fmt) return 0; - } - - switch (xif) - { - case XCB_IMAGE_FORMAT_XY_BITMAP: - if (depth != 1) return 0; - - case XCB_IMAGE_FORMAT_XY_PIXMAP: - case XCB_IMAGE_FORMAT_Z_PIXMAP: - return xcb_image_create(w, h, xif, - fmt->scanline_pad, - fmt->depth, fmt->bits_per_pixel, - setup->bitmap_format_scanline_unit, - setup->image_byte_order, - setup->bitmap_format_bit_order, - base, bytes, data); - - default: - break; - } - - return 0; -} - -static xcb_format_t * -_ecore_xcb_image_find_format(const xcb_setup_t *setup, - uint8_t depth) -{ - xcb_format_t *fmt, *fmtend; - - CHECK_XCB_CONN; - - fmt = xcb_setup_pixmap_formats(setup); - fmtend = fmt + xcb_setup_pixmap_formats_length(setup); - for (; fmt != fmtend; ++fmt) - if (fmt->depth == depth) - return fmt; - - return 0; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_input.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_input.c deleted file mode 100644 index 6cf3ebf6e6..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_input.c +++ /dev/null @@ -1,274 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_XINPUT -# include -# include -#endif - -/* FIXME: this is a guess. can't find defines for touch events in xcb libs - * online */ -/* these are not yet defined in xcb support for xi2 - so manually create */ -#ifndef XCB_INPUT_DEVICE_TOUCH_BEGIN -#define XCB_INPUT_DEVICE_TOUCH_BEGIN 18 -#endif -#ifndef XCB_INPUT_DEVICE_TOUCH_END -#define XCB_INPUT_DEVICE_TOUCH_END 19 -#endif -#ifndef XCB_INPUT_DEVICE_TOUCH_UPDATE -#define XCB_INPUT_DEVICE_TOUCH_UPDATE 21 -#endif - -#ifndef XCB_INPUT_POINTER_EMULATED_MASK -#define XCB_INPUT_POINTER_EMULATED_MASK (1 << 16) -#endif - -/* local variables */ -static Eina_Bool _input_avail = EINA_FALSE; - -/* external variables */ -int _ecore_xcb_event_input = 0; - -void -_ecore_xcb_input_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XINPUT - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_input_id); -#endif -} - -void -_ecore_xcb_input_finalize(void) -{ -#ifdef ECORE_XCB_XINPUT - xcb_input_get_extension_version_cookie_t cookie; - xcb_input_get_extension_version_reply_t *reply; - char buff[128]; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XINPUT - cookie = - xcb_input_get_extension_version_unchecked(_ecore_xcb_conn, 127, buff); - reply = - xcb_input_get_extension_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - _input_avail = EINA_TRUE; - free(reply); - } - - if (_input_avail) - { - const xcb_query_extension_reply_t *ext_reply; - - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_input_id); - if (ext_reply) - _ecore_xcb_event_input = ext_reply->first_event; - } -#endif -} - -void -_ecore_xcb_input_shutdown(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); -} - -void -#ifdef ECORE_XCB_XINPUT -_ecore_xcb_input_handle_event(xcb_generic_event_t *event) -#else -_ecore_xcb_input_handle_event(xcb_generic_event_t * event EINA_UNUSED) -#endif -{ -#ifdef ECORE_XCB_XINPUT - xcb_ge_event_t *ev; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - /* FIXME: look at xlib ecore_x_xi2.c to copy logic in when i can find an - * xcb-input lib to test with */ -#ifdef ECORE_XCB_XINPUT - ev = (xcb_ge_event_t *)event; - switch (ev->event_type) - { - case XCB_INPUT_DEVICE_MOTION_NOTIFY: - { - xcb_input_device_motion_notify_event_t *de; - unsigned int child_win = 0; - - de = (xcb_input_device_motion_notify_event_t *)ev->pad1; - child_win = (de->child ? de->child : de->event); - _ecore_xcb_event_mouse_move(de->time, de->state, de->event_x, - de->event_y, de->root_x, de->root_y, - de->event, child_win, de->root, - de->same_screen, de->device_id, - 1, 1, 1.0, 0.0, - de->event_x, de->event_y, - de->root_x, de->root_y); - } - break; - - case XCB_INPUT_DEVICE_BUTTON_PRESS: - { - xcb_input_device_button_press_event_t *de; - unsigned int child_win = 0; - - de = (xcb_input_device_button_press_event_t *)ev->pad1; - child_win = (de->child ? de->child : de->event); - _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN, - de->time, de->state, de->detail, - de->event_x, de->event_y, - de->root_x, de->root_y, de->event, - child_win, de->root, - de->same_screen, de->device_id, - 1, 1, 1.0, 0.0, - de->event_x, de->event_y, - de->root_x, de->root_y); - } - break; - - case XCB_INPUT_DEVICE_BUTTON_RELEASE: - { - xcb_input_device_button_release_event_t *de; - unsigned int child_win = 0; - - de = (xcb_input_device_button_release_event_t *)ev->pad1; - child_win = (de->child ? de->child : de->event); - _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP, - de->time, de->state, de->detail, - de->event_x, de->event_y, - de->root_x, de->root_y, de->event, - child_win, de->root, - de->same_screen, de->device_id, - 1, 1, 1.0, 0.0, - de->event_x, de->event_y, - de->root_x, de->root_y); - } - break; - - case XCB_INPUT_DEVICE_TOUCH_UPDATE: - { - xcb_input_device_motion_notify_event_t *de; - unsigned int child_win = 0; - - de = (xcb_input_device_motion_notify_event_t *)ev->pad1; - child_win = (de->child ? de->child : de->event); - _ecore_xcb_event_mouse_move(de->time, de->state, de->event_x, - de->event_y, de->root_x, de->root_y, - de->event, child_win, de->root, - de->same_screen, de->device_id, - 1, 1, 1.0, 0.0, - de->event_x, de->event_y, - de->root_x, de->root_y); - } - break; - - case XCB_INPUT_DEVICE_TOUCH_BEGIN: - { - xcb_input_device_button_press_event_t *de; - unsigned int child_win = 0; - - de = (xcb_input_device_button_press_event_t *)ev->pad1; - child_win = (de->child ? de->child : de->event); - _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN, - de->time, de->state, de->detail, - de->event_x, de->event_y, - de->root_x, de->root_y, de->event, - child_win, de->root, - de->same_screen, de->device_id, - 1, 1, 1.0, 0.0, - de->event_x, de->event_y, - de->root_x, de->root_y); - } - break; - - case XCB_INPUT_DEVICE_TOUCH_END: - { - xcb_input_device_button_release_event_t *de; - unsigned int child_win = 0; - - de = (xcb_input_device_button_release_event_t *)ev->pad1; - child_win = (de->child ? de->child : de->event); - _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP, - de->time, de->state, de->detail, - de->event_x, de->event_y, - de->root_x, de->root_y, de->event, - child_win, de->root, - de->same_screen, de->device_id, - 1, 1, 1.0, 0.0, - de->event_x, de->event_y, - de->root_x, de->root_y); - } - break; - - default: - break; - } -#endif -} - -EAPI Eina_Bool -ecore_x_input_multi_select(Ecore_X_Window win) -{ - Eina_Bool find = EINA_FALSE; -#ifdef ECORE_XCB_XINPUT - xcb_input_list_input_devices_cookie_t dcookie; - xcb_input_list_input_devices_reply_t *dreply; - xcb_input_device_info_iterator_t diter; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_input_avail) return EINA_FALSE; - - /* FIXME: i can't seemingly test this! no xcb input lib so can't look and - * test and look at types etc. - look at xlib code and copy logic over - * when we can */ -#ifdef ECORE_XCB_XINPUT - dcookie = xcb_input_list_input_devices_unchecked(_ecore_xcb_conn); - dreply = - xcb_input_list_input_devices_reply(_ecore_xcb_conn, dcookie, NULL); - if (!dreply) return EINA_FALSE; - - diter = xcb_input_list_input_devices_devices_iterator(dreply); - while (diter.rem) - { - xcb_input_device_info_t *dev; - const xcb_input_event_class_t iclass[] = - { - XCB_INPUT_DEVICE_BUTTON_PRESS, - XCB_INPUT_DEVICE_BUTTON_RELEASE, - XCB_INPUT_DEVICE_MOTION_NOTIFY, - XCB_INPUT_DEVICE_TOUCH_BEGIN, - XCB_INPUT_DEVICE_TOUCH_END, - XCB_INPUT_DEVICE_TOUCH_UPDATE - }; - - dev = diter.data; - if (dev->device_use == XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_DEVICE) - { - DBG("Device %d", dev->device_id); - DBG("\tType: %d", dev->device_type); - DBG("\tNum Classes: %d", dev->num_class_info); - DBG("\tUse: %d", dev->device_use); - - xcb_input_select_extension_event(_ecore_xcb_conn, win, - sizeof(iclass) / sizeof(xcb_input_event_class_t), - iclass); - find = EINA_TRUE; - } - xcb_input_device_info_next(&diter); - } - free(dreply); -#endif - - return find; - win = 0; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_keymap.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_keymap.c deleted file mode 100644 index 6c112464b0..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_keymap.c +++ /dev/null @@ -1,491 +0,0 @@ -#include "ecore_xcb_private.h" -#define NEED_KEYSYM_TABLE -#define NEED_VTABLE -#include "ecore_xcb_keysym_table.h" -#include -#include - -/* local function prototypes */ -static int _ecore_xcb_keymap_mask_get(void *reply, - xcb_keysym_t sym); -static xcb_keysym_t _ecore_xcb_keymap_string_to_keysym(const char *str); -static int _ecore_xcb_keymap_translate_key(xcb_keycode_t keycode, - unsigned int modifiers, - unsigned int *modifiers_return, - xcb_keysym_t *keysym_return); -static int _ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym, - unsigned int modifiers, - char *buffer, - int bytes); - -/* local variables */ -static xcb_key_symbols_t *_ecore_xcb_keysyms; -static int _ecore_xcb_mode_switch = 0; - -/* public variables */ -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_MODIFIER_ALTGR = 0; -EAPI int ECORE_X_LOCK_SCROLL = 0; -EAPI int ECORE_X_LOCK_NUM = 0; -EAPI int ECORE_X_LOCK_CAPS = 0; -EAPI int ECORE_X_LOCK_SHIFT = 0; - -void -_ecore_xcb_keymap_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_keysyms = xcb_key_symbols_alloc(_ecore_xcb_conn); -} - -void -_ecore_xcb_keymap_finalize(void) -{ - xcb_get_modifier_mapping_cookie_t cookie; - xcb_get_modifier_mapping_reply_t *reply; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_modifier_mapping_unchecked(_ecore_xcb_conn); - reply = xcb_get_modifier_mapping_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - { - xcb_key_symbols_free(_ecore_xcb_keysyms); - return; - } - - _ecore_xcb_mode_switch = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch); - - ECORE_X_MODIFIER_SHIFT = _ecore_xcb_keymap_mask_get(reply, XK_Shift_L); - ECORE_X_MODIFIER_CTRL = _ecore_xcb_keymap_mask_get(reply, XK_Control_L); - - ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Alt_L); - if (!ECORE_X_MODIFIER_ALT) - ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Meta_L); - if (!ECORE_X_MODIFIER_ALT) - ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Super_L); - - ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Super_L); - if (!ECORE_X_MODIFIER_WIN) - ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Meta_L); - - ECORE_X_MODIFIER_ALTGR = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch); - - 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_keymap_mask_get(reply, XK_Scroll_Lock); - ECORE_X_LOCK_NUM = _ecore_xcb_keymap_mask_get(reply, XK_Num_Lock); - ECORE_X_LOCK_CAPS = _ecore_xcb_keymap_mask_get(reply, XK_Caps_Lock); - ECORE_X_LOCK_SHIFT = _ecore_xcb_keymap_mask_get(reply, XK_Shift_Lock); -} - -void -_ecore_xcb_modifiers_get(void) -{ - _ecore_xcb_keymap_finalize(); -} - -void -_ecore_xcb_keymap_shutdown(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (_ecore_xcb_keysyms) xcb_key_symbols_free(_ecore_xcb_keysyms); -} - -void -_ecore_xcb_keymap_refresh(xcb_mapping_notify_event_t *event) -{ - CHECK_XCB_CONN; - xcb_refresh_keyboard_mapping(_ecore_xcb_keysyms, event); -} - -xcb_keysym_t -_ecore_xcb_keymap_keycode_to_keysym(xcb_keycode_t keycode, - int col) -{ - xcb_keysym_t key0, key1; - - CHECK_XCB_CONN; - if (col & _ecore_xcb_mode_switch) - { - key0 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 4); - key1 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 5); - } - else - { - key0 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 0); - key1 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 1); - } - - if (key1 == XCB_NO_SYMBOL) - key1 = key0; - - if ((col & ECORE_X_LOCK_NUM) && - ((xcb_is_keypad_key(key1)) || (xcb_is_private_keypad_key(key1)))) - { - if ((col & XCB_MOD_MASK_SHIFT) || - ((col & XCB_MOD_MASK_LOCK) && (col & ECORE_X_LOCK_SHIFT))) - return key0; - else - return key1; - } - else if (!(col & XCB_MOD_MASK_SHIFT) && !(col & XCB_MOD_MASK_LOCK)) - return key0; - else if (!(col & XCB_MOD_MASK_SHIFT) && - (col & XCB_MOD_MASK_LOCK && (col & ECORE_X_LOCK_CAPS))) - return key1; - else if ((col & XCB_MOD_MASK_SHIFT) && - (col & XCB_MOD_MASK_LOCK) && (col & ECORE_X_LOCK_CAPS)) - return key0; - else if ((col & XCB_MOD_MASK_SHIFT) || - (col & XCB_MOD_MASK_LOCK && (col & ECORE_X_LOCK_SHIFT))) - return key1; - - return XCB_NO_SYMBOL; -} - -xcb_keycode_t * -_ecore_xcb_keymap_keysym_to_keycode(xcb_keysym_t keysym) -{ - CHECK_XCB_CONN; - return xcb_key_symbols_get_keycode(_ecore_xcb_keysyms, keysym); -} - -char * -_ecore_xcb_keymap_keysym_to_string(xcb_keysym_t keysym) -{ - int i = 0, n = 0, h = 0, idx = 0; - const unsigned char *entry; - unsigned char val1, val2, val3, val4; - - CHECK_XCB_CONN; - if (!keysym) return NULL; - if (keysym == XK_VoidSymbol) keysym = 0; - if (keysym <= 0x1fffffff) - { - val1 = (keysym >> 24); - val2 = ((keysym >> 16) & 0xff); - val3 = ((keysym >> 8) & 0xff); - val4 = (keysym & 0xff); - i = keysym % VTABLESIZE; - h = i + 1; - n = VMAXHASH; - while ((idx = hashKeysym[i])) - { - entry = &_ecore_xcb_keytable[idx]; - if ((entry[0] == val1) && (entry[1] == val2) && - (entry[2] == val3) && (entry[3] == val4)) - return (char *)entry + 4; - if (!--n) break; - i += h; - if (i >= VTABLESIZE) i -= VTABLESIZE; - } - } - - if ((keysym >= 0x01000100) && (keysym <= 0x0110ffff)) - { - xcb_keysym_t val; - char *s = NULL; - int i = 0; - - val = (keysym & 0xffffff); - if (val & 0xff0000) - i = 10; - else - i = 6; - - if (!(s = malloc(i))) return NULL; - i--; - s[i--] = '\0'; - for (; i; i--) - { - val1 = (val & 0xf); - val >>= 4; - if (val1 < 10) - s[i] = '0' + val1; - else - s[i] = 'A' + val1 - 10; - } - s[i] = 'U'; - return s; - } - - return NULL; -} - -xcb_keycode_t -_ecore_xcb_keymap_string_to_keycode(const char *key) -{ - if (!strncmp(key, "Keycode-", 8)) - return atoi(key + 8); - else - { - xcb_keysym_t keysym = XCB_NO_SYMBOL; - xcb_keycode_t *keycodes, keycode = 0; - int i = 0; - - CHECK_XCB_CONN; - - keysym = _ecore_xcb_keymap_string_to_keysym(key); - if (keysym == XCB_NO_SYMBOL) return XCB_NO_SYMBOL; - - keycodes = _ecore_xcb_keymap_keysym_to_keycode(keysym); - if (!keycodes) return XCB_NO_SYMBOL; - - while (keycodes[i] != XCB_NO_SYMBOL) - { - if (keycodes[i] != 0) - { - keycode = keycodes[i]; - break; - } - i++; - } - return keycode; - } -} - -int -_ecore_xcb_keymap_lookup_string(xcb_keycode_t keycode, - int state, - char *buffer, - int bytes, - xcb_keysym_t *sym) -{ - unsigned int modifiers = 0; - xcb_keysym_t keysym; - - CHECK_XCB_CONN; - if (!_ecore_xcb_keymap_translate_key(keycode, state, &modifiers, &keysym)) - return 0; - - if (sym) *sym = keysym; - - return _ecore_xcb_keymap_translate_keysym(keysym, state, buffer, bytes); -} - -EAPI const char * -ecore_x_keysym_string_get(int keysym) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_keymap_keysym_to_string(keysym); -} - -EAPI int -ecore_x_keysym_keycode_get(const char *keyname) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_keymap_string_to_keycode(keyname); -} - -/* local functions */ -static int -_ecore_xcb_keymap_mask_get(void *reply, - xcb_keysym_t sym) -{ - xcb_get_modifier_mapping_reply_t *rep; - xcb_keysym_t sym2; - int mask = 0; - 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 - }; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - rep = (xcb_get_modifier_mapping_reply_t *)reply; - if ((rep) && (rep->keycodes_per_modifier > 0)) - { - int i = 0; - xcb_keycode_t *modmap; - - modmap = xcb_get_modifier_mapping_keycodes(rep); - for (i = 0; i < (8 * rep->keycodes_per_modifier); i++) - { - int j = 0; - - for (j = 0; j < 8; j++) - { - sym2 = - xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, - modmap[i], j); - if (sym2 != 0) break; - } - if (sym2 == sym) - { - mask = masks[i / rep->keycodes_per_modifier]; - break; - } - } - } - - return mask; -} - -static xcb_keysym_t -_ecore_xcb_keymap_string_to_keysym(const char *str) -{ - int i = 0, n = 0, h = 0; - unsigned long sig = 0; - const char *p = NULL; - int c = 0, idx = 0; - const unsigned char *entry; - unsigned char sig1, sig2; - long unsigned int val; - - p = str; - while ((c = *p++)) - sig = (sig << 1) + c; - - i = (sig % KTABLESIZE); - h = i + 1; - sig1 = (sig >> 8) & 0xff; - sig2 = sig & 0xff; - n = KMAXHASH; - - while ((idx = hashString[i])) - { - entry = &_ecore_xcb_keytable[idx]; - if ((entry[0] == sig1) && (entry[1] == sig2) && - !strcmp(str, (char *)entry + 6)) - { - val = ((entry[2] << 24) | (entry[3] << 16) | - (entry[4] << 8) | (entry[5])); - if (!val) val = 0xffffff; - return val; - } - if (!--n) break; - i += h; - if (i >= KTABLESIZE) i -= KTABLESIZE; - } - - if (*str == 'U') - { - val = 0; - for (p = &str[1]; *p; p++) - { - c = *p; - if (('0' <= c) && (c <= '9')) - val = (val << 4) + c - '0'; - else if (('a' <= c) && (c <= 'f')) - val = (val << 4) + c - 'a' + 10; - else if (('A' <= c) && (c <= 'F')) - val = (val << 4) + c - 'A' + 10; - else - return XCB_NO_SYMBOL; - if (val > 0x10ffff) return XCB_NO_SYMBOL; - } - if ((val < 0x20) || ((val > 0x7e) && (val < 0xa0))) - return XCB_NO_SYMBOL; - if (val < 0x100) return val; - return val | 0x01000000; - } - - if ((strlen(str) > 2) && (str[0] == '0') && (str[1] == 'x')) - { - char *tmp = NULL; - - val = strtoul(str, &tmp, 16); - if ((val == ULONG_MAX) || ((tmp) && (*tmp != '\0'))) - return XCB_NO_SYMBOL; - else - return val; - } - - if (!strncmp(str, "XF86_", 5)) - { - long unsigned int ret; - char *tmp; - - tmp = strdup(str); - if (!tmp) return XCB_NO_SYMBOL; - memmove(&tmp[4], &tmp[5], strlen(str) - 5 + 1); - ret = _ecore_xcb_keymap_string_to_keysym(tmp); - free(tmp); - return ret; - } - - return XCB_NO_SYMBOL; -} - -static int -_ecore_xcb_keymap_translate_key(xcb_keycode_t keycode, - unsigned int modifiers, - unsigned int *modifiers_return, - xcb_keysym_t *keysym_return) -{ - xcb_keysym_t sym; - - if (!_ecore_xcb_keysyms) return 0; - - sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, modifiers); - - if (modifiers_return) - *modifiers_return = ((XCB_MOD_MASK_SHIFT | XCB_MOD_MASK_LOCK) | - _ecore_xcb_mode_switch | ECORE_X_LOCK_NUM); - if (keysym_return) - *keysym_return = sym; - - return 1; -} - -static int -_ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym, - unsigned int modifiers, - char *buffer, - int bytes) -{ - unsigned long hbytes = 0; - unsigned char c; - - if (!keysym) return 0; - hbytes = (keysym >> 8); - - if (!(bytes && - ((hbytes == 0) || - ((hbytes == 0xFF) && - (((keysym >= XK_BackSpace) && (keysym <= XK_Clear)) || - (keysym == XK_Return) || (keysym == XK_Escape) || - (keysym == XK_KP_Space) || (keysym == XK_KP_Tab) || - (keysym == XK_KP_Enter) || - ((keysym >= XK_KP_Multiply) && (keysym <= XK_KP_9)) || - (keysym == XK_KP_Equal) || (keysym == XK_Delete)))))) - return 0; - - if (keysym == XK_KP_Space) - c = (XK_space & 0x7F); - else if (hbytes == 0xFF) - c = (keysym & 0x7F); - else - c = (keysym & 0xFF); - - if (modifiers & ECORE_X_MODIFIER_CTRL) - { - if (((c >= '@') && (c < '\177')) || c == ' ') - c &= 0x1F; - else if (c == '2') - c = '\000'; - else if ((c >= '3') && (c <= '7')) - c -= ('3' - '\033'); - else if (c == '8') - c = '\177'; - else if (c == '/') - c = '_' & 0x1F; - } - buffer[0] = c; - return 1; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_mwm.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_mwm.c deleted file mode 100644 index 6c9533136f..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_mwm.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "ecore_xcb_private.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 -{ - uint32_t flags; - uint32_t functions; - uint32_t decorations; - int32_t inputmode; - uint32_t status; -} MWMHints; - -/** - * @defgroup Ecore_X_MWM_Group MWM related functions. - * - * Functions related to MWM. - */ - -/** - * Sets the borderless flag of a window using MWM. - * - * @param win The window. - * @param borderless The borderless flag. - * - * @ingroup Ecore_X_MWM_Group - */ -EAPI void -ecore_x_mwm_borderless_set(Ecore_X_Window win, - Eina_Bool borderless) -{ - uint32_t data[5] = { 0, 0, 0, 0, 0 }; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - data[0] = 2; - data[2] = !borderless; - - ecore_x_window_prop_property_set(win, - ECORE_X_ATOM_MOTIF_WM_HINTS, - ECORE_X_ATOM_MOTIF_WM_HINTS, 32, - (void *)data, 5); -} - -EAPI Eina_Bool -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) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - MWMHints *mwmhints = NULL; - int ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = - xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, - ECORE_X_ATOM_MOTIF_WM_HINTS, - ECORE_X_ATOM_MOTIF_WM_HINTS, 0, UINT_MAX); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - if ((reply->format != 32) || (reply->value_len == 0)) - { - free(reply); - return EINA_FALSE; - } - - 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 = EINA_TRUE; - } - free(reply); - return ret; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_netwm.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_netwm.c deleted file mode 100644 index ae801d3407..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_netwm.c +++ /dev/null @@ -1,1604 +0,0 @@ -#include "ecore_xcb_private.h" - -/* local function prototypes */ -/* static void _ecore_xcb_netwm_startup_info_free(void *data); */ -static Ecore_X_Atom _ecore_xcb_netwm_window_type_atom_get(Ecore_X_Window_Type type); -static Ecore_X_Window_Type _ecore_xcb_netwm_window_type_type_get(Ecore_X_Atom atom); -static Ecore_X_Atom _ecore_xcb_netwm_window_state_atom_get(Ecore_X_Window_State state); -static Ecore_X_Atom _ecore_xcb_netwm_action_atom_get(Ecore_X_Action action); - -/* local variables */ -//static Eina_Hash *_startup_info = NULL; - -/* local structures */ -typedef struct _Ecore_Xcb_Startup_Info Ecore_Xcb_Startup_Info; -struct _Ecore_Xcb_Startup_Info -{ - Ecore_X_Window win; - int init, size; - char *buffer; - int length; - - /* sequence info fields */ - char *id, *name; - int screen; - char *bin, *icon; - int desktop, timestamp; - char *description, *wmclass; - int silent; -}; - -EAPI void -ecore_x_netwm_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -// _startup_info = -// eina_hash_string_superfast_new(_ecore_xcb_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; -} - -EAPI Eina_Bool -ecore_x_netwm_pid_get(Ecore_X_Window win, - int *pid) -{ - uint32_t tmp; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID, &tmp, 1)) - return EINA_FALSE; - - if (pid) *pid = tmp; - - return EINA_TRUE; -} - -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 Eina_Bool -ecore_x_netwm_window_type_get(Ecore_X_Window win, - Ecore_X_Window_Type *type) -{ - Ecore_X_Atom *atoms; - int num = 0; - - 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_xcb_netwm_window_type_type_get(atoms[0]); - - if (atoms) free(atoms); - - if (num >= 1) return EINA_TRUE; - return EINA_FALSE; -} - -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_xcb_netwm_window_type_atom_get(type); - ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, &atom, 1); -} - -EAPI int -ecore_x_netwm_window_types_get(Ecore_X_Window win, - Ecore_X_Window_Type **types) -{ - int num = 0, i = 0; - 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) - { - if (atoms) free(atoms); - return 0; - } - - for (i = 0; i < num; i++) - atoms2[i] = _ecore_xcb_netwm_window_type_type_get(atoms[i]); - if (atoms) free(atoms); - - if (types) - *types = atoms2; - else - free(atoms2); - - return num; -} - -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_get(win, ECORE_X_ATOM_NET_WM_NAME); - return 1; -} - -EAPI void -ecore_x_netwm_name_set(Ecore_X_Window win, - const char *name) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_NAME, name); -} - -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 Eina_Bool -ecore_x_netwm_opacity_get(Ecore_X_Window win, - unsigned int *opacity) -{ - unsigned int tmp = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, - &tmp, 1)) - return EINA_FALSE; - - if (opacity) *opacity = tmp; - - return EINA_TRUE; -} - -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(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, - &check, 1); - ecore_x_window_prop_string_set(check, ECORE_X_ATOM_NET_WM_NAME, wm_name); - ecore_x_window_prop_string_set(root, ECORE_X_ATOM_NET_WM_NAME, wm_name); - ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, - &check, 1); -} - -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 Eina_Bool -ecore_x_netwm_supported_get(Ecore_X_Window root, - Ecore_X_Atom **supported, - int *num) -{ - int num_ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (num) *num = 0; - if (supported) *supported = NULL; - - num_ret = - ecore_x_window_prop_atom_list_get(root, ECORE_X_ATOM_NET_SUPPORTED, - supported); - if (num_ret <= 0) return EINA_FALSE; - if (num) *num = num_ret; - - return EINA_TRUE; -} - -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 = NULL, *t = NULL; - const char *s; - uint32_t len = 0, i, l; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - for (i = 0; i < n_desks; i++) - { - s = ((names) ? names[i] : NULL); - if (!s) - { - /* Default to "Desk-" */ - sprintf(ss, "Desk-%d", i); - s = ss; - } - - l = strlen(s) + 1; - t = realloc(buf, len + 1); - if (t) - { - buf = t; - 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); -// ecore_x_flush(); - free(buf); -} - -EAPI void -ecore_x_netwm_desk_size_set(Ecore_X_Window root, - unsigned int width, - unsigned int height) -{ - uint32_t 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 unsigned int * -ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks) -{ - int ret; - unsigned int *areas = NULL; - - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - ret = ecore_x_window_prop_card32_list_get(root, ECORE_X_ATOM_NET_WORKAREA, - &areas); - if (!areas) - { - if (n_desks) *n_desks = 0; - return 0; - } - if (n_desks) *n_desks = ret / 4; - return areas; -} - -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, - Eina_Bool on) -{ - unsigned int val = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - val = ((on) ? 1 : 0); - ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, - &val, 1); -} - -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_get(win, ECORE_X_ATOM_NET_STARTUP_ID); - } - - 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_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id); -} - -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, - Eina_Bool set) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_NET_WM_STATE; - ev.data.data32[0] = !!set; - ev.data.data32[1] = _ecore_xcb_netwm_window_state_atom_get(s1); - ev.data.data32[2] = _ecore_xcb_netwm_window_state_atom_get(s2); - /* 1 == normal client, if used 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_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); -// ecore_x_flush(); -} - -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 = 0; - - 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_xcb_netwm_window_state_atom_get(state[i]); - - ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_STATE, set, num); - free(set); -} - -EAPI Eina_Bool -ecore_x_netwm_window_state_get(Ecore_X_Window win, - Ecore_X_Window_State **state, - unsigned int *num) -{ - Ecore_X_Atom *atoms; - int ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (num) *num = 0; - if (state) *state = NULL; - - ret = - ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE, &atoms); - - if (ret <= 0) return EINA_FALSE; - - if (state) - { - *state = malloc(ret * sizeof(Ecore_X_Window_State)); - if (*state) - { - int i = 0; - - for (i = 0; i < ret; i++) - (*state)[i] = _ecore_xcb_netwm_window_state_get(atoms[i]); - if (num) *num = ret; - } - } - - free(atoms); - - return EINA_TRUE; -} - -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) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_NET_ACTIVE_WINDOW; - ev.data.data32[0] = type; - ev.data.data32[1] = XCB_CURRENT_TIME; - ev.data.data32[2] = current_win; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, root, - (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); -// ecore_x_flush(); -} - -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); -} - -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 Eina_Bool -ecore_x_screen_is_composited(int screen) -{ - char buff[32]; - xcb_get_selection_owner_cookie_t ocookie; - xcb_get_selection_owner_reply_t *oreply; - Ecore_X_Window win; - static Ecore_X_Atom atom = XCB_NONE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - snprintf(buff, sizeof(buff), "_NET_WM_CM_S%i", screen); - - if (atom == XCB_NONE) - { - xcb_intern_atom_cookie_t acookie; - xcb_intern_atom_reply_t *areply; - - acookie = - xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(buff), buff); - areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); - if (!areply) return EINA_FALSE; - atom = areply->atom; - free(areply); - } - if (atom == XCB_NONE) return EINA_FALSE; - - ocookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, atom); - oreply = xcb_get_selection_owner_reply(_ecore_xcb_conn, ocookie, NULL); - if (!oreply) return EINA_FALSE; - win = oreply->owner; - free(oreply); - - return (win != XCB_NONE) ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_x_screen_is_composited_set(int screen, - Ecore_X_Window win) -{ - static Ecore_X_Atom atom = XCB_NONE; - char buff[32]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - snprintf(buff, sizeof(buff), "_NET_WM_CM_S%i", screen); - if (atom == XCB_NONE) - { - xcb_intern_atom_cookie_t acookie; - xcb_intern_atom_reply_t *areply; - - acookie = - xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(buff), buff); - areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); - if (!areply) return; - atom = areply->atom; - free(areply); - } - if (atom == XCB_NONE) return; - xcb_set_selection_owner(_ecore_xcb_conn, win, atom, - _ecore_xcb_events_last_time_get()); -} - -EAPI void -ecore_x_netwm_ping_send(Ecore_X_Window win) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_WM_PROTOCOLS; - ev.data.data32[0] = ECORE_X_ATOM_NET_WM_PING; - ev.data.data32[1] = ecore_x_current_time_get(); - ev.data.data32[2] = win; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); -} - -EAPI void -ecore_x_netwm_frame_size_set(Ecore_X_Window win, - int fl, - int fr, - int ft, - int fb) -{ - uint32_t 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 Eina_Bool -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 EINA_FALSE; - - if (fl) *fl = frames[0]; - if (fr) *fr = frames[1]; - if (ft) *ft = frames[2]; - if (fb) *fb = frames[3]; - - return EINA_TRUE; -} - -EAPI void -ecore_x_netwm_sync_request_send(Ecore_X_Window win, - unsigned int serial) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - - /* FIXME: Maybe need XSyncIntToValue ?? */ - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_WM_PROTOCOLS; - ev.data.data32[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; - ev.data.data32[1] = _ecore_xcb_events_last_time_get(); - ev.data.data32[2] = serial; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(_ecore_xcb_conn, 0, win, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); -} - -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 Eina_Bool -ecore_x_netwm_desktop_get(Ecore_X_Window win, - unsigned int *desk) -{ - unsigned int tmp = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP, - &tmp, 1)) - return EINA_FALSE; - - if (desk) *desk = tmp; - - return EINA_TRUE; -} - -EAPI void -ecore_x_netwm_desktop_request_send(Ecore_X_Window win, - Ecore_X_Window root, - unsigned int desktop) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - 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_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); -// ecore_x_flush(); -} - -EAPI void -ecore_x_netwm_moveresize_request_send(Ecore_X_Window win, - int x, - int y, - Ecore_X_Netwm_Direction direction, - unsigned int button) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = ECORE_X_ATOM_NET_WM_MOVERESIZE; - ev.data.data32[0] = x; - ev.data.data32[1] = y; - ev.data.data32[2] = direction; - ev.data.data32[3] = button; - ev.data.data32[4] = 1; - - xcb_send_event(_ecore_xcb_conn, 0, win, - (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); -} - -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 Eina_Bool -ecore_x_netwm_handled_icons_get(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS, - NULL, 0)) - return EINA_FALSE; - - return EINA_TRUE; -} - -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_get(win, ECORE_X_ATOM_NET_WM_ICON_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_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME, name); -} - -EAPI void -ecore_x_netwm_icons_set(Ecore_X_Window win, - Ecore_X_Icon *icon, - int num) -{ - unsigned int *data, *p, *p2; - unsigned int i, size, x, y; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - size = 0; - for (i = 0; i < (unsigned int)num; i++) - { - size += 2 + (icon[i].width * icon[i].height); - } - data = malloc(size * sizeof(unsigned int)); - if (!data) return; - p = data; - for (i = 0; i < (unsigned int)num; i++) - { - p[0] = icon[i].width; - p[1] = icon[i].height; - p += 2; - p2 = icon[i].data; - for (y = 0; y < icon[i].height; y++) - { - for (x = 0; x < icon[i].width; x++) - { - unsigned int r, g, b, a; - - a = (*p2 >> 24) & 0xff; - r = (*p2 >> 16) & 0xff; - g = (*p2 >> 8 ) & 0xff; - b = (*p2 ) & 0xff; - if ((a > 0) && (a < 255)) - { - r = (r * 255) / a; - g = (g * 255) / a; - b = (b * 255) / a; - } - *p = (a << 24) | (r << 16) | (g << 8) | b; - p++; - p2++; - } - } - } - ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON, - data, size); - free(data); -} - -EAPI Eina_Bool -ecore_x_netwm_icons_get(Ecore_X_Window win, - Ecore_X_Icon **icon, - int *num) -{ - int num_ret = 0; - unsigned int i = 0, len = 0, icons = 0; - unsigned int *data, *p, *src; - - 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) || (!data)) - { - if (data) free(data); - return EINA_FALSE; - } - if (num_ret < 2) - { - if (data) free(data); - return EINA_FALSE; - } - - icons = 0; - p = data; - while (p) - { - len = (p[0] * p[1]); - p += (len + 2); - if ((p - data) > num_ret) - { - if (data) free(data); - return EINA_FALSE; - } - icons++; - if ((p - data) == num_ret) p = NULL; - } - if (num) *num = icons; - if (!icon) - { - if (data) free(data); - return EINA_TRUE; - } - - *icon = malloc(icons * sizeof(Ecore_X_Icon)); - if (!(*icon)) - { - if (data) free(data); - return EINA_FALSE; - } - - /* 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 EINA_FALSE; - } - - 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); - } - - if (data) free(data); - return EINA_TRUE; -} - -EAPI void -ecore_x_netwm_icon_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_NET_WM_ICON_GEOMETRY, - geom, 4); -} - -EAPI Eina_Bool -ecore_x_netwm_icon_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_NET_WM_ICON_GEOMETRY, - geom, 4); - if (ret != 4) return EINA_FALSE; - if (x) *x = geom[0]; - if (y) *y = geom[1]; - if (w) *w = geom[2]; - if (h) *h = geom[3]; - - return EINA_TRUE; -} - -EAPI void -ecore_x_netwm_strut_set(Ecore_X_Window win, - int l, - int r, - int t, - int b) -{ - unsigned int strut[4]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - strut[0] = l; - strut[1] = r; - strut[2] = t; - strut[3] = b; - ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); -} - -EAPI Eina_Bool -ecore_x_netwm_strut_get(Ecore_X_Window win, - int *l, - int *r, - int *t, - int *b) -{ - unsigned int strut[4]; - int ret = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ret = - ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); - if (ret != 4) return EINA_FALSE; - - if (l) *l = strut[0]; - if (r) *r = strut[1]; - if (t) *t = strut[2]; - if (b) *b = strut[3]; - - return EINA_TRUE; -} - -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 Eina_Bool -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) -{ - unsigned int strut[12]; - int ret = 0; - - 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 EINA_FALSE; - - 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 EINA_TRUE; -} - -EAPI void -ecore_x_netwm_user_time_set(Ecore_X_Window win, - unsigned int t) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME, &t, 1); -} - -EAPI Eina_Bool -ecore_x_netwm_user_time_get(Ecore_X_Window win, - unsigned int *t) -{ - unsigned int tmp; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME, - &tmp, 1)) - return EINA_FALSE; - - if (t) *t = tmp; - - return EINA_TRUE; -} - -EAPI void -ecore_x_netwm_visible_name_set(Ecore_X_Window win, - const char *name) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_window_prop_string_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_get(win, - ECORE_X_ATOM_NET_WM_VISIBLE_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_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_get(win, - ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME); - } - - return 1; -} - -EAPI Eina_Bool -ecore_x_netwm_sync_counter_get(Ecore_X_Window win, - Ecore_X_Sync_Counter *counter) -{ - unsigned int tmp; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!ecore_x_window_prop_card32_get(win, - ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, - &tmp, 1)) - return EINA_FALSE; - - if (counter) *counter = tmp; - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, - Ecore_X_Action action) -{ - int num = 0, i = 0; - Ecore_X_Atom *atoms, atom; - Eina_Bool ret = EINA_FALSE; - - 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 EINA_FALSE; - - atom = _ecore_xcb_netwm_action_atom_get(action); - for (i = 0; i < num; i++) - { - if (atoms[i] == atom) - { - ret = EINA_TRUE; - break; - } - } - - if (atoms) free(atoms); - return ret; -} - -EAPI Eina_Bool -ecore_x_netwm_allowed_action_get(Ecore_X_Window win, - Ecore_X_Action **action, - unsigned int *num) -{ - Ecore_X_Atom *atoms; - int num_ret = 0; - - 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 EINA_FALSE; - if (action) - { - *action = malloc(num_ret * sizeof(Ecore_X_Action)); - if (*action) - { - int i = 0; - - for (i = 0; i < num_ret; i++) - (*action)[i] = _ecore_xcb_netwm_action_atom_get(atoms[i]); - } - if (num) *num = num_ret; - } - free(atoms); - return EINA_TRUE; -} - -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 = 0; - - 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_xcb_netwm_action_atom_get(action[i]); - - ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, - set, num); - free(set); -} - -/* local functions */ -int -_ecore_xcb_netwm_startup_info_begin(Ecore_X_Window win EINA_UNUSED, - uint8_t data EINA_UNUSED) -{ - // TODO: TBD - return 1; -} - -int -_ecore_xcb_netwm_startup_info(Ecore_X_Window win EINA_UNUSED, - uint8_t data EINA_UNUSED) -{ - // TODO: TBD - return 1; -} - -/* static void */ -/* _ecore_xcb_netwm_startup_info_free(void *data) */ -/* { */ -/* Ecore_Xcb_Startup_Info *info; */ - -/* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ - -/* if (!(info = data)) 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); */ -/* } */ - -static Ecore_X_Atom -_ecore_xcb_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; - } -} - -static Ecore_X_Window_Type -_ecore_xcb_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_xcb_netwm_window_state_atom_get(Ecore_X_Window_State state) -{ - switch (state) - { - 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; - } -} - -Ecore_X_Window_State -_ecore_xcb_netwm_window_state_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_NET_WM_STATE_MODAL) - return ECORE_X_WINDOW_STATE_MODAL; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_STICKY) - return ECORE_X_WINDOW_STATE_STICKY; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT) - return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ) - return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_SHADED) - return ECORE_X_WINDOW_STATE_SHADED; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR) - return ECORE_X_WINDOW_STATE_SKIP_TASKBAR; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER) - return ECORE_X_WINDOW_STATE_SKIP_PAGER; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_HIDDEN) - return ECORE_X_WINDOW_STATE_HIDDEN; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN) - return ECORE_X_WINDOW_STATE_FULLSCREEN; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_ABOVE) - return ECORE_X_WINDOW_STATE_ABOVE; - else if (atom == ECORE_X_ATOM_NET_WM_STATE_BELOW) - return ECORE_X_WINDOW_STATE_BELOW; - else if (atom == 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_xcb_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; - } -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c deleted file mode 100644 index f9bf525f7a..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c +++ /dev/null @@ -1,128 +0,0 @@ -#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; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - 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); - -// ecore_x_flush(); - 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_free_pixmap(_ecore_xcb_conn, pmap); -// ecore_x_flush(); -} - -/** - * 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__); - CHECK_XCB_CONN; - - xcb_copy_area(_ecore_xcb_conn, pmap, dest, gc, sx, sy, dx, dy, w, h); -// ecore_x_flush(); -} - -/** - * 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); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_private.h b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_private.h deleted file mode 100644 index 240210ca0d..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_private.h +++ /dev/null @@ -1,468 +0,0 @@ -#ifndef __ECORE_XCB_PRIVATE_H__ -# define __ECORE_XCB_PRIVATE_H__ - -//# define LOGFNS 1 - -# ifdef HAVE_CONFIG_H -# include "config.h" -# endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -# include // included for close & gethostname functions - -/* generic xcb includes */ -# include -# include -# include -# include - -/* EFL includes */ -# include "Ecore.h" -# include "Ecore_Input.h" -# include "Ecore_X.h" - -/* logging */ -extern int _ecore_xcb_log_dom; - -# ifdef ECORE_XCB_DEFAULT_LOG_COLOR -# undef ECORE_XCB_DEFAULT_LOG_COLOR -# endif -# define ECORE_XCB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE - -# ifdef ERR -# undef ERR -# endif -# define ERR(...) EINA_LOG_DOM_ERR(_ecore_xcb_log_dom, __VA_ARGS__) - -# ifdef DBG -# undef DBG -# endif -# define DBG(...) EINA_LOG_DOM_DBG(_ecore_xcb_log_dom, __VA_ARGS__) - -# ifdef INF -# undef INF -# endif -# define INF(...) EINA_LOG_DOM_INFO(_ecore_xcb_log_dom, __VA_ARGS__) - -# ifdef WRN -# undef WRN -# endif -# define WRN(...) EINA_LOG_DOM_WARN(_ecore_xcb_log_dom, __VA_ARGS__) - -# ifdef CRIT -# undef CRIT -# endif -# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_xcb_log_dom, __VA_ARGS__) - -# ifdef LOGFNS -# include -# define LOGFN(fl, ln, fn) printf("-ECORE-XCB: %25s: %5i - %s\n", fl, ln, fn); -# else -# define LOGFN(fl, ln, fn) -# endif - -# ifndef MAXHOSTNAMELEN -# define MAXHOSTNAMELEN 256 -# endif - -# ifndef MIN -# define MIN(x, y) (((x) > (y)) ? (y) : (x)) -# endif - -# ifndef MAX -# define MAX(a, b) ((a < b) ? b : a) -# endif - -#define CHECK_XCB_CONN \ - { \ - if (xcb_connection_has_error(_ecore_xcb_conn)) \ - { \ - DBG("XCB Connection Has Error !!"); \ - _ecore_xcb_io_error_handle(NULL); \ - } \ - } - -/* enums */ -typedef enum _Ecore_Xcb_Encoding_Style Ecore_Xcb_Encoding_Style; - -enum _Ecore_Xcb_Encoding_Style -{ - XcbStringStyle, - XcbCompoundTextStyle, - XcbTextStyle, - XcbStdICCTextStyle, - XcbUTF8StringStyle -}; - -/* structures */ -typedef struct _Ecore_X_DND_Source Ecore_X_DND_Source; -typedef struct _Ecore_X_DND_Target Ecore_X_DND_Target; -typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern; -typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter; -typedef struct _Ecore_X_Selection_Parser Ecore_X_Selection_Parser; -typedef struct _Ecore_Xcb_Textproperty Ecore_Xcb_Textproperty; - -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, suppress; - int await_status; -}; - -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; -}; - -struct _Ecore_X_Selection_Intern -{ - Ecore_X_Window win; - Ecore_X_Atom selection; - unsigned char *data; - int length; - Ecore_X_Time time; -}; - -struct _Ecore_X_Selection_Converter -{ - Ecore_X_Atom target; - Eina_Bool (*convert)(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *type, - int *size_type); - Ecore_X_Selection_Converter *next; -}; - -struct _Ecore_X_Selection_Parser -{ - char *target; - void *(*parse)(const char *target, void *data, int size, int format); - Ecore_X_Selection_Parser *next; -}; - -struct _Ecore_Xcb_Textproperty -{ - char *value; - Ecore_X_Atom encoding; - unsigned int format, nitems; -}; - -/* external variables */ -extern Ecore_X_Connection *_ecore_xcb_conn; -extern Ecore_X_Screen *_ecore_xcb_screen; -extern double _ecore_xcb_double_click_time; -extern int16_t _ecore_xcb_event_last_root_x; -extern int16_t _ecore_xcb_event_last_root_y; - -/* external variables for extension events */ -extern int _ecore_xcb_event_damage; -extern int _ecore_xcb_event_randr; -extern int _ecore_xcb_event_screensaver; -extern int _ecore_xcb_event_shape; -extern int _ecore_xcb_event_sync; -extern int _ecore_xcb_event_xfixes; -extern int _ecore_xcb_event_input; -extern int _ecore_xcb_event_gesture; - -extern Ecore_X_Atom _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_NUM]; - -extern int _ecore_xcb_button_grabs_num; -extern int _ecore_xcb_key_grabs_num; -extern Ecore_X_Window *_ecore_xcb_button_grabs; -extern Ecore_X_Window *_ecore_xcb_key_grabs; -extern Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data, - int type, - void *event); -extern void *_ecore_xcb_window_grab_replay_data; - -/* private function prototypes */ -void _ecore_xcb_error_handler_init(void); -void _ecore_xcb_error_handler_shutdown(void); - -void _ecore_xcb_atoms_init(void); -void _ecore_xcb_atoms_finalize(void); - -void _ecore_xcb_extensions_init(void); -void _ecore_xcb_extensions_finalize(void); - -void _ecore_xcb_shape_init(void); -void _ecore_xcb_shape_finalize(void); - -void _ecore_xcb_screensaver_init(void); -void _ecore_xcb_screensaver_finalize(void); - -void _ecore_xcb_sync_init(void); -void _ecore_xcb_sync_finalize(void); -void _ecore_xcb_sync_magic_send(int val, - Ecore_X_Window win); - -void _ecore_xcb_render_init(void); -void _ecore_xcb_render_finalize(void); -Eina_Bool _ecore_xcb_render_argb_get(void); -Eina_Bool _ecore_xcb_render_anim_get(void); -Eina_Bool _ecore_xcb_render_avail_get(void); - -Eina_Bool _ecore_xcb_render_visual_supports_alpha(Ecore_X_Visual visual); -uint32_t _ecore_xcb_render_find_visual_id(int type, - Eina_Bool check_alpha); -Ecore_X_Visual *_ecore_xcb_render_visual_get(int visual_id); - -void _ecore_xcb_randr_init(void); -void _ecore_xcb_randr_finalize(void); - -void _ecore_xcb_gesture_init(void); -void _ecore_xcb_gesture_finalize(void); -void _ecore_xcb_gesture_shutdown(void); - -void _ecore_xcb_xfixes_init(void); -void _ecore_xcb_xfixes_finalize(void); -Eina_Bool _ecore_xcb_xfixes_avail_get(void); - -void _ecore_xcb_damage_init(void); -void _ecore_xcb_damage_finalize(void); - -void _ecore_xcb_composite_init(void); -void _ecore_xcb_composite_finalize(void); - -void _ecore_xcb_dpms_init(void); -void _ecore_xcb_dpms_finalize(void); - -void _ecore_xcb_cursor_init(void); -void _ecore_xcb_cursor_finalize(void); - -void _ecore_xcb_xinerama_init(void); -void _ecore_xcb_xinerama_finalize(void); - -void _ecore_xcb_dnd_init(void); -void _ecore_xcb_dnd_shutdown(void); -Ecore_X_DND_Source *_ecore_xcb_dnd_source_get(void); -Ecore_X_DND_Target *_ecore_xcb_dnd_target_get(void); -void _ecore_xcb_dnd_drag(Ecore_X_Window root, - int x, - int y); - -void _ecore_xcb_selection_init(void); -void _ecore_xcb_selection_shutdown(void); -void *_ecore_xcb_selection_parse(const char *target, - void *data, - int size, - int format); -char *_ecore_xcb_selection_target_get(Ecore_X_Atom target); -Ecore_X_Selection_Intern *_ecore_xcb_selection_get(Ecore_X_Atom selection); - -# ifdef HAVE_ICONV -Eina_Bool _ecore_xcb_utf8_textlist_to_textproperty(char **list, - int count, - Ecore_Xcb_Encoding_Style style, - Ecore_Xcb_Textproperty *ret); -# endif -Eina_Bool _ecore_xcb_mb_textlist_to_textproperty(char **list, - int count, - Ecore_Xcb_Encoding_Style style, - Ecore_Xcb_Textproperty *ret); -Eina_Bool _ecore_xcb_textlist_to_textproperty(const char *type, - char **list, - int count, - Ecore_Xcb_Encoding_Style style, - Ecore_Xcb_Textproperty *ret); - -# ifdef HAVE_ICONV -Eina_Bool _ecore_xcb_utf8_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, - char ***list_ret, - int *count_ret); -# endif -Eina_Bool _ecore_xcb_mb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, - char ***list_ret, - int *count_ret); -Eina_Bool _ecore_xcb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, - const char *type, - char ***list_ret, - int *count_ret); - -void _ecore_xcb_events_init(void); -void _ecore_xcb_events_shutdown(void); -void _ecore_xcb_events_handle(xcb_generic_event_t *ev); -Ecore_X_Time _ecore_xcb_events_last_time_get(void); -unsigned int _ecore_xcb_events_modifiers_get(unsigned int state); -void _ecore_xcb_event_mouse_move(uint16_t timestamp, - uint16_t modifiers, - int16_t x, - int16_t y, - int16_t root_x, - int16_t root_y, - xcb_window_t event_win, - xcb_window_t win, - xcb_window_t root_win, - uint8_t same_screen, - int dev, - double radx, - double rady, - double pressure, - double angle, - int16_t mx, - int16_t my, - int16_t mrx, - int16_t mry); -Ecore_Event_Mouse_Button *_ecore_xcb_event_mouse_button(int event, - uint16_t timestamp, - uint16_t modifiers, - xcb_button_t buttons, - int16_t x, - int16_t y, - int16_t root_x, - int16_t root_y, - xcb_window_t event_win, - xcb_window_t win, - xcb_window_t root_win, - uint8_t same_screen, - int dev, - double radx, - double rady, - double pressure, - double angle, - int16_t mx, - int16_t my, - int16_t mrx, - int16_t mry); - -void _ecore_xcb_keymap_init(void); -void _ecore_xcb_keymap_finalize(void); -void _ecore_xcb_keymap_shutdown(void); -void _ecore_xcb_keymap_refresh(xcb_mapping_notify_event_t *event); -xcb_keysym_t _ecore_xcb_keymap_keycode_to_keysym(xcb_keycode_t keycode, - int col); -xcb_keycode_t *_ecore_xcb_keymap_keysym_to_keycode(xcb_keysym_t keysym); -char *_ecore_xcb_keymap_keysym_to_string(xcb_keysym_t keysym); -xcb_keycode_t _ecore_xcb_keymap_string_to_keycode(const char *key); -int _ecore_xcb_keymap_lookup_string(xcb_keycode_t keycode, - int state, - char *buffer, - int bytes, - xcb_keysym_t *sym); - -void _ecore_xcb_input_init(void); -void _ecore_xcb_input_finalize(void); -void _ecore_xcb_input_shutdown(void); -# ifdef ECORE_XCB_XINPUT -void _ecore_xcb_input_handle_event(xcb_generic_event_t *event); -# else -void _ecore_xcb_input_handle_event(xcb_generic_event_t *event); -# endif - -void _ecore_xcb_dri_init(void); -void _ecore_xcb_dri_finalize(void); - -void _ecore_xcb_xtest_init(void); -void _ecore_xcb_xtest_finalize(void); - -Ecore_X_Window _ecore_xcb_window_root_of_screen_get(int screen); -void _ecore_xcb_window_prop_string_utf8_set(Ecore_X_Window win, - Ecore_X_Atom atom, - const char *str); -Ecore_X_Visual _ecore_xcb_window_visual_get(Ecore_X_Window win); -void _ecore_xcb_window_button_grab_remove(Ecore_X_Window win); -void _ecore_xcb_window_key_grab_remove(Ecore_X_Window win); -void _ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win, - Ecore_X_Window child_win, - int type, - void *event, - Ecore_X_Time timestamp); - -int _ecore_xcb_netwm_startup_info_begin(Ecore_X_Window win, - uint8_t data); -int _ecore_xcb_netwm_startup_info(Ecore_X_Window win, - uint8_t data); -Ecore_X_Window_State _ecore_xcb_netwm_window_state_get(Ecore_X_Atom atom); - -int _ecore_xcb_error_handle(xcb_generic_error_t *err); -int _ecore_xcb_io_error_handle(xcb_generic_error_t *err); - -xcb_image_t *_ecore_xcb_image_create_native(int w, - int h, - xcb_image_format_t format, - uint8_t depth, - void *base, - uint32_t bytes, - uint8_t *data); - -void _ecore_xcb_xdefaults_init(void); -void _ecore_xcb_xdefaults_shutdown(void); -char *_ecore_xcb_xdefaults_string_get(const char *prog, - const char *param); -int _ecore_xcb_xdefaults_int_get(const char *prog, - const char *param); - -void _ecore_xcb_modifiers_get(void); - -#endif diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c deleted file mode 100644 index a2a4e6271f..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_randr.c +++ /dev/null @@ -1,3807 +0,0 @@ -/* TODO: List of missing functions - * - * ecore_x_randr_crtc_clone_set - * ecore_x_randr_output_crtc_set - * ecore_x_randr_edid_version_get - * ecore_x_randr_edid_info_has_valid_checksum - * ecore_x_randr_edid_manufacturer_name_get - * ecore_x_randr_edid_display_ascii_get - * ecore_x_randr_edid_display_serial_get - * ecore_x_randr_edid_model_get - * ecore_x_randr_edid_manufacturer_serial_number_get - * ecore_x_randr_edid_manufacturer_model_get - * ecore_x_randr_edid_dpms_available_get - * ecore_x_randr_edid_dpms_standby_available_get - * ecore_x_randr_edid_dpms_suspend_available_get - * ecore_x_randr_edid_dpms_off_available_get - * ecore_x_randr_edid_display_aspect_ratio_preferred_get - * ecore_x_randr_edid_display_aspect_ratios_get - * ecore_x_randr_edid_display_colorscheme_get - * ecore_x_randr_edid_display_type_digital_get - * ecore_x_randr_edid_display_interface_type_get - * ecore_x_randr_screen_backlight_level_set - * ecore_x_randr_output_subpixel_order_get - * ecore_x_randr_output_wired_clones_get - * ecore_x_randr_output_compatibility_list_get - * ecore_x_randr_output_signal_formats_get - * ecore_x_randr_output_signal_format_set - * ecore_x_randr_output_signal_properties_get - * ecore_x_randr_output_connector_number_get - * ecore_x_randr_output_connector_type_get - * ecore_x_randr_crtc_panning_area_get - * ecore_x_randr_crtc_panning_area_set - * ecore_x_randr_crtc_tracking_area_get - * ecore_x_randr_crtc_tracking_area_set - * ecore_x_randr_crtc_border_area_get - * ecore_x_randr_crtc_border_area_set - */ - -#include "ecore_xcb_private.h" -# ifdef ECORE_XCB_RANDR -# include -# endif - -#define Ecore_X_Randr_None 0 -#define Ecore_X_Randr_Unset -1 - -#define RANDR_1_1 ((1 << 16) | 1) -#define RANDR_1_2 ((1 << 16) | 2) -#define RANDR_1_3 ((1 << 16) | 3) - -#define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) return ret -#define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) return ret -#define RANDR_CHECK_1_3_RET(ret) if (_randr_version < RANDR_1_3) return ret - -#define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3) -#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12 -#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13 -#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36 -#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3 -#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5 -#define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13 - -#define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ - for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18) - -#define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \ - _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ - if ((block[0] == 0) && (block[1] == 0)) - -/* local function prototypes */ -static Eina_Bool _ecore_xcb_randr_output_validate(Ecore_X_Window root, - Ecore_X_Randr_Output output); -static Eina_Bool _ecore_xcb_randr_crtc_validate(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc); -static Eina_Bool _ecore_xcb_randr_root_validate(Ecore_X_Window root); -static int _ecore_xcb_randr_root_to_screen(Ecore_X_Window root); -#ifdef ECORE_XCB_RANDR -static xcb_randr_get_screen_resources_reply_t *_ecore_xcb_randr_12_get_resources(Ecore_X_Window win); -static xcb_randr_get_screen_resources_current_reply_t *_ecore_xcb_randr_13_get_resources(Ecore_X_Window win); -#endif -static xcb_timestamp_t _ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win); -static xcb_timestamp_t _ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win); - -static Ecore_X_Randr_Mode *_ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num, - int *npreferred); -static Ecore_X_Randr_Mode *_ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num, - int *npreferred); -static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode); -static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode); -static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root, - int *num); -static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root, - int *num); -static void _ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode, - int *w, - int *h); -static void _ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode, - int *w, - int *h); -static Ecore_X_Randr_Output *_ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num); -static Ecore_X_Randr_Output *_ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num); -static Ecore_X_Randr_Crtc *_ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num); -static Ecore_X_Randr_Crtc *_ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num); -static char *_ecore_xcb_randr_12_output_name_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *len); -static char *_ecore_xcb_randr_13_output_name_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *len); -static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root, - Ecore_X_Randr_Output output); -static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root, - Ecore_X_Randr_Output output); -static Ecore_X_Randr_Output *_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root, - int *num); -static Ecore_X_Randr_Output *_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root, - int *num); -static Ecore_X_Randr_Crtc _ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root, - Ecore_X_Randr_Output output); -static Ecore_X_Randr_Crtc _ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root, - Ecore_X_Randr_Output output); - -/* local variables */ -static Eina_Bool _randr_avail = EINA_FALSE; -static int _randr_version = -1; - -/* external variables */ -int _ecore_xcb_event_randr = -1; - -void -_ecore_xcb_randr_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_RANDR - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id); -#endif -} - -void -_ecore_xcb_randr_finalize(void) -{ -#ifdef ECORE_XCB_RANDR - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_RANDR - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_randr_query_version_cookie_t cookie; - xcb_randr_query_version_reply_t *reply; - - cookie = - xcb_randr_query_version_unchecked(_ecore_xcb_conn, - XCB_RANDR_MAJOR_VERSION, - XCB_RANDR_MINOR_VERSION); - reply = xcb_randr_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - if ((reply->major_version >= XCB_RANDR_MAJOR_VERSION) && - (reply->minor_version >= XCB_RANDR_MINOR_VERSION)) - _randr_avail = EINA_TRUE; - - _randr_version = - ((reply->major_version << 16) | reply->minor_version); - - free(reply); - } - - if (_randr_avail) - _ecore_xcb_event_randr = ext_reply->first_event; - } -#endif -} - -static Eina_Bool -#ifdef ECORE_XCB_RANDR -_ecore_xcb_randr_root_validate(Ecore_X_Window root) -#else -_ecore_xcb_randr_root_validate(Ecore_X_Window root EINA_UNUSED) -#endif -{ -#ifdef ECORE_XCB_RANDR - Ecore_X_Randr_Screen scr = -1; -# define RANDR_VALIDATE_ROOT(screen, root) \ - ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_RANDR - if ((root) && RANDR_VALIDATE_ROOT(scr, root)) - return EINA_TRUE; -#endif - - return EINA_FALSE; -} - -static int -_ecore_xcb_randr_root_to_screen(Ecore_X_Window root) -{ - int count = 0, num = 0; - - CHECK_XCB_CONN; - - count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); - for (num = 0; num < count; num++) - if (_ecore_xcb_window_root_of_screen_get(num) == root) - return num; - - return -1; -} - -/* public functions */ - -/* - * @brief Query whether RandR is available or not. - * - * @return @c EINA_TRUE if extension is available, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_randr_query(void) -{ - return _randr_avail; -} - -/* - * @return version of the RandRR extension supported by the server or, - * in case RandRR extension is not available, Ecore_X_Randr_Unset (=-1). - * bit version information: 31 MAJOR 16 | 15 MINOR 0 - */ -EAPI int -ecore_x_randr_version_get(void) -{ - return _randr_version; -} - -/* - * @param root window which's primary output will be queried - */ -EAPI Ecore_X_Randr_Orientation -ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root) -{ - int ret = Ecore_X_Randr_None; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - ret = reply->rotations; - free(reply); - } -#endif - - return ret; -} - -/* - * @param root window which's primary output will be queried - * @return the current orientation of the root window's screen primary output - */ -EAPI Ecore_X_Randr_Orientation -ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root) -{ - int ret = Ecore_X_Randr_None; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - ret = reply->rotation; - free(reply); - } -#endif - - return ret; -} - -/* - * @brief Sets a given screen's primary output's orientation. - * - * @param root Window which's screen's primary output will be queried. - * @param orientation Orientation which should be set for the root window's - * screen primary output. - * @return @c EINA_TRUE if the primary output's orientation could be - * successfully altered. - */ -EAPI Eina_Bool -ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, - Ecore_X_Randr_Orientation orientation) -{ - int ret = EINA_FALSE; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - xcb_randr_set_screen_config_cookie_t scookie; - xcb_randr_set_screen_config_reply_t *sreply; - - scookie = - xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, - XCB_CURRENT_TIME, - reply->config_timestamp, - reply->sizeID, orientation, - reply->rate); - sreply = - xcb_randr_set_screen_config_reply(_ecore_xcb_conn, scookie, NULL); - if (!sreply) - ret = EINA_FALSE; - else - { - ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? - EINA_TRUE : EINA_FALSE; - free(sreply); - } - free(reply); - } -#endif - - return ret; -} - -/* - * @brief gets a screen's primary output's possible sizes - * @param root window which's primary output will be queried - * @param num number of sizes reported as supported by the screen's primary output - * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL - */ -EAPI Ecore_X_Randr_Screen_Size_MM * -ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, - int *num) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; - Ecore_X_Randr_Screen_Size_MM *ret = NULL; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - int len = 0, i = 0; - xcb_randr_screen_size_t *sizes; - - len = xcb_randr_get_screen_info_sizes_length(reply); - sizes = xcb_randr_get_screen_info_sizes(reply); - if ((!sizes) || (len <= 0)) - { - free(reply); - return NULL; - } - if (num) *num = len; - ret = calloc(len, sizeof(Ecore_X_Randr_Screen_Size_MM)); - if (!ret) - { - free(reply); - return NULL; - } - for (i = 0; i < len; i++) - { - ret[i].width = sizes[i].width; - ret[i].height = sizes[i].height; - ret[i].width_mm = sizes[i].mwidth; - ret[i].height_mm = sizes[i].mheight; - } - - free(reply); - } - - return ret; -#else - return NULL; -#endif -} - -/* - * @brief get the current set size of a given screen's primary output - * @param root window which's primary output will be queried - * @param w the current size's width - * @param h the current size's height - * @param w_mm the current size's width in mm - * @param h_mm the current size's height in mm - * @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set() - */ -EAPI void -ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, - int *w, - int *h, - int *w_mm, - int *h_mm, - int *size_index) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - int len = 0, idx = 0; - xcb_randr_screen_size_t *sizes; - - len = xcb_randr_get_screen_info_sizes_length(reply); - sizes = xcb_randr_get_screen_info_sizes(reply); - if ((!sizes) || (len <= 0)) - { - free(reply); - return; - } - idx = reply->sizeID; - if ((idx < len) && (idx >= 0)) - { - if (w) *w = sizes[idx].width; - if (h) *h = sizes[idx].height; - if (w_mm) *w_mm = sizes[idx].mwidth; - if (h_mm) *h_mm = sizes[idx].mheight; - if (size_index) *size_index = idx; - } - - free(reply); - } -#endif -} - -/* - * @brief Sets a given screen's primary output size, but disables all other - * outputs at the same time. - * - * @param root Window which's primary output will be queried. - * @param size_index Within the list of sizes reported as supported by the root - * window's screen primary output. - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure due to e.g. - * invalid times. - */ -EAPI Eina_Bool -ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, - int size_index) -{ - Eina_Bool ret = EINA_FALSE; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - if (!((size_index >= 0) && (_ecore_xcb_randr_root_validate(root)))) - return EINA_FALSE; - - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - int len = 0; - - len = xcb_randr_get_screen_info_sizes_length(reply); - if (len <= 0) - { - free(reply); - return EINA_FALSE; - } - if ((size_index < len) && (size_index >= 0)) - { - xcb_randr_set_screen_config_cookie_t scookie; - xcb_randr_set_screen_config_reply_t *sreply; - - scookie = - xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, - XCB_CURRENT_TIME, - reply->config_timestamp, - size_index, - reply->rotation, - reply->rate); - sreply = - xcb_randr_set_screen_config_reply(_ecore_xcb_conn, - scookie, NULL); - if (!sreply) - ret = EINA_FALSE; - else - { - ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? - EINA_TRUE : EINA_FALSE; - free(sreply); - } - } - - free(reply); - } -#endif - return ret; -} - -/* - * @param root window which's primary output will be queried - * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0 - */ -EAPI Ecore_X_Randr_Refresh_Rate -ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; - Ecore_X_Randr_Refresh_Rate ret = 0.0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - if (!_ecore_xcb_randr_root_validate(root)) return ret; - - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - ret = reply->rate; - free(reply); - } - - return ret; -#else - return 0.0; -#endif -} - -/* - * @param root window which's primary output will be queried - * @param size_index referencing the size to query valid refresh rates for - * @return currently used refresh rate or - if request failed or RandRR is not available - NULL - */ -EAPI Ecore_X_Randr_Refresh_Rate * -ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, - int size_index, - int *num) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; - Ecore_X_Randr_Refresh_Rate *ret = NULL; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - if (!_ecore_xcb_randr_root_validate(root)) return ret; - - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - int len = 0; - - len = xcb_randr_get_screen_info_rates_length(reply); - if (num) *num = len; - - ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * len); - if (ret) - { - xcb_randr_refresh_rates_iterator_t iter; - int i = 0; - - iter = xcb_randr_get_screen_info_rates_iterator(reply); - while (i++ < size_index) - xcb_randr_refresh_rates_next(&iter); - - memcpy(ret, xcb_randr_refresh_rates_rates(iter.data), - sizeof(Ecore_X_Randr_Refresh_Rate) * len); - } - free(reply); - } - - return ret; -#else - return NULL; -#endif -} - -/* - * @brief Sets the current primary output's refresh rate. - * - * @param root Window which's primary output will be queried. - * @param size_index Referencing the size to be set. - * @param rate The refresh rate to be set. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root, - int size_index, - Ecore_X_Randr_Refresh_Rate rate) -{ - Eina_Bool ret = EINA_FALSE; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_info_cookie_t cookie; - xcb_randr_get_screen_info_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - if (_randr_version < RANDR_1_1) return EINA_FALSE; - - cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - xcb_randr_set_screen_config_cookie_t scookie; - xcb_randr_set_screen_config_reply_t *sreply; - - scookie = - xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, - XCB_CURRENT_TIME, - reply->config_timestamp, - size_index, - reply->rotation, rate); - sreply = - xcb_randr_set_screen_config_reply(_ecore_xcb_conn, - scookie, NULL); - if (!sreply) - ret = EINA_FALSE; - else - { - ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? - EINA_TRUE : EINA_FALSE; - free(sreply); - } - free(reply); - } -#endif - - return ret; -} - -/* - * @brief Free detailed mode information. The pointer handed in will be set to - * @c NULL after freeing the memory. - * - * @param mode_info The mode information that should be freed. - */ -EAPI void -ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - RANDR_CHECK_1_2_RET(); - - if (!mode_info) return; - - if (mode_info->name) free(mode_info->name); - free(mode_info); - mode_info = NULL; -} - -/* - * @param root window which's screen should be queried - * @return Ecore_X_Randr_Ouptut_Id or - if query failed or none is set - Ecore_X_Randr_None - */ -EAPI Ecore_X_Randr_Output -ecore_x_randr_primary_output_get(Ecore_X_Window root) -{ - Ecore_X_Randr_Output ret = Ecore_X_Randr_None; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_output_primary_cookie_t cookie; - xcb_randr_get_output_primary_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_3_RET(Ecore_X_Randr_None); - - if (!_ecore_xcb_randr_root_validate(root)) - return Ecore_X_Randr_None; - - cookie = xcb_randr_get_output_primary_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_output_primary_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - ret = reply->output; - free(reply); - } -#endif - return ret; -} - -/* - * @param root window which's screen should be queried - * @param output that should be set as given root window's screen primary output - */ -EAPI void -ecore_x_randr_primary_output_set(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_3_RET(); - - if ((output) && (_ecore_xcb_randr_root_validate(root))) - xcb_randr_set_output_primary(_ecore_xcb_conn, root, output); -#endif -} - -EAPI Ecore_X_Randr_Mode * -ecore_x_randr_output_modes_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num, - int *npreferred) -{ - Ecore_X_Randr_Mode *modes = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (_randr_version >= RANDR_1_3) - { - modes = - _ecore_xcb_randr_13_output_modes_get(root, output, num, npreferred); - } - else if (_randr_version == RANDR_1_2) - { - modes = - _ecore_xcb_randr_12_output_modes_get(root, output, num, npreferred); - } -#endif - - return modes; -} - -EAPI Eina_Bool -ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None)) - return EINA_FALSE; - - xcb_randr_add_output_mode(_ecore_xcb_conn, output, mode); - return EINA_TRUE; -#endif - return EINA_FALSE; -} - -/* - * @brief get detailed information for a given mode id - * @param root window which's screen's ressources are queried - * @param mode the XID which identifies the mode of interest - * @return mode's detailed information - */ -EAPI Ecore_X_Randr_Mode_Info * -ecore_x_randr_mode_info_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode) -{ - Ecore_X_Randr_Mode_Info *ret = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (!_ecore_xcb_randr_root_validate(root)) return NULL; - - if (_randr_version >= RANDR_1_3) - ret = _ecore_xcb_randr_13_mode_info_get(root, mode); - else if (_randr_version == RANDR_1_2) - ret = _ecore_xcb_randr_12_mode_info_get(root, mode); -#endif - return ret; -} - -/* - * @brief add a mode to a display - * @param root window to which's screen's ressources are added - * @param mode_info - * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode - * adding failed. - * @since 1.2.0 - */ -EAPI Ecore_X_Randr_Mode -ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info) -{ - Ecore_X_Randr_Mode mode = Ecore_X_Randr_None; -#ifdef ECORE_XCB_RANDR - xcb_randr_create_mode_cookie_t cookie; - xcb_randr_create_mode_reply_t *reply; - xcb_randr_mode_info_t info; - int namelen = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if (!mode_info) return Ecore_X_Randr_None; - if (!_ecore_xcb_randr_root_validate(root)) return Ecore_X_Randr_None; - - namelen = strlen(mode_info->name); - - memset(&info, 0, sizeof(info)); - info.width = mode_info->width; - info.height = mode_info->height; - info.dot_clock = mode_info->dotClock; - info.hsync_start = mode_info->hSyncStart; - info.hsync_end = mode_info->hSyncEnd; - info.htotal = mode_info->hTotal; - info.hskew = mode_info->hSkew; - info.vsync_start = mode_info->vSyncStart; - info.vsync_end = mode_info->vSyncEnd; - info.vtotal = mode_info->vTotal; - info.mode_flags = mode_info->modeFlags; - info.name_len = namelen; - - cookie = - xcb_randr_create_mode_unchecked(_ecore_xcb_conn, root, info, - namelen, mode_info->name); - reply = xcb_randr_create_mode_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - mode = mode_info->xid; - free(reply); - } -#endif - return mode; -} - -/* - * @brief get detailed information for all modes related to a root window's screen - * @param root window which's screen's ressources are queried - * @param num number of modes returned - * @return modes' information - */ -EAPI Ecore_X_Randr_Mode_Info ** -ecore_x_randr_modes_info_get(Ecore_X_Window root, - int *num) -{ - Ecore_X_Randr_Mode_Info **ret = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (num) *num = 0; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (!_ecore_xcb_randr_root_validate(root)) return NULL; - - if (_randr_version >= RANDR_1_3) - ret = _ecore_xcb_randr_13_modes_info_get(root, num); - else if (_randr_version == RANDR_1_2) - ret = _ecore_xcb_randr_12_modes_info_get(root, num); -#endif - return ret; -} - -/** - * @brief Gets the width and hight of a given mode. - * - * @param root Window which's screen's ressources are queried. - * @param mode The mode which's size is to be looked up. - * @param w Width of given mode in px. - * @param h Height of given mode in px. - */ -EAPI void -ecore_x_randr_mode_size_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode, - int *w, - int *h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(); - - if (mode == Ecore_X_Randr_None) return; - - if (_randr_version >= RANDR_1_3) - _ecore_xcb_randr_13_mode_size_get(root, mode, w, h); - else if (_randr_version == RANDR_1_2) - _ecore_xcb_randr_12_mode_size_get(root, mode, w, h); -#endif -} - -/** - * @brief Gets the EDID information of an attached output if available. - * Note that this information is not to be compared using ordinary string - * comparison functions, since it includes 0-bytes. - * - * @param root Window this information should be queried from. - * @param output The XID of the output. - * @param length Length of the byte-array. If @c NULL, request will fail. - * @return EDID information of the output. - */ -EAPI unsigned char * -ecore_x_randr_output_edid_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - unsigned long *length) -{ - unsigned char *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_output_property_cookie_t cookie; - xcb_randr_get_output_property_reply_t *reply; - Ecore_X_Atom atom; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if ((!length) || (!_ecore_xcb_randr_output_validate(root, output))) - return NULL; - - atom = ecore_x_atom_get("EDID"); - cookie = - xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, output, atom, - XCB_GET_PROPERTY_TYPE_ANY, - 0, 100, 0, 0); - reply = - xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - if ((reply->type == XCB_ATOM_INTEGER) && (reply->format == 8)) - { - if (length) *length = reply->num_items; - if ((ret = malloc(reply->num_items * sizeof(unsigned char)))) - { - memcpy(ret, xcb_randr_get_output_property_data(reply), - (reply->num_items * sizeof(unsigned char))); - } - } - free(reply); - } -#endif - return ret; -} - -/** - * @brief Gets the outputs which might be used simultaneously on the same CRTC. - * - * @param root Window that this information should be queried for. - * @param output The output which's clones we concern. - * @param num Number of possible clones. - * @return The existing outputs, @c NULL otherwise. - */ -EAPI Ecore_X_Randr_Output * -ecore_x_randr_output_clones_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num) -{ - Ecore_X_Randr_Output *outputs = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (output == Ecore_X_Randr_None) return NULL; - - if (_randr_version >= RANDR_1_3) - outputs = _ecore_xcb_randr_13_output_clones_get(root, output, num); - else if (_randr_version == RANDR_1_2) - outputs = _ecore_xcb_randr_12_output_clones_get(root, output, num); -#endif - return outputs; -} - -EAPI Ecore_X_Randr_Crtc * -ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num) -{ - Ecore_X_Randr_Crtc *crtcs = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (output == Ecore_X_Randr_None) return NULL; - - if (_randr_version >= RANDR_1_3) - crtcs = _ecore_xcb_randr_13_output_possible_crtcs_get(root, output, num); - else if (_randr_version == RANDR_1_2) - crtcs = _ecore_xcb_randr_12_output_possible_crtcs_get(root, output, num); -#endif - return crtcs; -} - -/** - * @brief gets the given output's name as reported by X - * @param root the window which's screen will be queried - * @param output The output name given to be reported. - * @param len length of returned c-string. - * @return name of the output as reported by X - */ -EAPI char * -ecore_x_randr_output_name_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *len) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (output == Ecore_X_Randr_None) return NULL; - - if (_randr_version >= RANDR_1_3) - return _ecore_xcb_randr_13_output_name_get(root, output, len); - else if (_randr_version == RANDR_1_2) - return _ecore_xcb_randr_12_output_name_get(root, output, len); -#endif - - return NULL; -} - -EAPI Ecore_X_Randr_Connection_Status -ecore_x_randr_output_connection_status_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN); - - if (output == Ecore_X_Randr_None) - return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; - - if (_randr_version >= RANDR_1_3) - return _ecore_xcb_randr_13_output_connection_status_get(root, output); - else if (_randr_version == RANDR_1_2) - return _ecore_xcb_randr_12_output_connection_status_get(root, output); -#endif - - return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; -} - -EAPI Ecore_X_Randr_Output * -ecore_x_randr_outputs_get(Ecore_X_Window root, - int *num) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (_randr_version >= RANDR_1_3) - return _ecore_xcb_randr_13_outputs_get(root, num); - else if (_randr_version == RANDR_1_2) - return _ecore_xcb_randr_12_outputs_get(root, num); -#endif - - return NULL; -} - -EAPI Ecore_X_Randr_Crtc -ecore_x_randr_output_crtc_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); - - if (output == Ecore_X_Randr_None) return Ecore_X_Randr_None; - - if (_randr_version >= RANDR_1_3) - return _ecore_xcb_randr_13_output_crtc_get(root, output); - else if (_randr_version == RANDR_1_2) - return _ecore_xcb_randr_12_output_crtc_get(root, output); -#endif - - return Ecore_X_Randr_None; -} - -EAPI void -ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w_mm, int *h_mm) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - xcb_timestamp_t timestamp = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (w_mm) *w_mm = 0; - if (h_mm) *h_mm = 0; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(); - - if ((output != Ecore_X_Randr_None) && (_randr_version >= RANDR_1_3)) - { - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - timestamp = reply->config_timestamp; - free(reply); - } - else if ((output != Ecore_X_Randr_None) && (_randr_version == RANDR_1_2)) - { - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - timestamp = reply->config_timestamp; - free(reply); - } - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL); - if (oreply) - { - if (w_mm) *w_mm = oreply->mm_width; - if (h_mm) *h_mm = oreply->mm_height; - free(oreply); - } -#endif -} - -/** - * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is - * auto enabled in it's preferred mode, when it was disabled before. - * - * @param root The root window which's default display will be queried. - * @param crtc The CRTC which's configuration should be altered. - * @param outputs An array of outputs, that should display this CRTC's content. - * @param noutputs Number of outputs in the array of outputs. If set to - * Ecore_X_Randr_Unset, current outputs and number of outputs will be used. If - * set to Ecore_X_Randr_None, CRTC will be disabled. - * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x - * coordinate will be assumed. - * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y - * coordinate will be assumed. - * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the - * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is - * assumed. - * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is - * used, the current mode is assumed. - * @return @c EINA_TRUE if the configuration alteration was successful, - * @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_randr_crtc_settings_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - Ecore_X_Randr_Output *outputs, - int noutputs, - int x, - int y, - Ecore_X_Randr_Mode mode, - Ecore_X_Randr_Orientation orientation) -{ - Eina_Bool ret = EINA_FALSE; -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_crtc_info_cookie_t ccookie; - xcb_randr_get_crtc_info_reply_t *creply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - ccookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); - creply = - xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ccookie, NULL); - if (creply) - { - xcb_randr_set_crtc_config_cookie_t scookie; - xcb_randr_set_crtc_config_reply_t *sreply; - - if ((mode == Ecore_X_Randr_None) || - (noutputs == Ecore_X_Randr_None)) - { - outputs = NULL; - noutputs = 0; - } - else if (noutputs == (int)Ecore_X_Randr_Unset) - { - outputs = xcb_randr_get_crtc_info_outputs(creply); - noutputs = creply->num_outputs; - } - if ((int)mode == Ecore_X_Randr_Unset) mode = creply->mode; - if (x < 0) x = creply->x; - if (y < 0) y = creply->y; - if ((int)orientation == Ecore_X_Randr_Unset) - orientation = creply->rotation; - - scookie = - xcb_randr_set_crtc_config_unchecked(_ecore_xcb_conn, - crtc, XCB_CURRENT_TIME, stamp, - x, y, mode, orientation, - noutputs, outputs); - sreply = - xcb_randr_set_crtc_config_reply(_ecore_xcb_conn, scookie, NULL); - if (sreply) - { - ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? - EINA_TRUE : EINA_FALSE; - free(sreply); - } - free(creply); - } -#endif - - return ret; -} - -/** - * @brief Sets a mode for a CRTC and the outputs attached to it. - * - * @param root The window's screen to be queried - * @param crtc The CRTC which shall be set - * @param outputs Array of outputs which have to be compatible with the mode. If - * @c NULL CRTC will be disabled. - * @param noutputs Number of outputs in array to be used. Use - * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs. - * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be - * disabled. If set to @c -1 the call will fail. - * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE - * otherwise. - */ -EAPI Eina_Bool -ecore_x_randr_crtc_mode_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - Ecore_X_Randr_Output *outputs, - int noutputs, - Ecore_X_Randr_Mode mode) -{ - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if ((int)mode == Ecore_X_Randr_Unset) return ret; - ret = - ecore_x_randr_crtc_settings_set(root, crtc, outputs, noutputs, - Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, - mode, Ecore_X_Randr_Unset); -#endif - - return ret; -} - -/** - * @brief Get the current set mode of a given CRTC - * @param root the window's screen to be queried - * @param crtc the CRTC which's should be queried - * @return currently set mode or - in case parameters are invalid - - * Ecore_X_Randr_Unset - */ -EAPI Ecore_X_Randr_Mode -ecore_x_randr_crtc_mode_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc) -{ - Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset; -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_crtc_info_cookie_t ocookie; - xcb_randr_get_crtc_info_reply_t *oreply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset); - - if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - ocookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); - oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); - if (oreply) - { - ret = oreply->mode; - free(oreply); - } -#endif - - return ret; -} - -EAPI Ecore_X_Randr_Orientation -ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc) -{ - Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_crtc_info_cookie_t ocookie; - xcb_randr_get_crtc_info_reply_t *oreply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); - - if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - ocookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); - oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); - if (oreply) - { - ret = oreply->rotation; - free(oreply); - } -#endif - - return ret; -} - -EAPI Eina_Bool -ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - Ecore_X_Randr_Orientation orientation) -{ - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if (orientation != Ecore_X_Randr_None) - { - ret = - ecore_x_randr_crtc_settings_set(root, crtc, NULL, - Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, - Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, - orientation); - } -#endif - return ret; -} - -EAPI Ecore_X_Randr_Orientation -ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc) -{ - Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_crtc_info_cookie_t ocookie; - xcb_randr_get_crtc_info_reply_t *oreply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); - - if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - ocookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); - oreply = - xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); - if (oreply) - { - ret = oreply->rotations; - free(oreply); - } -#endif - - return ret; -} - -/* - * @brief get a CRTC's possible outputs. - * @param root the root window which's screen will be queried - * @param num number of possible outputs referenced by given CRTC - */ -EAPI Ecore_X_Randr_Output * -ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *num) -{ - Ecore_X_Randr_Output *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_crtc_info_cookie_t ocookie; - xcb_randr_get_crtc_info_reply_t *oreply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - ocookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); - oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); - if (oreply) - { - if (num) *num = oreply->num_possible_outputs; - ret = malloc(sizeof(Ecore_X_Randr_Output) * - oreply->num_possible_outputs); - if (ret) - { - memcpy(ret, xcb_randr_get_crtc_info_possible(oreply), - sizeof(Ecore_X_Randr_Output) * - oreply->num_possible_outputs); - } - free(oreply); - } -#endif - - return ret; -} - -/* - * @brief get all known CRTCs related to a root window's screen - * @param root window which's screen's ressources are queried - * @param num number of CRTCs returned - * @return CRTC IDs - */ -EAPI Ecore_X_Randr_Crtc * -ecore_x_randr_crtcs_get(Ecore_X_Window root, - int *num) -{ - Ecore_X_Randr_Crtc *ret = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (_randr_version >= RANDR_1_3) - { - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - if (num) *num = reply->num_crtcs; - ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); - if (ret) - memcpy(ret, xcb_randr_get_screen_resources_current_crtcs(reply), - sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); - free(reply); - } - } - else if (_randr_version == RANDR_1_2) - { - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - if (num) *num = reply->num_crtcs; - ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); - if (ret) - memcpy(ret, xcb_randr_get_screen_resources_crtcs(reply), - sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); - free(reply); - } - } -#endif - - return ret; -} - -/* - * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead. - * @brief Get the CRTCs, which display a certain window. - * - * @param window Window the displaying CRTCs shall be found for. - * @param num The number of CRTCs displaying the window. - * @return Array of CRTCs that display a certain window. @c NULL if no CRTCs - * was found that displays the specified window. - */ -EAPI Ecore_X_Randr_Crtc * -ecore_x_randr_current_crtc_get(Ecore_X_Window window, - int *num) -{ - return ecore_x_randr_window_crtcs_get(window, num); -} - -/* - * @brief Get the CRTCs, which display a certain window. - * - * @param window Window the displaying crtcs shall be found for. - * @param num The number of crtcs displaying the window. - * @return Array of crtcs that display a certain window. @c NULL if no crtcs - * was found that displays the specified window. - * @since 1.2.0 - */ -EAPI Ecore_X_Randr_Crtc * -ecore_x_randr_window_crtcs_get(Ecore_X_Window window, - int *num) -{ -#ifdef ECORE_XCB_RANDR - Ecore_X_Window root; - Eina_Rectangle w_geo, c_geo; - Ecore_X_Randr_Crtc *crtcs, *ret = NULL; - Ecore_X_Randr_Mode mode; - int ncrtcs, i, nret = 0; - xcb_translate_coordinates_cookie_t cookie; - xcb_translate_coordinates_reply_t *trans; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - ecore_x_window_geometry_get(window, &w_geo.x, &w_geo.y, &w_geo.w, &w_geo.h); - - root = ecore_x_window_root_get(window); - crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs); - if (!crtcs) goto _ecore_x_randr_window_crtcs_get_fail; - - /* now get window RELATIVE to root window - thats what matters. */ - cookie = xcb_translate_coordinates(_ecore_xcb_conn, window, root, 0, 0); - trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); - w_geo.x = trans->dst_x; - w_geo.y = trans->dst_y; - free(trans); - - ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc)); - if (!ret) - { - free(crtcs); - goto _ecore_x_randr_window_crtcs_get_fail; - } - for (i = 0, nret = 0; i < ncrtcs; i++) - { - /* if crtc is not enabled, don't bother about it any further */ - mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]); - if (mode == Ecore_X_Randr_None) continue; - - ecore_x_randr_crtc_geometry_get(root, crtcs[i], &c_geo.x, &c_geo.y, - &c_geo.w, &c_geo.h); - if (eina_rectangles_intersect(&w_geo, &c_geo)) - { - ret[nret] = crtcs[i]; - nret++; - } - } - free(crtcs); - - if (num) *num = nret; - return ret; - -_ecore_x_randr_window_crtcs_get_fail: -#endif - if (num) *num = 0; - return NULL; -} - -/* - * @brief get a CRTC's outputs. - * @param root the root window which's screen will be queried - * @param num number of outputs referenced by given CRTC - */ -EAPI Ecore_X_Randr_Output * -ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *num) -{ - Ecore_X_Randr_Output *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_crtc_info_cookie_t ocookie; - xcb_randr_get_crtc_info_reply_t *oreply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(NULL); - - if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - ocookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); - oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); - if (oreply) - { - if (num) *num = oreply->num_outputs; - ret = malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_outputs); - if (ret) - memcpy(ret, xcb_randr_get_crtc_info_outputs(oreply), - sizeof(Ecore_X_Randr_Output) * oreply->num_outputs); - free(oreply); - } -#endif - - return ret; -} - -EAPI void -ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *x, - int *y, - int *w, - int *h) -{ -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_crtc_info_cookie_t ocookie; - xcb_randr_get_crtc_info_reply_t *oreply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(); - - if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return; - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - ocookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); - oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); - if (oreply) - { - if (x) *x = oreply->x; - if (y) *y = oreply->y; - if (w) *w = oreply->width; - if (h) *h = oreply->height; - free(oreply); - } -#endif -} - -/** - * @brief Sets a CRTC relative to another one. - * - * @param root The window on which CRTC's position will be set. - * @param crtc_r1 The CRTC to be positioned. - * @param crtc_r2 The CRTC the position should be relative to. - * @param policy The relation between the crtcs. - * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at - * CRTC2's borders. - * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE - * if repositioning failed or if position of new crtc would be out of given - * screen's min/max bounds. - */ -EAPI Eina_Bool -ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc_r1, - Ecore_X_Randr_Crtc crtc_r2, - Ecore_X_Randr_Output_Policy policy, - Ecore_X_Randr_Relative_Alignment alignment) -{ -#ifdef ECORE_XCB_RANDR - Eina_Rectangle r1, r2; - int w_max = 0, h_max = 0, cw = 0, ch = 0, xn = -1, yn = -1; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == 0) || - (ecore_x_randr_crtc_mode_get(root, crtc_r2) == 0)) - return EINA_FALSE; - - if ((!_ecore_xcb_randr_crtc_validate(root, crtc_r1) || - (!(crtc_r1 != crtc_r2) && (!_ecore_xcb_randr_crtc_validate(root, crtc_r2))))) - return EINA_FALSE; - - ecore_x_randr_crtc_geometry_get(root, crtc_r1, &r1.x, &r1.y, &r1.w, &r1.h); - ecore_x_randr_crtc_geometry_get(root, crtc_r2, &r2.x, &r2.y, &r2.w, &r2.h); - ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); - ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); - - switch (policy) - { - case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT: - xn = (r2.x + r2.w); - if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) - yn = -1; - else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) - yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0))); - else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) - yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0)); - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: - xn = (r2.x - r1.w); - if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) - yn = -1; - else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) - yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0))); - else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) - yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0)); - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_BELOW: - yn = (r2.y + r2.h); - if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) - xn = -1; - else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) - xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0))); - else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) - xn = ((int)((double)cw / 2.0)); - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: - yn = (r2.y - r1.h); - if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) - xn = -1; - else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) - xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0))); - else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) - xn = ((int)((double)cw / 2.0)); - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: - return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2.x, r2.y); - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_NONE: - break; - default: - return EINA_FALSE; - } - - if ((xn == r1.x) && (yn == r1.x)) return EINA_TRUE; - if (((yn + r1.h) > h_max) || ((xn + r1.w) > w_max)) - return EINA_FALSE; - - return ecore_x_randr_crtc_pos_set(root, crtc_r1, xn, yn); -#endif - - return EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, - const Ecore_X_Randr_Crtc *not_moved, - int num, - int dx, - int dy) -{ - Eina_Bool ret = EINA_FALSE; -#ifdef ECORE_XCB_RANDR - Ecore_X_Randr_Crtc *crtcs = NULL, *move = NULL; - int i = 0, j = 0, k = 0, n = 0, total = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - if ((num <= 0) || (!not_moved) || (!_ecore_xcb_randr_root_validate(root))) - return EINA_FALSE; - - crtcs = ecore_x_randr_crtcs_get(root, &total); - n = (total - num); - move = malloc(sizeof(Ecore_X_Randr_Crtc) * n); - if (move) - { - for (i = 0, k = 0; (i < total) && (k < n); i++) - { - for (j = 0; j < num; j++) - if (crtcs[i] == not_moved[j]) break; - if (j == num) - move[k++] = crtcs[i]; - } - ret = ecore_x_randr_move_crtcs(root, move, n, dx, dy); - free(move); - free(crtcs); - } -#endif - - return ret; -} - -EAPI void -ecore_x_randr_crtc_pos_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *x, - int *y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(); - - ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL); -#endif -} - -/* - * @brief Sets the position of given CRTC within root window's screen. - * - * @param root The window's screen to be queried. - * @param crtc The CRTC which's position within the mentioned screen is to be - * altered. - * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current - * value will be kept. - * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current - * value will be kept. - * @return @c EINA_TRUE if position could be successfully be altered. - */ -EAPI Eina_Bool -ecore_x_randr_crtc_pos_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int x, - int y) -{ - Eina_Bool ret = EINA_FALSE; -#ifdef ECORE_XCB_RANDR - int w = 0, h = 0, nw = 0, nh = 0; - Eina_Rectangle rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - ecore_x_randr_crtc_geometry_get(root, crtc, - &rect.x, &rect.y, &rect.w, &rect.h); - ecore_x_randr_screen_current_size_get(root, &w, &h, NULL, NULL); - if (x < 0) x = rect.x; - if (y < 0) y = rect.y; - if ((x + rect.w) > w) - nw = (x + rect.w); - if ((y + rect.h) > h) - nh = (y + rect.h); - - if ((nw != 0) || (nh != 0)) - { - if (!ecore_x_randr_screen_current_size_set(root, nw, nh, 0, 0)) - return EINA_FALSE; - } - - ret = ecore_x_randr_crtc_settings_set(root, crtc, NULL, -1, x, y, -1, -1); -#endif - - return ret; -} - -EAPI void -ecore_x_randr_crtc_size_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *w, - int *h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(); - ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h); -#endif -} - -EAPI Ecore_X_Randr_Refresh_Rate -ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - Ecore_X_Randr_Mode mode) -{ - Ecore_X_Randr_Refresh_Rate ret = 0.0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(0.0); - - if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return 0.0; - - if (_randr_version >= RANDR_1_3) - { - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - xcb_randr_mode_info_iterator_t miter; - - miter = - xcb_randr_get_screen_resources_current_modes_iterator(reply); - while (miter.rem) - { - xcb_randr_mode_info_t *minfo; - - minfo = miter.data; - if (minfo->id == mode) - { - if ((minfo->htotal) && (minfo->vtotal)) - { - ret = ((double)minfo->dot_clock / - ((double)minfo->htotal * - (double)minfo->vtotal)); - } - break; - } - xcb_randr_mode_info_next(&miter); - } - free(reply); - } - } - else if (_randr_version == RANDR_1_2) - { - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - xcb_randr_mode_info_iterator_t miter; - - miter = xcb_randr_get_screen_resources_modes_iterator(reply); - while (miter.rem) - { - xcb_randr_mode_info_t *minfo; - - minfo = miter.data; - if (minfo->id == mode) - { - if ((minfo->htotal) && (minfo->vtotal)) - { - ret = ((double)minfo->dot_clock / - ((double)minfo->htotal * - (double)minfo->vtotal)); - } - break; - } - xcb_randr_mode_info_next(&miter); - } - free(reply); - } - } -#endif - return ret; -} - -/* - * @brief Move given CRTCs belonging to the given root window's screen dx/dy - * pixels relative to their current position. The screen size will be - * automatically adjusted if necessary and possible. - * - * @param root Window which's screen's resources are used. - * @param crtcs List of CRTCs to be moved. - * @param ncrtc Number of CRTCs in array. - * @param dx Amount of pixels the CRTCs should be moved in x direction. - * @param dy Amount of pixels the CRTCs should be moved in y direction. - * @return @c EINA_TRUE if all crtcs could be moved successfully. - */ -EAPI Eina_Bool -ecore_x_randr_move_crtcs(Ecore_X_Window root, - const Ecore_X_Randr_Crtc *crtcs, - int num, - int dx, - int dy) -{ - Eina_Bool ret = EINA_TRUE; -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_crtc_info_reply_t *oreply[num]; - int i = 0, cw = 0, ch = 0; - int mw = 0, mh = 0, nw = 0, nh = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if (!_ecore_xcb_randr_root_validate(root)) return EINA_FALSE; - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh); - ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); - nw = cw; - nh = ch; - - for (i = 0; i < num; i++) - { - xcb_randr_get_crtc_info_cookie_t ocookie; - - ocookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], - stamp); - oreply[i] = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply[i]) - { - if (((oreply[i]->x + dx) < 0) || - ((oreply[i]->y + dy) < 0) || - ((oreply[i]->x + oreply[i]->width + dx) > mw) || - ((oreply[i]->y + oreply[i]->height + dy) > mh)) - { - continue; - } - nw = MAX((int)(oreply[i]->x + oreply[i]->width + dx), nw); - nh = MAX((int)(oreply[i]->y + oreply[i]->height + dy), nh); - } - } - - if ((nw > cw) || (nh > ch)) - { - if (!ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1)) - { - for (i = 0; i < num; i++) - if (oreply[i]) free(oreply[i]); - - return EINA_FALSE; - } - } - - for (i = 0; ((i < num) && (oreply[i])); i++) - { - if (!oreply[i]) continue; - if (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1, - (oreply[i]->x + dx), - (oreply[i]->y + dy), - oreply[i]->mode, - oreply[i]->rotation)) - { - ret = EINA_FALSE; - break; - } - } - - if (i < num) - { - while (i-- >= 0) - { - if (oreply[i]) - ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1, - (oreply[i]->x - dx), - (oreply[i]->y - dy), - oreply[i]->mode, - oreply[i]->rotation); - } - } - - for (i = 0; i < num; i++) - if (oreply[i]) free(oreply[i]); -#endif - - return ret; -} - -/** - * @brief enable event selection. This enables basic interaction with - * output/crtc events and requires RRandR >= 1.2. - * @param win select this window's properties for RandRR events - * @param on enable/disable selecting - */ -EAPI void -ecore_x_randr_events_select(Ecore_X_Window win, - Eina_Bool on) -{ -#ifdef ECORE_XCB_RANDR - uint16_t mask = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - if (on) - { - mask = XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE; - if (_randr_version >= ((1 << 16) | 2)) - { - mask |= (XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | - XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | - XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY); - } - } - - xcb_randr_select_input(_ecore_xcb_conn, win, mask); -#endif -} - -/** - * @brief removes unused screen space. The most upper left CRTC is set to 0x0 - * and all other CRTCs dx,dy respectively. - * @param root the window's screen which will be reset. - */ -EAPI void -ecore_x_randr_screen_reset(Ecore_X_Window root) -{ -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - Ecore_X_Randr_Crtc *crtcs = NULL; - int total = 0, i = 0, w = 0, h = 0; - int dx = 100000, dy = 100000, num = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - if (!_ecore_xcb_randr_root_validate(root)) return; - crtcs = ecore_x_randr_crtcs_get(root, &total); - - if (_randr_version >= RANDR_1_3) - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - else if (_randr_version == RANDR_1_2) - stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); - - /* I hate declaring variables inside code like this, but we need the - * value of 'total' before we can */ - Ecore_X_Randr_Crtc enabled[total]; - - for (i = 0; i < total; i++) - { - xcb_randr_get_crtc_info_cookie_t ocookie; - xcb_randr_get_crtc_info_reply_t *oreply; - - ocookie = - xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], stamp); - oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (!oreply) continue; - if ((oreply->mode <= 0) || (oreply->num_outputs == 0)) - { - free(oreply); - continue; - } - - enabled[num++] = crtcs[i]; - if ((int)(oreply->x + oreply->width) > w) - w = (oreply->x + oreply->width); - if ((int)(oreply->y + oreply->height) > h) - h = (oreply->y + oreply->height); - - if (oreply->x < dx) dx = oreply->x; - if (oreply->y < dy) dy = oreply->y; - - free(oreply); - } - free(crtcs); - - if ((dx > 0) || (dy > 0)) - { - if (ecore_x_randr_move_crtcs(root, enabled, num, -dx, -dy)) - { - w -= dx; - h -= dy; - } - } - - ecore_x_randr_screen_current_size_set(root, w, h, -1, -1); -#endif -} - -/* - * @param root window which's screen will be queried - * @param wmin minimum width the screen can be set to - * @param hmin minimum height the screen can be set to - * @param wmax maximum width the screen can be set to - * @param hmax maximum height the screen can be set to - */ -EAPI void -ecore_x_randr_screen_size_range_get(Ecore_X_Window root, - int *minw, - int *minh, - int *maxw, - int *maxh) -{ -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_size_range_cookie_t cookie; - xcb_randr_get_screen_size_range_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(); - - cookie = xcb_randr_get_screen_size_range_unchecked(_ecore_xcb_conn, root); - reply = xcb_randr_get_screen_size_range_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - if (minw) *minw = reply->min_width; - if (minh) *minh = reply->min_height; - if (maxw) *maxw = reply->max_width; - if (maxh) *maxh = reply->max_height; - free(reply); - } -#endif -} - -/* - * @param w width of screen in px - * @param h height of screen in px - */ -EAPI void -ecore_x_randr_screen_current_size_get(Ecore_X_Window root, - int *w, - int *h, - int *w_mm, - int *h_mm) -{ -#ifdef ECORE_XCB_RANDR - Ecore_X_Randr_Screen scr = 0; - xcb_screen_t *s; -# define RANDR_VALIDATE_ROOT(screen, root) \ - ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(); - - if (!RANDR_VALIDATE_ROOT(scr, root)) return; - - s = ecore_x_screen_get(scr); - if (w) *w = s->width_in_pixels; - if (h) *h = s->height_in_pixels; - if (w_mm) *w_mm = s->width_in_millimeters; - if (h_mm) *h_mm = s->height_in_millimeters; -#endif -} - -/* - * @param root Window which's screen's size should be set. If invalid (e.g. - * @c NULL) no action is taken. - * @param w Width in px the screen should be set to. If out of valid - * boundaries, current value is assumed. - * @param h Height in px the screen should be set to. If out of valid - * boundaries, current value is assumed. - * @param w_mm Width in mm the screen should be set to. If @c 0, current - * aspect is assumed. - * @param h_mm Height in mm the screen should be set to. If @c 0, current - * aspect is assumed. - * @return @c EINA_TRUE if request was successfully sent or screen is already - * in requested size, @c EINA_FALSE if parameters are invalid. - */ -EAPI Eina_Bool -ecore_x_randr_screen_current_size_set(Ecore_X_Window root, - int w, - int h, - int w_mm, - int h_mm) -{ - Eina_Bool ret = EINA_TRUE; -#ifdef ECORE_XCB_RANDR - Ecore_X_Randr_Screen scr; - int wc = 0, hc = 0, w_mm_c = 0, h_mm_c = 0; - int mw = 0, mh = 0, xw = 0, xh = 0; -# define RANDR_VALIDATE_ROOT(screen, root) \ - ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if (!RANDR_VALIDATE_ROOT(scr, root)) return EINA_FALSE; - ecore_x_randr_screen_current_size_get(root, &wc, &hc, &w_mm_c, &h_mm_c); - if ((w == wc) && (h == hc) && (w_mm == w_mm_c) && (h_mm == h_mm_c)) - return EINA_TRUE; - ecore_x_randr_screen_size_range_get(root, &mw, &mh, &xw, &xh); - if (((w != 1) && ((w < mw) || (w > xw))) || - ((h != -1) && ((h < mh) || (h > xh)))) return EINA_FALSE; - - if (w <= 0) - w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; - if (h <= 0) - h = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; - - /* NB: Hmmmm, xlib version divides w_mm by width ... that seems wrong */ - if (w_mm <= 0) - w_mm = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_millimeters; - if (h_mm <= 0) - h_mm = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_millimeters; - - xcb_randr_set_screen_size(_ecore_xcb_conn, root, w, h, w_mm, h_mm); -#endif - - return ret; -} - -/* - * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead. - * @brief Get the outputs, which display a certain window. - * - * @param window Window the displaying outputs shall be found for. - * @param num The number of outputs displaying the window. - * @return Array of outputs that display a certain window. @c NULL if no - * outputs was found that displays the specified window. - */ - -Ecore_X_Randr_Output * -ecore_x_randr_current_output_get(Ecore_X_Window window, - int *num) -{ - return ecore_x_randr_window_outputs_get(window, num); -} - -/* - * @brief Get the outputs, which display a certain window. - * - * @param window Window the displaying outputs shall be found for. - * @param num The number of outputs displaying the window. - * @return Array of outputs that display a certain window. @c NULL if no - * outputs was found that displays the specified window. - */ -EAPI Ecore_X_Randr_Output * -ecore_x_randr_window_outputs_get(Ecore_X_Window window, - int *num) -{ -#ifdef ECORE_XCB_RANDR - Ecore_X_Window root; - Ecore_X_Randr_Crtc *crtcs; - Ecore_X_Randr_Output *outputs, *ret = NULL, *tret; - int ncrtcs, noutputs, i, nret = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (num) *num = 0; - -#ifdef ECORE_XCB_RANDR - if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail; - - root = ecore_x_window_root_get(window); - if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs))) - goto _ecore_x_randr_current_output_get_fail; - - for (i = 0, nret = 0; i < ncrtcs; i++) - { - - outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i], - &noutputs); - if (!outputs) - goto _ecore_x_randr_current_output_get_fail_free; - tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output))); - if (!tret) goto _ecore_x_randr_current_output_get_fail_free; - ret = tret; - memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output))); - nret += noutputs; - free(outputs); - outputs = NULL; - } - free(crtcs); - - if (num) - *num = nret; - - return ret; - -_ecore_x_randr_current_output_get_fail_free: - free(outputs); - free(crtcs); - free(ret); -_ecore_x_randr_current_output_get_fail: -#endif - if (num) *num = 0; - return NULL; -} - -/* - * @brief get the backlight level of the given output - * @param root window which's screen should be queried - * @param output from which the backlight level should be retrieved - * @return the backlight level - */ -EAPI double -ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ -#ifdef ECORE_XCB_RANDR - Ecore_X_Atom _backlight; - xcb_intern_atom_cookie_t acookie; - xcb_intern_atom_reply_t *areply; - xcb_randr_get_output_property_cookie_t cookie; - xcb_randr_get_output_property_reply_t *reply; - xcb_randr_query_output_property_cookie_t qcookie; - xcb_randr_query_output_property_reply_t *qreply; - double dvalue; - long value, max, min; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(-1); - - acookie = - xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, - strlen("Backlight"), "Backlight"); - areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); - - if (!areply) - { - ERR("Backlight property is not suppported on this server or driver"); - return -1; - } - else - { - _backlight = areply->atom; - free(areply); - } - - if (!_ecore_xcb_randr_output_validate(root, output)) - { - ERR("Invalid output"); - return -1; - } - - cookie = - xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, - output, _backlight, - XCB_ATOM_NONE, 0, 4, 0, 0); - reply = - xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) - { - WRN("Backlight not supported on this output"); - return -1; - } - - if ((reply->format != 32) || (reply->num_items != 1) || - (reply->type != XCB_ATOM_INTEGER)) - { - free(reply); - return -1; - } - - value = *((long *)xcb_randr_get_output_property_data(reply)); - free (reply); - - /* I have the current value of the backlight */ - /* Now retrieve the min and max intensities of the output */ - qcookie = - xcb_randr_query_output_property_unchecked(_ecore_xcb_conn, - output, _backlight); - qreply = - xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL); - if (qreply) - { - dvalue = -1; - if ((qreply->range) && - (xcb_randr_query_output_property_valid_values_length(qreply) == 2)) - { - int32_t *vals; - - vals = xcb_randr_query_output_property_valid_values(qreply); - /* finally convert the current value in the interval [0..1] */ - min = vals[0]; - max = vals[1]; - dvalue = ((double)(value - min)) / ((double)(max - min)); - } - free(qreply); - return dvalue; - } -#endif - return -1; -} - -/* - * @brief Set the backlight level of a given output. - * - * @param root Window which's screen should be queried. - * @param output That should be set. - * @param level For which the backlight should be set. - * @return @c EINA_TRUE in case of success. - */ -EAPI Eina_Bool -ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, - Ecore_X_Randr_Output output, - double level) -{ -#ifdef ECORE_XCB_RANDR - Ecore_X_Atom _backlight; - xcb_intern_atom_cookie_t acookie; - xcb_intern_atom_reply_t *areply; - xcb_randr_query_output_property_cookie_t qcookie; - xcb_randr_query_output_property_reply_t *qreply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if ((level < 0) || (level > 1)) - { - ERR("Backlight level should be between 0 and 1"); - return EINA_FALSE; - } - - if (!_ecore_xcb_randr_output_validate(root, output)) - { - ERR("Wrong output value"); - return EINA_FALSE; - } - - acookie = - xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, - strlen("Backlight"), "Backlight"); - areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); - if (!areply) - { - WRN("Backlight property is not suppported on this server or driver"); - return EINA_FALSE; - } - else - { - _backlight = areply->atom; - free(areply); - } - - qcookie = - xcb_randr_query_output_property_unchecked(_ecore_xcb_conn, - output, _backlight); - qreply = - xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL); - if (qreply) - { - if ((qreply->range) && (qreply->length == 2)) - { - int32_t *vals; - double min, max, tmp; - long n; - - vals = xcb_randr_query_output_property_valid_values(qreply); - min = vals[0]; - max = vals[1]; - tmp = (level * (max - min)) + min; - n = tmp; - if (n > max) n = max; - if (n < min) n = min; - xcb_randr_change_output_property(_ecore_xcb_conn, output, - _backlight, XCB_ATOM_INTEGER, - 32, XCB_PROP_MODE_REPLACE, - 1, (unsigned char *)&n); - ecore_x_flush(); // needed - } - - free(qreply); - return EINA_TRUE; - } -#endif - return EINA_FALSE; -} - -/* - * @brief Check if a backlight is available. - * - * @return Whether a backlight is available. - */ -EAPI Eina_Bool -ecore_x_randr_output_backlight_available(void) -{ -#ifdef ECORE_XCB_RANDR - Ecore_X_Atom _backlight; - xcb_intern_atom_cookie_t acookie; - xcb_intern_atom_reply_t *areply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - acookie = - xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, - strlen("Backlight"), "Backlight"); - areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); - - if (!areply) - { - ERR("Backlight property is not suppported on this server or driver"); - return EINA_FALSE; - } - else - { - _backlight = areply->atom; - free(areply); - return EINA_TRUE; - } -#endif - return EINA_FALSE; -} - -EAPI int -ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length) -{ - if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) && - (ecore_x_randr_edid_has_valid_header(edid, edid_length))) - return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) | - edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR]; - return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; -} - -EAPI char * -ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length) -{ - unsigned char *block = NULL; - int version = 0; - - version = ecore_x_randr_edid_version_get(edid, edid_length); - if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; - - _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) - { - if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc) - { - char *name, *p; - const char *edid_name; - - edid_name = (const char *)block + - _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; - name = - malloc(sizeof(char) * - _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); - if (!name) return NULL; - - strncpy(name, edid_name, - (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); - name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; - for (p = name; *p; p++) - if ((*p < ' ') || (*p > '~')) *p = 0; - - return name; - } - } - return NULL; -} - -EAPI Eina_Bool -ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length) -{ - const unsigned char header[] = - { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 - }; - - if ((!edid) || (edid_length < 8)) return EINA_FALSE; - if (!memcmp(edid, header, 8)) return EINA_TRUE; - return EINA_FALSE; -} - -/* local functions */ -static Eina_Bool -_ecore_xcb_randr_output_validate(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if ((output) && (_ecore_xcb_randr_root_validate(root))) - { - if (_randr_version >= RANDR_1_3) - { - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - int len = 0, i = 0; - xcb_randr_output_t *outputs; - - len = - xcb_randr_get_screen_resources_current_outputs_length(reply); - outputs = - xcb_randr_get_screen_resources_current_outputs(reply); - for (i = 0; i < len; i++) - { - if (outputs[i] == output) - { - ret = EINA_TRUE; - break; - } - } - free(reply); - } - } - else if (_randr_version == RANDR_1_2) - { - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - int len = 0, i = 0; - xcb_randr_output_t *outputs; - - len = xcb_randr_get_screen_resources_outputs_length(reply); - outputs = xcb_randr_get_screen_resources_outputs(reply); - for (i = 0; i < len; i++) - { - if (outputs[i] == output) - { - ret = EINA_TRUE; - break; - } - } - free(reply); - } - } - } -#endif - return ret; -} - -/** - * @brief Validates a CRTC for a given root window's screen. - * - * @param root The window which's default display will be queried. - * @param crtc The CRTC to be validated. - * @return In case it is found @c EINA_TRUE will be returned, else - * @c EINA_FALSE is returned. - */ -static Eina_Bool -_ecore_xcb_randr_crtc_validate(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc) -{ - Eina_Bool ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if (((int)crtc == Ecore_X_Randr_None) || ((int)crtc == Ecore_X_Randr_Unset)) - return ret; - - if ((crtc) && (_ecore_xcb_randr_root_validate(root))) - { - if (_randr_version >= RANDR_1_3) - { - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - int i = 0; - xcb_randr_crtc_t *crtcs; - - crtcs = xcb_randr_get_screen_resources_current_crtcs(reply); - for (i = 0; i < reply->num_crtcs; i++) - { - if (crtcs[i] == crtc) - { - ret = EINA_TRUE; - break; - } - } - free(reply); - } - } - else if (_randr_version == RANDR_1_2) - { - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - int i = 0; - xcb_randr_crtc_t *crtcs; - - crtcs = xcb_randr_get_screen_resources_crtcs(reply); - for (i = 0; i < reply->num_crtcs; i++) - { - if (crtcs[i] == crtc) - { - ret = EINA_TRUE; - break; - } - } - free(reply); - } - } - } -#endif - - return ret; -} - -static Ecore_X_Randr_Mode * -_ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num, - int *npreferred) -{ - Ecore_X_Randr_Mode *modes = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - if (num) *num = oreply->num_modes; - if (npreferred) *npreferred = oreply->num_preferred; - - modes = malloc(sizeof(Ecore_X_Randr_Mode) * - oreply->num_modes); - if (modes) - { - xcb_randr_mode_t *rmodes; - int len = 0; - - len = xcb_randr_get_output_info_modes_length(oreply); - rmodes = xcb_randr_get_output_info_modes(oreply); - memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len); - } - free(oreply); - } - free(reply); - } -#endif - return modes; -} - -static Ecore_X_Randr_Mode * -_ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num, - int *npreferred) -{ - Ecore_X_Randr_Mode *modes = NULL; -#ifdef ECORE_XCB_RANDR - xcb_timestamp_t stamp = 0; - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, stamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL); - if (oreply) - { - if (num) *num = oreply->num_modes; - if (npreferred) *npreferred = oreply->num_preferred; - - modes = malloc(sizeof(Ecore_X_Randr_Mode) * oreply->num_modes); - if (modes) - { - xcb_randr_mode_t *rmodes; - int len = 0; - - len = xcb_randr_get_output_info_modes_length(oreply); - rmodes = xcb_randr_get_output_info_modes(oreply); - memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len); - } - free(oreply); - } -#endif - return modes; -} - -static Ecore_X_Randr_Mode_Info * -_ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode) -{ - Ecore_X_Randr_Mode_Info *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) - { - uint8_t *nbuf; - xcb_randr_mode_info_iterator_t miter; - - nbuf = xcb_randr_get_screen_resources_names(reply); - miter = xcb_randr_get_screen_resources_modes_iterator(reply); - while (miter.rem) - { - xcb_randr_mode_info_t *minfo; - - minfo = miter.data; - nbuf += minfo->name_len; - - if (minfo->id == mode) - { - ret->xid = minfo->id; - ret->width = minfo->width; - ret->height = minfo->height; - ret->dotClock = minfo->dot_clock; - ret->hSyncStart = minfo->hsync_start; - ret->hSyncEnd = minfo->hsync_end; - ret->hTotal = minfo->htotal; - ret->vSyncStart = minfo->vsync_start; - ret->vSyncEnd = minfo->vsync_end; - ret->vTotal = minfo->vtotal; - ret->modeFlags = minfo->mode_flags; - - ret->name = NULL; - ret->nameLength = minfo->name_len; - if (ret->nameLength > 0) - { - ret->name = malloc(ret->nameLength + 1); - if (ret->name) - memcpy(ret->name, nbuf, ret->nameLength + 1); - } - - break; - } - xcb_randr_mode_info_next(&miter); - } - } - - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Mode_Info * -_ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode) -{ - Ecore_X_Randr_Mode_Info *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) - { - uint8_t *nbuf; - xcb_randr_mode_info_iterator_t miter; - - nbuf = xcb_randr_get_screen_resources_current_names(reply); - miter = - xcb_randr_get_screen_resources_current_modes_iterator(reply); - while (miter.rem) - { - xcb_randr_mode_info_t *minfo; - - minfo = miter.data; - nbuf += minfo->name_len; - - if (minfo->id == mode) - { - ret->xid = minfo->id; - ret->width = minfo->width; - ret->height = minfo->height; - ret->dotClock = minfo->dot_clock; - ret->hSyncStart = minfo->hsync_start; - ret->hSyncEnd = minfo->hsync_end; - ret->hTotal = minfo->htotal; - ret->vSyncStart = minfo->vsync_start; - ret->vSyncEnd = minfo->vsync_end; - ret->vTotal = minfo->vtotal; - ret->modeFlags = minfo->mode_flags; - - ret->name = NULL; - ret->nameLength = minfo->name_len; - if (ret->nameLength > 0) - { - ret->name = malloc(ret->nameLength + 1); - if (ret->name) - memcpy(ret->name, nbuf, ret->nameLength + 1); - } - - break; - } - xcb_randr_mode_info_next(&miter); - } - } - - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Mode_Info ** -_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root, - int *num) -{ - Ecore_X_Randr_Mode_Info **ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - if (num) *num = reply->num_modes; - ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes); - if (ret) - { - xcb_randr_mode_info_iterator_t miter; - int i = 0; - uint8_t *nbuf; - - nbuf = xcb_randr_get_screen_resources_names(reply); - miter = xcb_randr_get_screen_resources_modes_iterator(reply); - while (miter.rem) - { - xcb_randr_mode_info_t *minfo; - - minfo = miter.data; - nbuf += minfo->name_len; - if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) - { - ret[i]->xid = minfo->id; - ret[i]->width = minfo->width; - ret[i]->height = minfo->height; - ret[i]->dotClock = minfo->dot_clock; - ret[i]->hSyncStart = minfo->hsync_start; - ret[i]->hSyncEnd = minfo->hsync_end; - ret[i]->hTotal = minfo->htotal; - ret[i]->vSyncStart = minfo->vsync_start; - ret[i]->vSyncEnd = minfo->vsync_end; - ret[i]->vTotal = minfo->vtotal; - ret[i]->modeFlags = minfo->mode_flags; - - ret[i]->name = NULL; - ret[i]->nameLength = minfo->name_len; - if (ret[i]->nameLength > 0) - { - ret[i]->name = malloc(ret[i]->nameLength + 1); - if (ret[i]->name) - memcpy(ret[i]->name, nbuf, - ret[i]->nameLength + 1); - } - } - else - { - while (i > 0) - free(ret[--i]); - free(ret); - ret = NULL; - break; - } - i++; - xcb_randr_mode_info_next(&miter); - } - } - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Mode_Info ** -_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root, - int *num) -{ - Ecore_X_Randr_Mode_Info **ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - if (num) *num = reply->num_modes; - ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes); - if (ret) - { - xcb_randr_mode_info_iterator_t miter; - int i = 0; - uint8_t *nbuf; - - nbuf = xcb_randr_get_screen_resources_current_names(reply); - miter = - xcb_randr_get_screen_resources_current_modes_iterator(reply); - while (miter.rem) - { - xcb_randr_mode_info_t *minfo; - - minfo = miter.data; - nbuf += minfo->name_len; - if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) - { - ret[i]->xid = minfo->id; - ret[i]->width = minfo->width; - ret[i]->height = minfo->height; - ret[i]->dotClock = minfo->dot_clock; - ret[i]->hSyncStart = minfo->hsync_start; - ret[i]->hSyncEnd = minfo->hsync_end; - ret[i]->hTotal = minfo->htotal; - ret[i]->vSyncStart = minfo->vsync_start; - ret[i]->vSyncEnd = minfo->vsync_end; - ret[i]->vTotal = minfo->vtotal; - ret[i]->modeFlags = minfo->mode_flags; - - ret[i]->name = NULL; - ret[i]->nameLength = minfo->name_len; - if (ret[i]->nameLength > 0) - { - ret[i]->name = malloc(ret[i]->nameLength + 1); - if (ret[i]->name) - memcpy(ret[i]->name, nbuf, - ret[i]->nameLength + 1); - } - } - else - { - while (i > 0) - free(ret[--i]); - free(ret); - ret = NULL; - break; - } - i++; - xcb_randr_mode_info_next(&miter); - } - } - free(reply); - } -#endif - return ret; -} - -static void -_ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode, - int *w, - int *h) -{ - if (w) *w = 0; - if (h) *h = 0; - -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - xcb_randr_mode_info_iterator_t miter; - - miter = xcb_randr_get_screen_resources_modes_iterator(reply); - while (miter.rem) - { - xcb_randr_mode_info_t *minfo; - - minfo = miter.data; - if (minfo->id == mode) - { - if (w) *w = minfo->width; - if (h) *h = minfo->height; - break; - } - xcb_randr_mode_info_next(&miter); - } - free(reply); - } -#endif -} - -static void -_ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode, - int *w, - int *h) -{ - if (w) *w = 0; - if (h) *h = 0; - -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - xcb_randr_mode_info_iterator_t miter; - - miter = xcb_randr_get_screen_resources_current_modes_iterator(reply); - while (miter.rem) - { - xcb_randr_mode_info_t *minfo; - - minfo = miter.data; - if (minfo->id == mode) - { - if (w) *w = minfo->width; - if (h) *h = minfo->height; - break; - } - xcb_randr_mode_info_next(&miter); - } - free(reply); - } -#endif -} - -static Ecore_X_Randr_Output * -_ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num) -{ - Ecore_X_Randr_Output *outputs = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - if (num) *num = oreply->num_clones; - - outputs = - malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones); - if (outputs) - { - memcpy(outputs, xcb_randr_get_output_info_clones(oreply), - sizeof(Ecore_X_Randr_Output) * oreply->num_clones); - } - free(oreply); - } - free(reply); - } -#endif - return outputs; -} - -static Ecore_X_Randr_Output * -_ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num) -{ - Ecore_X_Randr_Output *outputs = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - if (num) *num = oreply->num_clones; - - outputs = - malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones); - if (outputs) - { - memcpy(outputs, xcb_randr_get_output_info_clones(oreply), - sizeof(Ecore_X_Randr_Output) * oreply->num_clones); - } - free(oreply); - } - free(reply); - } -#endif - return outputs; -} - -static Ecore_X_Randr_Crtc * -_ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num) -{ - Ecore_X_Randr_Crtc *crtcs = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - if (num) *num = oreply->num_crtcs; - - crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); - if (crtcs) - { - memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply), - sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); - } - free(oreply); - } - free(reply); - } -#endif - return crtcs; -} - -static Ecore_X_Randr_Crtc * -_ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num) -{ - Ecore_X_Randr_Crtc *crtcs = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - if (num) *num = oreply->num_crtcs; - - crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); - if (crtcs) - { - memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply), - sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); - } - free(oreply); - } - free(reply); - } -#endif - return crtcs; -} - -static char * -_ecore_xcb_randr_12_output_name_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *len) -{ - char *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - uint8_t *nbuf; - - nbuf = xcb_randr_get_output_info_name(oreply); - nbuf += oreply->name_len; - - if (len) *len = oreply->name_len; - if (oreply->name_len > 0) - { - ret = malloc(oreply->name_len + 1); - if (ret) - memcpy(ret, nbuf, oreply->name_len + 1); - } - - free(oreply); - } - free(reply); - } -#endif - return ret; -} - -static char * -_ecore_xcb_randr_13_output_name_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *len) -{ - char *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - uint8_t *nbuf; - - nbuf = xcb_randr_get_output_info_name(oreply); - nbuf += oreply->name_len; - - if (len) *len = oreply->name_len; - if (oreply->name_len > 0) - { - ret = malloc(oreply->name_len + 1); - if (ret) - memcpy(ret, nbuf, oreply->name_len + 1); - } - - free(oreply); - } - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Connection_Status -_ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ - Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - ret = oreply->connection; - free(oreply); - } - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Connection_Status -_ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ - Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - ret = oreply->connection; - free(oreply); - } - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Output * -_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root, - int *num) -{ - Ecore_X_Randr_Output *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - if (num) *num = reply->num_outputs; - ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs); - if (ret) - memcpy(ret, xcb_randr_get_screen_resources_outputs(reply), - sizeof(Ecore_X_Randr_Output) * reply->num_outputs); - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Output * -_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root, - int *num) -{ - Ecore_X_Randr_Output *ret = NULL; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - if (num) *num = reply->num_outputs; - ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs); - if (ret) - memcpy(ret, xcb_randr_get_screen_resources_current_outputs(reply), - sizeof(Ecore_X_Randr_Output) * reply->num_outputs); - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Crtc -_ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ - Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - ret = oreply->crtc; - free(oreply); - } - free(reply); - } -#endif - return ret; -} - -static Ecore_X_Randr_Crtc -_ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ - Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(root); - if (reply) - { - xcb_randr_get_output_info_cookie_t ocookie; - xcb_randr_get_output_info_reply_t *oreply; - - ocookie = - xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, - reply->config_timestamp); - oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, - ocookie, NULL); - if (oreply) - { - ret = oreply->crtc; - free(oreply); - } - free(reply); - } -#endif - return ret; -} - -static xcb_randr_get_screen_resources_reply_t * -_ecore_xcb_randr_12_get_resources(Ecore_X_Window win) -{ - xcb_randr_get_screen_resources_cookie_t cookie; - xcb_randr_get_screen_resources_reply_t *reply; - - cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, win); - reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); - return reply; -} - -static xcb_randr_get_screen_resources_current_reply_t * -_ecore_xcb_randr_13_get_resources(Ecore_X_Window win) -{ - xcb_randr_get_screen_resources_current_cookie_t cookie; - xcb_randr_get_screen_resources_current_reply_t *reply; - - cookie = - xcb_randr_get_screen_resources_current_unchecked(_ecore_xcb_conn, win); - reply = - xcb_randr_get_screen_resources_current_reply(_ecore_xcb_conn, - cookie, NULL); - return reply; -} - -static xcb_timestamp_t -_ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win) -{ - xcb_timestamp_t stamp = 0; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_reply_t *reply; - - reply = _ecore_xcb_randr_12_get_resources(win); - stamp = reply->config_timestamp; - free(reply); -#endif - return stamp; -} - -static xcb_timestamp_t -_ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win) -{ - xcb_timestamp_t stamp = 0; -#ifdef ECORE_XCB_RANDR - xcb_randr_get_screen_resources_current_reply_t *reply; - - reply = _ecore_xcb_randr_13_get_resources(win); - stamp = reply->config_timestamp; - free(reply); -#endif - return stamp; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_region.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_region.c deleted file mode 100644 index a221d8fc37..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_region.c +++ /dev/null @@ -1,159 +0,0 @@ -#include "ecore_xcb_private.h" -#include - -/* - * [ ] XPolygonRegion - * [ ] XShrinkRegion - * [ ] XClipBox - * [ ] XXorRegion - */ - -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 Eina_Bool -ecore_x_xregion_set(Ecore_X_XRegion *region, - Ecore_X_GC gc) -{ - xcb_rectangle_t *rects; - pixman_box16_t *boxes; - int num = 0, i = 0; - - CHECK_XCB_CONN; - - if (!region) return EINA_FALSE; - - boxes = pixman_region_rectangles((pixman_region16_t *)region, &num); - if ((!boxes) || (num == 0)) return EINA_FALSE; - - rects = (xcb_rectangle_t *)malloc(sizeof(xcb_rectangle_t) * num); - if (!rects) return EINA_FALSE; - - 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_xcb_conn, XCB_CLIP_ORDERING_YX_BANDED, - gc, 0, 0, num, rects); - -// ecore_x_flush(); - return EINA_TRUE; -} - -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 Eina_Bool -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 Eina_Bool -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 Eina_Bool -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 Eina_Bool -ecore_x_xregion_subtract(Ecore_X_XRegion *dst, - Ecore_X_XRegion *rm, - Ecore_X_XRegion *rs) -{ - return pixman_region_subtract((pixman_region16_t *)dst, - (pixman_region16_t *)rm, - (pixman_region16_t *)rs); -} - -EAPI Eina_Bool -ecore_x_xregion_is_empty(Ecore_X_XRegion *region) -{ - if (!region) return EINA_TRUE; - - return !pixman_region_not_empty((pixman_region16_t *)region); -} - -EAPI Eina_Bool -ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, - Ecore_X_XRegion *r2) -{ - if ((!r1) || (!r2)) return EINA_FALSE; - - return pixman_region_equal((pixman_region16_t *)r1, - (pixman_region16_t *)r2); -} - -EAPI Eina_Bool -ecore_x_xregion_point_contain(Ecore_X_XRegion *region, - int x, - int y) -{ - if (!region) return EINA_FALSE; - - return pixman_region_contains_point((pixman_region16_t *)region, x, y, NULL); -} - -EAPI Eina_Bool -ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, - Ecore_X_Rectangle *rect) -{ - pixman_box16_t box; - - if ((!region) || (!rect)) return EINA_FALSE; - - 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); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_render.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_render.c deleted file mode 100644 index f36b4d2489..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_render.c +++ /dev/null @@ -1,225 +0,0 @@ -#include "ecore_xcb_private.h" -#include // for isupper/tolower -#ifdef ECORE_XCB_RENDER -# include -# include -#endif - -/* local function prototypes */ -static Eina_Bool _ecore_xcb_render_parse_boolean(char *v); - -/* local variables */ -static Eina_Bool _render_avail = EINA_FALSE; -static Eina_Bool _render_argb = EINA_FALSE; -static Eina_Bool _render_anim = EINA_FALSE; - -void -_ecore_xcb_render_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_RENDER - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_render_id); -#endif -} - -void -_ecore_xcb_render_finalize(void) -{ -#ifdef ECORE_XCB_RENDER - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_RENDER - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_render_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_render_query_version_cookie_t cookie; - xcb_render_query_version_reply_t *reply; - - cookie = - xcb_render_query_version_unchecked(_ecore_xcb_conn, - XCB_RENDER_MAJOR_VERSION, - XCB_RENDER_MINOR_VERSION); - reply = xcb_render_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { -// if ((reply->major_version >= XCB_RENDER_MAJOR_VERSION) && - if (reply->minor_version >= XCB_RENDER_MINOR_VERSION) - { - char *v = NULL; - - _render_avail = EINA_TRUE; - _ecore_xcb_xdefaults_init(); - if ((reply->major_version > 0) || (reply->minor_version >= 5)) - { - _render_argb = EINA_TRUE; - v = getenv("XCURSOR_CORE"); - if (!v) - v = _ecore_xcb_xdefaults_string_get("Xcursor", "core"); - if ((v) && (_ecore_xcb_render_parse_boolean(v))) - _render_argb = EINA_FALSE; - } - if ((_render_argb) && - ((reply->major_version > 0) || (reply->minor_version >= 8))) - { - _render_anim = EINA_TRUE; - v = getenv("XCURSOR_ANIM"); - if (!v) - v = _ecore_xcb_xdefaults_string_get("Xcursor", "anim"); - if ((v) && (_ecore_xcb_render_parse_boolean(v))) - _render_anim = EINA_FALSE; - } - _ecore_xcb_xdefaults_shutdown(); - } - } - free(reply); - } -#endif -} - -Eina_Bool -_ecore_xcb_render_avail_get(void) -{ - return _render_avail; -} - -Eina_Bool -_ecore_xcb_render_argb_get(void) -{ - return _render_argb; -} - -Eina_Bool -_ecore_xcb_render_anim_get(void) -{ - return _render_anim; -} - -Eina_Bool -_ecore_xcb_render_visual_supports_alpha(Ecore_X_Visual visual) -{ - Eina_Bool ret = EINA_FALSE; -#ifdef ECORE_XCB_RENDER - const xcb_render_query_pict_formats_reply_t *reply; - xcb_render_pictvisual_t *vis; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!visual) return EINA_FALSE; - if (!_render_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_RENDER - reply = xcb_render_util_query_formats(_ecore_xcb_conn); - if (!reply) return EINA_FALSE; - - vis = - xcb_render_util_find_visual_format(reply, - ((xcb_visualtype_t *)visual)->visual_id); - if (vis) - { - xcb_render_pictforminfo_t temp; - xcb_render_pictforminfo_t *format; - - temp.id = vis->format; - format = - xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID, &temp, 0); - - if ((format->type == XCB_RENDER_PICT_TYPE_DIRECT) && - (format->direct.alpha_mask)) - ret = EINA_TRUE; - } - -#endif - - return ret; -} - -uint32_t -_ecore_xcb_render_find_visual_id(int type, - Eina_Bool check_alpha) -{ -#ifdef ECORE_XCB_RENDER - const xcb_render_query_pict_formats_reply_t *reply; - xcb_render_pictvisual_t *visual = NULL; - xcb_render_pictscreen_iterator_t screens; - xcb_render_pictdepth_iterator_t depths; - xcb_render_pictvisual_iterator_t visuals; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_render_avail) return 0; - -#ifdef ECORE_XCB_RENDER - reply = xcb_render_util_query_formats(_ecore_xcb_conn); - if (!reply) return 0; - - for (screens = xcb_render_query_pict_formats_screens_iterator(reply); - screens.rem; xcb_render_pictscreen_next(&screens)) - { - for (depths = xcb_render_pictscreen_depths_iterator(screens.data); - depths.rem; xcb_render_pictdepth_next(&depths)) - { - for (visuals = xcb_render_pictdepth_visuals_iterator(depths.data); - visuals.rem; xcb_render_pictvisual_next(&visuals)) - { - xcb_render_pictforminfo_t temp; - xcb_render_pictforminfo_t *format; - - visual = visuals.data; - temp.id = visual->format; - - format = - xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID, - &temp, 0); - if (!format) continue; - if (format->type == type) - { - if (check_alpha) - { - if (format->direct.alpha_mask) - return visual->visual; - } - else - return visual->visual; - } - } - } - } -#endif - - return 0; -} - -/* local function prototypes */ -static Eina_Bool -_ecore_xcb_render_parse_boolean(char *v) -{ - char c; - - c = *v; - if (isupper((int)c)) - c = tolower(c); - if ((c == 't') || (c == 'y') || (c == '1')) - return EINA_TRUE; - if ((c == 'f') || (c == 'n') || (c == '0')) - return EINA_FALSE; - if (c == 'o') - { - char d; - - d = v[1]; - if (isupper((int)d)) - d = tolower(d); - if (d == 'n') return EINA_TRUE; - if (d == 'f') return EINA_FALSE; - } - return EINA_FALSE; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c deleted file mode 100644 index 6106450c88..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c +++ /dev/null @@ -1,370 +0,0 @@ -#include "ecore_xcb_private.h" -# ifdef ECORE_XCB_SCREENSAVER -# include -# endif - -/* local variables */ -static Eina_Bool _screensaver_avail = EINA_FALSE; - -/* external variables */ -int _ecore_xcb_event_screensaver = -1; - -void -_ecore_xcb_screensaver_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_SCREENSAVER - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); -#endif -} - -void -_ecore_xcb_screensaver_finalize(void) -{ -#ifdef ECORE_XCB_SCREENSAVER - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_SCREENSAVER - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_screensaver_query_version_cookie_t cookie; - xcb_screensaver_query_version_reply_t *reply; - - cookie = - xcb_screensaver_query_version_unchecked(_ecore_xcb_conn, - XCB_SCREENSAVER_MAJOR_VERSION, - XCB_SCREENSAVER_MINOR_VERSION); - reply = - xcb_screensaver_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - if ((reply->server_major_version >= XCB_SCREENSAVER_MAJOR_VERSION) && - (reply->server_minor_version >= XCB_SCREENSAVER_MINOR_VERSION)) - _screensaver_avail = EINA_TRUE; - - free(reply); - } - - if (_screensaver_avail) - _ecore_xcb_event_screensaver = ext_reply->first_event; - } -#endif -} - -EAPI int -ecore_x_screensaver_idle_time_get(void) -{ - int ret = 0; -#ifdef ECORE_XCB_SCREENSAVER - xcb_screensaver_query_info_cookie_t cookie; - xcb_screensaver_query_info_reply_t *reply; - Ecore_X_Window root; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return 0; - -#ifdef ECORE_XCB_SCREENSAVER - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - cookie = xcb_screensaver_query_info_unchecked(_ecore_xcb_conn, root); - reply = xcb_screensaver_query_info_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - ret = (reply->ms_until_server / 1000); - free(reply); -#endif - - return ret; -} - -EAPI void -ecore_x_screensaver_set(int timeout, - int interval, - int prefer_blanking, - int allow_exposures) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return; - -#ifdef ECORE_XCB_SCREENSAVER - xcb_set_screen_saver(_ecore_xcb_conn, - timeout, interval, prefer_blanking, allow_exposures); -#endif -} - -EAPI void -ecore_x_screensaver_timeout_set(int timeout) -{ -#ifdef ECORE_XCB_SCREENSAVER - xcb_get_screen_saver_cookie_t cookie; - xcb_get_screen_saver_reply_t *reply; - uint16_t pint; - uint8_t pblank, pexpo; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return; - -#ifdef ECORE_XCB_SCREENSAVER - cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - pint = reply->interval; - pblank = reply->prefer_blanking; - pexpo = reply->allow_exposures; - free(reply); - xcb_set_screen_saver(_ecore_xcb_conn, timeout, pint, pblank, pexpo); -#endif -} - -EAPI int -ecore_x_screensaver_timeout_get(void) -{ - int timeout = 0; -#ifdef ECORE_XCB_SCREENSAVER - xcb_get_screen_saver_cookie_t cookie; - xcb_get_screen_saver_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return 0; - -#ifdef ECORE_XCB_SCREENSAVER - cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - timeout = reply->timeout; - free(reply); -#endif - - return timeout; -} - -EAPI void -ecore_x_screensaver_blank_set(int blank) -{ -#ifdef ECORE_XCB_SCREENSAVER - xcb_get_screen_saver_cookie_t cookie; - xcb_get_screen_saver_reply_t *reply; - uint16_t pint, pto; - uint8_t pexpo; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return; - -#ifdef ECORE_XCB_SCREENSAVER - cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - pto = reply->timeout; - pint = reply->interval; - pexpo = reply->allow_exposures; - free(reply); - xcb_set_screen_saver(_ecore_xcb_conn, pto, pint, blank, pexpo); -#endif -} - -EAPI int -ecore_x_screensaver_blank_get(void) -{ - int blank = 0; -#ifdef ECORE_XCB_SCREENSAVER - xcb_get_screen_saver_cookie_t cookie; - xcb_get_screen_saver_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return 0; - -#ifdef ECORE_XCB_SCREENSAVER - cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - blank = reply->prefer_blanking; - free(reply); -#endif - - return blank; -} - -EAPI void -ecore_x_screensaver_expose_set(int expose) -{ -#ifdef ECORE_XCB_SCREENSAVER - xcb_get_screen_saver_cookie_t cookie; - xcb_get_screen_saver_reply_t *reply; - uint16_t pint, pto; - uint8_t pblank; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return; - -#ifdef ECORE_XCB_SCREENSAVER - cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - pto = reply->timeout; - pint = reply->interval; - pblank = reply->prefer_blanking; - free(reply); - xcb_set_screen_saver(_ecore_xcb_conn, pto, pint, pblank, expose); -#endif -} - -EAPI int -ecore_x_screensaver_expose_get(void) -{ - int expose = 0; -#ifdef ECORE_XCB_SCREENSAVER - xcb_get_screen_saver_cookie_t cookie; - xcb_get_screen_saver_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return 0; - -#ifdef ECORE_XCB_SCREENSAVER - cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - expose = reply->allow_exposures; - free(reply); -#endif - - return expose; -} - -EAPI void -ecore_x_screensaver_interval_set(int interval) -{ -#ifdef ECORE_XCB_SCREENSAVER - xcb_get_screen_saver_cookie_t cookie; - xcb_get_screen_saver_reply_t *reply; - uint16_t pto; - uint8_t pblank, pexpose; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return; - -#ifdef ECORE_XCB_SCREENSAVER - cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - pto = reply->timeout; - pblank = reply->prefer_blanking; - pexpose = reply->allow_exposures; - free(reply); - xcb_set_screen_saver(_ecore_xcb_conn, pto, interval, pblank, pexpose); -#endif -} - -EAPI int -ecore_x_screensaver_interval_get(void) -{ - int interval = 0; -#ifdef ECORE_XCB_SCREENSAVER - xcb_get_screen_saver_cookie_t cookie; - xcb_get_screen_saver_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return 0; - -#ifdef ECORE_XCB_SCREENSAVER - cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); - reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - interval = reply->interval; - free(reply); -#endif - - return interval; -} - -EAPI void -ecore_x_screensaver_event_listen_set(Eina_Bool on) -{ -#ifdef ECORE_XCB_SCREENSAVER - Ecore_X_Window root; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_screensaver_avail) return; - -#ifdef ECORE_XCB_SCREENSAVER - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - if (on) - xcb_screensaver_select_input(_ecore_xcb_conn, root, - XCB_SCREENSAVER_EVENT_NOTIFY_MASK | - XCB_SCREENSAVER_EVENT_CYCLE_MASK); - else - xcb_screensaver_select_input(_ecore_xcb_conn, root, 0); -#endif -} - -EAPI Eina_Bool -ecore_x_screensaver_event_available_get(void) -{ - return _screensaver_avail; -} - -EAPI Eina_Bool -ecore_x_screensaver_custom_blanking_enable(void) -{ -#ifdef ECORE_XCB_SCREENSAVER - uint32_t mask_list[9]; - - xcb_screensaver_set_attributes_checked - (_ecore_xcb_conn, - ((xcb_screen_t *)_ecore_xcb_screen)->root, - -9999, -9999, 1, 1, 0, - XCB_WINDOW_CLASS_INPUT_ONLY, - XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT, - 0, mask_list); - return EINA_TRUE; -#else - return EINA_FALSE; -#endif -} - -EAPI Eina_Bool -ecore_x_screensaver_custom_blanking_disable(void) -{ -#ifdef ECORE_XCB_SCREENSAVER - xcb_screensaver_unset_attributes_checked - (_ecore_xcb_conn, - ((xcb_screen_t *)_ecore_xcb_screen)->root); - return EINA_TRUE; -#else - return EINA_FALSE; -#endif -} diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_selection.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_selection.c deleted file mode 100644 index 6d5c5aca4c..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_selection.c +++ /dev/null @@ -1,1026 +0,0 @@ -#include "ecore_xcb_private.h" -//#include "Ecore_X_Atoms.h" - -#define ECORE_XCB_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x)) - -/* local function prototypes */ -static void *_ecore_xcb_selection_parser_text(const char *target EINA_UNUSED, - void *data, - int size, - int format EINA_UNUSED); -static void *_ecore_xcb_selection_parser_files(const char *target, - void *data, - int size, - int format EINA_UNUSED); -static void *_ecore_xcb_selection_parser_targets(const char *target EINA_UNUSED, - void *data, - int size, - int format EINA_UNUSED); - -//static int _ecore_xcb_selection_data_free(void *data); -static int _ecore_xcb_selection_data_text_free(void *data); -static int _ecore_xcb_selection_data_targets_free(void *data); -static int _ecore_xcb_selection_data_files_free(void *data); -static int _ecore_xcb_selection_data_default_free(void *data); -static Eina_Bool _ecore_xcb_selection_set(Ecore_X_Window win, - const void *data, - int size, - Ecore_X_Atom selection); -static void _ecore_xcb_selection_request(Ecore_X_Window win, - Ecore_X_Atom selection, - const char *target); -static Ecore_X_Atom _ecore_xcb_selection_target_atom_get(const char *target); - -/* local variables */ -static Ecore_X_Selection_Intern _selections[4]; -static Ecore_X_Selection_Converter *_converters = NULL; -static Ecore_X_Selection_Parser *_parsers = NULL; - -/* local functions */ -void -_ecore_xcb_selection_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - memset(_selections, 0, sizeof(_selections)); - - /* init converters */ - ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT, - ecore_x_selection_converter_text); - ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING, - ecore_x_selection_converter_text); - 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); - - /* init parsers */ - ecore_x_selection_parser_add("text/plain", - _ecore_xcb_selection_parser_text); - ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING, - _ecore_xcb_selection_parser_text); - ecore_x_selection_parser_add("text/uri-list", - _ecore_xcb_selection_parser_files); - ecore_x_selection_parser_add("_NETSCAPE_URL", - _ecore_xcb_selection_parser_files); - ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS, - _ecore_xcb_selection_parser_targets); -} - -void -_ecore_xcb_selection_shutdown(void) -{ - Ecore_X_Selection_Converter *cnv; - Ecore_X_Selection_Parser *prs; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* free selection converters */ - cnv = _converters; - while (cnv) - { - Ecore_X_Selection_Converter *tmp; - - tmp = cnv->next; - free(cnv); - cnv = tmp; - } - _converters = NULL; - - /* free parsers */ - prs = _parsers; - while (prs) - { - Ecore_X_Selection_Parser *tmp; - - tmp = prs; - prs = prs->next; - free(tmp->target); - free(tmp); - } - _parsers = NULL; -} - -/* public functions */ -EAPI void -ecore_x_selection_converter_atom_add(Ecore_X_Atom target, - Eina_Bool (*func)(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *type, - int *size_type)) -{ - 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)); - if (!cnv->next) return; - cnv = cnv->next; - } - else - { - _converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); - if (!_converters) return; - cnv = _converters; - } - cnv->target = target; - cnv->convert = func; -} - -EAPI void -ecore_x_selection_converter_add(char *target, - Eina_Bool (*func)(char *target, - void *data, - int size, - void **date_ret, - int *size_ret, - Ecore_X_Atom *atom_ret, - int *ret)) -{ - Ecore_X_Atom atarget; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((!func) || (!target)) return; - atarget = _ecore_xcb_selection_target_atom_get(target); - ecore_x_selection_converter_atom_add(atarget, func); -} - -EAPI void -ecore_x_selection_converter_del(char *target) -{ - Ecore_X_Atom atarget; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!target) return; - atarget = _ecore_xcb_selection_target_atom_get(target); - ecore_x_selection_converter_atom_del(atarget); -} - -EAPI void -ecore_x_selection_converter_atom_del(Ecore_X_Atom target) -{ - Ecore_X_Selection_Converter *conv, *pconv = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - conv = _converters; - while (conv) - { - if (conv->target == target) - { - if (pconv) - pconv->next = conv->next; - else - _converters = conv->next; - free(conv); - return; - } - pconv = conv; - conv = conv->next; - } -} - -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; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!target) return; - prs = _parsers; - if (prs) - { - 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, *pprs = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!target) return; - - prs = _parsers; - while (prs) - { - if (!strcmp(prs->target, target)) - { - if (pprs) - pprs->next = prs->next; - else - _parsers = prs->next; - free(prs->target); - free(prs); - return; - } - pprs = prs; - prs = prs->next; - } -} - -/** - * 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 Eina_Bool -ecore_x_selection_primary_set(Ecore_X_Window win, - const void *data, - int size) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_selection_set(win, 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 Eina_Bool -ecore_x_selection_primary_clear(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, - ECORE_X_ATOM_SELECTION_PRIMARY); -} - -EAPI void -ecore_x_selection_primary_request(Ecore_X_Window win, - const char *target) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_PRIMARY, target); -} - -/** - * 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 Eina_Bool -ecore_x_selection_secondary_set(Ecore_X_Window win, - const void *data, - int size) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_selection_set(win, 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 Eina_Bool -ecore_x_selection_secondary_clear(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, - ECORE_X_ATOM_SELECTION_SECONDARY); -} - -EAPI void -ecore_x_selection_secondary_request(Ecore_X_Window win, - const char *target) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_SECONDARY, target); -} - -/** - * 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 Eina_Bool -ecore_x_selection_xdnd_set(Ecore_X_Window win, - const void *data, - int size) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_selection_set(win, 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 Eina_Bool -ecore_x_selection_xdnd_clear(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, - ECORE_X_ATOM_SELECTION_XDND); -} - -EAPI void -ecore_x_selection_xdnd_request(Ecore_X_Window win, - const char *target) -{ - Ecore_X_Atom atom; - Ecore_X_DND_Target *_target; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - _target = _ecore_xcb_dnd_target_get(); - atom = _ecore_xcb_selection_target_atom_get(target); - - xcb_convert_selection(_ecore_xcb_conn, win, ECORE_X_ATOM_SELECTION_XDND, - atom, ECORE_X_ATOM_SELECTION_PROP_XDND, _target->time); -} - -/** - * 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 Eina_Bool -ecore_x_selection_clipboard_set(Ecore_X_Window win, - const void *data, - int size) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_selection_set(win, 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 Eina_Bool -ecore_x_selection_clipboard_clear(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, - ECORE_X_ATOM_SELECTION_CLIPBOARD); -} - -EAPI void -ecore_x_selection_clipboard_request(Ecore_X_Window win, - const char *target) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_CLIPBOARD, target); -} - -EAPI Eina_Bool -ecore_x_selection_convert(Ecore_X_Atom selection, - Ecore_X_Atom target, - void **data_ret, - int *size, - Ecore_X_Atom *targtype, - int *typesize) -{ - Ecore_X_Selection_Intern *sel; - Ecore_X_Selection_Converter *cnv; - void *data; - char *tgt_str; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - sel = _ecore_xcb_selection_get(selection); - tgt_str = _ecore_xcb_selection_target_get(target); - - for (cnv = _converters; cnv; cnv = cnv->next) - { - if (cnv->target == target) - { - int r = 0; - - r = cnv->convert(tgt_str, sel->data, sel->length, &data, size, - targtype, typesize); - free(tgt_str); - if (r) - { - if (data_ret) *data_ret = data; - return r; - } - else - return EINA_FALSE; - } - } - - return EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_selection_notify_send(Ecore_X_Window requestor, - Ecore_X_Atom selection, - Ecore_X_Atom target, - Ecore_X_Atom property, - Ecore_X_Time tim) -{ - xcb_selection_notify_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - memset(&ev, 0, sizeof(xcb_selection_notify_event_t)); - - ev.response_type = XCB_SELECTION_NOTIFY; - ev.requestor = requestor; - ev.selection = selection; - ev.target = target; - ev.property = property; - ev.time = tim; - - xcb_send_event(_ecore_xcb_conn, 0, requestor, - XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); -// ecore_x_flush(); - - return EINA_TRUE; -} - -EAPI void -ecore_x_selection_owner_set(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Time tim) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_set_selection_owner(_ecore_xcb_conn, win, atom, tim); -} - -EAPI Ecore_X_Window -ecore_x_selection_owner_get(Ecore_X_Atom atom) -{ - xcb_get_selection_owner_cookie_t cookie; - xcb_get_selection_owner_reply_t *reply; - Ecore_X_Window ret; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_selection_owner(_ecore_xcb_conn, atom); - reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - ret = reply->owner; - free(reply); - return ret; -} - -void * -_ecore_xcb_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); - if (sel) return sel; - } - } - - sel = calloc(1, sizeof(Ecore_X_Selection_Data)); - if (!sel) return NULL; - sel->free = _ecore_xcb_selection_data_default_free; - sel->length = size; - sel->format = format; - sel->data = data; - - return sel; -} - -Ecore_X_Selection_Intern * -_ecore_xcb_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; -} - -/* local functions */ -static Eina_Bool -_ecore_xcb_selection_set(Ecore_X_Window win, - const void *data, - int size, - Ecore_X_Atom selection) -{ - xcb_get_selection_owner_cookie_t cookie; - xcb_get_selection_owner_reply_t *reply; - int in = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_set_selection_owner(_ecore_xcb_conn, win, selection, XCB_CURRENT_TIME); - - cookie = xcb_get_selection_owner(_ecore_xcb_conn, selection); - reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - if (reply->owner != win) - { - free(reply); - return EINA_FALSE; - } - free(reply); - - 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 EINA_FALSE; - - if (data) - { - unsigned char *buff = NULL; - - _selections[in].win = win; - _selections[in].selection = selection; - _selections[in].length = size; - _selections[in].time = _ecore_xcb_events_last_time_get(); - - buff = malloc(size); - if (!buff) return EINA_FALSE; - memcpy(buff, data, size); - _selections[in].data = buff; - } - else if (_selections[in].data) - { - free(_selections[in].data); - memset(&_selections[in], 0, sizeof(Ecore_X_Selection_Data)); - } - - return EINA_TRUE; -} - -static void -_ecore_xcb_selection_request(Ecore_X_Window win, - Ecore_X_Atom selection, - const char *target) -{ - Ecore_X_Atom atarget, prop; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - 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; - - atarget = _ecore_xcb_selection_target_atom_get(target); - - xcb_convert_selection(_ecore_xcb_conn, win, selection, atarget, prop, - XCB_CURRENT_TIME); -} - -EAPI Eina_Bool -ecore_x_selection_converter_text(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *type EINA_UNUSED, - int *size_type EINA_UNUSED) -{ - Ecore_Xcb_Encoding_Style style; - Ecore_Xcb_Textproperty ret; - char *str; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!data) || (!size)) return EINA_FALSE; - - if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) - style = XcbTextStyle; - else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) - style = XcbCompoundTextStyle; - else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) - style = XcbStringStyle; -#ifdef HAVE_ICONV - else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) - style = XcbUTF8StringStyle; -#endif - else - return EINA_FALSE; - - str = alloca(size + 1); - memcpy(str, data, size); - str[size] = '\0'; - -#ifdef HAVE_ICONV - if (_ecore_xcb_utf8_textlist_to_textproperty(&str, 1, style, &ret)) - { - int size = 0; - - size = (strlen((char *)ret.value) + 1); - *data_ret = malloc(size); - if (!*data_ret) return EINA_FALSE; - memcpy(*data_ret, ret.value, size); - *size_ret = size; - if (ret.value) free(ret.value); - return EINA_TRUE; - } -#else - if (_ecore_xcb_mb_textlist_to_textproperty(&str, 1, style, &ret)) - { - int size = 0; - - size = (strlen((char *)ret.value) + 1); - *data_ret = malloc(size); - if (!*data_ret) return EINA_FALSE; - memcpy(*data_ret, ret.value, size); - *size_ret = size; - if (ret.value) free(ret.value); - return EINA_TRUE; - } -#endif - else - return EINA_TRUE; -} - -static void * -_ecore_xcb_selection_parser_text(const char *target EINA_UNUSED, - void *data, - int size, - int format EINA_UNUSED) -{ - Ecore_X_Selection_Data_Text *sel; - unsigned char *_data; - void *t; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(_data = data)) return NULL; - - sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); - if (!sel) return NULL; - - if (_data && _data[size - 1]) - { - size++; - t = realloc(_data, size); - if (!t) - { - free(sel); - return NULL; - } - _data = t; - _data[size - 1] = 0; - } - sel->text = (char *)_data; - ECORE_XCB_SELECTION_DATA(sel)->length = size; - ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT; - ECORE_XCB_SELECTION_DATA(sel)->data = _data; - ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_text_free; - return sel; -} - -static void * -_ecore_xcb_selection_parser_files(const char *target, - void *data, - int size, - int format EINA_UNUSED) -{ - Ecore_X_Selection_Data_Files *sel; - char *_data, *tmp, *t, **t2; - int i = 0, is = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((strcmp(target, "text/uri-list")) && - (strcmp(target, "_NETSCAPE_URL"))) return NULL; - - if (!(_data = data)) return NULL; - - sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files)); - if (!sel) return NULL; - - ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_files_free; - - if (_data && _data[size - 1]) - { - size++; - t = realloc(_data, size); - if (!t) - { - free(sel); - return NULL; - } - _data = t; - _data[size - 1] = 0; - } - - tmp = malloc(size); - if (!tmp) - { - free(sel); - return NULL; - } - - 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++; - t2 = realloc(sel->files, sel->num_files * sizeof(char *)); - if (t2) - { - sel->files = t2; - sel->files[sel->num_files - 1] = strdup(tmp); - } - tmp[0] = 0; - i = 0; - } - } - } - if (i > 0) - { - tmp[i] = 0; - sel->num_files++; - t2 = realloc(sel->files, sel->num_files * sizeof(char *)); - if (t2) - { - sel->files = t2; - sel->files[sel->num_files - 1] = strdup(tmp); - } - } - if (tmp) free(tmp); - if (_data) free(_data); - - ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES; - ECORE_XCB_SELECTION_DATA(sel)->length = sel->num_files; - - return ECORE_XCB_SELECTION_DATA(sel); -} - -static void * -_ecore_xcb_selection_parser_targets(const char *target EINA_UNUSED, - void *data, - int size, - int format EINA_UNUSED) -{ - Ecore_X_Selection_Data_Targets *sel; - unsigned long *targets; - int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!(targets = (unsigned long *)data)) return NULL; - - sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); - if (!sel) return NULL; - - sel->num_targets = (size - 2); - sel->targets = malloc((size - 2) * sizeof(char *)); - if (!sel->targets) - { - free(sel); - return NULL; - } - - for (i = 2; i < size; i++) - { - xcb_get_atom_name_cookie_t cookie; - xcb_get_atom_name_reply_t *reply; - char *name = NULL; - int len = 0; - - cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, targets[i]); - reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - len = xcb_get_atom_name_name_length(reply); - name = (char *)malloc(sizeof(char) * (len + 1)); - if (name) - { - memcpy(name, xcb_get_atom_name_name(reply), len); - name[len] = '\0'; - sel->targets[i - 2] = name; - } - free(reply); - } - } - - ECORE_XCB_SELECTION_DATA(sel)->free = - _ecore_xcb_selection_data_targets_free; - ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS; - ECORE_XCB_SELECTION_DATA(sel)->length = size; - ECORE_XCB_SELECTION_DATA(sel)->data = data; - - return sel; -} - -/* - static int - _ecore_xcb_selection_data_free(void *data) - { - Ecore_X_Selection_Data *sel; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sel = data)) return 0; - if (sel->data) free(sel->data); - free(sel); - return 1; - } - */ - -static int -_ecore_xcb_selection_data_text_free(void *data) -{ - Ecore_X_Selection_Data_Text *sel; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sel = data)) return 0; - if (sel->text) free(sel->text); - free(sel); - return 1; -} - -static int -_ecore_xcb_selection_data_targets_free(void *data) -{ - Ecore_X_Selection_Data_Targets *sel; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sel = data)) return 0; - if (sel->targets) free(sel->targets); - free(ECORE_XCB_SELECTION_DATA(sel)->data); - free(sel); - return 1; -} - -static int -_ecore_xcb_selection_data_files_free(void *data) -{ - Ecore_X_Selection_Data_Files *sel; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(sel = data)) return 0; - if (sel->files) - { - int i = 0; - - for (i = 0; i < sel->num_files; i++) - if (sel->files[i]) free(sel->files[i]); - if (sel->files) free(sel->files); - } - free(sel); - return 0; -} - -static int -_ecore_xcb_selection_data_default_free(void *data) -{ - Ecore_X_Selection_Data *sel; - - if (!(sel = data)) return 1; - free(sel->data); - free(sel); - return 1; -} - -static Ecore_X_Atom -_ecore_xcb_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_xcb_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 - return ecore_x_atom_name_get(target); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_shape.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_shape.c deleted file mode 100644 index 913f1992b9..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_shape.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_SHAPE -# include -#endif - -/* external variables */ -int _ecore_xcb_event_shape = -1; - -void -_ecore_xcb_shape_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_SHAPE - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shape_id); -#endif -} - -void -_ecore_xcb_shape_finalize(void) -{ -#ifdef ECORE_XCB_SHAPE - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_SHAPE - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_shape_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_shape_query_version_cookie_t cookie; - xcb_shape_query_version_reply_t *reply; - Eina_Bool _shape_avail; - - _shape_avail = EINA_FALSE; - cookie = xcb_shape_query_version_unchecked(_ecore_xcb_conn); - reply = xcb_shape_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - _shape_avail = EINA_TRUE; - free(reply); - } - - if (_shape_avail) - _ecore_xcb_event_shape = ext_reply->first_event; - } -#endif -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_sync.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_sync.c deleted file mode 100644 index 75f4e4f2be..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_sync.c +++ /dev/null @@ -1,338 +0,0 @@ -#include "ecore_xcb_private.h" -# ifdef ECORE_XCB_SYNC -# include -# endif - -/* local variables */ -static Eina_Bool _sync_avail = EINA_FALSE; - -/* external variables */ -int _ecore_xcb_event_sync = -1; - -void -_ecore_xcb_sync_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_SYNC - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_sync_id); -#endif -} - -void -_ecore_xcb_sync_finalize(void) -{ -#ifdef ECORE_XCB_SYNC - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_SYNC - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_sync_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_sync_initialize_cookie_t cookie; - xcb_sync_initialize_reply_t *reply; - - cookie = - xcb_sync_initialize_unchecked(_ecore_xcb_conn, - XCB_SYNC_MAJOR_VERSION, - XCB_SYNC_MINOR_VERSION); - reply = xcb_sync_initialize_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - if (reply->major_version >= 3) _sync_avail = EINA_TRUE; - free(reply); - } - - if (_sync_avail) - _ecore_xcb_event_sync = ext_reply->first_event; - } -#endif -} - -void -_ecore_xcb_sync_magic_send(int val, - Ecore_X_Window win) -{ - xcb_client_message_event_t ev; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - memset(&ev, 0, sizeof(xcb_client_message_event_t)); - ev.response_type = XCB_CLIENT_MESSAGE; - ev.format = 32; - ev.window = win; - ev.type = 27777; - ev.data.data32[0] = 0x7162534; - ev.data.data32[1] = (0x10000000 + val); - ev.data.data32[2] = win; - - xcb_send_event(_ecore_xcb_conn, 0, win, XCB_EVENT_MASK_NO_EVENT, - (const char *)&ev); -// ecore_x_flush(); -} - -/* public functions */ -EAPI Ecore_X_Sync_Alarm -ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter) -{ -#ifdef ECORE_XCB_SYNC - uint32_t list[6], mask; - xcb_sync_int64_t init; - Ecore_X_Sync_Alarm alarm; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!counter)) return 0; - -#ifdef ECORE_XCB_SYNC - init.lo = 0; - init.hi = 0; - xcb_sync_set_counter(_ecore_xcb_conn, counter, init); - - 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); - list[0] = counter; - list[1] = XCB_SYNC_VALUETYPE_ABSOLUTE; - list[2] = 1; - list[3] = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON; - list[4] = 1; - list[5] = 1; - alarm = xcb_generate_id(_ecore_xcb_conn); - - xcb_sync_create_alarm(_ecore_xcb_conn, alarm, mask, list); - ecore_x_sync(); // needed - - return alarm; -#endif - return 0; -} - -EAPI Eina_Bool -ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!alarm)) return EINA_FALSE; - -#ifdef ECORE_XCB_SYNC - xcb_sync_destroy_alarm(_ecore_xcb_conn, alarm); -// ecore_x_flush(); - return EINA_TRUE; -#endif - - return EINA_FALSE; -} - -EAPI Eina_Bool -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; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!counter)) return EINA_FALSE; - -#ifdef ECORE_XCB_SYNC - cookie = xcb_sync_query_counter_unchecked(_ecore_xcb_conn, counter); - reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - if (val) *val = (unsigned int)reply->counter_value.lo; - free(reply); - return EINA_TRUE; - } -#endif - return EINA_FALSE; -} - -EAPI void -ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, - int by) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_int64_t v; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!counter)) return; - -#ifdef ECORE_XCB_SYNC - v.hi = (by < 0) ? ~0 : 0; - v.lo = by; - - xcb_sync_change_counter(_ecore_xcb_conn, counter, v); -// ecore_x_flush(); -#endif -} - -EAPI void -ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, - int val) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_query_counter_cookie_t cookie; - xcb_sync_query_counter_reply_t *reply; - xcb_sync_int64_t v1, v2; - xcb_sync_waitcondition_t cond; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!counter)) return; - -#ifdef ECORE_XCB_SYNC - cookie = xcb_sync_query_counter_unchecked(_ecore_xcb_conn, counter); - reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - v1 = reply->counter_value; - free(reply); - - v1.hi = (val < 0) ? ~0 : 0; - v1.lo = val; - v2.hi = ((val + 1) < 0) ? ~0 : 0; - v2.lo = (val + 1); - - cond.trigger.counter = counter; - cond.trigger.wait_type = XCB_SYNC_VALUETYPE_ABSOLUTE; - cond.trigger.wait_value = v1; - cond.trigger.test_type = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON; - cond.event_threshold = v2; - - xcb_sync_await(_ecore_xcb_conn, 1, &cond); -// ecore_x_flush(); -#endif -} - -EAPI Ecore_X_Sync_Counter -ecore_x_sync_counter_new(int val) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_counter_t counter; - xcb_sync_int64_t v; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_sync_avail) return 0; - -#ifdef ECORE_XCB_SYNC - v.hi = (val < 0) ? ~0 : 0; - v.lo = val; - - counter = xcb_generate_id(_ecore_xcb_conn); - xcb_sync_create_counter(_ecore_xcb_conn, counter, v); -// ecore_x_flush(); - - return counter; -#endif - - return 0; -} - -EAPI void -ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!counter)) return; - -#ifdef ECORE_XCB_SYNC - xcb_sync_destroy_counter(_ecore_xcb_conn, counter); -// ecore_x_flush(); -#endif -} - -EAPI void -ecore_x_sync_counter_set(Ecore_X_Sync_Counter counter, - int val) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_int64_t v; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!counter)) return; - -#ifdef ECORE_XCB_SYNC - v.hi = (val < 0) ? ~0 : 0; - v.lo = val; - - xcb_sync_set_counter(_ecore_xcb_conn, counter, v); -// ecore_x_flush(); -#endif -} - -EAPI void -ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter, - int val_hi, - unsigned int val_lo) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_int64_t v; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!counter)) return; - -#ifdef ECORE_XCB_SYNC - v.hi = val_hi; - v.lo = val_lo; - - xcb_sync_set_counter(_ecore_xcb_conn, counter, v); -// ecore_x_flush(); -#endif -} - -EAPI Eina_Bool -ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter, - int *val_hi, - unsigned int *val_lo) -{ -#ifdef ECORE_XCB_SYNC - xcb_sync_query_counter_cookie_t cookie; - xcb_sync_query_counter_reply_t *reply; - xcb_sync_int64_t value; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if ((!_sync_avail) || (!counter)) return EINA_FALSE; - -#ifdef ECORE_XCB_SYNC - cookie = - xcb_sync_query_counter_unchecked(_ecore_xcb_conn, - (xcb_sync_counter_t)counter); - reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - value = reply->counter_value; - free(reply); - if (val_hi) *val_hi = (int)value.hi; - if (val_lo) *val_lo = (unsigned int)value.lo; - return EINA_TRUE; -#endif - - return EINA_FALSE; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c deleted file mode 100644 index 2a5c854494..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_textlist.c +++ /dev/null @@ -1,509 +0,0 @@ -#include "ecore_xcb_private.h" -//#include "Ecore_X_Atoms.h" -#include -#ifdef HAVE_ICONV -# include -#endif -#ifndef CODESET -# define CODESET "INVALID" -#endif - -static int _ecore_xcb_textlist_get_buffer_size(Eina_Bool is_wide, - void *list, - int count); -static int _ecore_xcb_textlist_get_wc_len(wchar_t *wstr); -static void *_ecore_xcb_textlist_alloc_list(Eina_Bool is_wide, - int count, - int nitems); -static void _ecore_xcb_textlist_copy_list(Eina_Bool is_wide, - void *text, - char **list, - int count); -static wchar_t *_ecore_xcb_textlist_copy_wchar(wchar_t *str1, - wchar_t *str2); -static int _ecore_xcb_textlist_len_wchar(wchar_t *str); - -#ifdef HAVE_ICONV -Eina_Bool -_ecore_xcb_utf8_textlist_to_textproperty(char **list, - int count, - Ecore_Xcb_Encoding_Style style, - Ecore_Xcb_Textproperty *ret) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_textlist_to_textproperty("utf8string", list, count, - style, ret); -} - -#endif - -Eina_Bool -_ecore_xcb_mb_textlist_to_textproperty(char **list, - int count, - Ecore_Xcb_Encoding_Style style, - Ecore_Xcb_Textproperty *ret) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_textlist_to_textproperty("multiByte", list, count, - style, ret); -} - -/* NB: This Function May Not Be Correct !!! - * (as I do not know text conversion, locales, etc, etc very well) - * - * Portions were ripped from libX11 XTextListToTextProperty - */ -Eina_Bool -_ecore_xcb_textlist_to_textproperty(const char *type, - char **list, - int count, - Ecore_Xcb_Encoding_Style style, - Ecore_Xcb_Textproperty *ret) -{ - Eina_Bool is_wide = EINA_FALSE; - Ecore_X_Atom encoding; - int len = 0, nitems = 0, i = 0; - size_t from_left = 0, to_left = 0; - int unconv_num = 0, val = 0; - char *buff, *to, *value, *from; - const char *to_type, *from_type; - char **mb = NULL; - wchar_t **wc = NULL; -#ifdef HAVE_ICONV - iconv_t conv; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!strcmp("wideChar", type)) is_wide = EINA_TRUE; - len = _ecore_xcb_textlist_get_buffer_size(is_wide, list, count); - if (!(buff = (char *)malloc(len * sizeof(char)))) return EINA_FALSE; - from_type = nl_langinfo(CODESET); - switch (style) - { - case XcbStringStyle: - case XcbStdICCTextStyle: - encoding = ECORE_X_ATOM_STRING; - to_type = nl_langinfo(CODESET); -// to_type = "string"; - break; - - case XcbUTF8StringStyle: - encoding = ECORE_X_ATOM_UTF8_STRING; - to_type = "UTF-8"; - break; - - case XcbCompoundTextStyle: - encoding = ECORE_X_ATOM_COMPOUND_TEXT; - to_type = nl_langinfo(CODESET); -// to_type = "compoundText"; - break; - - case XcbTextStyle: - encoding = ECORE_X_ATOM_TEXT; - to_type = nl_langinfo(CODESET); -// to_type = "multiByte"; - if (!is_wide) - { - nitems = 0; - mb = (char **)list; - to = buff; - for (i = 0; ((i < count) && (len > 0)); i++) - { - if (*mb) strcpy(to, *mb); - else *to = '\0'; - from_left = (*mb ? strlen(*mb) : 0) + 1; - nitems += from_left; - to += from_left; - mb++; - } - unconv_num = 0; - goto done; - } - break; - - default: - free(buff); - return EINA_FALSE; - break; - } - - if (count < 1) - { - nitems = 0; - goto done; - } - -retry: -#ifdef HAVE_ICONV - conv = iconv_open(to_type, from_type); -#endif - - if (is_wide) - wc = (wchar_t **)list; - else - mb = (char **)list; - - to = buff; - to_left = len; - unconv_num = 0; - for (i = 1; to_left > 0; i++) - { - if (is_wide) - { - from = (char *)*wc; - from_left = _ecore_xcb_textlist_get_wc_len(*wc); - wc++; - } - else - { - from = *mb; - from_left = (*mb ? strlen(*mb) : 0); - mb++; - } - -#ifdef HAVE_ICONV - val = iconv(conv, &from, &from_left, &to, &to_left); -#endif - if (val < 0) continue; - if ((val > 0) && (style == XcbStdICCTextStyle) && - (encoding == ECORE_X_ATOM_STRING)) - { -#ifdef HAVE_ICONV - iconv_close(conv); -#endif - encoding = ECORE_X_ATOM_COMPOUND_TEXT; - goto retry; - } - - unconv_num += val; - *to++ = '\0'; - to_left--; - if (i >= count) break; - } - -#ifdef HAVE_ICONV - iconv_close(conv); -#endif - nitems = (to - buff); - -done: - if (nitems <= 0) nitems = 1; - if (!(value = (char *)malloc(nitems * sizeof(char)))) - { - free(buff); - return EINA_FALSE; - } - if (nitems == 1) - *value = 0; - else - memcpy(value, buff, nitems); - nitems--; - free(buff); - - ret->value = value; - ret->encoding = encoding; - ret->format = 8; - ret->nitems = nitems; - - return EINA_TRUE; -} - -#ifdef HAVE_ICONV -Eina_Bool -_ecore_xcb_utf8_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, - char ***list_ret, - int *count_ret) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_textproperty_to_textlist(text_prop, "utf8String", - list_ret, count_ret); -} - -#endif - -Eina_Bool -_ecore_xcb_mb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, - char ***list_ret, - int *count_ret) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return _ecore_xcb_textproperty_to_textlist(text_prop, "multiByte", - list_ret, count_ret); -} - -Eina_Bool -_ecore_xcb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, - const char *type, - char ***list_ret, - int *count_ret) -{ - Eina_Bool is_wide = EINA_FALSE; - Eina_Bool do_strcpy = EINA_FALSE; - const char *from_type; - char *buff, *to, *from; - char *lptr, *sptr; - int nitems = 0, len = 0, num = 0, ret = 0; - size_t from_left = 0, to_left = 0; -#ifdef HAVE_ICONV - iconv_t conv = 0; -#endif - - *list_ret = NULL; - *count_ret = 0; - if (!strcmp("wideChar", type)) is_wide = EINA_TRUE; - - nitems = text_prop->nitems; - if (nitems <= 0) return EINA_TRUE; - - if (text_prop->format != 8) return EINA_FALSE; - - from_type = nl_langinfo(CODESET); - if (text_prop->encoding == ECORE_X_ATOM_UTF8_STRING) - from_type = "UTF-8"; - - if (is_wide) - len = (text_prop->nitems + 1) * sizeof(wchar_t); - else - { - if (!strcmp(type, "utf8String")) - len = text_prop->nitems * 6 + 1; - else - len = text_prop->nitems * MB_CUR_MAX + 1; - } - - buff = (char *)malloc(len * sizeof(char)); - if (!buff) return EINA_FALSE; - - to = buff; - to_left = len; - - if (!strcmp(from_type, type)) - do_strcpy = EINA_TRUE; - else - { -#ifdef HAVE_ICONV - conv = iconv_open(type, from_type); -#endif - if (!conv) - { - free(buff); - return EINA_FALSE; - } - } - - lptr = sptr = text_prop->value; - num = *count_ret = 0; - while (1) - { - if ((nitems == 0) || (*sptr == 0)) - { - from = lptr; - from_left = sptr - lptr; - lptr = sptr; - if (do_strcpy) - { - int l = 0; - - l = MIN(from_left, to_left); - strncpy(to, from, l); - from += len; - to += len; - from_left -= l; - to_left -= l; - ret = 0; - } - else - ret = iconv(conv, &from, &from_left, &to, &to_left); - - if (ret < 0) continue; - num += ret; - (*count_ret)++; - if (nitems == 0) break; - lptr = ++sptr; - if (is_wide) - { - *((wchar_t *)to) = (wchar_t)0; - to += sizeof(wchar_t); - to_left -= sizeof(wchar_t); - } - else - { - *((char *)to) = '\0'; - to++; - to_left--; - } - } - else - sptr++; - - nitems--; - } - -#if HAVE_ICONV - if (!do_strcpy) iconv_close(conv); -#endif - - if (is_wide) - { - *((wchar_t *)to) = (wchar_t)0; - to_left -= sizeof(wchar_t); - } - else - { - *((char *)to) = '\0'; - to_left--; - } - - *list_ret = - _ecore_xcb_textlist_alloc_list(is_wide, *count_ret, (len - to_left)); - if (*list_ret) - _ecore_xcb_textlist_copy_list(is_wide, buff, *list_ret, *count_ret); - - free(buff); - - return EINA_TRUE; -} - -static int -_ecore_xcb_textlist_get_buffer_size(Eina_Bool is_wide, - void *list, - int count) -{ - int len = 0; - char **mb; - wchar_t **wc; - - if (!list) return 0; - if (is_wide) - { - wc = (wchar_t **)list; - for (; count-- > 0; wc++) - if (*wc) len += _ecore_xcb_textlist_get_wc_len(*wc) + 1; - len *= 5; - } - else - { - mb = (char **)list; - for (; count-- > 0; mb++) - if (*mb) len += strlen(*mb) + 1; - len *= 3; - } - len = (len / 2048 + 1) * 2048; - return len; -} - -static int -_ecore_xcb_textlist_get_wc_len(wchar_t *wstr) -{ - wchar_t *ptr; - - ptr = wstr; - while (*ptr) - ptr++; - - return ptr - wstr; -} - -static void * -_ecore_xcb_textlist_alloc_list(Eina_Bool is_wide, - int count, - int nitems) -{ - if (is_wide) - { - wchar_t **list; - - list = (wchar_t **)malloc(count * sizeof(wchar_t *)); - if (!list) return NULL; - *list = (wchar_t *)malloc(nitems * sizeof(wchar_t)); - if (!*list) - { - free(list); - return NULL; - } - return *list; - } - else - { - char **list; - - list = (char **)malloc(count * sizeof(char *)); - if (!list) return NULL; - *list = (char *)malloc(nitems * sizeof(char)); - if (!*list) - { - free(list); - return NULL; - } - return *list; - } -} - -static void -_ecore_xcb_textlist_copy_list(Eina_Bool is_wide, - void *text, - char **list, - int count) -{ - int len = 0; - - if (is_wide) - { - wchar_t *txt, *str, **wlist; - - txt = (wchar_t *)text; - wlist = (wchar_t **)list; - for (str = *wlist; count > 0; count--, wlist++) - { - _ecore_xcb_textlist_copy_wchar(str, txt); - *wlist = str; - len = (_ecore_xcb_textlist_len_wchar(str) + 1); - str += len; - txt += len; - } - } - else - { - char *txt, *str, **slist; - - txt = (char *)text; - slist = (char **)list; - for (str = *slist; count > 0; count--, slist++) - { - strcpy(str, txt); - *slist = str; - len = strlen(str) + 1; - str += len; - txt += len; - } - } -} - -static wchar_t * -_ecore_xcb_textlist_copy_wchar(wchar_t *str1, - wchar_t *str2) -{ - wchar_t *tmp; - - tmp = str1; - while ((*str1++ = *str2++)) - ; - return tmp; -} - -static int -_ecore_xcb_textlist_len_wchar(wchar_t *str) -{ - wchar_t *ptr; - - ptr = str; - while (*ptr) - ptr++; - return ptr - str; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_vsync.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_vsync.c deleted file mode 100644 index 7888796f9a..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_vsync.c +++ /dev/null @@ -1,375 +0,0 @@ -#include "ecore_xcb_private.h" -# include -# include -# include - -#define ECORE_XCB_VSYNC_DRI2 1 -#define DRM_EVENT_CONTEXT_VERSION 2 - -#ifdef ECORE_XCB_VSYNC_DRI2 - -/* relevant header bits of dri/drm inlined here to avoid needing external */ -/* headers to build drm */ -typedef unsigned int drm_magic_t; - -typedef enum -{ - DRM_VBLANK_ABSOLUTE = 0x00000000, - DRM_VBLANK_RELATIVE = 0x00000001, - DRM_VBLANK_EVENT = 0x04000000, - DRM_VBLANK_FLIP = 0x08000000, - DRM_VBLANK_NEXTONMISS = 0x10000000, - DRM_VBLANK_SECONDARY = 0x20000000, - DRM_VBLANK_SIGNAL = 0x40000000 -} drmVBlankSeqType; - -typedef struct _drmVBlankReq -{ - drmVBlankSeqType type; - unsigned int sequence; - unsigned long signal; -} drmVBlankReq; - -typedef struct _drmVBlankReply -{ - drmVBlankSeqType type; - unsigned int sequence; - long tval_sec, tval_usec; -} drmVBlankReply; - -typedef union _drmVBlank -{ - drmVBlankReq request; - drmVBlankReply reply; -} drmVBlank; - -typedef struct _drmEventContext -{ - int version; - void (*vblank_handler)(int fd, - unsigned int sequence, - unsigned int tv_sec, - unsigned int tv_usec, - void *user_data); - void (*page_flip_handler)(int fd, - unsigned int sequence, - unsigned int tv_sec, - unsigned int tv_usec, - void *user_data); -} drmEventContext; - -static int (*sym_drmClose)(int fd) = NULL; -static int (*sym_drmGetMagic)(int fd, - drm_magic_t *magic) = NULL; -static int (*sym_drmWaitVBlank)(int fd, - drmVBlank *vbl) = NULL; -static int (*sym_drmHandleEvent)(int fd, - drmEventContext *evctx) = NULL; - -/* dri */ -static Bool (*sym_DRI2QueryExtension)(Display *display, - int *eventBase, - int *errorBase) = NULL; -static Bool (*sym_DRI2QueryVersion)(Display *display, - int *major, - int *minor) = NULL; -static Bool (*sym_DRI2Connect)(Display *display, - XID window, - char **driverName, - char **deviceName) = NULL; -static Bool (*sym_DRI2Authenticate)(Display *display, - XID window, - drm_magic_t magic) = NULL; - -/* local function prototypes */ -static Eina_Bool _ecore_xcb_dri_link(void); -static Eina_Bool _ecore_xcb_dri_start(void); -static void _ecore_xcb_dri_shutdown(void); - -static Eina_Bool _ecore_xcb_dri_cb(void *data EINA_UNUSED, - Ecore_Fd_Handler *fdh EINA_UNUSED); -static void _ecore_xcb_dri_tick_begin(void *data EINA_UNUSED); -static void _ecore_xcb_dri_tick_end(void *data EINA_UNUSED); -static void _ecore_xcb_dri_tick_schedule(void); -static void _ecore_xcb_dri_vblank_handler(int fd EINA_UNUSED, - unsigned int frame EINA_UNUSED, - unsigned int sec EINA_UNUSED, - unsigned int usec EINA_UNUSED, - void *data EINA_UNUSED); - -/* local variables */ -static Ecore_X_Window _vsync_root = 0; -static int _drm_fd = -1; -static Ecore_Fd_Handler *_drm_fdh = NULL; -static unsigned int _drm_magic = 0; -static Eina_Bool _drm_event_busy = EINA_FALSE; -static void *_drm_lib = NULL; -static void *_dri_lib = NULL; -static drmEventContext _drm_evctx; -#endif - -void -_ecore_xcb_dri_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); -} - -void -_ecore_xcb_dri_finalize(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); -} - -EAPI Eina_Bool -ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win) -{ -#ifdef ECORE_XCB_VSYNC_DRI2 - Ecore_X_Window root; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_VSYNC_DRI2 - root = ecore_x_window_root_get(win); - if (root != _vsync_root) - { - _vsync_root = root; - if (_vsync_root) - { - if (!_ecore_xcb_dri_link()) - { - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); - return EINA_FALSE; - } - _ecore_xcb_dri_shutdown(); - if (!_ecore_xcb_dri_start()) - { - _vsync_root = 0; - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); - return EINA_FALSE; - } - ecore_animator_custom_source_tick_begin_callback_set - (_ecore_xcb_dri_tick_begin, NULL); - ecore_animator_custom_source_tick_end_callback_set - (_ecore_xcb_dri_tick_end, NULL); - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); - } - else - { - if (_drm_fd >= 0) - { - _ecore_xcb_dri_shutdown(); - ecore_animator_custom_source_tick_begin_callback_set - (NULL, NULL); - ecore_animator_custom_source_tick_end_callback_set - (NULL, NULL); - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); - } - } - } - return EINA_TRUE; -#else - return EINA_FALSE; - win = 0; -#endif -} - -/* local functions */ -#ifdef ECORE_XCB_VSYNC_DRI2 -static Eina_Bool -_ecore_xcb_dri_link(void) -{ - const char *_drm_libs[] = - { - "libdrm.so.2", - "libdrm.so.1", - "libdrm.so.0", - "libdrm.so", - NULL, - }; - const char *_dri_libs[] = - { - "libdri2.so.2", - "libdri2.so.1", - "libdri2.so.0", - "libdri2.so", - "libGL.so.4", - "libGL.so.3", - "libGL.so.2", - "libGL.so.1", - "libGL.so.0", - "libGL.so", - NULL, - }; - int i = 0, fail = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -# define SYM(lib, xx) \ - do { \ - sym_## xx = dlsym(lib, #xx); \ - if (!(sym_## xx)) { \ - fprintf(stderr, "%s\n", dlerror()); \ - fail = 1; \ - } \ - } while (0); - - if (_drm_lib) return EINA_TRUE; - - for (i = 0; _drm_libs[i]; i++) - { - _drm_lib = dlopen(_drm_libs[i], (RTLD_LOCAL | RTLD_LAZY)); - if (_drm_lib) - { - fail = 0; - SYM(_drm_lib, drmClose); - SYM(_drm_lib, drmGetMagic); - SYM(_drm_lib, drmWaitVBlank); - SYM(_drm_lib, drmHandleEvent); - if (fail) - { - dlclose(_drm_lib); - _drm_lib = NULL; - } - else - break; - } - } - if (!_drm_lib) return EINA_FALSE; - for (i = 0; _dri_libs[i]; i++) - { - if ((_dri_lib = dlopen(_dri_libs[i], (RTLD_LOCAL | RTLD_LAZY)))) - { - fail = 0; - SYM(_dri_lib, DRI2QueryExtension); - SYM(_dri_lib, DRI2QueryVersion); - SYM(_dri_lib, DRI2Connect); - SYM(_dri_lib, DRI2Authenticate); - if (fail) - { - dlclose(_dri_lib); - _dri_lib = NULL; - } - else - break; - } - } - if (!_dri_lib) - { - dlclose(_drm_lib); - _drm_lib = NULL; - return EINA_FALSE; - } - - return EINA_TRUE; -} - -static Eina_Bool -_ecore_xcb_dri_start(void) -{ - Ecore_X_Display *disp; - int _dri2_event = 0, _dri2_error = 0; - int _dri2_major = 0, _dri2_minor = 0; - char *device = NULL, *driver = NULL; - - disp = ecore_x_display_get(); - if (!sym_DRI2QueryExtension(disp, &_dri2_event, &_dri2_error)) - return 0; - if (!sym_DRI2QueryVersion(disp, &_dri2_major, &_dri2_minor)) - return 0; - if (_dri2_major < 2) return 0; - if (!sym_DRI2Connect(disp, _vsync_root, &driver, &device)) - return 0; - - _drm_fd = open(device, O_RDWR); - if (_drm_fd < 0) return 0; - - sym_drmGetMagic(_drm_fd, &_drm_magic); - if (!sym_DRI2Authenticate(disp, _vsync_root, _drm_magic)) - { - close(_drm_fd); - _drm_fd = -1; - return EINA_FALSE; - } - - memset(&_drm_evctx, 0, sizeof(_drm_evctx)); - _drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; - _drm_evctx.vblank_handler = _ecore_xcb_dri_vblank_handler; - _drm_evctx.page_flip_handler = NULL; - - _drm_fdh = ecore_main_fd_handler_add(_drm_fd, ECORE_FD_READ, - _ecore_xcb_dri_cb, NULL, NULL, NULL); - if (!_drm_fdh) - { - close(_drm_fd); - _drm_fd = -1; - return EINA_FALSE; - } - - return EINA_TRUE; -} - -static void -_ecore_xcb_dri_shutdown(void) -{ - if (_drm_fd >= 0) - { - close(_drm_fd); - _drm_fd = -1; - } - if (_drm_fdh) - { - ecore_main_fd_handler_del(_drm_fdh); - _drm_fdh = NULL; - } -} - -static Eina_Bool -_ecore_xcb_dri_cb(void *data EINA_UNUSED, - Ecore_Fd_Handler *fdh EINA_UNUSED) -{ - sym_drmHandleEvent(_drm_fd, &_drm_evctx); - return ECORE_CALLBACK_RENEW; -} - -static void -_ecore_xcb_dri_tick_begin(void *data EINA_UNUSED) -{ - _drm_event_busy = EINA_TRUE; - _ecore_xcb_dri_tick_schedule(); -} - -static void -_ecore_xcb_dri_tick_end(void *data EINA_UNUSED) -{ - _drm_event_busy = EINA_FALSE; -} - -static void -_ecore_xcb_dri_tick_schedule(void) -{ - drmVBlank vbl; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - vbl.request.type = (DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT); - vbl.request.sequence = 1; - vbl.request.signal = 0; - - sym_drmWaitVBlank(_drm_fd, &vbl); -} - -static void -_ecore_xcb_dri_vblank_handler(int fd EINA_UNUSED, - unsigned int frame EINA_UNUSED, - unsigned int sec EINA_UNUSED, - unsigned int usec EINA_UNUSED, - void *data EINA_UNUSED) -{ - ecore_animator_custom_tick(); - if (_drm_event_busy) _ecore_xcb_dri_tick_schedule(); -} - -#endif diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c deleted file mode 100644 index f8405fe1ec..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c +++ /dev/null @@ -1,2238 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_RENDER -# include -#endif -#ifdef ECORE_XCB_SHAPE -# include -#endif -#ifdef ECORE_XCB_XPRINT -#include -#endif - -/* local function prototypes */ -static Ecore_X_Window _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent, - int x, - int y, - int w, - int h, - uint8_t override_redirect, - uint8_t save_under); -static Ecore_X_Window _ecore_xcb_window_at_xy_get(Ecore_X_Window base, - int bx, - int by, - int x, - int y, - Ecore_X_Window *skip, - int skip_num); -static int _ecore_xcb_window_modifiers_get(unsigned int state); -static xcb_visualtype_t *_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id); -#ifdef ECORE_XCB_XPRINT -static xcb_screen_t *_ecore_xcb_window_screen_of_display(int screen); -#endif - -/* local variables */ -static int ignore_num = 0; -static Ecore_X_Window *ignore_list = NULL; - -/* external variables */ -int _ecore_xcb_button_grabs_num = 0; -int _ecore_xcb_key_grabs_num = 0; -Ecore_X_Window *_ecore_xcb_button_grabs = NULL; -Ecore_X_Window *_ecore_xcb_key_grabs = NULL; -Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data, - int type, - void *event); -void *_ecore_xcb_window_grab_replay_data; - -/** - * @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) -{ - Ecore_X_Window win; - uint32_t mask, mask_list[9]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (parent == 0) - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - /* NB: Order here is very important due to xcb_cw_t enum */ - 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); - - mask_list[0] = XCB_BACK_PIXMAP_NONE; - mask_list[1] = 0; - mask_list[2] = XCB_GRAVITY_NORTH_WEST; - mask_list[3] = XCB_GRAVITY_NORTH_WEST; - mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL; - mask_list[5] = 0; - mask_list[6] = 0; - mask_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); - mask_list[8] = XCB_EVENT_MASK_NO_EVENT; - - win = xcb_generate_id(_ecore_xcb_conn); - xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, - win, parent, x, y, w, h, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - XCB_COPY_FROM_PARENT, mask, mask_list); - - if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root) - 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) -{ - Ecore_X_Window win; - uint32_t mask, mask_list[9]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (parent == 0) - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - /* NB: Order here is very important due to xcb_cw_t enum */ - 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); - - mask_list[0] = XCB_BACK_PIXMAP_NONE; - mask_list[1] = 0; - mask_list[2] = XCB_GRAVITY_NORTH_WEST; - mask_list[3] = XCB_GRAVITY_NORTH_WEST; - mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL; - mask_list[5] = 1; - mask_list[6] = 0; - mask_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); - mask_list[8] = XCB_EVENT_MASK_NO_EVENT; - - win = xcb_generate_id(_ecore_xcb_conn); - xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, - win, parent, x, y, w, h, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - XCB_COPY_FROM_PARENT, mask, mask_list); - - 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) -{ - Ecore_X_Window win; - uint32_t mask, mask_list[3]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__) - CHECK_XCB_CONN; - - if (parent == 0) - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - /* NB: Order here is very important due to xcb_cw_t enum */ - mask = (XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | - XCB_CW_DONT_PROPAGATE); - - mask_list[0] = 1; - mask_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); - mask_list[2] = XCB_EVENT_MASK_NO_EVENT; - - win = xcb_generate_id(_ecore_xcb_conn); - xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, - win, parent, x, y, w, h, 0, - XCB_WINDOW_CLASS_INPUT_ONLY, - XCB_COPY_FROM_PARENT, mask, mask_list); - - return win; -} - -/** - * 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) -{ - Ecore_X_Window win = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0); - - return win; -} - -/** - * 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) -{ - Ecore_X_Window win = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 0, 0); - - 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_argb_new(Ecore_X_Window parent, - int x, - int y, - int w, - int h) -{ - Ecore_X_Window win = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0); - - return win; -} - -/** - * @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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (win) - { - /* xcb_destroy_notify_event_t ev; */ - /* Ecore_X_Window root; */ - - /* 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 *reply; */ - - /* cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); */ - /* reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); */ - /* if (!reply) return; */ - /* root = reply->root; */ - /* free(reply); */ - /* } */ - - /* memset(&ev, 0, sizeof(xcb_destroy_notify_event_t)); */ - - /* ev.response_type = XCB_DESTROY_NOTIFY; */ - /* ev.window = win; */ - /* ev.event = root; */ - - /* xcb_send_event(_ecore_xcb_conn, 0, root, */ - /* XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | */ - /* XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, */ - /* (const char *)&ev); */ - - xcb_destroy_window(_ecore_xcb_conn, win); -// ecore_x_flush(); - } -} - -/** - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!win) return; - ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, - XCB_EVENT_MASK_NO_EVENT, - ECORE_X_ATOM_WM_DELETE_WINDOW, - XCB_CURRENT_TIME, 0, 0, 0); -} - -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) -{ - uint16_t vmask = 0; - uint32_t vlist[7]; - unsigned int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - - if (mask & XCB_CONFIG_WINDOW_X) - { - vmask |= XCB_CONFIG_WINDOW_X; - vlist[i++] = x; - } - if (mask & XCB_CONFIG_WINDOW_Y) - { - vmask |= XCB_CONFIG_WINDOW_Y; - vlist[i++] = y; - } - if (mask & XCB_CONFIG_WINDOW_WIDTH) - { - vmask |= XCB_CONFIG_WINDOW_WIDTH; - vlist[i++] = w; - } - if (mask & XCB_CONFIG_WINDOW_HEIGHT) - { - vmask |= XCB_CONFIG_WINDOW_HEIGHT; - vlist[i++] = h; - } - if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) - { - vmask |= XCB_CONFIG_WINDOW_BORDER_WIDTH; - vlist[i++] = border_width; - } - if (mask & XCB_CONFIG_WINDOW_SIBLING) - { - vmask |= XCB_CONFIG_WINDOW_SIBLING; - vlist[i++] = sibling; - } - if (mask & XCB_CONFIG_WINDOW_STACK_MODE) - { - vmask |= XCB_CONFIG_WINDOW_STACK_MODE; - vlist[i++] = stack_mode; - } - - xcb_configure_window(_ecore_xcb_conn, win, vmask, - (const uint32_t *)&vlist); -// ecore_x_flush(); -} - -/** - * @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) -{ - uint32_t list[2], mask; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - - mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y); - list[0] = x; - list[1] = y; - - xcb_configure_window(_ecore_xcb_conn, win, mask, - (const uint32_t *)&list); -// ecore_x_flush(); -} - -/** - * 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) -{ - uint32_t list[2], mask; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - if (w < 1) w = 1; - if (h < 1) h = 1; - - mask = (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT); - list[0] = w; - list[1] = h; - - xcb_configure_window(_ecore_xcb_conn, win, mask, - (const uint32_t *)&list); -// ecore_x_flush(); -} - -/** - * 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) -{ - uint32_t list[4], mask; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - if (w < 1) w = 1; - if (h < 1) h = 1; - - mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT); - list[0] = x; - list[1] = y; - list[2] = w; - list[3] = h; - - xcb_configure_window(_ecore_xcb_conn, win, mask, - (const uint32_t *)&list); -// ecore_x_flush(); -} - -/** - * 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__); - - 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 border_width) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) return; - - list = border_width; - - xcb_configure_window(_ecore_xcb_conn, win, - XCB_CONFIG_WINDOW_BORDER_WIDTH, &list); -// ecore_x_flush(); -} - -/** - * @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) -{ - uint32_t list[] = { XCB_STACK_MODE_ABOVE }; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_configure_window(_ecore_xcb_conn, win, - XCB_CONFIG_WINDOW_STACK_MODE, list); -// ecore_x_flush(); -} - -/** - * 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) -{ - uint32_t list[] = { XCB_STACK_MODE_BELOW }; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_configure_window(_ecore_xcb_conn, win, - XCB_CONFIG_WINDOW_STACK_MODE, list); -// ecore_x_flush(); -} - -/** - * 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); -} - -/** - * @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_Group - */ -EAPI void -ecore_x_window_defaults_set(Ecore_X_Window win) -{ - char buff[MAXHOSTNAMELEN], **argv; - int argc; - pid_t pid; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - gethostname(buff, MAXHOSTNAMELEN); - buff[MAXHOSTNAMELEN - 1] = '\0'; - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, - ECORE_X_ATOM_WM_CLIENT_MACHINE, ECORE_X_ATOM_STRING, - 8, strlen(buff), buff); - - 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); -} - -/** - * @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__); - CHECK_XCB_CONN; - - if (win) - xcb_map_window(_ecore_xcb_conn, 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (win) - { - xcb_unmap_notify_event_t ev; - Ecore_X_Window root; - - 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 *reply; - - cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); - reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - root = reply->root; - free(reply); - } - - xcb_unmap_window(_ecore_xcb_conn, win); - memset(&ev, 0, sizeof(xcb_unmap_notify_event_t)); - - ev.response_type = XCB_UNMAP_NOTIFY; - ev.window = win; - ev.event = root; - 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); - -// ecore_x_flush(); - } -} - -/** - * @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__); - CHECK_XCB_CONN; - - if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - xcb_set_input_focus(_ecore_xcb_conn, - XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME); -// ecore_x_flush(); -} - -/** - * 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 time EINA_UNUSED) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - xcb_set_input_focus(_ecore_xcb_conn, - XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME); -// ecore_x_flush(); -} - -/** - * @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 parent, - int x, - int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (parent == 0) - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - xcb_reparent_window(_ecore_xcb_conn, win, parent, x, y); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_pixmap_set(Ecore_X_Window win, - Ecore_X_Pixmap pixmap) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = pixmap; - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_BACK_PIXMAP, &list); -// ecore_x_flush(); -} - -/** - * 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 red, - unsigned short green, - unsigned short blue) -{ - xcb_alloc_color_cookie_t cookie; - xcb_alloc_color_reply_t *reply; - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = - xcb_alloc_color_unchecked(_ecore_xcb_conn, - ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap, - red, green, blue); - reply = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return; - list = reply->pixel; - free(reply); - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_BACK_PIXEL, &list); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_pixel_gravity_set(Ecore_X_Window win, - Ecore_X_Gravity gravity) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = gravity; - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_BIT_GRAVITY, &list); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_gravity_set(Ecore_X_Window win, - Ecore_X_Gravity gravity) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = gravity; - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_WIN_GRAVITY, &list); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_override_set(Ecore_X_Window win, - Eina_Bool override) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = override; - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_OVERRIDE_REDIRECT, &list); -// ecore_x_flush(); -} - -/** - * @brief Show the cursor on a window of type Ecore_X_Window. - * @param win The window for which the cursor will be showed. - * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE. - */ -EAPI void -ecore_x_window_cursor_show(Ecore_X_Window win, - Eina_Bool show) -{ - uint32_t list = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - if (!show) - { - Ecore_X_Cursor cursor; - Ecore_X_Pixmap p, m; - Ecore_X_GC gc; - xcb_point_t point; - - p = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, 1, p, win, 1, 1); - m = xcb_generate_id(_ecore_xcb_conn); - xcb_create_pixmap(_ecore_xcb_conn, 1, m, win, 1, 1); - gc = xcb_generate_id(_ecore_xcb_conn); - xcb_create_gc(_ecore_xcb_conn, gc, win, 0, NULL); - xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list); - point.x = 0; - point.y = 0; - xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN, - win, gc, 1, &point); - xcb_free_gc(_ecore_xcb_conn, gc); - - cursor = xcb_generate_id(_ecore_xcb_conn); - xcb_create_cursor(_ecore_xcb_conn, cursor, - p, m, 0, 0, 0, 0, 0, 0, 0, 0); - list = cursor; - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_CURSOR, &list); - - xcb_free_cursor(_ecore_xcb_conn, cursor); - xcb_free_pixmap(_ecore_xcb_conn, m); - xcb_free_pixmap(_ecore_xcb_conn, p); - } - else - { - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_CURSOR, &list); - } -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_cursor_set(Ecore_X_Window win, - Ecore_X_Cursor cursor) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = cursor; - - xcb_change_window_attributes(_ecore_xcb_conn, win, XCB_CW_CURSOR, &list); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_container_manage(Ecore_X_Window win) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY); - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_EVENT_MASK, &list); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_client_manage(Ecore_X_Window win) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = (XCB_EVENT_MASK_VISIBILITY_CHANGE | - XCB_EVENT_MASK_FOCUS_CHANGE | - XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY); - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_EVENT_MASK, &list); - -#ifdef ECORE_XCB_SHAPE - xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE); -#endif -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_sniff(Ecore_X_Window win) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_PROPERTY_CHANGE); - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_EVENT_MASK, &list); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_client_sniff(Ecore_X_Window win) -{ - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - list = (XCB_EVENT_MASK_VISIBILITY_CHANGE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_FOCUS_CHANGE | - XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE); - - xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_EVENT_MASK, &list); -#ifdef ECORE_XCB_SHAPE - xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE); -#endif -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_area_clear(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_clear_area(_ecore_xcb_conn, 0, win, x, y, w, h); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_area_expose(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_clear_area(_ecore_xcb_conn, 1, win, x, y, w, h); -// ecore_x_flush(); -} - -EAPI void -ecore_x_window_save_set_add(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, win); -} - -EAPI void -ecore_x_window_save_set_del(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, win); -} - -/** - * gets the window that has focus. - * @return The window that has focus. - * @ingroup Ecore_X_Window_Focus_Functions - */ -EAPI Ecore_X_Window -ecore_x_window_focus_get(void) -{ - xcb_get_input_focus_cookie_t cookie; - xcb_get_input_focus_reply_t *reply; - Ecore_X_Window focus = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn); - reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - focus = reply->focus; - free(reply); - return focus; -} - -EAPI int -ecore_x_window_argb_get(Ecore_X_Window win) -{ - uint8_t ret = 0; -#ifdef ECORE_XCB_RENDER - Ecore_X_Visual visual; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -// if (!win) return ret; - -#ifdef ECORE_XCB_RENDER - /* grab the window's visual */ - visual = _ecore_xcb_window_visual_get(win); - - /* check if this visual supports alpha */ - ret = _ecore_xcb_render_visual_supports_alpha(visual); -#endif - - return ret; -} - -EAPI Eina_Bool -ecore_x_window_manage(Ecore_X_Window win) -{ - xcb_get_window_attributes_cookie_t cookie; - xcb_get_window_attributes_reply_t *reply; - xcb_void_cookie_t change_cookie; - xcb_generic_error_t *err; - uint32_t list; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_window_attributes(_ecore_xcb_conn, win); - reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - ecore_x_sync(); // needed - - list = (XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | - XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | - reply->your_event_mask); - free(reply); - - change_cookie = xcb_change_window_attributes(_ecore_xcb_conn, win, - XCB_CW_EVENT_MASK, &list); - - ecore_x_sync(); // needed - - err = xcb_request_check(_ecore_xcb_conn, change_cookie); - if (err) - { - _ecore_xcb_error_handle(err); - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_window_attributes_get(Ecore_X_Window win, - Ecore_X_Window_Attributes *att_ret) -{ - xcb_get_window_attributes_cookie_t cookie; - xcb_get_window_attributes_reply_t *reply; - xcb_get_geometry_cookie_t gcookie; - xcb_get_geometry_reply_t *greply; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); - reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes)); - - if (reply->map_state != XCB_MAP_STATE_UNMAPPED) - att_ret->visible = EINA_TRUE; - - if (reply->map_state == XCB_MAP_STATE_VIEWABLE) - att_ret->viewable = EINA_TRUE; - - if (reply->override_redirect) - att_ret->override = EINA_TRUE; - - if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY) - att_ret->input_only = EINA_TRUE; - - if (reply->save_under) - att_ret->save_under = EINA_TRUE; - - 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 = _ecore_xcb_window_find_visual_by_id(reply->visual); - - free(reply); - - gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); - greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL); - if (!greply) return EINA_TRUE; - - /* xcb_translate_coordinates_reply_t *trans; */ - /* xcb_query_tree_cookie_t tcookie; */ - /* xcb_query_tree_reply_t *treply; */ - - /* tcookie = xcb_query_tree(_ecore_xcb_conn, win); */ - /* treply = xcb_query_tree_reply(_ecore_xcb_conn, tcookie, NULL); */ - - /* trans = */ - /* xcb_translate_coordinates_reply(_ecore_xcb_conn, */ - /* xcb_translate_coordinates(_ecore_xcb_conn, */ - /* win, treply->parent, greply->x, greply->y), NULL); */ - /* free(treply); */ - - att_ret->root = greply->root; - att_ret->depth = greply->depth; -// att_ret->x = trans->dst_x; -// att_ret->y = trans->dst_y; - att_ret->x = greply->x; - att_ret->y = greply->y; - att_ret->w = greply->width; - att_ret->h = greply->height; - att_ret->border = greply->border_width; - -// free(trans); - - free(greply); - return EINA_TRUE; -} - -/** - * 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 *width, - int *height) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - ecore_x_drawable_geometry_get(win, NULL, NULL, width, height); -} - -/** - * 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 = 0, j = 0, count = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - 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)); - if (!ignore_list) return; - ignore_list[ignore_num++] = win; - } - } - else - { - if (!ignore_list) return; - for (count = ignore_num, i = 0, j = 0; i < count; i++) - { - if (win != ignore_list[i]) - ignore_list[j++] = ignore_list[i]; - else - ignore_num--; - } - if (ignore_num <= 0) - { - free(ignore_list); - ignore_list = NULL; - return; - } - - 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (num) *num = ignore_num; - return ignore_list; -} - -/** - * 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; - uint8_t i, num; - Ecore_X_Window *roots = NULL; -#ifdef ECORE_XCB_XPRINT - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!num_ret) return NULL; - if (num_ret) *num_ret = 0; - - /* if (xcb_connection_has_error(_ecore_xcb_conn)) */ - /* { */ - /* DBG("XCB Connection Has Error !!!"); */ - /* return NULL; */ - /* } */ - - num = ecore_x_screen_count_get(); - -#ifdef ECORE_XCB_XPRINT - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_x_print_print_query_screens_cookie_t cookie; - xcb_x_print_print_query_screens_reply_t *reply; - - cookie = xcb_x_print_print_query_screens_unchecked(_ecore_xcb_conn); - reply = - xcb_x_print_print_query_screens_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - xcb_window_t *screens; - int psnum = 0, overlap = 0, j = 0, k = 0; - - psnum = xcb_x_print_print_query_screens_roots_length(reply); - screens = xcb_x_print_print_query_screens_roots(reply); - for (i = 0; i < num; i++) - { - for (j = 0; j < psnum; j++) - { - xcb_screen_t *s; - - if ((s = _ecore_xcb_window_screen_of_display(i))) - { - if (s->root == screens[j]) - overlap++; - } - } - } - if (!(roots = malloc((num - overlap) - * sizeof(Ecore_X_Window)))) return NULL; - for (i = 0; i < num; i++) - { - Eina_Bool is_print = EINA_FALSE; - - for (j = 0; j < psnum; j++) - { - xcb_screen_t *s; - - if ((s = _ecore_xcb_window_screen_of_display(i))) - { - if (s->root == screens[j]) - { - is_print = EINA_TRUE; - break; - } - } - } - if (!is_print) - { - xcb_screen_t *s; - - if ((s = _ecore_xcb_window_screen_of_display(i))) - { - roots[k] = s->root; - k++; - } - } - } - if (num_ret) *num_ret = k; - free(reply); - } - else - { - /* Fallback to default method */ - iter = - xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL; - if (num_ret) *num_ret = num; - for (i = 0; iter.rem; xcb_screen_next(&iter), i++) - roots[i] = iter.data->root; - } - } - else - { - /* Fallback to default method */ - iter = - xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL; - if (num_ret) *num_ret = num; - for (i = 0; iter.rem; xcb_screen_next(&iter), i++) - roots[i] = iter.data->root; - } -#else - iter = - xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL; - if (num_ret) *num_ret = num; - for (i = 0; iter.rem; xcb_screen_next(&iter), i++) - roots[i] = iter.data->root; -#endif - - return roots; -} - -EAPI Ecore_X_Window * -ecore_x_window_children_get(Ecore_X_Window win, - int *num) -{ - xcb_query_tree_cookie_t cookie; - xcb_query_tree_reply_t *reply; - Ecore_X_Window *windows = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (num) *num = 0; - cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, win); - reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return NULL; - - if (num) *num = reply->children_len; - if (reply->children_len > 0) - { - windows = malloc(sizeof(Ecore_X_Window) * reply->children_len); - if (windows) - { - unsigned int i = 0; - xcb_window_t *w; - - w = xcb_query_tree_children(reply); - for (i = 0; i < reply->children_len; i++) - windows[i] = w[i]; - } - } - - free(reply); - return windows; -} - -/** - * 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) -{ - xcb_get_geometry_cookie_t gcookie; - xcb_get_geometry_reply_t *greply; - Ecore_X_Window window = 0; - - /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ - CHECK_XCB_CONN; - - gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); - greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL); - if (!greply) return 0; - window = greply->root; - free(greply); - - return window; -} - -EAPI Ecore_X_Window -ecore_x_window_root_first_get(void) -{ - return ((xcb_screen_t *)_ecore_xcb_screen)->root; -} - -/** - * Retrieves the geometry of the given window. - * - * Note that the x & y coordingates are relative to your parent. In - * particular for reparenting window managers - relative to you window border. - * If you want screen coordinates either walk the window tree to the root, - * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary - * applications can use elm_win_screen_position_get(). - * - * @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__); - CHECK_XCB_CONN; - - if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - ecore_x_drawable_geometry_get(win, x, y, w, h); -} - -/** - * 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 root, win = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - ecore_x_grab(); - win = _ecore_xcb_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. - * @param skip The list of windows to be skipped. - * @param skip_num The number of windows to be skipped. - * @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 root, win = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - ecore_x_grab(); - win = _ecore_xcb_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 = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - ecore_x_grab(); - win = _ecore_xcb_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) -{ - xcb_query_tree_cookie_t cookie; - xcb_query_tree_reply_t *reply; - Ecore_X_Window window = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -// if (!win) return 0; - cookie = xcb_query_tree(_ecore_xcb_conn, win); - reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - window = reply->parent; - free(reply); - - return window; -} - -/** - * 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) -{ - xcb_get_window_attributes_cookie_t cookie; - xcb_get_window_attributes_reply_t *reply; - int ret = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); - reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - if (reply->map_state == XCB_MAP_STATE_VIEWABLE) - ret = EINA_TRUE; - - free(reply); - return ret; -} - -EAPI void -ecore_x_window_button_grab(Ecore_X_Window win, - int button, - Ecore_X_Event_Mask mask, - int mod, - int any_mod) -{ - int i = 0; - uint16_t m, locks[8], ev; - uint8_t b; - Ecore_X_Window *t; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - b = button; - if (b == 0) - b = XCB_BUTTON_INDEX_ANY; - - m = _ecore_xcb_window_modifiers_get(mod); - if (any_mod) m = XCB_MOD_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 = mask; - for (i = 0; i < 8; i++) - xcb_grab_button(_ecore_xcb_conn, 0, win, ev, - XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, - XCB_NONE, XCB_NONE, b, m | locks[i]); - - _ecore_xcb_button_grabs_num++; - t = realloc(_ecore_xcb_button_grabs, - _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window)); - if (!t) return; - - _ecore_xcb_button_grabs = t; - _ecore_xcb_button_grabs[_ecore_xcb_button_grabs_num - 1] = win; -} - -EAPI void -ecore_x_window_button_ungrab(Ecore_X_Window win, - int button, - int mod, - int any_mod) -{ - int i = 0; - uint16_t m = 0, locks[8]; - uint8_t b; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - b = button; - if (b == 0) b = XCB_BUTTON_INDEX_ANY; - - m = _ecore_xcb_window_modifiers_get(mod); - if (any_mod) m = XCB_MOD_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, b, win, m | locks[i]); - - _ecore_xcb_sync_magic_send(1, win); -} - -EAPI void -ecore_x_window_key_grab(Ecore_X_Window win, - const char *key, - int mod, - int any_mod) -{ - xcb_keycode_t keycode = XCB_NO_SYMBOL; - uint16_t m = 0, locks[8]; - int i = 0; - Ecore_X_Window *t; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - keycode = _ecore_xcb_keymap_string_to_keycode(key); - if (keycode == XCB_NO_SYMBOL) return; - - m = _ecore_xcb_window_modifiers_get(mod); - if (any_mod) m = XCB_MOD_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, 0, win, m | locks[i], - keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); - _ecore_xcb_key_grabs_num++; - t = realloc(_ecore_xcb_key_grabs, - _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window)); - if (!t) return; - _ecore_xcb_key_grabs = t; - _ecore_xcb_key_grabs[_ecore_xcb_key_grabs_num - 1] = win; -} - -EAPI void -ecore_x_window_key_ungrab(Ecore_X_Window win, - const char *key, - int mod, - int any_mod) -{ - xcb_keycode_t keycode = XCB_NO_SYMBOL; - uint16_t m = 0, locks[8]; - int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - keycode = _ecore_xcb_keymap_string_to_keycode(key); - if (keycode == XCB_NO_SYMBOL) return; - - m = _ecore_xcb_window_modifiers_get(mod); - if (any_mod) m = XCB_MOD_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, win, m | locks[i]); - - _ecore_xcb_sync_magic_send(2, win); -} - -/* local functions */ -Ecore_X_Window -_ecore_xcb_window_root_of_screen_get(int screen) -{ - xcb_screen_iterator_t iter; - - CHECK_XCB_CONN; - iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - for (; iter.rem; --screen, xcb_screen_next(&iter)) - if (screen == 0) - { - xcb_screen_t *s; - - if ((s = iter.data)) - return s->root; - } - return 0; -} - -static Ecore_X_Window -_ecore_xcb_window_argb_internal_new(Ecore_X_Window parent, - int x, - int y, - int w, - int h, - uint8_t override_redirect, - uint8_t save_under) -{ - Ecore_X_Window win = 0; -#ifdef ECORE_XCB_RENDER - uint32_t value_list[10]; - uint32_t value_mask; - uint32_t vis; - Ecore_X_Colormap colormap; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_RENDER - if (parent == 0) - parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - vis = - _ecore_xcb_render_find_visual_id(XCB_RENDER_PICT_TYPE_DIRECT, EINA_TRUE); - - 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_BACK_PIXMAP_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, 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); -#endif - - return win; -} - -static Ecore_X_Window -_ecore_xcb_window_at_xy_get(Ecore_X_Window base, - int bx, - int by, - int x, - int y, - Ecore_X_Window *skip, - int skip_num) -{ - xcb_query_tree_cookie_t cookie; - xcb_query_tree_reply_t *reply; - Ecore_X_Window *windows = NULL; - int wx, wy, ww, wh, num, i = 0; - Eina_Bool skipit = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!ecore_x_window_visible_get(base)) return 0; - - 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; - - cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, base); - reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - - num = reply->children_len; - windows = xcb_query_tree_children(reply); - - for (i = (num - 1); i >= 0; --i) - { - skipit = EINA_FALSE; - - if (skip) - { - int j = 0; - - for (j = 0; j < skip_num; j++) - { - if (windows[i] == skip[j]) - { - skipit = EINA_TRUE; - goto onward; - } - } - } -onward: - if (!skipit) - { - Ecore_X_Window child = 0; - - child = - _ecore_xcb_window_at_xy_get(windows[i], - wx, wy, x, y, skip, skip_num); - if (child) - { - if (reply) free(reply); - return child; - } - } - } - - if (reply) free(reply); - return base; -} - -Ecore_X_Visual -_ecore_xcb_window_visual_get(Ecore_X_Window win) -{ - xcb_get_window_attributes_cookie_t cookie; - xcb_get_window_attributes_reply_t *reply; - Ecore_X_Visual visual = 0; - - CHECK_XCB_CONN; - - cookie = xcb_get_window_attributes(_ecore_xcb_conn, win); - reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - visual = _ecore_xcb_window_find_visual_by_id(reply->visual); - free(reply); - - return visual; -} - -void -_ecore_xcb_window_button_grab_remove(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (_ecore_xcb_button_grabs_num > 0) - { - int i = 0, shuffle = 0; - - for (i = 0; i < _ecore_xcb_button_grabs_num; i++) - { - if (shuffle) - _ecore_xcb_button_grabs[i - 1] = _ecore_xcb_button_grabs[i]; - - if ((!shuffle) && (_ecore_xcb_button_grabs[i] == win)) - shuffle = 1; - } - - if (shuffle) - { - Ecore_X_Window *t; - - _ecore_xcb_button_grabs_num--; - if (_ecore_xcb_button_grabs_num <= 0) - { - free(_ecore_xcb_button_grabs); - _ecore_xcb_button_grabs = NULL; - return; - } - - t = realloc(_ecore_xcb_button_grabs, - _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window)); - if (!t) return; - _ecore_xcb_button_grabs = t; - } - } -} - -void -_ecore_xcb_window_key_grab_remove(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (_ecore_xcb_key_grabs_num > 0) - { - int i = 0, shuffle = 0; - - for (i = 0; i < _ecore_xcb_key_grabs_num; i++) - { - if (shuffle) - _ecore_xcb_key_grabs[i - 1] = _ecore_xcb_key_grabs[i]; - - if ((!shuffle) && (_ecore_xcb_key_grabs[i] == win)) - shuffle = 1; - } - - if (shuffle) - { - Ecore_X_Window *t; - - _ecore_xcb_key_grabs_num--; - if (_ecore_xcb_key_grabs_num <= 0) - { - free(_ecore_xcb_key_grabs); - _ecore_xcb_key_grabs = NULL; - return; - } - - t = realloc(_ecore_xcb_key_grabs, - _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window)); - if (!t) return; - _ecore_xcb_key_grabs = t; - } - } -} - -void -_ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win, - Ecore_X_Window child_win, - int type, - void *event, - Ecore_X_Time timestamp) -{ - int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - for (i = 0; i < _ecore_xcb_button_grabs_num; i++) - { - if ((_ecore_xcb_button_grabs[i] == event_win) || - (_ecore_xcb_button_grabs[i] == child_win)) - { - Eina_Bool replay = EINA_FALSE; - - if (_ecore_xcb_window_grab_replay_func) - { - replay = - _ecore_xcb_window_grab_replay_func(_ecore_xcb_window_grab_replay_data, - type, event); - } - if (replay) - { - xcb_allow_events(_ecore_xcb_conn, - XCB_ALLOW_REPLAY_POINTER, timestamp); - } - else - { - xcb_allow_events(_ecore_xcb_conn, - XCB_ALLOW_ASYNC_POINTER, timestamp); - } - break; - } - } -} - -static int -_ecore_xcb_window_modifiers_get(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_MODIFIER_ALTGR) - xmodifiers |= ECORE_X_MODIFIER_ALTGR; - 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; - if (state & ECORE_EVENT_LOCK_SHIFT) - xmodifiers |= ECORE_X_LOCK_SHIFT; - - return xmodifiers; -} - -static xcb_visualtype_t * -_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id) -{ - xcb_depth_iterator_t diter; - xcb_visualtype_iterator_t viter; - - CHECK_XCB_CONN; - diter = xcb_screen_allowed_depths_iterator(_ecore_xcb_screen); - for (; diter.rem; xcb_depth_next(&diter)) - { - viter = xcb_depth_visuals_iterator(diter.data); - for (; viter.rem; xcb_visualtype_next(&viter)) - { - if (viter.data->visual_id == id) - return viter.data; - } - } - return 0; -} - -#ifdef ECORE_XCB_XPRINT -static xcb_screen_t * -_ecore_xcb_window_screen_of_display(int screen) -{ - xcb_screen_iterator_t iter; - - CHECK_XCB_CONN; - iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); - for (; iter.rem; --screen, xcb_screen_next(&iter)) - if (screen == 0) - return iter.data; - - return NULL; -} - -#endif diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c deleted file mode 100644 index e00fdc1963..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c +++ /dev/null @@ -1,720 +0,0 @@ -#include "ecore_xcb_private.h" -#include - -EAPI int -ecore_x_window_prop_card32_get(Ecore_X_Window win, - Ecore_X_Atom atom, - unsigned int *val, - unsigned int len) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - int num = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, - ECORE_X_ATOM_CARDINAL, 0, 0x7fffffff); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return -1; - - if ((reply->type != ECORE_X_ATOM_CARDINAL) || (reply->format != 32)) - num = -1; - else if (reply->value_len == 0) - num = 0; - else - { - if (reply->value_len < len) - len = reply->value_len; - - if (val) - { - unsigned int i = 0; - unsigned char *v; - - v = xcb_get_property_value(reply); - for (i = 0; i < len; i++) - val[i] = ((uint32_t *)v)[i]; - num = len; - } - } - - if (reply) free(reply); - return num; -} - -EAPI void -ecore_x_window_prop_card32_set(Ecore_X_Window win, - Ecore_X_Atom atom, - unsigned int *val, - unsigned int num) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#if SIZEOF_INT == SIZEOF_LONG - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, - ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)val); -// ecore_x_flush(); -#else - long *v2; - unsigned int i; - - v2 = malloc(num * sizeof(long)); - if (!v2) return; - for (i = 0; i < num; i++) - v2[i] = val[i]; - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, - ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)v2); - free(v2); -// ecore_x_flush(); -#endif -} - -EAPI int -ecore_x_window_prop_card32_list_get(Ecore_X_Window win, - Ecore_X_Atom atom, - unsigned int **list) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - int num = -1; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (list) *list = NULL; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, - XCB_ATOM_CARDINAL, 0, 0x7fffffff); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return -1; - - if ((reply->type != XCB_ATOM_CARDINAL) || (reply->format != 32)) - num = -1; - else if ((reply->value_len == 0) || (!xcb_get_property_value(reply))) - num = 0; - else - { - num = reply->value_len; - if (list) - { - unsigned int *val; - void *data; - int i = 0; - - val = malloc(num * sizeof(unsigned int)); - if (!val) - { - free(reply); - return -1; - } - data = xcb_get_property_value(reply); - for (i = 0; i < num; i++) - val[i] = ((uint32_t *)data)[i]; - *list = val; - } - } - - free(reply); - return num; -} - -EAPI int -ecore_x_window_prop_atom_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom *list, - unsigned int len) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len); -} - -EAPI void -ecore_x_window_prop_atom_set(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom *list, - unsigned int num) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - /* xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, */ - /* ECORE_X_ATOM_ATOM, 32, num, list); */ - ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_ATOM, list, num); -} - -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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#if SIZEOF_INT == SIZEOF_LONG - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, - type, 32, num, (unsigned char *)xids); -// ecore_x_flush(); -#else - long *v2; - unsigned int i; - - v2 = malloc(num * sizeof(long)); - if (!v2) return; - for (i = 0; i < num; i++) - v2[i] = xids[i]; - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, - type, 32, num, (unsigned char *)v2); - free(v2); -// ecore_x_flush(); -#endif -} - -EAPI int -ecore_x_window_prop_xid_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom type, - Ecore_X_ID *xids, - unsigned int len) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - int num = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - num = len; - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, type, - 0, 0x7fffffff); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return -1; - - if ((reply->type != type) || (reply->format != 32)) - num = -1; - else if (reply->value_len == 0) - num = 0; - else - { - unsigned int i = 0; - unsigned char *v; - - if (reply->value_len < len) - len = reply->value_len; - - v = xcb_get_property_value(reply); - for (i = 0; i < len; i++) - xids[i] = ((uint32_t *)v)[i]; - - num = len; - } - - if (reply) free(reply); - return num; -} - -EAPI void -ecore_x_window_prop_string_set(Ecore_X_Window win, - Ecore_X_Atom type, - const char *str) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, type, - ECORE_X_ATOM_UTF8_STRING, 8, strlen(str), str); -// ecore_x_flush(); -} - -EAPI char * -ecore_x_window_prop_string_get(Ecore_X_Window win, - Ecore_X_Atom type) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - char *str = NULL; - int len = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - cookie = - xcb_get_property_unchecked(_ecore_xcb_conn, 0, - win ? win : ((xcb_screen_t *)_ecore_xcb_screen)->root, - type, XCB_GET_PROPERTY_TYPE_ANY, 0, 1000000L); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return NULL; - - len = ((reply->value_len * reply->format) / 8); - str = (char *)malloc((len + 1) * sizeof(char)); - memcpy(str, xcb_get_property_value(reply), len); - str[len] = '\0'; - - if (reply->type != ECORE_X_ATOM_UTF8_STRING) - { - Ecore_Xcb_Textproperty prop; - int count = 0; - char **list = NULL; - Eina_Bool ret = EINA_FALSE; - - prop.value = strdup(str); - prop.nitems = len; - prop.encoding = reply->type; - -#ifdef HAVE_ICONV - ret = _ecore_xcb_utf8_textproperty_to_textlist(&prop, &list, &count); -#else - ret = _ecore_xcb_mb_textproperty_to_textlist(&prop, &list, &count); -#endif - if (ret) - { - if (count > 0) - str = strdup(list[0]); - else - str = strdup((char *)prop.value); - - if (list) free(list); - } - else - str = strdup((char *)prop.value); - } - - free(reply); - return str; -} - -EAPI int -ecore_x_window_prop_window_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Window *list, - unsigned int len) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_WINDOW, list, len); -} - -EAPI void -ecore_x_window_prop_window_set(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Window *list, - unsigned int num) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_WINDOW, list, num); -} - -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, ECORE_X_ATOM_WINDOW, plst); -} - -EAPI Ecore_X_Atom -ecore_x_window_prop_any_type(void) -{ - return XCB_ATOM_ANY; -} - -EAPI void -ecore_x_window_prop_property_del(Ecore_X_Window win, - Ecore_X_Atom property) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - xcb_delete_property(_ecore_xcb_conn, win, property); -} - -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 num) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (win == 0) - win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - if (size != 32) - { - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, - property, type, size, num, (unsigned char *)data); -// ecore_x_flush(); - } - else - { - uint32_t *dat; - int i = 0, *ptr; - - dat = malloc(sizeof(uint32_t) * num); - if (dat) - { - for (ptr = (int *)data, i = 0; i < num; i++) - dat[i] = ptr[i]; - xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, - property, type, size, num, - (unsigned char *)dat); - free(dat); -// ecore_x_flush(); - } - } -} - -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) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - int format = 0; - unsigned int i = 0; - void *value; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (num) *num = 0; - - if (data) - *data = NULL; - else - return 0; - - if (win == 0) - win = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - cookie = - xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, - property, type, 0, UINT_MAX); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - if ((reply->format != size) || (reply->value_len == 0)) - { - free(reply); - return 0; - } - - if (!(*data = malloc(reply->value_len * reply->format / 8))) - { - free(reply); - return 0; - } - - value = xcb_get_property_value(reply); - switch (reply->format) - { - case 8: - for (i = 0; i < reply->value_len; i++) - (*data)[i] = ((unsigned char *)value)[i]; - break; - - case 16: - for (i = 0; i < reply->value_len; i++) - ((unsigned short *)*data)[i] = ((unsigned short *)value)[i]; - break; - - case 32: - for (i = 0; i < reply->value_len; i++) - ((unsigned int *)*data)[i] = ((uint32_t *)value)[i]; - break; - } - - if (num) *num = reply->value_len; - format = reply->format; - free(reply); - return format; -} - -EAPI int -ecore_x_window_prop_atom_list_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom **list) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, list); -} - -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, ECORE_X_ATOM_ATOM, item, op); -} - -EAPI int -ecore_x_window_prop_xid_list_get(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Atom type, - Ecore_X_ID **xids) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - int num = -1; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (xids) *xids = NULL; - - cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, type, - 0, 0x7fffffff); - reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return -1; - - if ((reply->type != type) || (reply->format != 32)) - num = -1; - else if ((reply->value_len == 0) || (!xcb_get_property_value(reply))) - num = 0; - else - { - Ecore_X_Atom *alst; - void *val; - - num = xcb_get_property_value_length(reply); - val = xcb_get_property_value(reply); - alst = malloc(num * sizeof(Ecore_X_ID)); - if (alst) - { - int i = 0; - - for (i = 0; i < num; i++) - alst[i] = ((uint32_t *)val)[i]; - *xids = alst; - } - } - - free(reply); - return num; -} - -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 = 0, num = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst); - if (num < 0) return; - - for (i = 0; i < num; i++) - { - if (lst[i] == item) break; - } - - if (i < num) - { - if (op == ECORE_X_PROP_LIST_ADD) - goto done; - num--; - for (; i < num; i++) - lst[i] = lst[i + 1]; - } - else - { - if (op == ECORE_X_PROP_LIST_REMOVE) - goto done; - 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); -} - -EAPI Eina_Bool -ecore_x_window_prop_protocol_isset(Ecore_X_Window win, - Ecore_X_WM_Protocol protocol) -{ - Eina_Bool ret = EINA_FALSE; - Ecore_X_Atom proto; -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_t protos; -#else - xcb_icccm_get_wm_protocols_reply_t protos; -#endif - xcb_get_property_cookie_t cookie; - uint8_t reply; - uint32_t count = 0, i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE; - - proto = _ecore_xcb_atoms_wm_protocol[protocol]; -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, - ECORE_X_ATOM_WM_PROTOCOLS); - reply = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL); -#else - cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, - ECORE_X_ATOM_WM_PROTOCOLS); - reply = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, - &protos, NULL); -#endif - if (!reply) return EINA_FALSE; - - count = protos.atoms_len; - for (i = 0; i < count; i++) - { - if (protos.atoms[i] == proto) - { - ret = EINA_TRUE; - break; - } - } - -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_wipe(&protos); -#else - xcb_icccm_get_wm_protocols_reply_wipe(&protos); -#endif - return ret; -} - -EAPI Ecore_X_WM_Protocol * -ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, - int *num_ret) -{ -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_t protos; -#else - xcb_icccm_get_wm_protocols_reply_t protos; -#endif - xcb_get_property_cookie_t cookie; - uint8_t reply; - uint32_t count = 0, i = 0; - Ecore_X_WM_Protocol *prot_ret = NULL; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!num_ret) return NULL; - - *num_ret = 0; - -#ifdef OLD_XCB_VERSION - cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, - ECORE_X_ATOM_WM_PROTOCOLS); - reply = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL); -#else - cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, - ECORE_X_ATOM_WM_PROTOCOLS); - reply = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, - &protos, NULL); -#endif - if (!reply) return NULL; - - count = protos.atoms_len; - if (count <= 0) - { -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_wipe(&protos); -#else - xcb_icccm_get_wm_protocols_reply_wipe(&protos); -#endif - return NULL; - } - - prot_ret = calloc(1, count * sizeof(Ecore_X_WM_Protocol)); - if (!prot_ret) - { -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_wipe(&protos); -#else - xcb_icccm_get_wm_protocols_reply_wipe(&protos); -#endif - return NULL; - } - - for (i = 0; i < count; 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_protocol[j] == protos.atoms[i]) - prot_ret[i] = j; - } - } - - if (num_ret) *num_ret = count; - -#ifdef OLD_XCB_VERSION - xcb_get_wm_protocols_reply_wipe(&protos); -#else - xcb_icccm_get_wm_protocols_reply_wipe(&protos); -#endif - return prot_ret; -} - -EAPI Ecore_X_Atom * -ecore_x_window_prop_list(Ecore_X_Window win, - int *num) -{ - xcb_list_properties_cookie_t cookie; - xcb_list_properties_reply_t *reply; - xcb_atom_t *atm; - Ecore_X_Atom *atoms; - int i = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (num) *num = 0; - - cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, win); - reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return NULL; - - atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom)); - if (!atoms) - { - free(reply); - return NULL; - } - - atm = xcb_list_properties_atoms(reply); - for (i = 0; i < reply->atoms_len; i++) - atoms[i] = atm[i]; - - if (num) *num = reply->atoms_len; - free(reply); - - return atoms; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c deleted file mode 100644 index d46e306c8d..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c +++ /dev/null @@ -1,410 +0,0 @@ -#include "ecore_xcb_private.h" - -typedef struct _Shadow Shadow; -struct _Shadow -{ - Shadow *parent, **children; - Ecore_X_Window win; - int children_num; - short x, y; - unsigned short w, h; -}; - -static Eina_Bool _inside_rects(Shadow *s, - int x, - int y, - int bx, - int by, - Ecore_X_Rectangle *rects, - int num); - -//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, **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, j; - - CHECK_XCB_CONN; - - cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window); - reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL); - if (!reply_attr) return NULL; - if (reply_attr->map_state != XCB_MAP_STATE_VIEWABLE) - { - free(reply_attr); - return NULL; - } - - free(reply_attr); - - 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 NULL; - - if (!(s = calloc(1, sizeof(Shadow)))) - { - free(reply_geom); - 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); - - cookie_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, window); - reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL); - if (reply_tree) - { - 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 = 0; - - 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 = 0; - - 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 = NULL; - int i = 0, num = 0; - - if ((roots = ecore_x_window_root_list(&num))) - { - 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 = 0; - - 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 = 0; - - 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; - Ecore_X_Rectangle *rects; - int i = 0, j = 0, wx = 0, wy = 0, num = 0; - - wx = s->x + bx; - wy = s->y + by; - if (!((x >= wx) && (y >= wy) && (x < (wx + s->w)) && (y < (wy + s->h)))) - return 0; - - rects = ecore_x_window_shape_rectangles_get(s->win, &num); - if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0; - num = 0; - rects = ecore_x_window_shape_input_rectangles_get(s->win, &num); - if (!_inside_rects(s, x, y, bx, by, rects, num)) 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); -} - -static Eina_Bool -_inside_rects(Shadow *s, - int x, - int y, - int bx, - int by, - Ecore_X_Rectangle *rects, - int num) -{ - Eina_Bool inside = EINA_FALSE; - int i = 0; - - if (!rects) return EINA_FALSE; - for (i = 0; i < num; i++) - { - if ((x >= s->x + bx + rects[i].x) && - (y >= s->y + by + rects[i].y) && - (x < (int)(s->x + bx + rects[i].x + rects[i].width)) && - (y < (int)(s->y + by + rects[i].y + rects[i].height))) - { - inside = EINA_TRUE; - break; - } - } - free(rects); - return inside; -} - -/** - * 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. - * @param skip The list of windows to be skipped. - * @param skip_num The number of windows to be skipped. - * @return The window at the desired 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 EINA_UNUSED, - Ecore_X_Window win) -{ - Shadow *s; - int i = 0; - - 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(); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c deleted file mode 100644 index 6206a51833..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c +++ /dev/null @@ -1,790 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_SHAPE -# include -#endif - -/** - * @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 input shape of the given window to that given by the pixmap @p mask. - * @param win The given window. - * @param mask A 1-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__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, - win, 0, 0, mask); -// ecore_x_flush(); -#else - return; - win = 0; - mask = 0; -#endif -} - -/** - * 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__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, - win, 0, 0, mask); -// ecore_x_flush(); -#else - return; - win = 0; - mask = 0; -#endif -} - -EAPI void -ecore_x_window_shape_window_set(Ecore_X_Window win, - Ecore_X_Window shape_win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, - XCB_SHAPE_SK_BOUNDING, win, 0, 0, shape_win); -// ecore_x_flush(); -#else - return; - win = 0; - shape_win = 0; -#endif -} - -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__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, - XCB_SHAPE_SK_BOUNDING, win, x, y, shape_win); -// ecore_x_flush(); -#else - return; - win = 0; - shape_win = 0; - x = 0; - y = 0; -#endif -} - -EAPI void -ecore_x_window_shape_rectangle_set(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, - XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, 1, &rect); -// ecore_x_flush(); -#else - return; - win = 0; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_rectangles_set(Ecore_X_Window win, - Ecore_X_Rectangle *rects, - int num) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t *rect = NULL; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!rects) return; - -#ifdef ECORE_XCB_SHAPE - if (num > 0) - { - int i = 0; - - if (!(rect = malloc(sizeof(xcb_rectangle_t) * num))) - return; - - 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; - } - } - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, - XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, num, (xcb_rectangle_t *)rect); - - if (rect) free(rect); -// ecore_x_flush(); -#else - return; - win = 0; - num = 0; - rects = NULL; -#endif -} - -EAPI void -ecore_x_window_shape_window_add(Ecore_X_Window win, - Ecore_X_Window shape_win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, - XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, - win, 0, 0, shape_win); -// ecore_x_flush(); -#else - return; - win = 0; - shape_win = 0; -#endif -} - -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__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, - XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, - win, x, y, shape_win); -// ecore_x_flush(); -#else - return; - win = 0; - shape_win = 0; - x = 0; - y = 0; -#endif -} - -EAPI void -ecore_x_window_shape_rectangle_add(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, - XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, 1, &rect); -// ecore_x_flush(); -#else - return; - win = 0; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SUBTRACT, - XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, 1, &rect); -// ecore_x_flush(); -#else - return; - win = 0; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_INTERSECT, - XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, 1, &rect); -// ecore_x_flush(); -#else - return; - win = 0; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_rectangles_add(Ecore_X_Window win, - Ecore_X_Rectangle *rects, - int num) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t *rect = NULL; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - if (num > 0) - { - int i = 0; - - if (!(rect = malloc(sizeof(xcb_rectangle_t) * num))) - return; - - 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; - } - } - - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, - XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, num, (xcb_rectangle_t *)&rect); - - if (rect) free(rect); -// ecore_x_flush(); -#else - return; - win = 0; - num = 0; - rects = NULL; -#endif -} - -EAPI Ecore_X_Rectangle * -ecore_x_window_shape_rectangles_get(Ecore_X_Window win, - int *num_ret) -{ - Ecore_X_Rectangle *rects = NULL; -#ifdef ECORE_XCB_SHAPE - xcb_shape_get_rectangles_cookie_t cookie; - xcb_shape_get_rectangles_reply_t *reply; - xcb_rectangle_t *r; - unsigned int i = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (num_ret) *num_ret = 0; - -#ifdef ECORE_XCB_SHAPE - cookie = - xcb_shape_get_rectangles(_ecore_xcb_conn, win, XCB_SHAPE_SK_BOUNDING); - reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return NULL; - if (num_ret) *num_ret = reply->rectangles_len; - - if (reply->rectangles_len < 1) - { - free(reply); - if (num_ret) *num_ret = 0; - return NULL; - } - - rects = malloc(sizeof(Ecore_X_Rectangle) * reply->rectangles_len); - if (!rects) - { - free(reply); - if (num_ret) *num_ret = 0; - return NULL; - } - r = xcb_shape_get_rectangles_rectangles(reply); - for (i = 0; i < reply->rectangles_len; i++) - { - rects[i].x = r[i].x; - rects[i].y = r[i].y; - rects[i].width = r[i].width; - rects[i].height = r[i].height; - } - - free(reply); - - return rects; -#else - return rects; - win = 0; -#endif -} - -EAPI void -ecore_x_window_shape_events_select(Ecore_X_Window win, - Eina_Bool on) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_select_input(_ecore_xcb_conn, win, on); -// ecore_x_flush(); -#else - return; - win = 0; - on = 0; -#endif -} - -EAPI Ecore_X_Rectangle * -ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win, - int *num_ret) -{ - Ecore_X_Rectangle *rects = NULL; -#ifdef ECORE_XCB_SHAPE - xcb_shape_get_rectangles_cookie_t cookie; - xcb_shape_get_rectangles_reply_t *reply; - xcb_rectangle_t *r; - unsigned int i = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (num_ret) *num_ret = 0; - -#ifdef ECORE_XCB_SHAPE - cookie = - xcb_shape_get_rectangles(_ecore_xcb_conn, win, XCB_SHAPE_SK_INPUT); - reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return NULL; - if (num_ret) *num_ret = reply->rectangles_len; - - if (reply->rectangles_len < 1) - { - free(reply); - if (num_ret) *num_ret = 0; - return NULL; - } - - rects = malloc(sizeof(Ecore_X_Rectangle) * reply->rectangles_len); - if (!rects) - { - free(reply); - if (num_ret) *num_ret = 0; - return NULL; - } - r = xcb_shape_get_rectangles_rectangles(reply); - for (i = 0; i < reply->rectangles_len; i++) - { - rects[i].x = r[i].x; - rects[i].y = r[i].y; - rects[i].width = r[i].width; - rects[i].height = r[i].height; - } - - free(reply); - - return rects; -#else - xcb_get_geometry_cookie_t cookie; - xcb_get_geometry_reply_t *reply; - - if (!(rects = malloc(sizeof(Ecore_X_Rectangle)))) - return NULL; - - /* get geometry */ - cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); - reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - rects[0].x = reply->x; - rects[0].y = reply->y; - rects[0].width = reply->width; - rects[0].height = reply->height; - free(reply); - } - if (num_ret) *num_ret = 1; - return rects; -#endif -} - -EAPI void -ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win, - Ecore_X_Rectangle *rects, - int num) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t *rect = NULL; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!rects) return; - -#ifdef ECORE_XCB_SHAPE - if (num > 0) - { - int i = 0; - - if (!(rect = malloc(sizeof(xcb_rectangle_t) * num))) - return; - - 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; - } - } - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, - XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, num, (xcb_rectangle_t *)rect); - - if (rect) free(rect); -// ecore_x_flush(); -#else - return; - win = 0; - num = 0; - rects = NULL; -#endif -} - -EAPI void -ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SUBTRACT, - XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, 1, &rect); -// ecore_x_flush(); -#else - return; - win = 0; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, - XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, 1, &rect); -// ecore_x_flush(); -#else - return; - win = 0; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_input_rectangle_set(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, - XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, 1, &rect); -// ecore_x_flush(); -#else - return; - win = 0; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win, - Ecore_X_Window shape_win, - int x, - int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, - XCB_SHAPE_SK_INPUT, win, x, y, shape_win); -// ecore_x_flush(); -#else - return; - win = 0; - shape_win = 0; - x = 0; - y = 0; -#endif -} - -EAPI void -ecore_x_window_shape_input_window_add_xy(Ecore_X_Window win, - Ecore_X_Window shape_win, - int x, - int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_INPUT, - XCB_SHAPE_SK_INPUT, win, x, y, shape_win); -// ecore_x_flush(); -#else - return; - win = 0; - shape_win = 0; - x = 0; - y = 0; -#endif -} - -EAPI void -ecore_x_window_shape_input_window_set(Ecore_X_Window win, - Ecore_X_Window shape_win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, - XCB_SHAPE_SK_INPUT, win, 0, 0, shape_win); -// ecore_x_flush(); -#else - return; - win = 0; - shape_win = 0; -#endif -} - -EAPI void -ecore_x_window_shape_input_rectangle_clip(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t rect; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_INTERSECT, - XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, 1, &rect); -// ecore_x_flush(); -#else - return; - win = 0; - x = 0; - y = 0; - w = 0; - h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win, - Ecore_X_Rectangle *rects, - int num) -{ -#ifdef ECORE_XCB_SHAPE - xcb_rectangle_t *rect = NULL; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - -#ifdef ECORE_XCB_SHAPE - if (num > 0) - { - int i = 0; - - if (!(rect = malloc(sizeof(xcb_rectangle_t) * num))) - return; - - 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; - } - } - - xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, - XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, - win, 0, 0, num, (xcb_rectangle_t *)&rect); - - if (rect) free(rect); -// ecore_x_flush(); -#else - return; - win = 0; - num = 0; - rects = NULL; -#endif -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c deleted file mode 100644 index e0e56102e2..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "ecore_xcb_private.h" -#include - -/* local function prototypes */ -static Eina_Bool _ecore_xcb_xdefaults_glob_match(const char *str, - const char *glob); - -/* local variables */ -static Eina_File *_ecore_xcb_xdefaults_file = NULL; -static char *_ecore_xcb_xdefaults_data = NULL; - -void -_ecore_xcb_xdefaults_init(void) -{ - char buff[PATH_MAX]; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - snprintf(buff, sizeof(buff), "%s/.Xdefaults", getenv("HOME")); - if ((_ecore_xcb_xdefaults_file = eina_file_open(buff, EINA_FALSE))) - { - eina_mmap_safety_enabled_set(EINA_TRUE); - - _ecore_xcb_xdefaults_data = - eina_file_map_all(_ecore_xcb_xdefaults_file, EINA_FILE_SEQUENTIAL); - } -} - -void -_ecore_xcb_xdefaults_shutdown(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!_ecore_xcb_xdefaults_file) return; - if (_ecore_xcb_xdefaults_data) - eina_file_map_free(_ecore_xcb_xdefaults_file, _ecore_xcb_xdefaults_data); - if (_ecore_xcb_xdefaults_file) eina_file_close(_ecore_xcb_xdefaults_file); -} - -char * -_ecore_xcb_xdefaults_string_get(const char *prog, - const char *param) -{ - char buff[1024], ret[1024]; - char *str = NULL; - char **ea = NULL; - unsigned int count = 0, i = 0; - - if ((!_ecore_xcb_xdefaults_data) || (!_ecore_xcb_xdefaults_file)) - return NULL; - - snprintf(buff, sizeof(buff), "*%s*.*%s*", prog, param); - - str = _ecore_xcb_xdefaults_data; - ea = eina_str_split_full(str, "\n", -1, &count); - for (i = 0; i < count; i++) - { - if (_ecore_xcb_xdefaults_glob_match(ea[i], buff)) - sscanf(ea[i], "%*[^:]:%*[ ]%s", ret); - } - if ((ea) && (ea[0])) - { - free(ea[0]); - free(ea); - } - - return strdup(ret); -} - -int -_ecore_xcb_xdefaults_int_get(const char *prog, - const char *param) -{ - char buff[1024]; - char *str = NULL; - char **ea = NULL; - unsigned int count = 0, i = 0; - int ret = -1; - - if ((!_ecore_xcb_xdefaults_data) || (!_ecore_xcb_xdefaults_file)) - return 0; - - snprintf(buff, sizeof(buff), "*%s*.*%s*", prog, param); - - str = _ecore_xcb_xdefaults_data; - ea = eina_str_split_full(str, "\n", -1, &count); - for (i = 0; i < count; i++) - { - if (_ecore_xcb_xdefaults_glob_match(ea[i], buff)) - sscanf(ea[i], "%*[^:]:%*[ ]%d", &ret); - } - if ((ea) && (ea[0])) - { - free(ea[0]); - free(ea); - } - - return ret; -} - -/* local functions */ -static Eina_Bool -_ecore_xcb_xdefaults_glob_match(const char *str, - const char *glob) -{ - if ((!str) || (!glob)) return EINA_FALSE; - if (glob[0] == 0) - { - if (str[0] == 0) return EINA_TRUE; - return EINA_FALSE; - } - if (!strcmp(glob, "*")) return EINA_TRUE; - if (!fnmatch(glob, str, 0)) return EINA_TRUE; - return EINA_FALSE; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c deleted file mode 100644 index 58444cdf1f..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c +++ /dev/null @@ -1,744 +0,0 @@ -#include "ecore_xcb_private.h" -# ifdef ECORE_XCB_XFIXES -# include -# endif - -/* local function prototypes */ -static xcb_rectangle_t *_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects, - int num); -static Ecore_X_Rectangle *_ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects, - int num); - -/* local variables */ -static Eina_Bool _xfixes_avail = EINA_FALSE; - -/* external variables */ -int _ecore_xcb_event_xfixes = -1; - -void -_ecore_xcb_xfixes_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XFIXES - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); -#endif -} - -void -_ecore_xcb_xfixes_finalize(void) -{ -#ifdef ECORE_XCB_XFIXES - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XFIXES - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_xfixes_query_version_cookie_t cookie; - xcb_xfixes_query_version_reply_t *reply; - - cookie = - xcb_xfixes_query_version_unchecked(_ecore_xcb_conn, - XCB_XFIXES_MAJOR_VERSION, - XCB_XFIXES_MINOR_VERSION); - reply = xcb_xfixes_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - /* NB: XFixes Extension >= 3 needed for shape stuff. - * for now, I am removing this check so that it matches the - * xlib code closer. If the extension version ends up being - * that important, then re-enable this */ - - /* if (reply->major_version >= 3) */ - _xfixes_avail = EINA_TRUE; - free(reply); - } - - if (_xfixes_avail) - _ecore_xcb_event_xfixes = ext_reply->first_event; - } -#endif -} - -EAPI Eina_Bool -ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection) -{ -#ifdef ECORE_XCB_XFIXES - Ecore_X_Window root = 0; - xcb_void_cookie_t cookie; - xcb_generic_error_t *err; - int mask = 0; -#endif - - CHECK_XCB_CONN; - - if (!_xfixes_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_XFIXES - root = ((xcb_screen_t *)_ecore_xcb_screen)->root; - - mask = (XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER | - XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY | - XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE); - - cookie = - xcb_xfixes_select_selection_input_checked(_ecore_xcb_conn, root, - selection, mask); - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - free(err); - return EINA_FALSE; - } - - return EINA_TRUE; -#endif - return EINA_FALSE; -} - -Eina_Bool -_ecore_xcb_xfixes_avail_get(void) -{ - return _xfixes_avail; -} - -/** - * @defgroup Ecore_X_Fixes_Group X Fixes Extension Functions - * - * Functions related to the X Fixes extension. - */ - -/** - * 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 = 0; -#ifdef ECORE_XCB_XFIXES - xcb_rectangle_t *xrects; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return 0; - -#ifdef ECORE_XCB_XFIXES - xrects = _ecore_xcb_rect_to_xcb(rects, num); - region = xcb_generate_id(_ecore_xcb_conn); - xcb_xfixes_create_region(_ecore_xcb_conn, region, num, xrects); - free(xrects); -// ecore_x_flush(); -#endif - - 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 = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return 0; - -#ifdef ECORE_XCB_XFIXES - region = xcb_generate_id(_ecore_xcb_conn); - xcb_xfixes_create_region_from_bitmap(_ecore_xcb_conn, region, bitmap); -// ecore_x_flush(); -#endif - - return region; -} - -/** - * Create a region from a window. - * @param win 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 win, - Ecore_X_Region_Type type) -{ - Ecore_X_Region region = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return 0; - -#ifdef ECORE_XCB_XFIXES - region = xcb_generate_id(_ecore_xcb_conn); - xcb_xfixes_create_region_from_window(_ecore_xcb_conn, region, win, type); -// ecore_x_flush(); -#endif - - 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 = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return 0; - -#ifdef ECORE_XCB_XFIXES - region = xcb_generate_id(_ecore_xcb_conn); - xcb_xfixes_create_region_from_gc(_ecore_xcb_conn, region, gc); -// ecore_x_flush(); -#endif - - 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 = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return 0; - -#ifdef ECORE_XCB_XFIXES - region = xcb_generate_id(_ecore_xcb_conn); - xcb_xfixes_create_region_from_picture(_ecore_xcb_conn, region, picture); -// ecore_x_flush(); -#endif - - 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_destroy_region(_ecore_xcb_conn, region); -// ecore_x_flush(); -#endif -} - -/** - * 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_XFIXES - xcb_rectangle_t *xrects; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xrects = _ecore_xcb_rect_to_xcb(rects, num); - xcb_xfixes_set_region(_ecore_xcb_conn, region, num, xrects); - free(xrects); -// ecore_x_flush(); -#endif -} - -/** - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - - // NB: Hmmmm...this may need converting to/fro xcb_rectangle_t -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_copy_region(_ecore_xcb_conn, source, dest); -// ecore_x_flush(); -#endif -} - -/** - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_union_region(_ecore_xcb_conn, source1, source2, dest); -// ecore_x_flush(); -#endif -} - -/** - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_intersect_region(_ecore_xcb_conn, source1, source2, dest); -// ecore_x_flush(); -#endif -} - -/** - * Make the subtraction 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 subtraction 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_subtract_region(_ecore_xcb_conn, source1, source2, dest); -// ecore_x_flush(); -#endif -} - -/** - * Make the subtraction 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_XFIXES - xcb_rectangle_t xrects; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xrects.x = bounds->x; - xrects.y = bounds->y; - xrects.width = bounds->width; - xrects.height = bounds->height; - - xcb_xfixes_invert_region(_ecore_xcb_conn, source, xrects, dest); -// ecore_x_flush(); -#endif -} - -/** - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_translate_region(_ecore_xcb_conn, region, dx, dy); -// ecore_x_flush(); -#endif -} - -/** - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_region_extents(_ecore_xcb_conn, source, dest); -// ecore_x_flush(); -#endif -} - -/** - * 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. - * - * @ingroup Ecore_X_Fixes_Group - */ -EAPI Ecore_X_Rectangle * -ecore_x_region_fetch(Ecore_X_Region region, - int *num, - Ecore_X_Rectangle *bounds) -{ - Ecore_X_Rectangle extents = { 0, 0, 0, 0 }; - Ecore_X_Rectangle *rects = NULL; -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_fetch_region_cookie_t cookie; - xcb_xfixes_fetch_region_reply_t *reply; - xcb_rectangle_t *r; - int n = 0; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (num) *num = 0; - if (bounds) *bounds = extents; - if (!_xfixes_avail) return NULL; - -#ifdef ECORE_XCB_XFIXES - cookie = xcb_xfixes_fetch_region_unchecked(_ecore_xcb_conn, region); - reply = xcb_xfixes_fetch_region_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return NULL; - - r = xcb_xfixes_fetch_region_rectangles(reply); - n = xcb_xfixes_fetch_region_rectangles_length(reply); - rects = _ecore_xcb_rect_to_ecore(r, n); - if (num) *num = n; - - /* rects = (Ecore_X_Rectangle *)malloc(n * sizeof(Ecore_X_Rectangle)); */ - /* if (!rects) */ - /* { */ - /* free(reply); */ - /* return NULL; */ - /* } */ - - /* for (i = 0; i < n; i++) */ - /* { */ - /* rects[i].x = r[i].x; */ - /* rects[i].y = r[i].y; */ - /* rects[i].width = r[i].width; */ - /* rects[i].height = r[i].height; */ - /* } */ - - (*bounds).x = reply->extents.x; - (*bounds).y = reply->extents.y; - (*bounds).width = reply->extents.width; - (*bounds).height = reply->extents.height; - - free(reply); -#endif - - return rects; -} - -/** - * 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) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_expand_region(_ecore_xcb_conn, source, dest, left, right, top, bottom); -// ecore_x_flush(); -#endif -} - -/** - * 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 The horizontal translation. - * @param y 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, - int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_set_gc_clip_region(_ecore_xcb_conn, gc, region, x, y); -// ecore_x_flush(); -#endif -} - -/** - * 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 The horizontal offset. - * @param y 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, - int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_set_window_shape_region(_ecore_xcb_conn, dest, type, x, y, region); -// ecore_x_flush(); -#endif -} - -/** - * Change clip-mask in picture to the specified region. - * @param region The region. - * @param picture The picture. - * @param x The X coordinate of the origin. - * @param y 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, - int y) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xfixes_avail) return; - -#ifdef ECORE_XCB_XFIXES - xcb_xfixes_set_picture_clip_region(_ecore_xcb_conn, picture, region, x, y); -// ecore_x_flush(); -#endif -} - -/* local function prototypes */ -static xcb_rectangle_t * -_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects, - int num) -{ - xcb_rectangle_t *xrect; - int i = 0; - - if (!num) return NULL; - - xrect = malloc(sizeof(xcb_rectangle_t) * 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_xcb_rect_to_ecore(xcb_rectangle_t *rects, - int num) -{ - Ecore_X_Rectangle *erect; - int i = 0; - - if (!num) return NULL; - - erect = malloc(sizeof(Ecore_X_Rectangle) * num); - if (!erect) return NULL; - - for (i = 0; i < num; i++) - { - erect[i].x = rects[i].x; - erect[i].y = rects[i].y; - erect[i].width = rects[i].width; - erect[i].height = rects[i].height; - } - - return erect; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c deleted file mode 100644 index 37a2339e9b..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_XINERAMA -# include -#endif - -/* local variables */ -static Eina_Bool _xinerama_avail = EINA_FALSE; -static Eina_Bool _xinerama_active = EINA_FALSE; - -void -_ecore_xcb_xinerama_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XINERAMA - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xinerama_id); -#endif -} - -void -_ecore_xcb_xinerama_finalize(void) -{ -#ifdef ECORE_XCB_XINERAMA - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XINERAMA - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xinerama_id); - if ((ext_reply) && (ext_reply->present)) - { - xcb_xinerama_query_version_cookie_t cookie; - xcb_xinerama_query_version_reply_t *reply; - - cookie = - xcb_xinerama_query_version_unchecked(_ecore_xcb_conn, - XCB_XINERAMA_MAJOR_VERSION, - XCB_XINERAMA_MINOR_VERSION); - reply = - xcb_xinerama_query_version_reply(_ecore_xcb_conn, cookie, NULL); - if (reply) - { - _xinerama_avail = EINA_TRUE; - // NB: Do we need to compare version numbers here ? - free(reply); - } - - if (_xinerama_avail) - { - xcb_xinerama_is_active_cookie_t acookie; - xcb_xinerama_is_active_reply_t *areply; - - acookie = xcb_xinerama_is_active_unchecked(_ecore_xcb_conn); - areply = - xcb_xinerama_is_active_reply(_ecore_xcb_conn, acookie, NULL); - if (areply) - { - _xinerama_active = areply->state; - free(areply); - } - } - } -#endif -} - -EAPI int -ecore_x_xinerama_screen_count_get(void) -{ - int count = 0; -#ifdef ECORE_XCB_XINERAMA - xcb_xinerama_query_screens_cookie_t cookie; - xcb_xinerama_query_screens_reply_t *reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_xinerama_avail) return 0; - -#ifdef ECORE_XCB_XINERAMA - cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn); - reply = - xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return 0; - count = reply->number; -#endif - - return count; -} - -EAPI Eina_Bool -ecore_x_xinerama_screen_geometry_get(int screen, - int *x, - int *y, - int *w, - int *h) -{ -#ifdef ECORE_XCB_XINERAMA - xcb_xinerama_query_screens_cookie_t cookie; - xcb_xinerama_query_screens_reply_t *reply; - xcb_xinerama_screen_info_t *info; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; - if (h) *h = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; - - if (!_xinerama_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_XINERAMA - cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn); - reply = - xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL); - if (!reply) return EINA_FALSE; - - info = xcb_xinerama_query_screens_screen_info(reply); - if (!info) - { - free(reply); - return EINA_FALSE; - } - - if (x) *x = info[screen].x_org; - if (y) *y = info[screen].y_org; - if (w) *w = info[screen].width; - if (h) *h = info[screen].height; - - free(reply); - return EINA_TRUE; -#endif - - return EINA_FALSE; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xtest.c b/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xtest.c deleted file mode 100644 index 7f76b2ccb5..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_xtest.c +++ /dev/null @@ -1,215 +0,0 @@ -#include "ecore_xcb_private.h" -#ifdef ECORE_XCB_XTEST -# include -# include -#endif - -/* local variables */ -static Eina_Bool _test_avail = EINA_FALSE; - -void -_ecore_xcb_xtest_init(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XTEST - xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_test_id); -#endif -} - -void -_ecore_xcb_xtest_finalize(void) -{ -#ifdef ECORE_XCB_XTEST - const xcb_query_extension_reply_t *ext_reply; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#ifdef ECORE_XCB_XTEST - ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_test_id); - if ((ext_reply) && (ext_reply->present)) - _test_avail = EINA_TRUE; -#endif -} - -EAPI Eina_Bool -#ifdef ECORE_XCB_XTEST -ecore_x_test_fake_key_down(const char *key) -#else -ecore_x_test_fake_key_down(const char *key EINA_UNUSED) -#endif -{ -#ifdef ECORE_XCB_XTEST - xcb_keycode_t keycode = 0; - xcb_void_cookie_t cookie; - xcb_generic_error_t *err; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_test_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_XTEST - keycode = _ecore_xcb_keymap_string_to_keycode(key); - if (keycode == XCB_NO_SYMBOL) return EINA_FALSE; - - cookie = - xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, - keycode, XCB_CURRENT_TIME, - ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - free(err); - return EINA_FALSE; - } - return EINA_TRUE; -#endif - - return EINA_FALSE; -} - -EAPI Eina_Bool -#ifdef ECORE_XCB_XTEST -ecore_x_test_fake_key_up(const char *key) -#else -ecore_x_test_fake_key_up(const char *key EINA_UNUSED) -#endif -{ -#ifdef ECORE_XCB_XTEST - xcb_keycode_t keycode = 0; - xcb_void_cookie_t cookie; - xcb_generic_error_t *err; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_test_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_XTEST - keycode = _ecore_xcb_keymap_string_to_keycode(key); - if (keycode == XCB_NO_SYMBOL) return EINA_FALSE; - - cookie = - xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, - keycode, XCB_CURRENT_TIME, - ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - free(err); - return EINA_FALSE; - } - return EINA_TRUE; -#endif - - return EINA_FALSE; -} - -EAPI Eina_Bool -#ifdef ECORE_XCB_XTEST -ecore_x_test_fake_key_press(const char *key) -#else -ecore_x_test_fake_key_press(const char *key EINA_UNUSED) -#endif -{ -#ifdef ECORE_XCB_XTEST - xcb_keycode_t keycode = 0; - xcb_keysym_t keysym = 0; - xcb_keycode_t shift_code = 0; - xcb_void_cookie_t cookie; - xcb_generic_error_t *err; - Eina_Bool shift = EINA_FALSE; -#endif - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - CHECK_XCB_CONN; - - if (!_test_avail) return EINA_FALSE; - -#ifdef ECORE_XCB_XTEST - keycode = _ecore_xcb_keymap_string_to_keycode(key); - keysym = _ecore_xcb_keymap_keycode_to_keysym(keycode, 0); - if (keysym == XCB_NO_SYMBOL) - { - keysym = _ecore_xcb_keymap_keycode_to_keysym(keycode, 1); - if (keysym != XCB_NO_SYMBOL) - shift = EINA_TRUE; - } - - if (shift) - { - xcb_keycode_t *keycodes; - int i = 0; - - keycodes = _ecore_xcb_keymap_keysym_to_keycode(XK_Shift_L); - while (keycodes[i] != XCB_NO_SYMBOL) - { - if (keycodes[i] != 0) - { - shift_code = keycodes[i]; - break; - } - i++; - } - } - - if (shift) - { - cookie = - xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, - shift_code, XCB_CURRENT_TIME, - ((xcb_screen_t *)_ecore_xcb_screen)->root, - 0, 0, 0); - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - free(err); - return EINA_FALSE; - } - } - - cookie = - xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, - keycode, XCB_CURRENT_TIME, - ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - free(err); - return EINA_FALSE; - } - cookie = - xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, - keycode, XCB_CURRENT_TIME, - ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - free(err); - return EINA_FALSE; - } - - if (shift) - { - cookie = - xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, - shift_code, XCB_CURRENT_TIME, - ((xcb_screen_t *)_ecore_xcb_screen)->root, - 0, 0, 0); - err = xcb_request_check(_ecore_xcb_conn, cookie); - if (err) - { - free(err); - return EINA_FALSE; - } - } - - return EINA_TRUE; -#endif - - return EINA_FALSE; -} diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x.c deleted file mode 100644 index d9b81bc0f8..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x.c +++ /dev/null @@ -1,2242 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include -#include -#include - -//#define LOGRT 1 - -#ifdef LOGRT -#include -#endif /* ifdef LOGRT */ - -#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 Eina_Bool _ecore_x_fd_handler(void *data, - Ecore_Fd_Handler *fd_handler); -static Eina_Bool _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_XRANDR */ -#ifdef ECORE_XFIXES -static int _ecore_x_event_fixes_selection_id = 0; -#endif /* ifdef ECORE_XFIXES */ -#ifdef ECORE_XDAMAGE -static int _ecore_x_event_damage_id = 0; -#endif /* ifdef ECORE_XDAMAGE */ -#ifdef ECORE_XGESTURE -static int _ecore_x_event_gesture_id = 0; -#endif /* ifdef ECORE_XGESTURE */ -#ifdef ECORE_XKB -static int _ecore_x_event_xkb_id = 0; -#endif /* ifdef ECORE_XKB */ -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; -Eina_Bool _ecore_x_xcursor = EINA_FALSE; - -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_MAPPING_CHANGE = 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_FIXES_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_GESTURE_NOTIFY_FLICK; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD; -EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP; -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_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_XKB_STATE_NOTIFY = 0; -EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0; - - -EAPI int ECORE_X_EVENT_GENERIC = 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_MODIFIER_ALTGR = 0; - -EAPI int ECORE_X_LOCK_SCROLL = 0; -EAPI int ECORE_X_LOCK_NUM = 0; -EAPI int ECORE_X_LOCK_CAPS = 0; -EAPI int ECORE_X_LOCK_SHIFT = 0; - -EAPI int ECORE_X_RAW_BUTTON_PRESS = 0; -EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0; -EAPI int ECORE_X_RAW_MOTION = 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 /* ifdef LOGRT */ - -/* wrapper to use XkbKeycodeToKeysym when possible */ -KeySym -_ecore_x_XKeycodeToKeysym(Display *display, KeyCode keycode, int idx) -{ -#ifdef ECORE_XKB - return XkbKeycodeToKeysym(display, keycode, 0, idx); -#else - return XKeycodeToKeysym(display, keycode, idx); -#endif -} - -void -_ecore_x_modifiers_get(void) -{ - /* 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_Meta_L); - - ECORE_X_MODIFIER_ALTGR = _ecore_x_key_mask_get(XK_Mode_switch); - - 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_LOCK_SHIFT = _ecore_x_key_mask_get(XK_Shift_Lock); -} - -/** - * @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 /* ifdef ECORE_XSS */ - int sync_base = 0; - int sync_err_base = 0; -#ifdef ECORE_XRANDR - int randr_base = 0; - int randr_err_base = 0; -#endif /* ifdef ECORE_XRANDR */ -#ifdef ECORE_XFIXES - int fixes_base = 0; - int fixes_err_base = 0; -#endif /* ifdef ECORE_XFIXES */ -#ifdef ECORE_XDAMAGE - int damage_base = 0; - int damage_err_base = 0; -#endif /* ifdef ECORE_XDAMAGE */ -#ifdef ECORE_XGESTURE - int gesture_base = 0; - int gesture_err_base = 0; -#endif /* ifdef ECORE_XGESTURE */ -#ifdef ECORE_XKB - int xkb_base = 0; -#endif /* ifdef ECORE_XKB */ - if (++_ecore_x_init_count != 1) - return _ecore_x_init_count; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); -#ifdef LOGRT - _logrt_init(); -#endif /* ifdef LOGRT */ - - eina_init(); - _ecore_xlib_log_dom = eina_log_domain_register - ("ecore_x", 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_init()) - goto shutdown_eina; - if (!ecore_event_init()) - goto shutdown_ecore; - -#ifdef EVAS_FRAME_QUEUING - XInitThreads(); -#endif /* ifdef EVAS_FRAME_QUEUING */ - _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 /* ifdef ECORE_XSS */ - - 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_XRANDR */ - -#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_XFIXES */ - -#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 /* ifdef ECORE_XDAMAGE */ - -#ifdef ECORE_XGESTURE - if (XGestureQueryExtension(_ecore_x_disp, &gesture_base, &gesture_err_base)) - _ecore_x_event_gesture_id = gesture_base; - - ECORE_X_EVENT_HANDLERS_GROW(gesture_base, GestureNumberEvents); -#endif /* ifdef ECORE_XGESTURE */ -#ifdef ECORE_XKB - { - int dummy; - - if (XkbQueryExtension(_ecore_x_disp, &dummy, &xkb_base, - &dummy, &dummy, &dummy)) - _ecore_x_event_xkb_id = xkb_base; - XkbSelectEventDetails(_ecore_x_disp, XkbUseCoreKbd, XkbStateNotify, - XkbAllStateComponentsMask, XkbGroupStateMask); - } - ECORE_X_EVENT_HANDLERS_GROW(xkb_base, XkbNumberEvents); -#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) ? EINA_TRUE : EINA_FALSE; -#endif /* ifdef ECORE_XCURSOR */ - _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 /* ifdef GenericEvent */ - - 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_XRANDR */ -#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_XFIXES */ -#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_XDAMAGE */ -#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); - if (_ecore_x_event_xkb_id) - _ecore_x_event_handlers[_ecore_x_event_xkb_id] = _ecore_x_event_handle_xkb; -#endif /* ifdef ECORE_XKB */ - -#ifdef ECORE_XGESTURE - if (_ecore_x_event_gesture_id) - { - _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyFlick] = - _ecore_x_event_handle_gesture_notify_flick; - _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyPan] = - _ecore_x_event_handle_gesture_notify_pan; - _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyPinchRotation] = - _ecore_x_event_handle_gesture_notify_pinchrotation; - _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyTap] = - _ecore_x_event_handle_gesture_notify_tap; - _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyTapNHold] = - _ecore_x_event_handle_gesture_notify_tapnhold; - _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyHold] = - _ecore_x_event_handle_gesture_notify_hold; - _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyGroup] = - _ecore_x_event_handle_gesture_notify_group; - } - -#endif /* ifdef ECORE_XGESTURE */ - - 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_MAPPING_CHANGE = 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_GESTURE_NOTIFY_FLICK = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new(); - ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_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_XKB_STATE_NOTIFY = ecore_event_type_new(); - ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new(); - - ECORE_X_EVENT_GENERIC = ecore_event_type_new(); - - ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new(); - ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new(); - ECORE_X_RAW_MOTION = ecore_event_type_new(); - } - - _ecore_x_modifiers_get(); - - _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_gesture_init(); - _ecore_x_input_init(); - _ecore_x_events_init(); - - _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456); - - 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(); -shutdown_ecore: - ecore_shutdown(); -shutdown_eina: - eina_log_domain_unregister(_ecore_xlib_log_dom); - _ecore_xlib_log_dom = -1; - eina_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__); - - ecore_main_fd_handler_del(_ecore_x_fd_handler_handle); - if (close_display) - XCloseDisplay(_ecore_x_disp); - else - { - close(ConnectionNumber(_ecore_x_disp)); - // FIXME: may have to clean up x display internal here -// getting segv here? hmmm. odd. disable -// XFree(_ecore_x_disp); - } - - free(_ecore_x_event_handlers); - _ecore_x_fd_handler_handle = NULL; - _ecore_x_disp = NULL; - _ecore_x_event_handlers = NULL; - _ecore_x_events_shutdown(); - _ecore_x_input_shutdown(); - _ecore_x_selection_shutdown(); - _ecore_x_dnd_shutdown(); - ecore_x_netwm_shutdown(); - - ecore_event_shutdown(); - ecore_shutdown(); - - eina_log_domain_unregister(_ecore_xlib_log_dom); - _ecore_xlib_log_dom = -1; - eina_shutdown(); - - 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. 0 is returned if an error occurs. - * @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_X_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); -} - -/** - * Retrieves the size of an Ecore_X_Screen. - * @param screen the handle to the screen to query. - * @param w where to return the width. May be NULL. Returns 0 on errors. - * @param h where to return the height. May be NULL. Returns 0 on errors. - * @ingroup Ecore_X_Display_Attr_Group - * @see ecore_x_default_screen_get() - * - * @since 1.1 - */ -EAPI void -ecore_x_screen_size_get(const Ecore_X_Screen *screen, - int *w, - int *h) -{ - Screen *s = (Screen *)screen; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (w) *w = 0; - if (h) *h = 0; - if (!s) return; - if (w) *w = s->width; - if (h) *h = s->height; -} - -/** - * Retrieves the number of screens. - * - * @return The count of the number of screens. - * @ingroup Ecore_X_Display_Attr_Group - * - * @since 1.1 - */ -EAPI int -ecore_x_screen_count_get(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - return ScreenCount(_ecore_x_disp); -} - -/** - * Retrieves the index number of the given screen. - * - * @param screen The screen for which the index will be retrieved. - * @return The index number of the screen. - * @ingroup Ecore_X_Display_Attr_Group - * - * @since 1.1 - */ -EAPI int -ecore_x_screen_index_get(const Ecore_X_Screen *screen) -{ - return XScreenNumberOfScreen((Screen *)screen); -} - -/** - * Retrieves the screen based on index number. - * - * @param idx The index that will be used to retrieve the screen. - * @return The Ecore_X_Screen at this index. - * @ingroup Ecore_X_Display_Attr_Group - * - * @since 1.1 - */ -EAPI Ecore_X_Screen * -ecore_x_screen_get(int idx) -{ - return XScreenOfDisplay(_ecore_x_disp, idx); -} - -/** - * 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 account for multihead or xinerama and - * xrander where different parts of the screen may have different 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; -} - -/** - * Invoke the standard system beep to alert users - * - * @param percent The volume at which the bell rings. Must be in the range - * [-100,+100]. If percent >= 0, the final volume will be: - * base - [(base * percent) / 100] + percent - * Otherwise, it's calculated as: - * base + [(base * percent) / 100] - * where @c base is the bell's base volume as set by XChangeKeyboardControl(3). - * - * @returns @c EINA_TRUE on success, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_bell(int percent) -{ - int ret; - - ret = XBell(_ecore_x_disp, percent); - if (ret == BadValue) - return EINA_FALSE; - - return EINA_TRUE; -} - -static Eina_Bool -_ecore_x_fd_handler(void *data, - Ecore_Fd_Handler *fd_handler EINA_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 /* ifdef ENABLE_XIM */ - 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 ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_ecore_x_fd_handler_buf(void *data, - Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - Display *d; - - d = data; - if (XPending(d)) - return ECORE_CALLBACK_RENEW; - - return ECORE_CALLBACK_CANCEL; -} - -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 = _ecore_x_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 /* ifdef ECORE_XPRINT */ - - 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(MAX((num - overlap) * sizeof(Window), 1)); - 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 /* ifdef ECORE_XPRINT */ - 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 /* ifdef ECORE_XPRINT */ - 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 EINA_UNUSED) -{ - if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) && - (ecore_x_error_code_get() == BadAccess)) - _ecore_x_window_manage_failed = 1; -} - -EAPI Eina_Bool -ecore_x_window_manage(Ecore_X_Window win) -{ - XWindowAttributes att; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True) - return EINA_FALSE; - - 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 EINA_FALSE; - } - - return EINA_TRUE; -} - -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 Eina_Bool -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 EINA_FALSE; - - 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 EINA_TRUE; -} - -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 Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_pointer_mapping_set(unsigned char *map, - int nmap) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return (XSetPointerMapping(_ecore_x_disp, map, nmap) == MappingSuccess) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_pointer_mapping_get(unsigned char *map, - int nmap) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return XGetPointerMapping(_ecore_x_disp, map, nmap) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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 EINA_TRUE; - - return EINA_FALSE; -} - -EAPI Eina_Bool -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 EINA_TRUE; - - return EINA_FALSE; -} - -EAPI void -ecore_x_pointer_ungrab(void) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XUngrabPointer(_ecore_x_disp, CurrentTime); -} - -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_keyboard_grab(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (XGrabKeyboard(_ecore_x_disp, win, False, - GrabModeAsync, GrabModeAsync, - CurrentTime) == GrabSuccess) - return EINA_TRUE; - - return EINA_FALSE; -} - -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; -Eina_Bool (*_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(Eina_Bool (*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; - Window *t; - - 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++; - t = realloc(_ecore_window_grabs, - _ecore_window_grabs_num * sizeof(Window)); - if (!t) return; - _ecore_window_grabs = t; - _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; - Window *t; - - 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--; - if (_ecore_window_grabs_num <= 0) - { - free(_ecore_window_grabs); - _ecore_window_grabs = NULL; - return; - } - t = realloc(_ecore_window_grabs, - _ecore_window_grabs_num * - sizeof(Window)); - if (!t) return; - _ecore_window_grabs = t; - } - } -} - -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; - Window *t; - - 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++; - t = realloc(_ecore_key_grabs, - _ecore_key_grabs_num * sizeof(Window)); - if (!t) return; - _ecore_key_grabs = t; - _ecore_key_grabs[_ecore_key_grabs_num - 1] = win; -} - -void -_ecore_x_key_grab_remove(Ecore_X_Window win) -{ - int i, shuffle = 0; - Window *t; - - 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--; - if (_ecore_key_grabs_num <= 0) - { - free(_ecore_key_grabs); - _ecore_key_grabs = NULL; - return; - } - t = realloc(_ecore_key_grabs, - _ecore_key_grabs_num * sizeof(Window)); - if (!t) return; - _ecore_key_grabs = t; - } - } -} - -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 mask The mask of the message to be sent. - * @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 @c EINA_TRUE on success @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -/** - * 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 @c 20. - * - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_mouse_in_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.xcrossing.type = EnterNotify; - xev.xcrossing.window = win; - xev.xcrossing.root = att.root; - xev.xcrossing.subwindow = win; - xev.xcrossing.time = _ecore_x_event_last_time; - xev.xcrossing.x = x; - xev.xcrossing.y = y; - xev.xcrossing.x_root = rx; - xev.xcrossing.y_root = ry; - xev.xcrossing.mode = NotifyNormal; - xev.xcrossing.detail = NotifyNonlinear; - xev.xcrossing.same_screen = 1; - xev.xcrossing.focus = 0; - xev.xcrossing.state = 0; - return XSendEvent(_ecore_x_disp, win, True, EnterWindowMask, &xev) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_mouse_out_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.xcrossing.type = LeaveNotify; - xev.xcrossing.window = win; - xev.xcrossing.root = att.root; - xev.xcrossing.subwindow = win; - xev.xcrossing.time = _ecore_x_event_last_time; - xev.xcrossing.x = x; - xev.xcrossing.y = y; - xev.xcrossing.x_root = rx; - xev.xcrossing.y_root = ry; - xev.xcrossing.mode = NotifyNormal; - xev.xcrossing.detail = NotifyNonlinear; - xev.xcrossing.same_screen = 1; - xev.xcrossing.focus = 0; - xev.xcrossing.state = 0; - return XSendEvent(_ecore_x_disp, win, True, LeaveWindowMask, &xev) ? EINA_TRUE : EINA_FALSE; -} - -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; -} - -/** - * Retrieve the Visual ID from a given Visual. - * - * @param visual The Visual to get the ID for. - * - * @return The visual id. - * @since 1.1.0 - */ -EAPI unsigned int -ecore_x_visual_id_get(Ecore_X_Visual visual) -{ - return XVisualIDFromVisual(visual); -} - -/** - * Retrieve the default Visual. - * - * @param disp The Display to get the Default Visual from - * @param screen The Screen. - * - * @return The default visual. - * @since 1.1.0 - */ -EAPI Ecore_X_Visual -ecore_x_default_visual_get(Ecore_X_Display *disp, - Ecore_X_Screen *screen) -{ - return DefaultVisual(disp, ecore_x_screen_index_get(screen)); -} - -/** - * Retrieve the default Colormap. - * - * @param disp The Display to get the Default Colormap from - * @param screen The Screen. - * - * @return The default colormap. - * @since 1.1.0 - */ -EAPI Ecore_X_Colormap -ecore_x_default_colormap_get(Ecore_X_Display *disp, - Ecore_X_Screen *screen) -{ - return DefaultColormap(disp, ecore_x_screen_index_get(screen)); -} - -/** - * Retrieve the default depth. - * - * @param disp The Display to get the Default Depth from - * @param screen The Screen. - * - * @return The default depth. - * @since 1.1.0 - */ -EAPI int -ecore_x_default_depth_get(Ecore_X_Display *disp, - Ecore_X_Screen *screen) -{ - return DefaultDepth(disp, ecore_x_screen_index_get(screen)); -} - -EAPI void -ecore_x_xkb_select_group(int group) -{ -#ifdef ECORE_XKB - XkbLockGroup(_ecore_x_disp, XkbUseCoreKbd, group); -#endif -} - -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ - -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_MODIFIER_ALTGR) - xmodifiers |= ECORE_X_MODIFIER_ALTGR; - - 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; - - if (state & ECORE_EVENT_LOCK_SHIFT) - xmodifiers |= ECORE_X_LOCK_SHIFT; - - return xmodifiers; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_atoms.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_atoms.c deleted file mode 100644 index 2aec7ce740..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_atoms.c +++ /dev/null @@ -1,109 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include - -#include "Ecore.h" -#include "ecore_x_private.h" -#include "Ecore_X.h" -#include "Ecore_X_Atoms.h" -#include "ecore_x_atoms_decl.h" - -void -_ecore_x_atoms_init(void) -{ - Atom *atoms; - char **names; - int i, num; - - num = sizeof(atom_items) / sizeof(Atom_Item); - atoms = alloca(num * sizeof(Atom)); - names = alloca(num * sizeof(char *)); - for (i = 0; i < num; i++) - names[i] = (char *) atom_items[i].name; - XInternAtoms(_ecore_x_disp, names, num, False, atoms); - for (i = 0; i < num; i++) - *(atom_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; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_composite.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_composite.c deleted file mode 100644 index b919db96d2..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_composite.c +++ /dev/null @@ -1,176 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include "ecore_x_private.h" -#include "Ecore_X.h" - -static Eina_Bool _composite_available = EINA_FALSE; - -void -_ecore_x_composite_init(void) -{ - _composite_available = EINA_FALSE; - -#ifdef ECORE_XCOMPOSITE - int major, minor; - - if (XCompositeQueryVersion(_ecore_x_disp, &major, &minor)) - { -# ifdef ECORE_XRENDER - if (XRenderQueryExtension(_ecore_x_disp, &major, &minor)) - { -# ifdef ECORE_XFIXES - if (XFixesQueryVersion(_ecore_x_disp, &major, &minor)) - { - _composite_available = EINA_TRUE; - } -# endif - } -# endif - } -#endif -} - -EAPI Eina_Bool -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 /* ifdef ECORE_XCOMPOSITE */ -} - -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 /* ifdef ECORE_XCOMPOSITE */ -} - -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 /* ifdef ECORE_XCOMPOSITE */ -} - -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 /* ifdef ECORE_XCOMPOSITE */ -} - -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 /* ifdef ECORE_XCOMPOSITE */ - return pixmap; -} - -EAPI void -ecore_x_composite_window_events_disable(Ecore_X_Window win) -{ -#ifdef ECORE_XCOMPOSITE - ecore_x_window_shape_input_rectangle_set(win, -1, -1, 1, 1); -#endif /* ifdef ECORE_XCOMPOSITE */ -} - -EAPI void -ecore_x_composite_window_events_enable(Ecore_X_Window win) -{ -#ifdef ECORE_XCOMPOSITE - ecore_x_window_shape_input_rectangle_set(win, 0, 0, 65535, 65535); -#endif /* ifdef ECORE_XCOMPOSITE */ -} - -EAPI Ecore_X_Window -ecore_x_composite_render_window_enable(Ecore_X_Window root) -{ - Ecore_X_Window win = 0; -#ifdef ECORE_XCOMPOSITE - win = XCompositeGetOverlayWindow(_ecore_x_disp, root); - ecore_x_composite_window_events_disable(win); -#endif /* ifdef ECORE_XCOMPOSITE */ - 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 /* ifdef ECORE_XCOMPOSITE */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_cursor.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_cursor.c deleted file mode 100644 index a968c56af2..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_cursor.c +++ /dev/null @@ -1,246 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - -#include "ecore_x_private.h" - -EAPI Eina_Bool -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 /* ifdef ECORE_XCURSOR */ - { - 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 /* ifdef ECORE_XCURSOR */ - size = 0; -#endif /* ifdef ECORE_XCURSOR */ -} - -EAPI int -ecore_x_cursor_size_get(void) -{ -#ifdef ECORE_XCURSOR - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return XcursorGetDefaultSize(_ecore_x_disp); -#else /* ifdef ECORE_XCURSOR */ - return 0; -#endif /* ifdef ECORE_XCURSOR */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_damage.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_damage.c deleted file mode 100644 index b094f85235..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_damage.c +++ /dev/null @@ -1,71 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include "ecore_x_private.h" -#include "Ecore_X.h" - -static Eina_Bool _damage_available = EINA_FALSE; -#ifdef ECORE_XDAMAGE -static int _damage_major, _damage_minor; -#endif /* ifdef ECORE_XDAMAGE */ - -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 = EINA_TRUE; - else - _damage_available = EINA_FALSE; - -#else /* ifdef ECORE_XDAMAGE */ - _damage_available = EINA_FALSE; -#endif /* ifdef ECORE_XDAMAGE */ -} - -EAPI Eina_Bool -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 /* ifdef ECORE_XDAMAGE */ - return 0; -#endif /* ifdef ECORE_XDAMAGE */ -} - -EAPI void -ecore_x_damage_free(Ecore_X_Damage damage) -{ -#ifdef ECORE_XDAMAGE - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XDamageDestroy(_ecore_x_disp, damage); -#endif /* ifdef ECORE_XDAMAGE */ -} - -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 /* ifdef ECORE_XDAMAGE */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_dnd.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_dnd.c deleted file mode 100644 index e4f74a7257..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_dnd.c +++ /dev/null @@ -1,706 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include -#include - -#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; -static void (*_posupdatecb)(void *, - Ecore_X_Xdnd_Position *); -static void *_posupdatedata; - -void -_ecore_x_dnd_init(void) -{ - if (!_ecore_x_dnd_init_count) - { - _source = calloc(1, sizeof(Ecore_X_DND_Source)); - if (!_source) return; - _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)); - if (!_target) - { - free(_source); - _source = NULL; - return; - } - _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 Eina_Bool -_ecore_x_dnd_converter_copy(char *target EINA_UNUSED, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *tprop EINA_UNUSED, - int *count EINA_UNUSED) -{ - XTextProperty text_prop; - char *mystr; - XICCEncodingStyle style = XTextStyle; - - if (!data || !size) - return EINA_FALSE; - - mystr = calloc(1, size + 1); - if (!mystr) - return EINA_FALSE; - - 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); - if (!*data_ret) - { - free(mystr); - return EINA_FALSE; - } - memcpy(*data_ret, text_prop.value, bufsize); - *size_ret = bufsize; - XFree(text_prop.value); - free(mystr); - return EINA_TRUE; - } - else - { - free(mystr); - return EINA_FALSE; - } -} - -EAPI void -ecore_x_dnd_aware_set(Ecore_X_Window win, - Eina_Bool 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; - Version_Cache_Item *t; - - 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; - - t = realloc(_version_cache, - _version_cache_alloc * - sizeof(Version_Cache_Item)); - if (!t) return 0; - _version_cache = t; - _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; - - t = realloc(_version_cache, _version_cache_alloc * - sizeof(Version_Cache_Item)); - if (!t) return 0; - _version_cache = t; - _version_cache[_version_cache_num - 1].win = win; - _version_cache[_version_cache_num - 1].ver = 0; - } - - return 0; -} - -EAPI Eina_Bool -ecore_x_dnd_type_isset(Ecore_X_Window win, - const char *type) -{ - int num, i, ret = EINA_FALSE; - 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 = EINA_TRUE; - break; - } - } - - XFree(data); - return ret; -} - -EAPI void -ecore_x_dnd_type_set(Ecore_X_Window win, - const char *type, - Eina_Bool 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); - } -} - -/** - * The DND position update cb is called Ecore_X sends a DND position to a - * client. - * - * It essentially mirrors some of the data sent in the position message. - * Generally this cb should be set just before position update is called. - * Please note well you need to look after your own data pointer if someone - * trashes you position update cb set. - * - * It is considered good form to clear this when the dnd event finishes. - * - * @param cb Callback to updated each time ecore_x sends a position update. - * @param data User data. - */ -EAPI void -ecore_x_dnd_callback_pos_update_set( - void (*cb)(void *, - Ecore_X_Xdnd_Position *data), - const void *data) -{ - _posupdatecb = cb; - _posupdatedata = (void *)data; /* Discard the const early */ -} - -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 Eina_Bool -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 EINA_FALSE; - - /* Take ownership of XdndSelection */ - if (!ecore_x_selection_xdnd_set(source, data, size)) - return EINA_FALSE; - - 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 EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_dnd_drop(void) -{ - XEvent xev; - int status = EINA_FALSE; - - 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 = EINA_TRUE; - } - 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(Eina_Bool will_accept, - Eina_Bool 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; -} - -EAPI 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); -} - -EAPI 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; - Ecore_X_Xdnd_Position pos; - 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; - } - } - - if (_posupdatecb) - { - pos.position.x = x; - pos.position.y = y; - pos.win = win; - pos.prev = _source->dest; - _posupdatecb(_posupdatedata, &pos); - } - - _source->prev.x = x; - _source->prev.y = y; - _source->prev.window = root; - _source->dest = win; -} - -/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_dpms.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_dpms.c deleted file mode 100644 index 23349f44e6..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_dpms.c +++ /dev/null @@ -1,247 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include "ecore_x_private.h" - -static Eina_Bool _dpms_available = EINA_FALSE; - -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 = EINA_TRUE; - else - _dpms_available = EINA_FALSE; - -#else /* ifdef ECORE_XDPMS */ - _dpms_available = EINA_FALSE; -#endif /* ifdef ECORE_XDPMS */ -} - -/** - * @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 Eina_Bool -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 Eina_Bool -ecore_x_dpms_capable_get(void) -{ -#ifdef ECORE_XDPMS - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return DPMSCapable(_ecore_x_disp) ? EINA_TRUE : EINA_FALSE; -#else /* ifdef ECORE_XDPMS */ - return EINA_FALSE; -#endif /* ifdef ECORE_XDPMS */ -} - -/** - * Checks the DPMS state of the display. - * @return @c 1 if DPMS is enabled, @c 0 otherwise. - * @ingroup Ecore_X_DPMS_Group - */ -EAPI Eina_Bool -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 ? EINA_TRUE : EINA_FALSE; -#else /* ifdef ECORE_XDPMS */ - return EINA_FALSE; -#endif /* ifdef ECORE_XDPMS */ -} - -/** - * 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 /* ifdef ECORE_XDPMS */ -} - -/** - * 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 /* ifdef ECORE_XDPMS */ -} - -/** - * 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 Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -#else /* ifdef ECORE_XDPMS */ - return EINA_FALSE; -#endif /* ifdef ECORE_XDPMS */ -} - -/** - * 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(void) -{ -#ifdef ECORE_XDPMS - unsigned short standby, suspend, off; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off); - return standby; -#else /* ifdef ECORE_XDPMS */ - return 0; -#endif /* ifdef ECORE_XDPMS */ -} - -/** - * 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(void) -{ -#ifdef ECORE_XDPMS - unsigned short standby, suspend, off; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off); - return suspend; -#else /* ifdef ECORE_XDPMS */ - return 0; -#endif /* ifdef ECORE_XDPMS */ -} - -/** - * 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(void) -{ -#ifdef ECORE_XDPMS - unsigned short standby, suspend, off; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off); - return off; -#else /* ifdef ECORE_XDPMS */ - return 0; -#endif /* ifdef ECORE_XDPMS */ -} - -/** - * Sets the standby timeout (in unit of seconds). - * @param new_timeout 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 /* ifdef ECORE_XDPMS */ -} - -/** - * Sets the suspend timeout (in unit of seconds). - * @param new_timeout 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 /* ifdef ECORE_XDPMS */ -} - -/** - * Sets the off timeout (in unit of seconds). - * @param new_timeout 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 /* ifdef ECORE_XDPMS */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_drawable.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_drawable.c deleted file mode 100644 index d1b41114da..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_drawable.c +++ /dev/null @@ -1,118 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#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); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_e.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_e.c deleted file mode 100644 index 430b24b117..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_e.c +++ /dev/null @@ -1,1670 +0,0 @@ -/* - * OLD E hints - */ - -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#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 Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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: break; - } - 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 = 0; - - 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: - break; - } - 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 Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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_access_action_next_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_read_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_up_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP, - 0, 0, 0); -} - -EAPI void -ecore_x_e_illume_access_action_down_send(Ecore_X_Window win) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - win, - ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN, - 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 Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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 Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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 Eina_Bool -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 EINA_FALSE; - - if (x) - *x = geom[0]; - - if (y) - *y = geom[1]; - - if (w) - *w = geom[2]; - - if (h) - *h = geom[3]; - - return EINA_TRUE; -} - -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 Eina_Bool -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 EINA_FALSE; - - if (x) - *x = geom[0]; - - if (y) - *y = geom[1]; - - if (w) - *w = geom[2]; - - if (h) - *h = geom[3]; - - return EINA_TRUE; -} - -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 Eina_Bool -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 EINA_FALSE; - - if (x) - *x = geom[0]; - - if (y) - *y = geom[1]; - - if (w) - *w = geom[2]; - - if (h) - *h = geom[3]; - - return EINA_TRUE; -} - -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: - break; - } - 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 Eina_Bool -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 EINA_FALSE; - - return val ? EINA_TRUE : EINA_FALSE; -} - -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 = 0; - - 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); -} - -static Ecore_X_Atom -_ecore_x_e_clipboard_atom_get(Ecore_X_Illume_Clipboard_State state) -{ - switch (state) - { - case ECORE_X_ILLUME_CLIPBOARD_STATE_ON: - return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON; - case ECORE_X_ILLUME_CLIPBOARD_STATE_OFF: - return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF; - default: - break; - } - return 0; -} - -static Ecore_X_Illume_Clipboard_State -_ecore_x_e_clipboard_state_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON) - return ECORE_X_ILLUME_CLIPBOARD_STATE_ON; - - if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF) - return ECORE_X_ILLUME_CLIPBOARD_STATE_OFF; - - return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; -} - -EAPI void -ecore_x_e_illume_clipboard_state_set(Ecore_X_Window win, - Ecore_X_Illume_Clipboard_State state) -{ - Ecore_X_Atom atom = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - atom = _ecore_x_e_clipboard_atom_get(state); - - ecore_x_window_prop_atom_set(win, - ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE, - &atom, 1); -} - -EAPI Ecore_X_Illume_Clipboard_State -ecore_x_e_illume_clipboard_state_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_CLIPBOARD_STATE, - &atom, 1)) - return ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN; - return _ecore_x_e_clipboard_state_get(atom); -} - -EAPI void -ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY, - geom, 4); -} - -EAPI Eina_Bool -ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY, - geom, 4); - if (ret != 4) return EINA_FALSE; - - if (x) *x = geom[0]; - if (y) *y = geom[1]; - if (w) *w = geom[2]; - if (h) *h = geom[3]; - - return EINA_TRUE; -} - -/* for sliding window */ -EAPI void -ecore_x_e_illume_sliding_win_state_set(Ecore_X_Window win, - unsigned int is_visible) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_window_prop_card32_set(win, - ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE, - &is_visible, 1); -} /* ecore_x_e_illume_sliding_win_state_set */ - -EAPI int -ecore_x_e_illume_sliding_win_state_get(Ecore_X_Window win) -{ - unsigned int is_visible = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ecore_x_window_prop_card32_get(win, - ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE, - &is_visible, 1)) - return 0; - - return is_visible; -} - -EAPI void -ecore_x_e_illume_sliding_win_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_SLIDING_WIN_GEOMETRY, - geom, 4); -} /* ecore_x_e_illume_sliding_win_geometry_set */ - -EAPI int -ecore_x_e_illume_sliding_win_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_SLIDING_WIN_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; -}/* ecore_x_e_illume_sliding_win_geometry_get */ - -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; // version - 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_draw_size_done_send(Ecore_X_Window root, - Ecore_X_Window win, - int w, - int h) -{ - 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] = 1; // version - xev.xclient.data.l[2] = w; // win width at draw time - xev.xclient.data.l[3] = h; // win height at draw time - xev.xclient.data.l[4] = 0; // later - - XSendEvent(_ecore_x_disp, root, False, - SubstructureRedirectMask | SubstructureNotifyMask, - &xev); -} - -/* - * @since 1.3 - * - */ -EAPI void -ecore_x_e_window_profile_list_set(Ecore_X_Window win, - const char **profiles, - unsigned int num_profiles) -{ - Ecore_X_Atom *atoms; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!win) - return; - - if (!num_profiles) - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE_LIST); - else - { - atoms = alloca(num_profiles * sizeof(Ecore_X_Atom)); - ecore_x_atoms_get(profiles, num_profiles, atoms); - ecore_x_window_prop_property_set(win, - ECORE_X_ATOM_E_PROFILE_LIST, - XA_ATOM, 32, (void *)atoms, - num_profiles); - } -} - -/* - * @since 1.3 - */ -EAPI Eina_Bool -ecore_x_e_window_profile_list_get(Ecore_X_Window win, - const char ***profiles, - int *ret_num) -{ - unsigned char *data; - Ecore_X_Atom *atoms; - int num, i; - - if (ret_num) - *ret_num = 0; - - if (profiles) - *profiles = NULL; - - if (!win) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ecore_x_window_prop_property_get(win, - ECORE_X_ATOM_E_PROFILE_LIST, - XA_ATOM, 32, &data, &num)) - return EINA_FALSE; - - if (ret_num) - *ret_num = num; - - if (profiles) - { - (*profiles) = calloc(num, sizeof(char *)); - if (!(*profiles)) - { - if (ret_num) - *ret_num = 0; - - if (data) - free(data); - - return EINA_FALSE; - } - - atoms = (Ecore_X_Atom *)data; - for (i = 0; i < num; i++) - (*profiles)[i] = ecore_x_atom_name_get(atoms[i]); - } - - if (data) - XFree(data); - - return EINA_TRUE; -} - -/* - * @since 1.3 - */ -EAPI void -ecore_x_e_window_profile_set(Ecore_X_Window win, - const char *profile) -{ - Ecore_X_Atom atom; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!win) - return; - - if (!profile) - ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE); - else - { - atom = ecore_x_atom_get(profile); - ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_PROFILE, - XA_ATOM, 32, (void *)&atom, 1); - } -} - -/* - * @since 1.3 - */ -EAPI char * -ecore_x_e_window_profile_get(Ecore_X_Window win) -{ - Ecore_X_Atom *atom = NULL; - unsigned char *data; - char *profile = NULL; - int num; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_PROFILE, - XA_ATOM, 32, &data, &num)) - return NULL; - - if (data) - atom = (Ecore_X_Atom *)data; - - if (atom) - profile = ecore_x_atom_name_get(atom[0]); - - return profile; -} - -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 EINA_TRUE; - } - - return EINA_FALSE; -} - -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); -} - -EAPI void -ecore_x_e_comp_pixmap_set(Ecore_X_Window win, - Ecore_X_Pixmap pixmap) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (pixmap) - ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_PIXMAP, - ECORE_X_ATOM_PIXMAP, &pixmap, 1); - else - ecore_x_window_prop_property_del(win, pixmap); -} - -EAPI Ecore_X_Pixmap -ecore_x_e_comp_pixmap_get(Ecore_X_Window win) -{ - int ret = 0; - Ecore_X_Pixmap pixmap = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ret = - ecore_x_window_prop_xid_get(win, - ECORE_X_ATOM_E_COMP_PIXMAP, - ECORE_X_ATOM_PIXMAP, - &pixmap, 1); - if (ret != 1) - return 0; - - return pixmap; -} - -static Ecore_X_Atom -_ecore_x_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state) -{ - switch (state) - { - case ECORE_X_ILLUME_INDICATOR_STATE_ON: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_ON; - - case ECORE_X_ILLUME_INDICATOR_STATE_OFF: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF; - - default: - break; - } - return 0; -} - -static Ecore_X_Illume_Indicator_State -_ecore_x_e_indicator_state_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_ON) - return ECORE_X_ILLUME_INDICATOR_STATE_ON; - - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF) - return ECORE_X_ILLUME_INDICATOR_STATE_OFF; - - return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; -} - -EAPI void -ecore_x_e_illume_indicator_state_set(Ecore_X_Window win, - Ecore_X_Illume_Indicator_State state) -{ - Ecore_X_Atom atom = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - atom = _ecore_x_e_indicator_atom_get(state); - ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE, - &atom, 1); -} - -EAPI Ecore_X_Illume_Indicator_State -ecore_x_e_illume_indicator_state_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_INDICATOR_STATE, - &atom, 1)) - return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; - - return _ecore_x_e_indicator_state_get(atom); -} - -EAPI void -ecore_x_e_illume_indicator_state_send(Ecore_X_Window win, - Ecore_X_Illume_Indicator_State state) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - _ecore_x_e_indicator_atom_get(state), - 0, 0, 0, 0); -} - -static Ecore_X_Atom -_ecore_x_e_indicator_opacity_atom_get(Ecore_X_Illume_Indicator_Opacity_Mode mode) -{ - switch (mode) - { - case ECORE_X_ILLUME_INDICATOR_OPAQUE: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE; - - case ECORE_X_ILLUME_INDICATOR_TRANSLUCENT: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT; - - case ECORE_X_ILLUME_INDICATOR_TRANSPARENT: - return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; - - default: - break; - } - return 0; -} - -static Ecore_X_Illume_Indicator_Opacity_Mode -_ecore_x_e_indicator_opacity_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE) - return ECORE_X_ILLUME_INDICATOR_OPAQUE; - - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT) - return ECORE_X_ILLUME_INDICATOR_TRANSLUCENT; - - if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT) - return ECORE_X_ILLUME_INDICATOR_TRANSPARENT; - - return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; -} - -EAPI void -ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win, - Ecore_X_Illume_Indicator_Opacity_Mode mode) -{ - Ecore_X_Atom atom = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - atom = _ecore_x_e_indicator_opacity_atom_get(mode); - ecore_x_window_prop_atom_set(win, - ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE, - &atom, 1); -} - -EAPI Ecore_X_Illume_Indicator_Opacity_Mode -ecore_x_e_illume_indicator_opacity_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_INDICATOR_OPACITY_MODE, - &atom, 1)) - return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; - - return _ecore_x_e_indicator_opacity_get(atom); -} - -EAPI void -ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, - Ecore_X_Illume_Indicator_Opacity_Mode mode) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_client_message32_send(win, - ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - _ecore_x_e_indicator_opacity_atom_get(mode), - 0, 0, 0, 0); -} - -static Ecore_X_Atom -_ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state) -{ - switch (state) - { - case ECORE_X_ILLUME_WINDOW_STATE_NORMAL: - return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL; - - case ECORE_X_ILLUME_WINDOW_STATE_FLOATING: - return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; - - default: - break; - } - return 0; -} - -static Ecore_X_Illume_Window_State -_ecore_x_e_illume_window_state_get(Ecore_X_Atom atom) -{ - if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL) - return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; - - if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING) - return ECORE_X_ILLUME_WINDOW_STATE_FLOATING; - - return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; -} - -EAPI void -ecore_x_e_illume_window_state_set(Ecore_X_Window win, - Ecore_X_Illume_Window_State state) -{ - Ecore_X_Atom atom = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - atom = _ecore_x_e_illume_window_state_atom_get(state); - ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_WINDOW_STATE, - &atom, 1); -} - -EAPI Ecore_X_Illume_Window_State -ecore_x_e_illume_window_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_WINDOW_STATE, - &atom, 1)) - return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; - - return _ecore_x_e_illume_window_state_get(atom); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_error.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_error.c deleted file mode 100644 index f6eb075b54..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_error.c +++ /dev/null @@ -1,126 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - -#include "Ecore.h" -#include "ecore_private.h" -#include "ecore_x_private.h" -#include "Ecore_X.h" - -static int _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; -static Ecore_X_ID _error_resource_id = 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 - */ -//FIXME: Use Ecore_X_Error_Code type when 2.0 is released -EAPI int -ecore_x_error_code_get(void) -{ - return _error_code; -} - -/** - * Get the resource id that caused the error. - * @return The resource id causing the X error - * - * Return the X resource id that caused the last X error - */ -EAPI Ecore_X_ID -ecore_x_error_resource_id_get(void) -{ - return _error_resource_id; -} - -void -_ecore_x_error_handler_init(void) -{ - XSetErrorHandler((XErrorHandler)_ecore_x_error_handle); - XSetIOErrorHandler((XIOErrorHandler)_ecore_x_io_error_handle); -} - -static int -_ecore_x_error_handle(Display *d, - XErrorEvent *ev) -{ - if (d == _ecore_x_disp) - { - _error_request_code = ev->request_code; - _error_code = ev->error_code; - _error_resource_id = ev->resourceid; - if (_error_func) - _error_func(_error_data); - } - return 0; -} - -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; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_events.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_events.c deleted file mode 100644 index 9ce7163d53..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_events.c +++ /dev/null @@ -1,2523 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include -#include -#include - -#include - -#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 /* ifndef CODESET */ - -typedef struct _Ecore_X_Mouse_Down_Info -{ - EINA_INLIST; - int dev; - Window last_win; - Window last_last_win; - Window last_event_win; - Window last_last_event_win; - Time last_time; - Time last_last_time; - Eina_Bool did_double : 1; - Eina_Bool did_triple : 1; -} Ecore_X_Mouse_Down_Info; - -static int _ecore_x_last_event_mouse_move = 0; -static Ecore_Event *_ecore_x_last_event_mouse_move_event = NULL; -static Eina_Inlist *_ecore_x_mouse_down_info_list = NULL; - -static void -_ecore_x_mouse_down_info_clear(void) -{ - Eina_Inlist *l = _ecore_x_mouse_down_info_list; - Ecore_X_Mouse_Down_Info *info = NULL; - while (l) - { - info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info); - l = eina_inlist_remove(l, l); - free(info); - } - _ecore_x_mouse_down_info_list = NULL; -} - -void -_ecore_x_events_init(void) -{ - //Actually, Nothing to do. -} - -void -_ecore_x_events_shutdown(void) -{ - _ecore_x_mouse_down_info_clear(); -} - -static Ecore_X_Mouse_Down_Info * -_ecore_x_mouse_down_info_get(int dev) -{ - Eina_Inlist *l = _ecore_x_mouse_down_info_list; - Ecore_X_Mouse_Down_Info *info = NULL; - - //Return the exist info - EINA_INLIST_FOREACH(l, info) - if (info->dev == dev) return info; - - //New Device. Add it. - info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info)); - if (!info) return NULL; - - info->dev = dev; - l = eina_inlist_append(l, (Eina_Inlist *)info); - _ecore_x_mouse_down_info_list = l; - return info; -} - -static void -_ecore_x_event_free_mouse_move(void *data EINA_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); -} - -static void -_ecore_x_event_free_xdnd_enter(void *data EINA_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 EINA_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_MODIFIER_ALTGR) - modifiers |= ECORE_EVENT_MODIFIER_ALTGR; - - 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; - - if (state & ECORE_X_LOCK_SHIFT) - modifiers |= ECORE_EVENT_LOCK_SHIFT; - - 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(_ecore_x_XKeycodeToKeysym(xevent->display, - xevent->keycode, 0)); - if (!keyname) - { - snprintf(keyname_buffer, - sizeof(keyname_buffer), - "Keycode-%i", - xevent->keycode); - keyname = keyname_buffer; - } - - sym = 0; - key = NULL; - compose = NULL; - 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); - if (!compose) - ERR("Ecore_X cannot convert input key string '%s' to UTF-8. " - "Is Eina built with iconv support?", compose_buffer); - tmp = compose; - } - - key = XKeysymToString(sym); - if (!key) - key = keyname; - - 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; - - Ecore_X_Mouse_Down_Info *down_info = _ecore_x_mouse_down_info_get(dev); - - if (down_info) - { - if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && - down_info->did_triple) - { - down_info->last_win = 0; - down_info->last_last_win = 0; - down_info->last_event_win = 0; - down_info->last_last_event_win = 0; - down_info->last_time = 0; - down_info->last_last_time = 0; - } - if (event_window == window) - { - if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) - { - //Check Double Clicked - if (((int)(timestamp - down_info->last_time) <= - (int)(1000 * _ecore_x_double_click_time)) && - (window == down_info->last_win) && - (event_window == down_info->last_event_win)) - { - e->double_click = 1; - down_info->did_double = EINA_TRUE; - } - else - { - down_info->did_double = EINA_FALSE; - down_info->did_triple = EINA_FALSE; - } - - //Check Triple Clicked - if (((int)(timestamp - down_info->last_last_time) <= - (int)(2 * 1000 * _ecore_x_double_click_time)) && - (window == down_info->last_win) && - (window == down_info->last_last_win) && - (event_window == down_info->last_event_win) && - (event_window == down_info->last_last_event_win) - ) - { - e->triple_click = 1; - down_info->did_triple = EINA_TRUE; - } - else - { - down_info->did_triple = EINA_FALSE; - } - } - else - { - if (down_info->did_double) - e->double_click = 1; - if (down_info->did_triple) - e->triple_click = 1; - } - } - } - - /* NB: Block commented out as _ecore_x_mouse_up_count appears to have - * no use. The variable is also commented out above. This code block is - * the only place that this variable is used, and appears to serve no - * purpose. - dh - 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); - - if ((down_info) && - (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && - (window == event_window) && - (!down_info->did_triple)) - { - down_info->last_last_win = down_info->last_win; - down_info->last_win = window; - down_info->last_last_event_win = down_info->last_event_win; - down_info->last_event_win = event_window; - down_info->last_last_time = down_info->last_time; - down_info->last_time = timestamp; - } - - return e; -} - -void -_ecore_x_event_handle_any_event(XEvent *xevent) -{ - XEvent *ev = malloc(sizeof(XEvent)); - if (!ev) return; - 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)) - { - Eina_Bool replay = EINA_FALSE; - - 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; - - 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)) - { - Eina_Bool replay = EINA_FALSE; - - 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; - } - } - } - } -} - -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; - - 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; - - 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 EINA_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 EINA_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; - { - 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; -/* errr..... why? paranoia. - 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 = NULL; - int len; - int typesize; - - 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 = None; - Ecore_X_Atom type; - - /* Set up defaults for strings first */ - type = xevent->xselectionrequest.target; - typesize = 8; - len = sd->length; - - if (!ecore_x_selection_convert(xevent->xselectionrequest.selection, - xevent->xselectionrequest.target, - &data, &len, &type, &typesize)) - /* Refuse selection, conversion to requested target failed */ - property = None; - else if (data) - { - /* FIXME: This does not properly handle large data transfers */ - ecore_x_window_prop_property_set( - xevent->xselectionrequest.requestor, - xevent->xselectionrequest. - property, - type, - typesize, - data, - len); - property = xevent->xselectionrequest.property; - free(data); - } - - ecore_x_selection_notify_send(xevent->xselectionrequest.requestor, - xevent->xselectionrequest.selection, - xevent->xselectionrequest.target, - property, - xevent->xselectionrequest.time); - } - } -} - -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) - { - /* fallback if targets handling is not working and try get the - * selection directly */ - XConvertSelection(_ecore_x_disp, selection, - ECORE_X_ATOM_UTF8_STRING, - selection, - xevent->xselection.requestor, - CurrentTime); - return; - } - } - else - format = ecore_x_window_prop_property_get(xevent->xselection.requestor, - xevent->xselection.property, - AnyPropertyType, 8, &data, - &num_ret); - - 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 = EINA_TRUE; - else - e->installed = EINA_FALSE; - - 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); - free(e); - 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."); - free(e); - 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; - Eina_Bool completed = EINA_TRUE; - - 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 = EINA_FALSE; - 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_Event_Mapping_Change *e; - - _ecore_x_last_event_mouse_move = 0; - XRefreshKeyboardMapping((XMappingEvent *)xevent); - _ecore_x_modifiers_get(); - e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change)); - if (!e) return; - switch (xevent->xmapping.request) - { - case MappingModifier: - e->type = ECORE_X_MAPPING_MODIFIER; - break; - - case MappingKeyboard: - e->type = ECORE_X_MAPPING_KEYBOARD; - break; - - case MappingPointer: - default: - e->type = ECORE_X_MAPPING_MOUSE; - break; - } - e->keycode = xevent->xmapping.first_keycode; - e->num = xevent->xmapping.count; - ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL); -} - -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; - switch (shape_event->kind) - { - case ShapeBounding: - e->type = ECORE_X_SHAPE_BOUNDING; - break; - - case ShapeClip: - e->type = ECORE_X_SHAPE_CLIP; - break; - - case ShapeInput: - e->type = ECORE_X_SHAPE_INPUT; - break; - - default: - break; - } - e->x = shape_event->x; - e->y = shape_event->y; - e->w = shape_event->width; - e->h = shape_event->height; - e->shaped = shape_event->shaped; - 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) || - (screensaver_event->state == ScreenSaverCycle)) - e->on = EINA_TRUE; - else - e->on = EINA_FALSE; - - e->time = screensaver_event->time; - ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL); -#else /* ifdef ECORE_XSS */ - xevent = NULL; -#endif /* ifdef ECORE_XSS */ -} - -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->size.width = randr_event->width; - e->size.height = randr_event->height; - e->time = randr_event->timestamp; - e->config_time = randr_event->config_timestamp; - e->size.width_mm = randr_event->mwidth; - e->size.height_mm = randr_event->mheight; - e->orientation = 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->orientation = randr_event->rotation; - e->geo.x = randr_event->x; - e->geo.y = randr_event->y; - e->geo.w = randr_event->width; - e->geo.h = 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->orientation = 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; - if (randr_event->state == PropertyNewValue) - e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD; - else - e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL; - 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_XRANDR */ - -#ifdef ECORE_XFIXES -void -_ecore_x_event_handle_fixes_selection_notify(XEvent *event) -{ - XFixesSelectionNotifyEvent *notify_event = - (XFixesSelectionNotifyEvent *)event; - Ecore_X_Event_Fixes_Selection_Notify *e; - Ecore_X_Atom sel; - - _ecore_x_last_event_mouse_move = 0; - /* Nothing here yet */ - - e = calloc(1, sizeof(*e)); - if (!e) - return; - - e->win = notify_event->window; - e->owner = notify_event->owner; - e->time = notify_event->timestamp; - e->selection_time = notify_event->selection_timestamp; - e->atom = sel = notify_event->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; - e->reason = notify_event->subtype; - - ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL); -} - -#endif /* ifdef ECORE_XFIXES */ - -#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 /* ifdef ECORE_XDAMAGE */ - -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 (data) - { - if (e->data) - XFreeEventData(_ecore_x_disp, (XGenericEventCookie *)data); - free(data); - } - free(e); -#else - return; - data = NULL; ev = NULL; -#endif /* ifdef ECORE_XI2 */ -} - -void -_ecore_x_event_handle_generic_event(XEvent *event) -{ -#ifdef ECORE_XI2 - XGenericEvent *generic_event; - Ecore_X_Event_Generic *e; - XGenericEventCookie *data; - - 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); - - data = malloc(sizeof(XGenericEventCookie)); - if (data) memcpy(data, &(event->xcookie), sizeof(XGenericEventCookie)); - ecore_event_add(ECORE_X_EVENT_GENERIC, - e, - _ecore_x_event_free_generic_event, - data); -#else - return; - event = NULL; -#endif /* ifdef ECORE_XI2 */ -} - -#ifdef ECORE_XGESTURE -void -_ecore_x_event_handle_gesture_notify_flick(XEvent *xevent) -{ - XGestureNotifyFlickEvent *xfe; - Ecore_X_Event_Gesture_Notify_Flick *e; - - _ecore_x_last_event_mouse_move = 0; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xfe = (XGestureNotifyFlickEvent *)xevent; - e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick)); - if (!e) - return; - - e->win = xfe->window; - e->time = xfe->time; - e->subtype = xfe->kind; - e->num_fingers = xfe->num_finger; - e->distance = xfe->distance; - e->duration = xfe->duration; - e->direction = xfe->direction; - e->angle = XFixedToDouble(xfe->angle); - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL); -} - -void -_ecore_x_event_handle_gesture_notify_pan(XEvent *xevent) -{ - XGestureNotifyPanEvent *xpe; - Ecore_X_Event_Gesture_Notify_Pan *e; - - _ecore_x_last_event_mouse_move = 0; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xpe = (XGestureNotifyPanEvent *)xevent; - e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan)); - if (!e) - return; - - e->win = xpe->window; - e->time = xpe->time; - e->subtype = xpe->kind; - e->num_fingers = xpe->num_finger; - e->dx = xpe->dx; - e->dy = xpe->dy; - e->distance = xpe->distance; - e->duration = xpe->duration; - e->direction = xpe->direction; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL); -} - -void -_ecore_x_event_handle_gesture_notify_pinchrotation(XEvent *xevent) -{ - XGestureNotifyPinchRotationEvent *xpre; - Ecore_X_Event_Gesture_Notify_PinchRotation *e; - - _ecore_x_last_event_mouse_move = 0; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xpre = (XGestureNotifyPinchRotationEvent *)xevent; - e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation)); - if (!e) - return; - - e->win = xpre->window; - e->time = xpre->time; - e->subtype = xpre->kind; - e->num_fingers = xpre->num_finger; - e->distance = xpre->distance; - e->cx = xpre->cx; - e->cy = xpre->cy; - e->zoom = XFixedToDouble(xpre->zoom); - e->angle = XFixedToDouble(xpre->angle); - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL); -} - -void -_ecore_x_event_handle_gesture_notify_tap(XEvent *xevent) -{ - XGestureNotifyTapEvent *xte; - Ecore_X_Event_Gesture_Notify_Tap *e; - - _ecore_x_last_event_mouse_move = 0; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xte = (XGestureNotifyTapEvent *)xevent; - e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap)); - if (!e) - return; - - e->win = xte->window; - e->time = xte->time; - e->subtype = xte->kind; - e->num_fingers = xte->num_finger; - e->cx = xte->cx; - e->cy = xte->cy; - e->tap_repeat = xte->tap_repeat; - e->interval = xte->interval; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL); -} - -void -_ecore_x_event_handle_gesture_notify_tapnhold(XEvent *xevent) -{ - XGestureNotifyTapNHoldEvent *xthe; - Ecore_X_Event_Gesture_Notify_TapNHold *e; - - _ecore_x_last_event_mouse_move = 0; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xthe = (XGestureNotifyTapNHoldEvent *)xevent; - e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold)); - if (!e) - return; - - e->win = xthe->window; - e->time = xthe->time; - e->subtype = xthe->kind; - e->num_fingers = xthe->num_finger; - e->cx = xthe->cx; - e->cy = xthe->cy; - e->interval = xthe->interval; - e->hold_time = xthe->holdtime; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL); -} - -void -_ecore_x_event_handle_gesture_notify_hold(XEvent *xevent) -{ - XGestureNotifyHoldEvent *xhe; - Ecore_X_Event_Gesture_Notify_Hold *e; - - _ecore_x_last_event_mouse_move = 0; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xhe = (XGestureNotifyHoldEvent *)xevent; - e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold)); - if (!e) - return; - - e->win = xhe->window; - e->time = xhe->time; - e->subtype = xhe->kind; - e->num_fingers = xhe->num_finger; - e->cx = xhe->cx; - e->cy = xhe->cy; - e->hold_time = xhe->holdtime; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL); -} - -void -_ecore_x_event_handle_gesture_notify_group(XEvent *xevent) -{ - XGestureNotifyGroupEvent *xge; - Ecore_X_Event_Gesture_Notify_Group *e; - - _ecore_x_last_event_mouse_move = 0; - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - xge = (XGestureNotifyGroupEvent *)xevent; - e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group)); - if (!e) - return; - - e->win = xge->window; - e->time = xge->time; - e->subtype = xge->kind; - e->num_groups = xge->num_group; - e->group_id = xge->groupid; - - ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL); -} - -#endif /* ifdef ECORE_XGESTURE */ -#ifdef ECORE_XKB -void -_ecore_x_event_handle_xkb(XEvent *xevent) -{ - XkbEvent *xkbev; - Ecore_X_Event_Xkb *e; - - xkbev = (XkbEvent *) xevent; - e = calloc(1, sizeof(Ecore_X_Event_Xkb)); - if (!e) - return; - e->group = xkbev->state.group; - if (xkbev->any.xkb_type == XkbStateNotify) - ecore_event_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, e, NULL, NULL); - else if ((xkbev->any.xkb_type == XkbNewKeyboardNotify) || - (xkbev->any.xkb_type == XkbMapNotify)) - { - if (xkbev->any.xkb_type == XkbMapNotify) - { - XkbMapNotifyEvent *xkbmapping; - - xkbmapping = (XkbMapNotifyEvent *)xkbev; - XkbRefreshKeyboardMapping(xkbmapping); - } - ecore_event_add(ECORE_X_EVENT_XKB_NEWKBD_NOTIFY, e, NULL, NULL); - } -} -#endif /* ifdef ECORE_XKB */ diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_fixes.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_fixes.c deleted file mode 100644 index da0a6c3ac9..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_fixes.c +++ /dev/null @@ -1,365 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - -#include "ecore_x_private.h" -#include "Ecore_X.h" - -static int _fixes_available; -#ifdef ECORE_XFIXES -static int _fixes_major, _fixes_minor; -#endif /* ifdef ECORE_XFIXES */ - -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; - - ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = ecore_event_type_new(); - } - else - _fixes_available = 0; - -#else /* ifdef ECORE_XFIXES */ - _fixes_available = 0; -#endif /* ifdef ECORE_XFIXES */ -} - -#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 /* ifdef ECORE_XFIXES */ - -EAPI Eina_Bool -ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection) -{ -#ifdef ECORE_XFIXES - if (_fixes_available) - { - XFixesSelectSelectionInput (_ecore_x_disp, - DefaultRootWindow(_ecore_x_disp), - selection, - XFixesSetSelectionOwnerNotifyMask | - XFixesSelectionWindowDestroyNotifyMask | - XFixesSelectionClientCloseNotifyMask); - return EINA_TRUE; - } -#endif - return EINA_FALSE; -} - -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 /* ifdef ECORE_XFIXES */ - return 0; -#endif /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ - return 0; -#endif /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ - return 0; -#endif /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ - return 0; -#endif /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ - return 0; -#endif /* ifdef ECORE_XFIXES */ -} - -EAPI void -ecore_x_region_free(Ecore_X_Region region) -{ -#ifdef ECORE_XFIXES - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XFixesDestroyRegion(_ecore_x_disp, region); -#endif /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ - return NULL; -#endif /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - -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 /* ifdef ECORE_XFIXES */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_gc.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_gc.c deleted file mode 100644 index 539636648f..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_gc.c +++ /dev/null @@ -1,171 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - -#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 idx; - int i; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!draw) - draw = DefaultRootWindow(_ecore_x_disp); - - memset(&gcv, 0, sizeof (gcv)); - - for (i = 0, idx = 0, mask = 1; i <= 22; i++, mask <<= 1) - { - switch (mask & value_mask) - { - case ECORE_X_GC_VALUE_MASK_FUNCTION: - gcv.function = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_PLANE_MASK: - gcv.plane_mask = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_FOREGROUND: - gcv.foreground = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_BACKGROUND: - gcv.background = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_LINE_WIDTH: - gcv.line_width = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_LINE_STYLE: - gcv.line_style = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_CAP_STYLE: - gcv.cap_style = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_JOIN_STYLE: - gcv.join_style = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_FILL_STYLE: - gcv.fill_style = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_FILL_RULE: - gcv.fill_rule = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_TILE: - gcv.tile = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_STIPPLE: - gcv.stipple = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X: - gcv.ts_x_origin = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y: - gcv.ts_y_origin = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_FONT: - gcv.font = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE: - gcv.subwindow_mode = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES: - gcv.graphics_exposures = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X: - gcv.clip_x_origin = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y: - gcv.clip_y_origin = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_CLIP_MASK: - gcv.clip_mask = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_DASH_OFFSET: - gcv.dash_offset = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_DASH_LIST: - gcv.dashes = value_list[idx]; - idx++; - break; - - case ECORE_X_GC_VALUE_MASK_ARC_MODE: - gcv.arc_mode = value_list[idx]; - idx++; - 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); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_gesture.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_gesture.c deleted file mode 100644 index dbde8b0db2..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_gesture.c +++ /dev/null @@ -1,137 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include "ecore_x_private.h" - -static Eina_Bool _gesture_available = EINA_FALSE; - -#ifdef ECORE_XGESTURE -static int _gesture_major, _gesture_minor, _gesture_patch; -int _gesture_version; -#endif /* ifdef ECORE_XGESTURE */ - -void -_ecore_x_gesture_init(void) -{ -#ifdef ECORE_XGESTURE - _gesture_major = 0; - _gesture_minor = 0; - _gesture_patch = 0; - _gesture_version = 0; - - if (XGestureQueryVersion(_ecore_x_disp, &_gesture_major, &_gesture_minor, &_gesture_patch)) - { - _gesture_version = (_gesture_major << 16) | _gesture_minor; - _gesture_available = EINA_TRUE; - } - else - _gesture_available = EINA_FALSE; -#else /* ifdef ECORE_XGESTURE */ - _gesture_available = EINA_FALSE; -#endif /* ifdef ECORE_XGESTURE */ -} - -/* - * @brief Query whether gesture is available or not. - * - * @return @c EINA_TRUE, if extension is available, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_gesture_supported(void) -{ - return _gesture_available; -} - -EAPI Eina_Bool -ecore_x_gesture_events_select(Ecore_X_Window win, - Ecore_X_Gesture_Event_Mask mask) -{ -#ifdef ECORE_XGESTURE - if (!_gesture_available) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XGestureSelectEvents(_ecore_x_disp, win, mask); - - return EINA_TRUE; -#else /* ifdef ECORE_XGESTURE */ - (void) win; - (void) mask; - return EINA_FALSE; -#endif /* ifdef ECORE_XGESTURE */ -} - -EAPI Ecore_X_Gesture_Event_Mask -ecore_x_gesture_events_selected_get(Ecore_X_Window win) -{ -#ifdef ECORE_XGESTURE - Ecore_X_Gesture_Event_Mask mask; - - if (!_gesture_available) - return ECORE_X_GESTURE_EVENT_MASK_NONE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (GestureSuccess != XGestureGetSelectedEvents(_ecore_x_disp, win, &mask)) - { - mask = ECORE_X_GESTURE_EVENT_MASK_NONE; - return mask; - } - - return mask; -#else /* ifdef ECORE_XGESTURE */ - (void) win; - return ECORE_X_GESTURE_EVENT_MASK_NONE; -#endif /* ifdef ECORE_XGESTURE */ -} - -EAPI Eina_Bool -ecore_x_gesture_event_grab(Ecore_X_Window win, - Ecore_X_Gesture_Event_Type type, - int num_fingers) -{ -#ifdef ECORE_XGESTURE - if (!_gesture_available) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (GestureGrabSuccess != XGestureGrabEvent(_ecore_x_disp, win, type, num_fingers, CurrentTime)) - { - return EINA_FALSE; - } - - return EINA_TRUE; -#else /* ifdef ECORE_XGESTURE */ - (void) win; - (void) type; - (void) num_fingers; - return EINA_FALSE; -#endif /* ifdef ECORE_XGESTURE */ -} - -EAPI Eina_Bool -ecore_x_gesture_event_ungrab(Ecore_X_Window win, - Ecore_X_Gesture_Event_Type type, - int num_fingers) -{ -#ifdef ECORE_XGESTURE - Ecore_X_Gesture_Event_Mask mask; - - if (!_gesture_available) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (GestureUngrabSuccess != XGestureUngrabEvent(_ecore_x_disp, win, type, num_fingers, CurrentTime)) - { - return EINA_FALSE; - } - - return EINA_TRUE; -#else /* ifdef ECORE_XGESTURE */ - (void) win; - (void) type; - (void) num_fingers; - return EINA_FALSE; -#endif /* ifdef ECORE_XGESTURE */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c deleted file mode 100644 index 8d6ea1f50e..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_icccm.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * Various ICCCM related functions. - * - * This is ALL the code involving anything ICCCM related. for both WM and - * client. - */ - -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include -#include - -#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, - Eina_Bool 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, - Eina_Bool 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 Eina_Bool -ecore_x_icccm_hints_get(Ecore_X_Window win, - Eina_Bool *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, - Eina_Bool *is_urgent) -{ - XWMHints *hints; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (accepts_focus) - *accepts_focus = EINA_TRUE; - - 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 = EINA_FALSE; - - hints = XGetWMHints(_ecore_x_disp, win); - if (hints) - { - if ((hints->flags & InputHint) && (accepts_focus)) - { - if (hints->input) - *accepts_focus = EINA_TRUE; - else - *accepts_focus = EINA_FALSE; - } - - 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 = EINA_TRUE; - - XFree(hints); - return EINA_TRUE; - } - - return EINA_FALSE; -} - -EAPI void -ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, - Eina_Bool 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 Eina_Bool -ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, - Eina_Bool *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 EINA_FALSE; - - if ((hint.flags & USPosition) || ((hint.flags & PPosition))) - { - if (request_pos) - *request_pos = EINA_TRUE; - } - else if (request_pos) - *request_pos = EINA_FALSE; - - 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 EINA_TRUE; -} - -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 /* ifdef X_HAVE_UTF8_STRING */ - list[0] = strdup(t); - ret = - XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle, - &xprop); -#endif /* ifdef X_HAVE_UTF8_STRING */ - 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 /* ifdef X_HAVE_UTF8_STRING */ - ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop, - &list, &num); -#endif /* ifdef X_HAVE_UTF8_STRING */ - - 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, - Eina_Bool 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 Eina_Bool -ecore_x_icccm_protocol_isset(Ecore_X_Window win, - Ecore_X_WM_Protocol protocol) -{ - Atom proto, *protos = NULL; - int i, protos_count = 0; - Eina_Bool ret = EINA_FALSE; - - /* check for invalid values */ - if (protocol >= ECORE_X_WM_PROTOCOL_NUM) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - proto = _ecore_x_atoms_wm_protocols[protocol]; - - if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count)) - return EINA_FALSE; - - for (i = 0; i < protos_count; i++) - if (protos[i] == proto) - { - ret = EINA_TRUE; - 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 /* ifdef X_HAVE_UTF8_STRING */ - list[0] = strdup(t); - ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1, - XStdICCTextStyle, &xprop); -#endif /* ifdef X_HAVE_UTF8_STRING */ - 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 /* ifdef X_HAVE_UTF8_STRING */ - ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop, - &list, &num); -#endif /* ifdef X_HAVE_UTF8_STRING */ - - 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 win 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 */ diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_image.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_image.c deleted file mode 100644 index def81104a2..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_image.c +++ /dev/null @@ -1,626 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include -#include -#include -#include - -#include "ecore_x_private.h" -#include "Ecore_X.h" - -#include -#include - -static int _ecore_x_image_shm_can = -1; -static int _ecore_x_image_err = 0; - -static int -_ecore_x_image_error_handler(Display *d EINA_UNUSED, - XErrorEvent *ev EINA_UNUSED) -{ - _ecore_x_image_err = 1; - return 0; -} - -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)) - { - 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) -{ - Eina_Bool ret = EINA_TRUE; - 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; - XGrabServer(_ecore_x_disp); - if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff)) - ret = EINA_FALSE; - XUngrabServer(_ecore_x_disp); - 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 = EINA_FALSE; - } - else - { - printf("currently unimplemented ecore_x_image_get without shm\n"); - ret = EINA_FALSE; - } - - return ret; -} - -EAPI void -ecore_x_image_put(Ecore_X_Image *im, - Ecore_X_Drawable draw, - Ecore_X_GC gc, - int x, - int y, - int sx, - int sy, - int w, - int h) -{ - Ecore_X_GC tgc = 0; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!gc) - { - XGCValues gcv; - memset(&gcv, 0, sizeof(gcv)); - gcv.subwindow_mode = IncludeInferiors; - tgc = XCreateGC(_ecore_x_disp, draw, GCSubwindowMode, &gcv); - gc = tgc; - } - if (!im->xim) _ecore_x_image_shm_create(im); - if (im->xim) - XShmPutImage(_ecore_x_disp, draw, gc, im->xim, sx, sy, x, y, w, h, False); - if (tgc) ecore_x_gc_free(tgc); -} - -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; -} - -EAPI Eina_Bool -ecore_x_image_is_argb32_get(Ecore_X_Image *im) -{ - Visual *vis = im->vis; - if (!im->xim) _ecore_x_image_shm_create(im); - if (((vis->class == TrueColor) || - (vis->class == DirectColor)) && - (im->depth >= 24) && - (vis->red_mask == 0xff0000) && - (vis->green_mask == 0x00ff00) && - (vis->blue_mask == 0x0000ff)) - { -#ifdef WORDS_BIGENDIAN - if (im->xim->bitmap_bit_order == MSBFirst) return EINA_TRUE; -#else - if (im->xim->bitmap_bit_order == LSBFirst) return EINA_TRUE; -#endif - } - return EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_image_to_argb_convert(void *src, - int sbpp, - int sbpl, - Ecore_X_Colormap c, - Ecore_X_Visual v, - int x, - int y, - int w, - int h, - unsigned int *dst, - int dbpl, - int dx, - int dy) -{ - Visual *vis = v; - XColor *cols = NULL; - int n = 0, nret = 0, i, row; - unsigned int pal[256], r, g, b; - enum - { - rgbnone = 0, - rgb565, - bgr565, - rgbx555, - argbx888, - abgrx888, - rgba888x, - bgra888x, - argbx666 - }; - int mode = 0; - - sbpp *= 8; - - n = vis->map_entries; - if ((n <= 256) && - ((vis->class == PseudoColor) || - (vis->class == StaticColor) || - (vis->class == GrayScale) || - (vis->class == StaticGray))) - { - if (!c) - c = DefaultColormap(_ecore_x_disp, - DefaultScreen(_ecore_x_disp)); - cols = alloca(n * sizeof(XColor)); - for (i = 0; i < n; i++) - { - cols[i].pixel = i; - cols[i].flags = DoRed | DoGreen | DoBlue; - cols[i].red = 0; - cols[i].green = 0; - cols[i].blue = 0; - } - XQueryColors(_ecore_x_disp, c, cols, n); - for (i = 0; i < n; i++) - { - pal[i] = 0xff000000 | - ((cols[i].red >> 8) << 16) | - ((cols[i].green >> 8) << 8) | - ((cols[i].blue >> 8)); - } - nret = n; - } - else if ((vis->class == TrueColor) || - (vis->class == DirectColor)) - { - if ((vis->red_mask == 0x00ff0000) && - (vis->green_mask == 0x0000ff00) && - (vis->blue_mask == 0x000000ff)) - mode = argbx888; - else if ((vis->red_mask == 0x000000ff) && - (vis->green_mask == 0x0000ff00) && - (vis->blue_mask == 0x00ff0000)) - mode = abgrx888; - else if ((vis->red_mask == 0xff000000) && - (vis->green_mask == 0x00ff0000) && - (vis->blue_mask == 0x0000ff00)) - mode = rgba888x; - else if ((vis->red_mask == 0x0000ff00) && - (vis->green_mask == 0x00ff0000) && - (vis->blue_mask == 0xff000000)) - mode = bgra888x; - else if ((vis->red_mask == 0x0003f000) && - (vis->green_mask == 0x00000fc0) && - (vis->blue_mask == 0x0000003f)) - mode = argbx666; - else if ((vis->red_mask == 0x0000f800) && - (vis->green_mask == 0x000007e0) && - (vis->blue_mask == 0x0000001f)) - mode = rgb565; - else if ((vis->red_mask == 0x0000001f) && - (vis->green_mask == 0x000007e0) && - (vis->blue_mask == 0x0000f800)) - mode = bgr565; - else if ((vis->red_mask == 0x00007c00) && - (vis->green_mask == 0x000003e0) && - (vis->blue_mask == 0x0000001f)) - mode = rgbx555; - else - return EINA_FALSE; - } - for (row = 0; row < h; row++) - { - unsigned char *s8; - unsigned short *s16; - unsigned int *s32; - unsigned int *dp, *de; - - dp = ((unsigned int *)(((unsigned char *)dst) + - ((dy + row) * dbpl))) + dx; - de = dp + w; - switch (sbpp) - { - case 8: - s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; - if (nret > 0) - { - while (dp < de) - { - *dp = pal[*s8]; - s8++; dp++; - } - } - else - return EINA_FALSE; - break; - - case 16: - s16 = ((unsigned short *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; - switch (mode) - { - case rgb565: - while (dp < de) - { - r = (*s16 & 0xf800) << 8; - g = (*s16 & 0x07e0) << 5; - b = (*s16 & 0x001f) << 3; - r |= (r >> 5) & 0xff0000; - g |= (g >> 6) & 0x00ff00; - b |= (b >> 5); - *dp = 0xff000000 | r | g | b; - s16++; dp++; - } - break; - - case bgr565: - while (dp < de) - { - r = (*s16 & 0x001f) << 19; - g = (*s16 & 0x07e0) << 5; - b = (*s16 & 0xf800) >> 8; - r |= (r >> 5) & 0xff0000; - g |= (g >> 6) & 0x00ff00; - b |= (b >> 5); - *dp = 0xff000000 | r | g | b; - s16++; dp++; - } - break; - - case rgbx555: - while (dp < de) - { - r = (*s16 & 0x7c00) << 9; - g = (*s16 & 0x03e0) << 6; - b = (*s16 & 0x001f) << 3; - r |= (r >> 5) & 0xff0000; - g |= (g >> 5) & 0x00ff00; - b |= (b >> 5); - *dp = 0xff000000 | r | g | b; - s16++; dp++; - } - break; - - default: - return EINA_FALSE; - break; - } - break; - - case 24: - case 32: - s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; - switch (mode) - { - case argbx888: - while (dp < de) - { - *dp = 0xff000000 | *s32; - s32++; dp++; - } - break; - - case abgrx888: - while (dp < de) - { - r = *s32 & 0x000000ff; - g = *s32 & 0x0000ff00; - b = *s32 & 0x00ff0000; - *dp = 0xff000000 | (r << 16) | (g) | (b >> 16); - s32++; dp++; - } - break; - - case rgba888x: - while (dp < de) - { - *dp = 0xff000000 | (*s32 >> 8); - s32++; dp++; - } - break; - - case bgra888x: - while (dp < de) - { - r = *s32 & 0x0000ff00; - g = *s32 & 0x00ff0000; - b = *s32 & 0xff000000; - *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24); - s32++; dp++; - } - break; - - case argbx666: - while (dp < de) - { - r = (*s32 & 0x3f000) << 6; - g = (*s32 & 0x00fc0) << 4; - b = (*s32 & 0x0003f) << 2; - r |= (r >> 6) & 0xff0000; - g |= (g >> 6) & 0x00ff00; - b |= (b >> 6); - *dp = 0xff000000 | r | g | b; - s32++; dp++; - } - break; - - default: - return EINA_FALSE; - break; - } - break; - break; - - default: - return EINA_FALSE; - break; - } - } - return EINA_TRUE; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_mwm.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_mwm.c deleted file mode 100644 index 7812cc23ae..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_mwm.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Various MWM related functions. - * - * This is ALL the code involving anything MWM related. for both WM and - * client. - */ - -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - -#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 Eina_Bool -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; - Eina_Bool ret; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ret = EINA_FALSE; - if (!ecore_x_window_prop_property_get(win, - ECORE_X_ATOM_MOTIF_WM_HINTS, - ECORE_X_ATOM_MOTIF_WM_HINTS, - 32, &p, &num)) - return EINA_FALSE; - - 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 = EINA_TRUE; - } - - free(mwmhints); - } - - return ret; -} - -EAPI void -ecore_x_mwm_borderless_set(Ecore_X_Window win, - Eina_Bool 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); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c deleted file mode 100644 index 3f08af8b9c..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_netwm.c +++ /dev/null @@ -1,2083 +0,0 @@ -/* - * _NET_WM... aka Extended Window Manager Hint (EWMH) functions. - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#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 /* if 0 */ -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(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); - ecore_x_window_prop_window_set(root, - ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, - &check, - 1); -} - -/* - * 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 Eina_Bool -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 EINA_FALSE; - - if (num) - *num = num_ret; - - return EINA_TRUE; -} - -/* - * 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, *t; - 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-" */ - sprintf(ss, "Desk-%d", i); - s = ss; - } - - l = strlen(s) + 1; - t = realloc(buf, len + l); - if (t) - { - buf = t; - 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 unsigned int * -ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks) -{ - int ret; - unsigned int *areas = NULL; - - if (!root) root = DefaultRootWindow(_ecore_x_disp); - - ret = ecore_x_window_prop_card32_list_get(root, ECORE_X_ATOM_NET_WORKAREA, - &areas); - if (!areas) - { - if (n_desks) *n_desks = 0; - return 0; - } - if (n_desks) *n_desks = ret / 4; - return areas; -} - -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, - Eina_Bool 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 Eina_Bool -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 ? EINA_TRUE : EINA_FALSE; -} - -/* - * _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 Eina_Bool -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 EINA_FALSE; - - if (left) - *left = strut[0]; - - if (right) - *right = strut[1]; - - if (top) - *top = strut[2]; - - if (bottom) - *bottom = strut[3]; - - return EINA_TRUE; -} - -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 Eina_Bool -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 EINA_FALSE; - - 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 EINA_TRUE; -} - -EAPI void -ecore_x_netwm_icons_set(Ecore_X_Window win, - Ecore_X_Icon *icon, - int num) -{ - unsigned int *data, *p, *p2; - unsigned int i, size, x, y; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - size = 0; - for (i = 0; i < (unsigned int)num; i++) - { - size += 2 + (icon[i].width * icon[i].height); - } - data = malloc(size * sizeof(unsigned int)); - if (!data) return; - p = data; - for (i = 0; i < (unsigned int)num; i++) - { - p[0] = icon[i].width; - p[1] = icon[i].height; - p += 2; - p2 = icon[i].data; - for (y = 0; y < icon[i].height; y++) - { - for (x = 0; x < icon[i].width; x++) - { - unsigned int r, g, b, a; - - a = (*p2 >> 24) & 0xff; - r = (*p2 >> 16) & 0xff; - g = (*p2 >> 8 ) & 0xff; - b = (*p2 ) & 0xff; - if ((a > 0) && (a < 255)) - { - // unpremul - r = (r * 255) / a; - g = (g * 255) / a; - b = (b * 255) / a; - } - *p = (a << 24) | (r << 16) | (g << 8) | b; - p++; - p2++; - } - } - } - ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON, - data, size); - free(data); -} - -EAPI Eina_Bool -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 EINA_FALSE; - - if (!data) - return EINA_FALSE; - - if (num_ret < 2) - { - free(data); - return EINA_FALSE; - } - - /* 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 EINA_FALSE; - } - - 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 EINA_TRUE; - } - - /* Allocate memory */ - *icon = malloc(icons * sizeof(Ecore_X_Icon)); - if (!(*icon)) - { - free(data); - return EINA_FALSE; - } - - /* 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 EINA_FALSE; - } - - 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 EINA_TRUE; -} - -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 Eina_Bool -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 EINA_FALSE; - - if (x) - *x = geometry[0]; - - if (y) - *y = geometry[1]; - - if (width) - *width = geometry[2]; - - if (height) - *height = geometry[3]; - - return EINA_TRUE; -} - -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 Eina_Bool -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 ? EINA_TRUE : EINA_FALSE; -} - -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 Eina_Bool -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 ? EINA_TRUE : EINA_FALSE; -} - -EAPI void -ecore_x_netwm_user_time_set(Ecore_X_Window win, - unsigned int tim) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME, - &tim, 1); -} - -EAPI Eina_Bool -ecore_x_netwm_user_time_get(Ecore_X_Window win, - unsigned int *tim) -{ - 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 (tim) - *tim = tmp; - - return ret == 1 ? EINA_TRUE : EINA_FALSE; -} - -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 Eina_Bool -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 EINA_FALSE; - - 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 EINA_TRUE; -} - -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 Eina_Bool -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 EINA_TRUE; - - return EINA_FALSE; -} - -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 Eina_Bool -ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, - Ecore_X_Action action) -{ - int num, i; - Ecore_X_Atom *atoms, atom; - Eina_Bool ret = EINA_FALSE; - - 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 Eina_Bool -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 EINA_FALSE; - - 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 EINA_TRUE; -} - -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 Eina_Bool -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 ? EINA_TRUE : EINA_FALSE; -} - -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 Eina_Bool -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 EINA_FALSE; - - if (fl) - *fl = frames[0]; - - if (fr) - *fr = frames[1]; - - if (ft) - *ft = frames[2]; - - if (fb) - *fb = frames[3]; - - return EINA_TRUE; -} - -EAPI Eina_Bool -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 ? EINA_TRUE : EINA_FALSE; -} - -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, - Eina_Bool 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); -} - -EAPI void -ecore_x_netwm_moveresize_request_send(Ecore_X_Window win, - int x, - int y, - Ecore_X_Netwm_Direction direction, - unsigned int button) -{ - XEvent xev; - - if (!win) - return; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - xev.xclient.window = win; - xev.xclient.type = ClientMessage; - xev.xclient.message_type = ECORE_X_ATOM_NET_WM_MOVERESIZE; - xev.xclient.format = 32; - xev.xclient.data.l[0] = x; - xev.xclient.data.l[1] = y; - xev.xclient.data.l[2] = direction; - xev.xclient.data.l[3] = button; - xev.xclient.data.l[4] = 1; - - XSendEvent(_ecore_x_disp, win, False, - SubstructureNotifyMask | SubstructureRedirectMask, &xev); -} - -int -_ecore_x_netwm_startup_info_begin(Ecore_X_Window win EINA_UNUSED, - char *data EINA_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 /* if 0 */ - return 1; -} - -int -_ecore_x_netwm_startup_info(Ecore_X_Window win EINA_UNUSED, - char *data EINA_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 /* if 0 */ - 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 /* if 0 */ - -/* - * 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 Eina_Bool -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 EINA_FALSE; - - win = XGetSelectionOwner(_ecore_x_disp, atom); - - return (win != None) ? EINA_TRUE : EINA_FALSE; -} - -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); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_pixmap.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_pixmap.c deleted file mode 100644 index 7b13615675..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_pixmap.c +++ /dev/null @@ -1,121 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#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); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_private.h b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_private.h deleted file mode 100644 index f962ffb4b2..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_private.h +++ /dev/null @@ -1,379 +0,0 @@ -#ifndef _ECORE_X_PRIVATE_H -#define _ECORE_X_PRIVATE_H - -#include -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif /* ifndef MAXHOSTNAMELEN */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef ECORE_XCURSOR -#include -#endif /* ifdef ECORE_XCURSOR */ -#ifdef ECORE_XPRINT -#include -#endif /* ifdef ECORE_XPRINT */ -#ifdef ECORE_XINERAMA -#include -#endif /* ifdef ECORE_XINERAMA */ -#ifdef ECORE_XRANDR -#include -#endif /* ifdef ECORE_XRANDR */ -#ifdef ECORE_XSS -#include -#endif /* ifdef ECORE_XSS */ -#ifdef ECORE_XRENDER -#include -#endif /* ifdef ECORE_XRENDER */ -#ifdef ECORE_XFIXES -#include -#endif /* ifdef ECORE_XFIXES */ -#ifdef ECORE_XCOMPOSITE -#include -#endif /* ifdef ECORE_XCOMPOSITE */ -#ifdef ECORE_XDAMAGE -#include -#endif /* ifdef ECORE_XDAMAGE */ -#ifdef ECORE_XGESTURE -#include -#include -#endif /* ifdef ECORE_XGESTURE */ -#ifdef ECORE_XDPMS -#include -#endif /* ifdef ECORE_XDPMS */ -#ifdef ECORE_XKB -#include -#endif /* ifdef ECORE_XKB */ -#ifdef ECORE_XI2 -#include -#endif /* ifdef ECORE_XI2 */ - -#ifndef XK_MISCELLANY -# define XK_MISCELLANY 1 -#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 /* ifdef ECORE_XLIB_DEFAULT_LOG_COLOR */ -#define ECORE_XLIB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE - -#ifdef ERR -# undef ERR -#endif /* ifdef ERR */ -#define ERR(...) EINA_LOG_DOM_ERR(_ecore_xlib_log_dom, __VA_ARGS__) - -#ifdef DBG -# undef DBG -#endif /* ifdef DBG */ -#define DBG(...) EINA_LOG_DOM_DBG(_ecore_xlib_log_dom, __VA_ARGS__) - -#ifdef INF -# undef INF -#endif /* ifdef INF */ -#define INF(...) EINA_LOG_DOM_INFO(_ecore_xlib_log_dom, __VA_ARGS__) - -#ifdef WRN -# undef WRN -#endif /* ifdef WRN */ -#define WRN(...) EINA_LOG_DOM_WARN(_ecore_xlib_log_dom, __VA_ARGS__) - -#ifdef CRIT -# undef CRIT -#endif /* ifdef CRIT */ -#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; - Eina_Bool (*convert)(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *type, int *typeseize); - 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 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 Eina_Bool _ecore_x_xcursor; - -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 Eina_Bool (*_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); -#ifdef ECORE_XGESTURE -void _ecore_x_event_handle_gesture_notify_flick(XEvent *xevent); -void _ecore_x_event_handle_gesture_notify_pan(XEvent *xevent); -void _ecore_x_event_handle_gesture_notify_pinchrotation(XEvent *xevent); -void _ecore_x_event_handle_gesture_notify_tap(XEvent *xevent); -void _ecore_x_event_handle_gesture_notify_tapnhold(XEvent *xevent); -void _ecore_x_event_handle_gesture_notify_hold(XEvent *xevent); -void _ecore_x_event_handle_gesture_notify_group(XEvent *xevent); -#endif /* ifdef ECORE_XGESTURE */ -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_XRANDR */ -#ifdef ECORE_XFIXES -void _ecore_x_event_handle_fixes_selection_notify(XEvent *xevent); -#endif /* ifdef ECORE_XFIXES */ -#ifdef ECORE_XDAMAGE -void _ecore_x_event_handle_damage_notify(XEvent *xevent); -#endif /* ifdef ECORE_XDAMAGE */ -#ifdef ECORE_XKB -void _ecore_x_event_handle_xkb(XEvent *xevent); -#endif /* ifdef ECORE_XKB */ -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); -Eina_Bool _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, - Ecore_X_Atom *targettype, - int *targetsize); -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_gesture_init(void); - -void _ecore_x_atoms_init(void); - -extern int _ecore_x_xi2_opcode; - -void _ecore_x_events_init(void); -void _ecore_x_events_shutdown(void); - -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); - -void _ecore_x_modifiers_get(void); -KeySym _ecore_x_XKeycodeToKeysym(Display *display, KeyCode keycode, int index); - -//#define LOGFNS 1 - -#ifdef LOGFNS -#include -#define LOGFN(fl, ln, fn) printf("-ECORE-X: %25s: %5i - %s\n", fl, ln, fn); -#else /* ifdef LOGFNS */ -#define LOGFN(fl, ln, fn) -#endif /* ifdef LOGFNS */ - -#endif /* ifndef _ECORE_X_PRIVATE_H */ diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr.c deleted file mode 100644 index 58a28305ac..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr.c +++ /dev/null @@ -1,103 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include "ecore_x_private.h" -#include "ecore_x_randr.h" - -static Eina_Bool _randr_available = EINA_FALSE; -#ifdef ECORE_XRANDR -static int _randr_major, _randr_minor; -int _randr_version; -#define RANDR_1_1 ((1 << 16) | 1) -#define RANDR_1_2 ((1 << 16) | 2) -#define RANDR_1_3 ((1 << 16) | 3) - -#define RANDR_VALIDATE_ROOT(screen, \ - root) ((screen = \ - XRRRootToScreen(_ecore_x_disp, \ - root)) != -1) - -#define Ecore_X_Randr_Unset -1 - -XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * dpy, - Window window); - -#endif /* ifdef ECORE_XRANDR */ - -void -_ecore_x_randr_init(void) -{ -#ifdef ECORE_XRANDR - _randr_major = 1; - _randr_minor = 3; - _randr_version = 0; - - _ecore_x_randr_get_screen_resources = NULL; - if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor)) - { - _randr_version = (_randr_major << 16) | _randr_minor; - if (_randr_version >= RANDR_1_3) - _ecore_x_randr_get_screen_resources = XRRGetScreenResourcesCurrent; - else if (_randr_version == RANDR_1_2) - _ecore_x_randr_get_screen_resources = XRRGetScreenResources; - - _randr_available = EINA_TRUE; - } - else - _randr_available = EINA_FALSE; - -#else - _randr_available = EINA_FALSE; -#endif -} - -/* - * @brief Query whether randr is available or not. - * - * @return @c EINA_TRUE, if extension is available, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_randr_query(void) -{ - return _randr_available; -} - -/* - * @return version of the RandR extension supported by the server or, in case - * RandR extension is not available, Ecore_X_Randr_Unset (=-1). - * bit version information: 31 MAJOR 16 | 15 MINOR 0 - */ -EAPI int -ecore_x_randr_version_get(void) -{ -#ifdef ECORE_XRANDR - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (_randr_available) - { - return _randr_version; - } - else - { - return Ecore_X_Randr_Unset; - } -#else - return -1; -#endif -} - -Eina_Bool -_ecore_x_randr_root_validate(Ecore_X_Window root) -{ -#ifdef ECORE_XRANDR - Ecore_X_Randr_Screen scr = -1; - if (root && RANDR_VALIDATE_ROOT(scr, root)) - return EINA_TRUE; - else - return EINA_FALSE; - -#else - return EINA_FALSE; -#endif -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr.h b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr.h deleted file mode 100644 index eca3c0c32c..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef ECORE_X_INLINE_X -#define ECORE_X_INLINE_X -Eina_Bool _ecore_x_randr_root_validate(Ecore_X_Window root); -Eina_Bool _ecore_x_randr_output_validate(Ecore_X_Window root, - Ecore_X_Randr_Output - output); -#endif diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_11.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_11.c deleted file mode 100644 index 7d2b3b34b5..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_11.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2 - */ - -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include "ecore_x_private.h" -#include "ecore_x_randr.h" -#include -#include -#include -#include - -#define Ecore_X_Randr_None 0 -#ifdef ECORE_XRANDR - -#define RANDR_1_1 ((1 << 16) | 1) - -#define RANDR_VALIDATE_ROOT(screen, \ - root) ((screen = \ - XRRRootToScreen(_ecore_x_disp, \ - root)) != -1) -#define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) \ - return ret - -extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * - dpy, - Window - window); -extern int _randr_version; -#endif /* ifdef ECORE_XRANDR */ - -/* - * @param root window which's primary output will be queried - */ -EAPI Ecore_X_Randr_Orientation -ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root) -{ -#ifdef ECORE_XRANDR - Rotation rot = Ecore_X_Randr_None, crot; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - rot = - XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, - root), &crot); - return rot; -#else /* ifdef ECORE_XRANDR */ - return Ecore_X_Randr_None; -#endif /* ifdef ECORE_XRANDR */ -} - -/* - * @param root window which's primary output will be queried - * @return the current orientation of the root window's screen primary output - */ -EAPI Ecore_X_Randr_Orientation -ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root) -{ -#ifdef ECORE_XRANDR - Rotation crot = Ecore_X_Randr_None; - XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, - root), &crot); - return crot; -#else /* ifdef ECORE_XRANDR */ - return Ecore_X_Randr_None; -#endif /* ifdef ECORE_XRANDR */ -} - -/* - * @brief Sets a given screen's primary output's orientation. - * - * @param root Window which's screen's primary output will be queried. - * @param orientation orientation which should be set for the root window's - * screen primary output. - * @return @c EINA_TRUE if the primary output's orientation could be - * successfully altered. - */ -EAPI Eina_Bool -ecore_x_randr_screen_primary_output_orientation_set( - Ecore_X_Window root, - Ecore_X_Randr_Orientation - orientation) -{ -#ifdef ECORE_XRANDR - XRRScreenConfiguration *xrr_screen_cfg = NULL; - int sizeid; - Rotation crot; - Eina_Bool ret = EINA_FALSE; - if (!(xrr_screen_cfg = XRRGetScreenInfo(_ecore_x_disp, root))) - return EINA_FALSE; - - sizeid = XRRConfigCurrentConfiguration(xrr_screen_cfg, &crot); - if (!XRRSetScreenConfig(_ecore_x_disp, xrr_screen_cfg, root, sizeid, - orientation, CurrentTime)) - ret = EINA_TRUE; - - if (xrr_screen_cfg) - XRRFreeScreenConfigInfo(xrr_screen_cfg); - - return ret; -#else /* ifdef ECORE_XRANDR */ - return EINA_FALSE; -#endif /* ifdef ECORE_XRANDR */ -} - -/* - * @brief gets a screen's primary output's possible sizes - * @param root window which's primary output will be queried - * @param num number of sizes reported as supported by the screen's primary output - * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL - */ -EAPI Ecore_X_Randr_Screen_Size_MM * -ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, - int *num) -{ -#ifdef ECORE_XRANDR - Ecore_X_Randr_Screen_Size_MM *ret = NULL; - XRRScreenSize *sizes; - int i, n; - - /* we don't have to free sizes, because they're hold in a cache inside X*/ - sizes = - XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, - root), &n); - if ((!sizes) || (n <= 0)) return NULL; - ret = calloc(n, sizeof(Ecore_X_Randr_Screen_Size_MM)); - 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; - ret[i].width_mm = sizes[i].mwidth; - ret[i].height_mm = sizes[i].mheight; - } - return ret; -#else /* ifdef ECORE_XRANDR */ - return NULL; -#endif /* ifdef ECORE_XRANDR */ -} - -EAPI void -ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, - int *w, - int *h, - int *w_mm, - int *h_mm, - int *size_index) -{ -#ifdef ECORE_XRANDR - XRRScreenSize *sizes; - XRRScreenConfiguration *sc = NULL; - int idx; - Rotation orientation; - int n; - - if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root))) - { - ERR("Couldn't get screen information for %d", root); - return; - } - - idx = XRRConfigCurrentConfiguration(sc, &orientation); - - sizes = - XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, - root), &n); - if ((idx < n) && (idx >= 0)) - { - if (w) - *w = sizes[idx].width; - - if (h) - *h = sizes[idx].height; - - if (w_mm) - *w_mm = sizes[idx].mwidth; - - if (h_mm) - *h_mm = sizes[idx].mheight; - - if (size_index) - *size_index = idx; - } - - XRRFreeScreenConfigInfo(sc); -#endif /* ifdef ECORE_XRANDR */ -} - -/* - * @brief Sets a given screen's primary output size, but disables all other - * outputs at the same time. - * - * @param root Window which's primary output will be queried. - * @param size_index Within the list of sizes reported as supported by the root - * window's screen primary output. - * @return @c EINA_TRUE on success, @c EINA_FALSE on failure due to e.g. - * invalid times. - */ -EAPI Eina_Bool -ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, - int size_index) -{ -#ifdef ECORE_XRANDR - XRRScreenConfiguration *sc = NULL; - Eina_Bool ret = EINA_FALSE; - int nsizes = 0; - - if (size_index >= 0 && _ecore_x_randr_root_validate(root)) - { - XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, - root), &nsizes); - - if (size_index < nsizes) - { - sc = XRRGetScreenInfo(_ecore_x_disp, root); - if (!XRRSetScreenConfig(_ecore_x_disp, sc, - root, size_index, - ECORE_X_RANDR_ORIENTATION_ROT_0, CurrentTime)) - { - ret = EINA_TRUE; - } - - if (sc) - XRRFreeScreenConfigInfo(sc); - } - } - - return ret; -#else /* ifdef ECORE_XRANDR */ - return EINA_FALSE; -#endif /* ifdef ECORE_XRANDR */ -} - -/* - * @param root window which's primary output will be queried - * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0 - */ -EAPI Ecore_X_Randr_Refresh_Rate -ecore_x_randr_screen_primary_output_current_refresh_rate_get( - Ecore_X_Window root) -{ -#ifdef ECORE_XRANDR - Ecore_X_Randr_Refresh_Rate ret = 0.0; - XRRScreenConfiguration *sc = NULL; - - if (!_ecore_x_randr_root_validate(root) || - !(sc = XRRGetScreenInfo(_ecore_x_disp, root))) - return ret; - - ret = XRRConfigCurrentRate(sc); - if (sc) - XRRFreeScreenConfigInfo(sc); - - return ret; -#else /* ifdef ECORE_XRANDR */ - return 0.0; -#endif /* ifdef ECORE_XRANDR */ -} - -/* - * @param root window which's primary output will be queried - * @param size_index referencing the size to query valid refresh rates for - * @return currently used refresh rate or - if request failed or RandRR is not available - NULL - */ -EAPI Ecore_X_Randr_Refresh_Rate * -ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, - int size_index, - int *num) -{ -#ifdef ECORE_XRANDR - Ecore_X_Randr_Refresh_Rate *ret = NULL, *rates = NULL; - Ecore_X_Randr_Screen scr; - int n; - - if (num - && RANDR_VALIDATE_ROOT(scr, root) - && (rates = XRRRates(_ecore_x_disp, scr, size_index, &n))) - { - if (rates && (ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * n))) - { - memcpy(ret, rates, (sizeof(Ecore_X_Randr_Refresh_Rate) * n)); - *num = n; - } - } - - return ret; -#else /* ifdef ECORE_XRANDR */ - return NULL; -#endif /* ifdef ECORE_XRANDR */ -} - -//>= 1.1 -/* - * @brief Sets the current primary output's refresh rate. - * - * @param root Window which's primary output will be queried. - * @param size_index Referencing the size to be set. - * @param rate The refresh rate to be set. - * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_randr_screen_primary_output_refresh_rate_set( - Ecore_X_Window root, - int size_index, - Ecore_X_Randr_Refresh_Rate - rate) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_1_RET(EINA_FALSE); - Eina_Bool ret = EINA_FALSE; - XRRScreenConfiguration *sc = NULL; - - if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root))) - return ret; - - if (!XRRSetScreenConfigAndRate(_ecore_x_disp, sc, - root, size_index, - RR_Rotate_0, rate, CurrentTime)) - ret = EINA_TRUE; - - XRRFreeScreenConfigInfo(sc); - return ret; -#else /* ifdef ECORE_XRANDR */ - return EINA_FALSE; -#endif /* ifdef ECORE_XRANDR */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12.c deleted file mode 100644 index 9e937d7bf7..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12.c +++ /dev/null @@ -1,2438 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include "ecore_x_private.h" -#include "ecore_x_randr.h" -#include -#include -#include -#include - -#define Ecore_X_Randr_None (Ecore_X_Randr_Crtc)0 -#define Ecore_X_Randr_Unset (Ecore_X_Randr_Crtc) - 1 - -#ifdef ECORE_XRANDR - -#define RANDR_1_2 ((1 << 16) | 2) - -#define RANDR_VALIDATE_ROOT(screen, root) \ - ((screen = XRRRootToScreen(_ecore_x_disp, root)) != -1) - -#define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) \ - return ret - -#define RANDR_PROPERTY_EDID "EDID" -#define RANDR_PROPERTY_BACKLIGHT "Backlight" -#define RANDR_PROPERTY_SIGNAL_FORMAT "SignalFormat" -#define RANDR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties" -#define RANDR_PROPERTY_CONNECTOR_TYPE "ConnectorType" -#define RANDR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber" -#define RANDR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList" -#define RANDR_PROPERTY_CLONE_LIST "CloneList" - -extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * - dpy, - Window - window); -extern int _randr_version; -#endif - -/** - * @brief Enable event selection. This enables basic interaction with - * output/crtc events and requires RandR >= 1.2. - * - * @param win Select this window's properties for RandR events. - * @param on Enable/disable selecting. - */ -EAPI void -ecore_x_randr_events_select(Ecore_X_Window win, - Eina_Bool 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); -#endif -} - -/** - * @brief Validates a CRTC for a given root window's screen. - * - * @param root The window which's default display will be queried. - * @param crtc The CRTC to be validated. - * @return In case it is found, @c EINA_TRUE will be returned, @c EINA_FALSE - * otherwise. - */ -static inline Eina_Bool -_ecore_x_randr_crtc_validate(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - XRRScreenResources *res = NULL; - int i; - Eina_Bool ret = EINA_FALSE; - - if ((crtc == Ecore_X_Randr_None) || - (crtc == Ecore_X_Randr_Unset)) - return ret; - - if (_ecore_x_randr_root_validate(root) && crtc && - (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - { - for (i = 0; i < res->ncrtc; i++) - { - if (res->crtcs[i] == crtc) - { - ret = EINA_TRUE; - break; - } - } - XRRFreeScreenResources(res); - } - - return ret; -#else - return EINA_FALSE; -#endif -} - -Eina_Bool -_ecore_x_randr_output_validate(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - Eina_Bool ret = EINA_FALSE; - XRRScreenResources *res = NULL; - int i; - - if (_ecore_x_randr_root_validate(root) && output && - (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - { - for (i = 0; i < res->noutput; i++) - { - if (res->outputs[i] == output) - { - ret = EINA_TRUE; - break; - } - } - XRRFreeScreenResources(res); - } - - return ret; -#else - return EINA_FALSE; -#endif -} - -static inline Eina_Bool -_ecore_x_randr_mode_validate(Ecore_X_Window root, - Ecore_X_Randr_Mode mode) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - Eina_Bool ret = EINA_FALSE; - XRRScreenResources *res = NULL; - int i; - - if (_ecore_x_randr_root_validate(root) && mode && - (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - { - for (i = 0; i < res->nmode; i++) - { - if (res->modes[i].id == mode) - { - ret = EINA_TRUE; - break; - } - } - XRRFreeScreenResources(res); - } - - return ret; -#else - return EINA_FALSE; -#endif -} - -/* - * @param w width of screen in px - * @param h height of screen in px - */ -EAPI void -ecore_x_randr_screen_current_size_get(Ecore_X_Window root, - int *w, - int *h, - int *w_mm, - int *h_mm) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - Ecore_X_Randr_Screen scr; - - if (!RANDR_VALIDATE_ROOT(scr, root)) - return; - - if (w) - *w = DisplayWidth(_ecore_x_disp, scr); - - if (h) - *h = DisplayHeight(_ecore_x_disp, scr); - - if (w_mm) - *w_mm = DisplayWidthMM(_ecore_x_disp, scr); - - if (h_mm) - *h_mm = DisplayHeightMM(_ecore_x_disp, scr); - -#endif -} - -/* - * @param root window which's screen will be queried - * @param wmin minimum width the screen can be set to - * @param hmin minimum height the screen can be set to - * @param wmax maximum width the screen can be set to - * @param hmax maximum height the screen can be set to - */ -EAPI void -ecore_x_randr_screen_size_range_get(Ecore_X_Window root, - int *wmin, - int *hmin, - int *wmax, - int *hmax) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - int twmin, thmin, twmax, thmax; - if (XRRGetScreenSizeRange (_ecore_x_disp, root, &twmin, &thmin, &twmax, - &thmax)) - { - if (wmin) - *wmin = twmin; - - if (hmin) - *hmin = thmin; - - if (wmax) - *wmax = twmax; - - if (hmax) - *hmax = thmax; - } - -#endif -} - -/* - * @param root Window which's screen's size should be set. If invalid (e.g. - * @c NULL) no action is taken. - * @param w Width in px the screen should be set to. If out of valid - * boundaries, current value is assumed. - * @param h Height in px the screen should be set to. If out of valid - * boundaries, current value is assumed. - * @param w_mm Width in mm the screen should be set to. If @c 0, current - * aspect is assumed. - * @param h_mm Height in mm the screen should be set to. If @c 0, current - * aspect is assumed. - * @return @c EINA_TRUE if request was successfully sent or screen is already - * in requested size, @c EINA_FALSE if parameters are invalid. - */ -EAPI Eina_Bool -ecore_x_randr_screen_current_size_set(Ecore_X_Window root, - int w, - int h, - int w_mm, - int h_mm) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - Ecore_X_Randr_Screen scr; - int w_c, h_c, w_mm_c, h_mm_c, twmin, thmin, twmax, thmax; - - if (!RANDR_VALIDATE_ROOT(scr, root)) - return EINA_FALSE; - - ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, &w_mm_c, &h_mm_c); - if ((w == w_c) && (h == h_c) && (w_mm_c == w_mm) && (h_mm_c == h_mm)) - return EINA_TRUE; - - ecore_x_randr_screen_size_range_get(root, &twmin, &thmin, &twmax, &thmax); - - if (((w != Ecore_X_Randr_None) && - ((w < twmin) || - (w > twmax))) || - ((h != Ecore_X_Randr_None) && ((h < thmin) || (h > thmax)))) - return EINA_FALSE; - - if (w <= 0) - w = DisplayWidth(_ecore_x_disp, scr); - - if (h <= 0) - h = DisplayHeight(_ecore_x_disp, scr); - - if (w_mm <= 0) - w_mm = - (int)(((double)(DisplayWidthMM(_ecore_x_disp, - scr) / - (double)DisplayWidth(_ecore_x_disp, - scr))) * (double)w); - - if (h_mm <= 0) - h_mm = - (int)(((double)(DisplayHeightMM(_ecore_x_disp, - scr) / - (double)DisplayHeight(_ecore_x_disp, - scr))) * (double)h); - - XRRSetScreenSize (_ecore_x_disp, root, w, h, w_mm, h_mm); - return EINA_TRUE; -#else - return EINA_FALSE; -#endif -} - -/* - * @brief get detailed information for all modes related to a root window's screen - * @param root window which's screen's ressources are queried - * @param num number of modes returned - * @return modes' information - */ -EAPI Ecore_X_Randr_Mode_Info ** -ecore_x_randr_modes_info_get(Ecore_X_Window root, - int *num) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - Ecore_X_Randr_Mode_Info **ret = NULL; - int i; - - if (_ecore_x_randr_root_validate(root) && - (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - { - if ((ret = - (Ecore_X_Randr_Mode_Info **)malloc(sizeof( - Ecore_X_Randr_Mode_Info *) - * - res->nmode))) - { - for (i = 0; i < res->nmode; i++) - { - if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) - { - ret[i]->xid = res->modes[i].id; - ret[i]->width = res->modes[i].width; - ret[i]->height = res->modes[i].height; - ret[i]->dotClock = res->modes[i].dotClock; - ret[i]->hSyncStart = res->modes[i].hSyncStart; - ret[i]->hSyncEnd = res->modes[i].hSyncEnd; - ret[i]->hTotal = res->modes[i].hTotal; - ret[i]->hSkew = res->modes[i].hSkew; - ret[i]->vSyncStart = res->modes[i].vSyncStart; - ret[i]->vSyncEnd = res->modes[i].vSyncEnd; - ret[i]->vTotal = res->modes[i].vTotal; - if ((ret[i]->name = (malloc(res->modes[i].nameLength + 1)))) - strncpy(ret[i]->name, res->modes[i].name, - (res->modes[i].nameLength + 1)); - else - ret[i]->name = NULL; - - ret[i]->nameLength = res->modes[i].nameLength; - ret[i]->modeFlags = res->modes[i].modeFlags; - } - else - { - while (i > 0) - free(ret[--i]); - free(ret); - ret = NULL; - break; - } - } - } - - if (ret && num) - *num = res->nmode; - - XRRFreeScreenResources(res); - } - - return ret; -#else - return NULL; -#endif -} - -/* - * @brief Add a mode to a display. - * - * @param root Window to which's screen's ressources are added. - * @param mode_info - * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode - * adding failed. - * @since 1.2.0 - */ -EAPI Ecore_X_Randr_Mode -ecore_x_randr_mode_info_add(Ecore_X_Window root, - Ecore_X_Randr_Mode_Info *mode_info) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - Ecore_X_Randr_Mode mode = Ecore_X_Randr_None; - - if (_ecore_x_randr_root_validate(root) && mode_info) - mode = XRRCreateMode(_ecore_x_disp, root, (XRRModeInfo*)mode_info); - - return mode; -#else - return Ecore_X_Randr_None; -#endif -} - -/* - * @brief Delete a mode from the display. - * - * @param mode_info - * @since 1.2.0 - */ -EAPI void -ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - - XRRDestroyMode(_ecore_x_disp, mode); -#else - return; -#endif -} - -/* - * @brief get detailed information for a given mode id - * @param root window which's screen's ressources are queried - * @param mode the XID which identifies the mode of interest - * @return mode's detailed information - */ -EAPI Ecore_X_Randr_Mode_Info * -ecore_x_randr_mode_info_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - Ecore_X_Randr_Mode_Info *ret = NULL; - int i; - - if (_ecore_x_randr_root_validate(root) && - (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - { - for (i = 0; i < res->nmode; i++) - { - if ((res->modes[i].id == mode) && - (ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) - { - ret->xid = res->modes[i].id; - ret->width = res->modes[i].width; - ret->height = res->modes[i].height; - ret->dotClock = res->modes[i].dotClock; - ret->hSyncStart = res->modes[i].hSyncStart; - ret->hSyncEnd = res->modes[i].hSyncEnd; - ret->hTotal = res->modes[i].hTotal; - ret->hSkew = res->modes[i].hSkew; - ret->vSyncStart = res->modes[i].vSyncStart; - ret->vSyncEnd = res->modes[i].vSyncEnd; - ret->vTotal = res->modes[i].vTotal; - ret->name = NULL; - ret->nameLength = 0; - if (res->modes[i].nameLength > 0) - { - ret->nameLength = res->modes[i].nameLength; - ret->name = malloc(res->modes[i].nameLength + 1); - if (ret->name) - memcpy(ret->name, res->modes[i].name, - res->modes[i].nameLength + 1); - } - ret->modeFlags = res->modes[i].modeFlags; - break; - } - } - XRRFreeScreenResources(res); - } - - return ret; -#else - return NULL; -#endif -} - -/* - * @brief Free detailed mode information. The pointer handed in will be set to - * @c NULL after freeing the memory. - * - * @param mode_info The mode information that should be freed. - */ -EAPI void -ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - if (!mode_info) - return; - - if (mode_info->name) - free(mode_info->name); - - free(mode_info); - mode_info = NULL; -#endif -} - -/* - * @brief Get all known CRTCs related to a root window's screen. - * - * @param root Window which's screen's ressources are queried. - * @param num Number of CRTCs returned. - * @return CRTC IDs. - */ -EAPI Ecore_X_Randr_Crtc * -ecore_x_randr_crtcs_get(Ecore_X_Window root, - int *num) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - Ecore_X_Randr_Crtc *ret = NULL; - - if (root && - (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - { - if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc) * res->ncrtc))) - { - int i = 0; - - if (num) *num = res->ncrtc; - - for (i = 0; i < res->ncrtc; i++) - ret[i] = res->crtcs[i]; - } - - XRRFreeScreenResources(res); - } - - return ret; -#else - return NULL; -#endif -} - -/* - * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead. - * @brief get the CRTCs, which display a certain window - * @param window window the displaying crtcs shall be found for - * @param num the number of crtcs displaying the window - * @return Array of crtcs that display a certain window. @c NULL if no crtcs - * was found that displays the specified window. - */ -EAPI Ecore_X_Randr_Crtc * -ecore_x_randr_current_crtc_get(Ecore_X_Window window, - int *num) -{ - return ecore_x_randr_window_crtcs_get(window, num); -} - -/* - * @brief get the CRTCs, which display a certain window - * @param window window the displaying crtcs shall be found for - * @param num the number of crtcs displaying the window - * @return Array of crtcs that display a certain window. @c NULL if no crtcs - * was found that displays the specified window. - * @since 1.2.0 - */ -EAPI Ecore_X_Randr_Crtc * -ecore_x_randr_window_crtcs_get(Ecore_X_Window window, - int *num) -{ -#ifdef ECORE_XRANDR - Ecore_X_Window root; - Eina_Rectangle w_geo, c_geo; - Ecore_X_Randr_Crtc *crtcs; - Ecore_X_Randr_Mode mode; - Ecore_X_Randr_Output *ret = NULL; - Window tw; - int ncrtcs, i, nret = 0, rx = 0, ry = 0; - - if (_randr_version < RANDR_1_2) goto _ecore_x_randr_window_crtcs_get_fail; - - ecore_x_window_geometry_get(window, - &w_geo.x, &w_geo.y, - &w_geo.w, &w_geo.h); - - root = ecore_x_window_root_get(window); - crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs); - if (!crtcs) goto _ecore_x_randr_window_crtcs_get_fail; - - /* now get window RELATIVE to root window - thats what matters. */ - XTranslateCoordinates(_ecore_x_disp, window, root, 0, 0, &rx, &ry, &tw); - w_geo.x = rx; - w_geo.y = ry; - - ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc)); - if (!ret) - { - free(crtcs); - goto _ecore_x_randr_window_crtcs_get_fail; - } - for (i = 0, nret = 0; i < ncrtcs; i++) - { - /* if crtc is not enabled, don't bother about it any further */ - mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]); - if (mode == Ecore_X_Randr_None) continue; - - ecore_x_randr_crtc_geometry_get(root, crtcs[i], - &c_geo.x, &c_geo.y, - &c_geo.w, &c_geo.h); - if (eina_rectangles_intersect(&w_geo, &c_geo)) - { - ret[nret] = crtcs[i]; - nret++; - } - } - free(crtcs); - - if (num) *num = nret; - return ret; - -_ecore_x_randr_window_crtcs_get_fail: -#endif - if (num) *num = 0; - return NULL; -} - -EAPI Ecore_X_Randr_Output * -ecore_x_randr_outputs_get(Ecore_X_Window root, - int *num) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - Ecore_X_Randr_Output *ret = NULL; - - if (root && - (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - { - if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput))) - { - int i = 0; - - if (num) *num = res->noutput; - - for (i = 0; i < res->noutput; i++) - ret[i] = res->outputs[i]; - } - - if (res) - XRRFreeScreenResources(res); - } - - return ret; -#else - return NULL; -#endif -} - -//Per Crtc -/* - * @brief get a CRTC's outputs. - * @param root the root window which's screen will be queried - * @param num number of outputs referenced by given CRTC - */ -EAPI Ecore_X_Randr_Output * -ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *num) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - Ecore_X_Randr_Output *ret = NULL; - XRRCrtcInfo *crtc_info = NULL; - - if (_ecore_x_randr_crtc_validate(root, crtc) && - (res = - _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)) && - (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) - { - if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput))) - { - int i = 0; - - if (num) *num = crtc_info->noutput; - - for (i = 0; i < crtc_info->noutput; i++) - ret[i] = crtc_info->outputs[i]; - } - - if (crtc_info) - XRRFreeCrtcInfo(crtc_info); - - if (res) - XRRFreeScreenResources(res); - } - - return ret; -#else - return NULL; -#endif -} - -/* - * @brief get a CRTC's possible outputs. - * @param root the root window which's screen will be queried - * @param num number of possible outputs referenced by given CRTC - */ -EAPI Ecore_X_Randr_Output * -ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *num) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - Ecore_X_Randr_Output *ret = NULL; - XRRCrtcInfo *crtc_info = NULL; - - if (_ecore_x_randr_crtc_validate(root, crtc) && - (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - { - if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) - { - if ((ret = - malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible))) - { - int i = 0; - - if (num) *num = crtc_info->npossible; - - for (i = 0; i < crtc_info->npossible; i++) - ret[i] = crtc_info->possible[i]; - } - - XRRFreeCrtcInfo(crtc_info); - } - - XRRFreeScreenResources(res); - } - - return ret; -#else - return NULL; -#endif -} - -EAPI void -ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *x, - int *y, - int *w, - int *h) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - XRRScreenResources *res = NULL; - XRRCrtcInfo *crtc_info = NULL; - - if (_ecore_x_randr_crtc_validate(root, - crtc) && - (res = - _ecore_x_randr_get_screen_resources (_ecore_x_disp, - root)) && - (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) - { - if (x) - *x = crtc_info->x; - - if (y) - *y = crtc_info->y; - - if (w) - *w = crtc_info->width; - - if (h) - *h = crtc_info->height; - - XRRFreeCrtcInfo(crtc_info); - XRRFreeScreenResources(res); - } - -#endif -} - -/* - * @brief Sets the position of given CRTC within root window's screen. - * - * @param root The window's screen to be queried. - * @param crtc The CRTC which's position within the mentioned screen is to be - * altered. - * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current - * value will be kept. - * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current - * value will be kept. - * @return @c EINA_TRUE if position could successfully be altered. - */ -EAPI Eina_Bool -ecore_x_randr_crtc_pos_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int x, - int y) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - int w_c, h_c, w_new = 0, h_new = 0; - Eina_Rectangle crtc_geo; - - ecore_x_randr_crtc_geometry_get(root, - crtc, - &crtc_geo.x, - &crtc_geo.y, - &crtc_geo.w, - &crtc_geo.h); - ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, NULL, NULL); - if (x < 0) - x = crtc_geo.x; - - if (y < 0) - y = crtc_geo.y; - - if ((x + crtc_geo.w) > w_c) - w_new = x + crtc_geo.w; - - if ((y + crtc_geo.h) > h_c) - h_new = y + crtc_geo.h; - - if ((w_new != 0) || (h_new != 0)) - if (!ecore_x_randr_screen_current_size_set(root, w_new, h_new, 0, 0)) - return EINA_FALSE; - - return ecore_x_randr_crtc_settings_set(root, - crtc, - NULL, - Ecore_X_Randr_Unset, - x, - y, - Ecore_X_Randr_Unset, - Ecore_X_Randr_Unset); -#else - return EINA_FALSE; -#endif -} - -/** - * @brief Get the current set mode of a given CRTC - * @param root the window's screen to be queried - * @param crtc the CRTC which's should be queried - * @return currently set mode or - in case parameters are invalid - - * Ecore_X_Randr_Unset - */ -EAPI Ecore_X_Randr_Mode -ecore_x_randr_crtc_mode_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset); - XRRScreenResources *res = NULL; - XRRCrtcInfo *crtc_info = NULL; - Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset; - if (_ecore_x_randr_root_validate(root) && - _ecore_x_randr_crtc_validate(root, - crtc) && - (res = - _ecore_x_randr_get_screen_resources(_ecore_x_disp, - root)) && - (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) - { - ret = crtc_info->mode; - XRRFreeCrtcInfo(crtc_info); - XRRFreeScreenResources(res); - } - - return ret; -#else - return Ecore_X_Randr_Unset; -#endif -} - -/** - * @brief Sets a mode for a CRTC and the outputs attached to it. - * - * @param root The window's screen to be queried. - * @param crtc The CRTC which shall be set. - * @param outputs Array of outputs which have to be compatible with the mode. - * If @c NULL, CRTC will be disabled. - * @param noutputs Number of outputs in array to be used. Use - * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs. - * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be - * disabled. If set to @c -1 the call will fail. - * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE - * otherwise. - */ -EAPI Eina_Bool -ecore_x_randr_crtc_mode_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - Ecore_X_Randr_Output *outputs, - int noutputs, - Ecore_X_Randr_Mode mode) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if (mode == Ecore_X_Randr_Unset) - return EINA_FALSE; - - return ecore_x_randr_crtc_settings_set(root, - crtc, - outputs, - noutputs, - Ecore_X_Randr_Unset, - Ecore_X_Randr_Unset, - mode, - Ecore_X_Randr_Unset); -#else - return EINA_FALSE; -#endif -} - -EAPI void -ecore_x_randr_crtc_size_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *w, - int *h) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h); -#endif -} - -EAPI Ecore_X_Randr_Refresh_Rate -ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - Ecore_X_Randr_Mode mode) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(0.0); - XRRScreenResources *res = NULL; - XRRCrtcInfo *crtc_info = NULL; - Ecore_X_Randr_Refresh_Rate ret = 0.0; - int i; - - if (_ecore_x_randr_crtc_validate(root, - crtc) && - (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - { - for (i = 0; i < res->nmode; i++) - if (res->modes[i].id == mode) - { - if (res->modes[i].hTotal && res->modes[i].vTotal) - ret = ((double)res->modes[i].dotClock / - ((double)res->modes[i].hTotal * - (double)res->modes[i].vTotal)); - - break; - } - } - - if (crtc_info) - XRRFreeCrtcInfo(crtc_info); - - if (res) - XRRFreeScreenResources(res); - - return ret; -#else - return 0.0; -#endif -} - -EAPI Ecore_X_Randr_Orientation -ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); - XRRCrtcInfo *crtc_info = NULL; - XRRScreenResources *res = NULL; - Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; - - if (_ecore_x_randr_crtc_validate(root, - crtc) && - (res = - _ecore_x_randr_get_screen_resources (_ecore_x_disp, - root)) && - (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) - { - ret = crtc_info->rotations; - } - if (crtc_info) - XRRFreeCrtcInfo(crtc_info); - - if (res) - XRRFreeScreenResources(res); - - return ret; -#else - return Ecore_X_Randr_None; -#endif -} - -EAPI Ecore_X_Randr_Orientation -ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); - XRRCrtcInfo *crtc_info = NULL; - XRRScreenResources *res = NULL; - Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; - - if (_ecore_x_randr_crtc_validate(root, - crtc) && - (res = - _ecore_x_randr_get_screen_resources (_ecore_x_disp, - root)) && - (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) - { - ret = crtc_info->rotation; - } - if (crtc_info) - XRRFreeCrtcInfo(crtc_info); - - if (res) - XRRFreeScreenResources(res); - - return ret; -#else - return Ecore_X_Randr_None; -#endif -} - -EAPI Eina_Bool -ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - Ecore_X_Randr_Orientation orientation) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - Eina_Bool ret = EINA_FALSE; - - if (orientation != Ecore_X_Randr_None) - { - ret = ecore_x_randr_crtc_settings_set(root, - crtc, - NULL, - Ecore_X_Randr_Unset, - Ecore_X_Randr_Unset, - Ecore_X_Randr_Unset, - Ecore_X_Randr_Unset, - orientation); - } - - return ret; -#else - return EINA_FALSE; -#endif -} - -EAPI void -ecore_x_randr_crtc_pos_get(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - int *x, - int *y) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - - ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL); -#endif -} - -EAPI Eina_Bool -ecore_x_randr_crtc_clone_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc original, - Ecore_X_Randr_Crtc clon) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - XRRScreenResources *res = NULL; - XRRCrtcInfo *clone_crtc_info = NULL; - Ecore_X_Randr_Mode original_mode = Ecore_X_Randr_None; - Ecore_X_Randr_Orientation original_orientation = Ecore_X_Randr_None; - Eina_Bool ret = EINA_FALSE; - int x, y; - - if (_ecore_x_randr_root_validate(root) && - _ecore_x_randr_crtc_validate(root, - original) && - _ecore_x_randr_crtc_validate(root, - clon) && - (res = - _ecore_x_randr_get_screen_resources (_ecore_x_disp, - root)) && - (clone_crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, clon))) - { - ecore_x_randr_crtc_geometry_get(root, original, &x, &y, NULL, NULL); - original_mode = ecore_x_randr_crtc_mode_get(root, original); - original_orientation = ecore_x_randr_crtc_orientation_get(root, - original); - ret = ecore_x_randr_crtc_settings_set(root, - clon, - NULL, - Ecore_X_Randr_Unset, - x, - y, - original_mode, - original_orientation); - XRRFreeCrtcInfo(clone_crtc_info); - XRRFreeScreenResources(res); - } - - return ret; -#else - return EINA_FALSE; -#endif -} - -/** - * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is - * auto enabled in it's preferred mode, when it was disabled before. - * - * @param root The root window which's default display will be queried. - * @param crtc The CRTC which's configuration should be altered. - * @param outputs An array of outputs, that should display this CRTC's content. - * @param noutputs Number of outputs in the array of outputs. If set to - * Ecore_X_Randr_Unset, current outputs and number of outputs will be used. - * If set to Ecore_X_Randr_None, CRTC will be disabled. - * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x - * corrdinate will be assumed. - * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y - * corrdinate will be assumed. - * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the - * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is - * assumed. - * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is - * used, the current mode is assumed. - * @return @c EINA_TRUE if the configuration alteration was successful, - * @c EINA_FALSE otherwise. - */ -EAPI Eina_Bool -ecore_x_randr_crtc_settings_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc, - Ecore_X_Randr_Output *outputs, - int noutputs, - int x, - int y, - Ecore_X_Randr_Mode mode, - Ecore_X_Randr_Orientation orientation) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - XRRScreenResources *res = NULL; - XRRCrtcInfo *crtc_info = NULL; - Eina_Bool ret = EINA_FALSE; - - if (_ecore_x_randr_crtc_validate(root, - crtc) && - (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - { - if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) - { - if ((mode == Ecore_X_Randr_None) || - (noutputs == Ecore_X_Randr_None)) - { - outputs = NULL; - noutputs = 0; - } - else if (noutputs == (int)Ecore_X_Randr_Unset) - { - outputs = (Ecore_X_Randr_Output *)crtc_info->outputs; - noutputs = crtc_info->noutput; - } - - if (mode == Ecore_X_Randr_Unset) - mode = crtc_info->mode; - - if (x < 0) - x = crtc_info->x; - - if (y < 0) - y = crtc_info->y; - - if (orientation == Ecore_X_Randr_Unset) - orientation = crtc_info->rotation; - - if (!XRRSetCrtcConfig(_ecore_x_disp, res, crtc, CurrentTime, - x, y, mode, orientation, (RROutput *)outputs, - noutputs)) - ret = EINA_TRUE; - - XRRFreeCrtcInfo(crtc_info); - } - - XRRFreeScreenResources(res); - } - - return ret; -#else - return EINA_FALSE; -#endif -} - -/** - * @brief Sets a CRTC relative to another one. - * - * @param root The root window which's default display will be set. - * @param crtc_r1 The CRTC to be positioned. - * @param crtc_r2 The CRTC the position should be relative to. - * @param policy The relation between the crtcs. - * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at - * CRTC2's borders. - * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE - * if repositioning failed or if position of new crtc would be out of given - * screen's min/max bounds. - */ -EAPI Eina_Bool -ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, - Ecore_X_Randr_Crtc crtc_r1, - Ecore_X_Randr_Crtc crtc_r2, - Ecore_X_Randr_Output_Policy policy, - Ecore_X_Randr_Relative_Alignment alignment) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - Eina_Rectangle r1_geo, r2_geo; - int w_max, h_max, cw, ch, x_n = Ecore_X_Randr_Unset, y_n = - Ecore_X_Randr_Unset; - /* - int r1_noutputs, r2_noutputs, r1_nmodes, i, j, outputs_mode_found, mode_w, mode_h; - Ecore_X_Randr_Output *r1_outputs, *r2_outputs, *r2_r1_outputs; - Ecore_X_Randr_Mode *r1_modes, r2_mode, r1_mode; - Eina_Bool ret; - */ - - if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == Ecore_X_Randr_None) - || (ecore_x_randr_crtc_mode_get(root, crtc_r2) == Ecore_X_Randr_None)) - return EINA_FALSE; - - if (!_ecore_x_randr_crtc_validate(root, crtc_r1) || - (!(crtc_r1 != crtc_r2) && - !_ecore_x_randr_crtc_validate(root, crtc_r2))) - return EINA_FALSE; - - ecore_x_randr_crtc_geometry_get(root, - crtc_r1, - &r1_geo.x, - &r1_geo.y, - &r1_geo.w, - &r1_geo.h); - ecore_x_randr_crtc_geometry_get(root, - crtc_r2, - &r2_geo.x, - &r2_geo.y, - &r2_geo.w, - &r2_geo.h); - ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); - ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); - - switch (policy) - { - case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT: - //set r1 right of r2 - x_n = r2_geo.x + r2_geo.w; - - switch (alignment) - { - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: - y_n = Ecore_X_Randr_Unset; - break; - - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: - y_n = - ((int)(((double)r2_geo.h / - 2.0) + (double)r2_geo.y - ((double)r1_geo.h / 2.0))); - break; - - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: - y_n = ((int)((double)ch / 2.0) - ((double)r1_geo.h / 2.0)); - break; - } - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: - //set r1 left of r2 - x_n = r2_geo.x - r1_geo.w; - - switch (alignment) - { - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: - y_n = Ecore_X_Randr_Unset; - break; - - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: - y_n = - ((int)(((double)r2_geo.h / - 2.0) + r2_geo.y - ((double)r1_geo.h / 2.0))); - break; - - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: - y_n = ((int)(((double)ch / 2.0) - ((double)r1_geo.h / 2.0))); - break; - } - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_BELOW: - //set r1 below r2 - y_n = r2_geo.y + r2_geo.h; - - switch (alignment) - { - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: - x_n = Ecore_X_Randr_Unset; - break; - - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: - x_n = - ((int)((((double)r2_geo.x + - (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0))); - break; - - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: - x_n = ((int)((double)cw / 2.0)); - break; - } - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: - y_n = r2_geo.y - r1_geo.h; - - //set r1 above r2 - switch (alignment) - { - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: - x_n = Ecore_X_Randr_Unset; - break; - - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: - x_n = - ((int)((((double)r2_geo.x + - (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0))); - break; - - case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: - x_n = ((int)((double)cw / 2.0)); - break; - } - break; - - case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: - return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y); - - /* entire cloning (including modesetting) - //all outputs of crtc1 capable of crtc2's current mode? - r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2); - if (!(r1_outputs = - ecore_x_randr_crtc_outputs_get(root, crtc_r1, - &r1_noutputs)) || - (r1_noutputs == 0)) - return EINA_FALSE; - - for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++) - { - if (!(r1_modes = - ecore_x_randr_output_modes_get(root, r1_outputs[i], - &r1_nmodes, NULL))) - { - free(r1_outputs); - return EINA_FALSE; - } - - for (j = 0; j < r1_nmodes; j++) - { - ecore_x_randr_mode_size_get(root, - r1_modes[j], - &mode_w, - &mode_h); - if ((mode_w == r2_geo.w) && (mode_h == r2_geo.h)) - { - r1_mode = r1_modes[j]; - ++outputs_mode_found; - free(r1_modes); - r1_modes = NULL; - break; - } - } - if (r1_modes) - free(r1_modes); - - if (outputs_mode_found <= i) - { - //an output doesn't support the set mode, cancel! - free(r1_outputs); - return EINA_FALSE; - } - } - free (r1_outputs); - //CRTC 1's outputs support a mode of same geometry as CRTC 2. - ret = - (ecore_x_randr_crtc_mode_set(root, crtc_r1, Ecore_X_Randr_None, - Ecore_X_Randr_None, - r1_mode) && - ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y)); - return ret; - */ - - /* entire cloning on same CRTC - //all outputs of crtc1 capable of crtc2's current mode? - r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2); - if (!(r1_outputs = - ecore_x_randr_crtc_outputs_get(root, crtc_r1, - &r1_noutputs)) || - (r1_noutputs == 0)) - return EINA_FALSE; - - for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++) - { - if (!(r1_modes = - ecore_x_randr_output_modes_get(root, r1_outputs[i], - &r1_nmodes, NULL))) - { - free(r1_outputs); - return EINA_FALSE; - } - - for (j = 0; j < r1_nmodes; j++) - { - if (r1_modes[j] == r2_mode) - { - ++outputs_mode_found; - free(r1_modes); - r1_modes = NULL; - break; - } - } - if (r1_modes) - free(r1_modes); - - if (outputs_mode_found <= i) - { - //an output doesn't support the set mode, cancel! - free(r1_outputs); - return EINA_FALSE; - } - } - //check whether crtc r2 can use all outputs of r1. - if (!(r2_outputs = - ecore_x_randr_crtc_possible_outputs_get(root, crtc_r2, - &r2_noutputs)) || - (r2_noutputs == 0)) - { - free(r1_outputs); - return EINA_FALSE; - } - - for (i = 0; i < r1_noutputs; i++) - { - for (j = 0; j < r2_noutputs; ) - { - if (r1_outputs[i] == r2_outputs[j]) - break; - - j++; - } - if (j == r2_noutputs) - { - //didn't find the output! - free (r1_outputs); - free (r2_outputs); - return EINA_FALSE; - } - } - - //apparently crtc2 supports all outputs of r1 - //TODO: check with the compatible list of outputs (property in RR1.3) - r2_r1_outputs = - malloc(sizeof(Ecore_X_Randr_Output) * (r1_noutputs + r2_noutputs)); - for (i = 0; i < r1_noutputs; i++) - { - r2_r1_outputs[i] = r1_outputs[i]; - } - free(r1_outputs); - for (; i < r2_noutputs; i++) - { - r2_r1_outputs[i] = r2_outputs[i]; - } - free(r2_outputs); - ret = - ecore_x_randr_crtc_mode_set(root, crtc_r2, r2_r1_outputs, - (r1_noutputs + r1_noutputs), r2_mode); - free (r2_r1_outputs); - return ret; - */ - case ECORE_X_RANDR_OUTPUT_POLICY_NONE: - break; - default: - return EINA_FALSE; - } - if ((x_n == r1_geo.x) && (y_n == r1_geo.x)) - return EINA_TRUE; - - //out of possible bounds? - if (((y_n + r1_geo.h) > h_max) || ((x_n + r1_geo.w) > w_max)) - return EINA_FALSE; - - return ecore_x_randr_crtc_pos_set(root, crtc_r1, x_n, y_n); -#else - return EINA_FALSE; -#endif -} - -/* - * @brief Add given mode to given output. - * - * @param output The output the mode is added to. - * @param mode The mode added to the output. - * @return @c EINA_FALSE if output or mode equal Ecore_X_Randr_None, else - * @c EINA_TRUE. - * Additionally, if xcb backend is used, the success of the addition is - * reported back directly. - * @since 1.2.0 - */ -EAPI Eina_Bool -ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, - Ecore_X_Randr_Mode mode) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - - if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None)) - return EINA_FALSE; - - XRRAddOutputMode(_ecore_x_disp, output, mode); - return EINA_TRUE; -#else - return EINA_FALSE; -#endif -} - -/* - * @brief delete given mode from given output - * @param output the output the mode is removed from - * @param mode the mode removed from the output - * @since 1.2.0 - */ -EAPI void -ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output, - Ecore_X_Randr_Mode mode) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - - if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None)) - return; - - XRRDeleteOutputMode(_ecore_x_disp, output, mode); -#else - return; -#endif -} - -EAPI Ecore_X_Randr_Mode * -ecore_x_randr_output_modes_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num, - int *npreferred) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - XRROutputInfo *output_info = NULL; - Ecore_X_Randr_Mode *modes = NULL; - - if ((output != Ecore_X_Randr_None) - && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) - && (output_info = - XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output))) - { - if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode))) - { - int i = 0; - - if (num) *num = output_info->nmode; - if (npreferred) *npreferred = output_info->npreferred; - - for (i = 0; i < output_info->nmode; i++) - modes[i] = output_info->modes[i]; - } - } - - if (output_info) - XRRFreeOutputInfo(output_info); - - if (res) - XRRFreeScreenResources(res); - - return modes; -#else - return NULL; -#endif -} - -EAPI Ecore_X_Randr_Crtc * -ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - XRROutputInfo *output_info = NULL; - Ecore_X_Randr_Crtc *crtcs = NULL; - - if ((output != Ecore_X_Randr_None)) - { - if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - { - if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) - { - if ((crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc))) - { - memcpy(crtcs, output_info->crtcs, (sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc)); - if (num) *num = output_info->ncrtc; - } - XRRFreeOutputInfo(output_info); - } - XRRFreeScreenResources(res); - } - } - return crtcs; -#else - return Ecore_X_Randr_None; -#endif -} - -/** - * @brief gets the the outputs which might be used simultenously on the same - * CRTC. - * @param root window that this information should be queried for. - * @param output the output which's clones we concern - * @param num number of possible clones - */ -EAPI Ecore_X_Randr_Output * -ecore_x_randr_output_clones_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *num) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - XRROutputInfo *output_info = NULL; - Ecore_X_Randr_Output *outputs = NULL; - - if ((output != Ecore_X_Randr_None)) - { - if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - { - if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) - { - if ((outputs = malloc(sizeof(Ecore_X_Randr_Output) * output_info->nclone))) - { - memcpy(outputs, output_info->clones, (sizeof(Ecore_X_Randr_Output) * output_info->nclone)); - if (num) *num = output_info->nclone; - } - XRRFreeOutputInfo(output_info); - } - XRRFreeScreenResources(res); - } - } - return outputs; -#else - return Ecore_X_Randr_None; -#endif -} - -EAPI Ecore_X_Randr_Crtc -ecore_x_randr_output_crtc_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); - XRRScreenResources *res = NULL; - XRROutputInfo *output_info = NULL; - Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; - - if ((output != Ecore_X_Randr_None)) - { - if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - { - if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) - { - ret = output_info->crtc; - XRRFreeOutputInfo(output_info); - } - XRRFreeScreenResources(res); - } - } - - return ret; -#else - return Ecore_X_Randr_None; -#endif -} - -/** - * @brief gets the given output's name as reported by X - * @param root the window which's screen will be queried - * @param output The output for which the name will be reported. - * @param len length of returned c-string. - * @return name of the output as reported by X - */ -EAPI char * -ecore_x_randr_output_name_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *len) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - XRRScreenResources *res = NULL; - XRROutputInfo *output_info = NULL; - char *ret = NULL; - - if ((output != Ecore_X_Randr_None) - && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) - && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) - { - /* - * Actually the below command is correct, but due to a bug in libXrandr - * it doesn't work. Therefore we stick with strlen(). - * Replace the line below with the following once this bug is - * fixed within libXrandr. - * - * *len = output_info->nameLen; - * - */ - if ((ret = strdup(output_info->name)) && len) - *len = strlen(ret); - - XRRFreeOutputInfo(output_info); - } - - if (res) - XRRFreeScreenResources(res); - - return ret; -#else - return NULL; -#endif -} - -/** - * @brief gets the width and hight of a given mode - * @param mode the mode which's size is to be looked up - * @param w width of given mode in px - * @param h height of given mode in px - */ -EAPI void -ecore_x_randr_mode_size_get(Ecore_X_Window root, - Ecore_X_Randr_Mode mode, - int *w, - int *h) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - XRRScreenResources *res = NULL; - int i; - - if ((mode != Ecore_X_Randr_None) - && (w || h) - && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - { - for (i = 0; i < res->nmode; i++) - { - if (res->modes[i].id == mode) - { - if (w) - *w = res->modes[i].width; - - if (h) - *h = res->modes[i].height; - - break; - } - } - } - - if (res) - XRRFreeScreenResources(res); - -#endif -} - -/** - * @brief gets the EDID information of an attached output if available. - * Note that this information is not to be compared using ordinary string - * comparison functions, since it includes 0-bytes. - * @param root window this information should be queried from - * @param output the XID of the output - * @param length length of the byte-array. If NULL, request will fail. - */ -EAPI unsigned char * -ecore_x_randr_output_edid_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - unsigned long *length) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(NULL); - Atom name = XInternAtom (_ecore_x_disp, RANDR_PROPERTY_EDID, False); - unsigned char *prop_data, *ret = NULL; - int actual_format; - unsigned long nitems, bytes_after; - Atom actual_type; - - if (!length || !_ecore_x_randr_output_validate(root, output)) - return NULL; - - if (XRRGetOutputProperty (_ecore_x_disp, output, name, - 0, 100, False, False, - AnyPropertyType, - &actual_type, &actual_format, - &nitems, &bytes_after, &prop_data) == Success) - { - if (actual_type == XA_INTEGER && actual_format == 8) - { - if ((ret = malloc(nitems * sizeof(unsigned char)))) - { - if (length && - (memcpy(ret, prop_data, (nitems * sizeof(unsigned char))))) - *length = nitems; - - return ret; - } - } - } - - return NULL; -#else - return NULL; -#endif -} - -EAPI Ecore_X_Randr_Connection_Status -ecore_x_randr_output_connection_status_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN); - XRRScreenResources *res = NULL; - XRROutputInfo *output_info = NULL; - Ecore_X_Randr_Connection_Status ret = - ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; - - if ((output != Ecore_X_Randr_None) - && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) - && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) - { - ret = output_info->connection; - } - - if (output_info) - XRRFreeOutputInfo(output_info); - - if (res) - XRRFreeScreenResources(res); - - return ret; -#else - return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; -#endif -} - -EAPI void -ecore_x_randr_output_size_mm_get(Ecore_X_Window root, - Ecore_X_Randr_Output output, - int *w_mm, - int *h_mm) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - XRRScreenResources *res = NULL; - XRROutputInfo *output_info = NULL; - - if ((output != Ecore_X_Randr_None) - && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - { - if ((output_info = - XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output))) - { - if (w_mm) - *w_mm = output_info->mm_width; - - if (h_mm) - *h_mm = output_info->mm_height; - - XRRFreeOutputInfo(output_info); - } - - XRRFreeScreenResources(res); - } - -#endif -} - -EAPI Eina_Bool -ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, - const Ecore_X_Randr_Crtc *not_moved, - int nnot_moved, - int dx, - int dy) -{ -#ifdef ECORE_XRANDR - Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL; - XRRScreenResources *res = NULL; - int i, j, k, n; - Eina_Bool ret; - - if ((nnot_moved <= 0) || (!not_moved) - || !_ecore_x_randr_root_validate(root) - || !(res = - _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - return EINA_FALSE; - - n = (res->ncrtc - nnot_moved); - if ((crtcs_to_be_moved = malloc(sizeof(Ecore_X_Randr_Crtc) * n))) - { - for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++) - { - for (j = 0; j < nnot_moved; j++) - { - if (res->crtcs[i] == not_moved[j]) - break; - } - if (j == nnot_moved) - //crtcs[i] is not in the 'not to move'-list - crtcs_to_be_moved[k++] = res->crtcs[i]; - } - } - - XRRFreeScreenResources(res); - ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy); - free(crtcs_to_be_moved); - return ret; -#else - return EINA_FALSE; -#endif -} - -/* - * @brief Move given CRTCs belonging to the given root window's screen dx/dy - * pixels relative to their current position. The screen size will be - * automatically adjusted if necessary and possible. - * - * @param root Window which's screen's resources are used. - * @param crtcs List of CRTCs to be moved. - * @param ncrtc Number of CRTCs in array. - * @param dx Amount of pixels the CRTCs should be moved in x direction. - * @param dy Amount of pixels the CRTCs should be moved in y direction. - * @return @c EINA_TRUE if all crtcs could be moved successfully. - */ -EAPI Eina_Bool -ecore_x_randr_move_crtcs(Ecore_X_Window root, - const Ecore_X_Randr_Crtc *crtcs, - int ncrtc, - int dx, - int dy) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - XRRScreenResources *res = NULL; - XRRCrtcInfo **crtc_info = NULL; - Eina_Bool ret = EINA_TRUE; - int i, cw, ch, w_max, h_max, nw, nh; - - crtc_info = alloca(sizeof(XRRCrtcInfo *) * ncrtc); - memset(crtc_info, 0, sizeof(XRRCrtcInfo *) * ncrtc); - if (_ecore_x_randr_root_validate(root) - && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) - { - ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); - ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); - nw = cw; - nh = ch; - - for (i = 0; - (i < ncrtc) && - (crtc_info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])); - i++) - { - if (((crtc_info[i]->x + dx) < 0) || - ((int)(crtc_info[i]->x + crtc_info[i]->width + dx) > w_max) - || ((crtc_info[i]->y + dy) < 0) || - ((int)(crtc_info[i]->y + crtc_info[i]->height + dy) > h_max) - ) - goto _ecore_x_randr_move_crtcs_fail_free_crtc_info; - - nw = MAX((int)(crtc_info[i]->x + crtc_info[i]->width + dx), nw); - nh = MAX((int)(crtc_info[i]->y + crtc_info[i]->height + dy), nh); - } - //not out of bounds - - //resize if necessary - if (!(((nw > cw) || - (nh > ch)) || - ecore_x_randr_screen_current_size_set(root, nw, nh, - Ecore_X_Randr_Unset, - Ecore_X_Randr_Unset))) - goto _ecore_x_randr_move_crtcs_fail_free_crtc_info; - - //actually move all the crtcs, keep their rotation and mode. - for (i = 0; (i < ncrtc) && crtc_info[i]; i++) - { - if ((crtc_info[i]) && - (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, - Ecore_X_Randr_Unset, - (crtc_info[i]->x + dx), - (crtc_info[i]->y + dy), - crtc_info[i]->mode, - crtc_info[i]->rotation))) - { - ret = EINA_FALSE; - break; - } - } - if (i < ncrtc) - { - //something went wrong, let's try to move the already moved crtcs - //back. - while ((i--) >= 0) - { - if (crtc_info[i]) - ecore_x_randr_crtc_settings_set(root, - crtcs[i], - NULL, - Ecore_X_Randr_Unset, - (crtc_info[i]->x - dx), - (crtc_info[i]->y - dy), - crtc_info[i]->mode, - crtc_info[i]->rotation); - } - } - - for (i = 0; i < ncrtc; i++) - { - if (crtc_info[i]) XRRFreeCrtcInfo(crtc_info[i]); - } - } - - XRRFreeScreenResources(res); - - return ret; -_ecore_x_randr_move_crtcs_fail_free_crtc_info: - while (i-- > 0) - XRRFreeCrtcInfo(crtc_info[i]); - XRRFreeScreenResources(res); - return EINA_FALSE; -#else - return EINA_FALSE; -#endif -} - -/** - * @brief removes unused screen space. The most upper left CRTC is set to 0x0 - * and all other CRTCs dx,dy respectively. - * @param root the window's screen which will be reset. - */ -EAPI void -ecore_x_randr_screen_reset(Ecore_X_Window root) -{ -#ifdef ECORE_XRANDR - XRRCrtcInfo *crtc_info = NULL; - XRRScreenResources *res = NULL; - //the 100000 are just a random huge number. - int i, dx_min = 100000, dy_min = 100000, w_n = 0, h_n = 0, nenabled_crtcs = 0; - - if (!_ecore_x_randr_root_validate(root) || - !(res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) - return; - - Ecore_X_Randr_Crtc enabled_crtcs[res->ncrtc]; - - for (i = 0; i < res->ncrtc; i++) - { - if (!(crtc_info = - XRRGetCrtcInfo(_ecore_x_disp, res, - res->crtcs[i])) || - (crtc_info->mode == Ecore_X_Randr_None) || - (crtc_info->mode == Ecore_X_Randr_Unset) - || ((crtc_info->noutput == 0))) - continue; - - enabled_crtcs[nenabled_crtcs++] = res->crtcs[i]; - - if ((int)(crtc_info->x + crtc_info->width) > w_n) - w_n = (crtc_info->x + crtc_info->width); - - if ((int)(crtc_info->y + crtc_info->height) > h_n) - h_n = (crtc_info->y + crtc_info->height); - - if (crtc_info->x < dx_min) - dx_min = crtc_info->x; - if (crtc_info->y < dy_min) - dy_min = crtc_info->y; - - XRRFreeCrtcInfo(crtc_info); - } - if ((dx_min > 0) || (dy_min > 0)) - { - if (ecore_x_randr_move_crtcs(root, enabled_crtcs, nenabled_crtcs, -dx_min, -dy_min)) - { - w_n -= dx_min; - h_n -= dy_min; - } - } - ecore_x_randr_screen_current_size_set(root, - w_n, - h_n, - Ecore_X_Randr_Unset, - Ecore_X_Randr_Unset); -#endif -} - -/** - * @brief Set up the backlight level to the given level. - * - * @param root The window's screen which will be set. - * @param level Of the backlight between @c 0 and @c 1. - */ - -EAPI void -ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, - double level) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(); - Atom _backlight; - XRRScreenResources *resources = NULL; - Ecore_X_Randr_Output output; - int o; - - if ((level < 0) || (level > 1)) - { - ERR("Wrong value for the backlight level. It should be between 0 and 1."); - return; - } - - /* - * To make sure that the _backlight atomic property still exists. - */ - _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); - if (_backlight == None) - { - WRN("Backlight setting is not supported on this server or driver"); - return; - } - - /* get the ressources */ - resources = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root); - if (!resources) return; - - for (o = 0; o < resources->noutput; o++) - { - output = resources->outputs[o]; - if (ecore_x_randr_output_backlight_level_get(root, output) >= 0) - { - ecore_x_randr_output_backlight_level_set(root, output, level); - } - } - XRRFreeScreenResources(resources); -#endif -} - -/* - * @brief Check if a backlight is available. - * @return Whether a backlight is available. - */ - -EAPI Eina_Bool -ecore_x_randr_output_backlight_available(void) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(-1); - Atom _backlight; - - _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); - - return (_backlight == None) ? EINA_FALSE : EINA_TRUE; - -#endif - return EINA_FALSE; -} - -/* - * @brief Get the backlight level of the given output. - * - * @param root Window which's screen should be queried. - * @param output From which the backlight level should be retrieved. - * @return The backlight level. - */ - -EAPI double -ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(-1); - Atom actual_type; - Atom _backlight; - XRRPropertyInfo *info = NULL; - double dvalue; - int actual_format; - long value, max, min; - unsigned long nitems; - unsigned long bytes_after; - unsigned char *prop = NULL; - - /* set backlight variable if not already done */ - - _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); - if (_backlight == None) - { - ERR("Backlight property is not suppported on this server or driver"); - return -1; - } - - if (!_ecore_x_randr_output_validate(root, output)) - { - ERR("Invalid output"); - return -1; - } - - if (XRRGetOutputProperty(_ecore_x_disp, output, _backlight, - 0, 4, False, False, None, - &actual_type, &actual_format, - &nitems, &bytes_after, &prop) != Success) - { - WRN("Backlight not supported on this output"); - return -1; - } - - if ((actual_type != XA_INTEGER) || (nitems != 1) || (actual_format != 32)) return -1; - - value = *((long *)prop); - free (prop); - - /* I have the current value of the backlight */ - /* Now retrieve the min and max intensities of the output */ - info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight); - if (info) - { - dvalue = -1; - if ((info->range) && (info->num_values == 2)) - { - /* finally convert the current value in the interval [0..1] */ - min = info->values[0]; - max = info->values[1]; - dvalue = ((double)(value - min)) / ((double)(max - min)); - } - free(info); - return dvalue; - } -#endif - return -1; -} - -/* - * @brief Set the backlight level of a given output. - * - * @param root Window which's screen should be queried. - * @param output That should be set. - * @param level For which the backlight should be set. - * @return @c EINA_TRUE in case of success. - */ - -EAPI Eina_Bool -ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, - Ecore_X_Randr_Output output, - double level) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_2_RET(EINA_FALSE); - Atom _backlight; - XRRPropertyInfo *info = NULL; - double min, max, tmp; - long new; - - if ((level < 0) || (level > 1)) - { - ERR("Backlight level should be between 0 and 1"); - return EINA_FALSE; - } - - if (!_ecore_x_randr_output_validate(root, output)) - { - ERR("Wrong output value"); - return EINA_FALSE; - } - - _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); - if (_backlight == None) - { - WRN("Backlight property is not suppported on this server or driver"); - return EINA_FALSE; - } - - info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight); - if (info) - { - if ((info->range) && (info->num_values == 2)) - { - min = info->values[0]; - max = info->values[1]; - tmp = (level * (max - min)) + min; - new = tmp; - if (new > max) new = max; - if (new < min) new = min; - XRRChangeOutputProperty(_ecore_x_disp, output, _backlight, XA_INTEGER, 32, - PropModeReplace, (unsigned char *)&new, 1); - XFlush(_ecore_x_disp); - } - free(info); - return EINA_TRUE; - } -#endif - return EINA_FALSE; -} - -/* - * @brief Get the outputs, which display a certain window. - * - * @param window Window the displaying outputs shall be found for - * @param num The number of outputs displaying the window - * @return Array of outputs that display a certain window. @c NULL if no - * outputs was found that displays the specified window. - */ - -EAPI Ecore_X_Randr_Output * -ecore_x_randr_window_outputs_get(Ecore_X_Window window, - int *num) -{ -#ifdef ECORE_XRANDR - Ecore_X_Window root; - Ecore_X_Randr_Crtc *crtcs; - Ecore_X_Randr_Output *outputs, *ret = NULL, *tret; - int ncrtcs, noutputs, i, nret = 0; - - if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail; - - root = ecore_x_window_root_get(window); - if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs))) - goto _ecore_x_randr_current_output_get_fail; - - for (i = 0, nret = 0; i < ncrtcs; i++) - { - - outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i], - &noutputs); - if (!outputs) - goto _ecore_x_randr_current_output_get_fail_free; - tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output))); - if (!tret) goto _ecore_x_randr_current_output_get_fail_free; - ret = tret; - memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output))); - nret += noutputs; - free(outputs); - outputs = NULL; - } - free(crtcs); - - if (num) - *num = nret; - - return ret; - -_ecore_x_randr_current_output_get_fail_free: - free(outputs); - free(crtcs); - free(ret); -_ecore_x_randr_current_output_get_fail: -#endif - if (num) *num = 0; - return NULL; -} - -/* - * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead. - * @brief Get the outputs, which display a certain window. - * - * @param window Window the displaying outputs shall be found for. - * @param num The number of outputs displaying the window. - * @return Array of outputs that display a certain window. @c NULL if no - * outputs was found that displays the specified window. - */ - -EAPI Ecore_X_Randr_Output * -ecore_x_randr_current_output_get(Ecore_X_Window window, - int *num) -{ - return ecore_x_randr_window_outputs_get(window, num); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c deleted file mode 100644 index 5bda332a06..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright 2006-2009 Red Hat, Inc. - * - * 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 - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, 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 (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * 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 NON-INFRINGEMENT. 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. - */ -/* Original Author: Adam Jackson */ -/* Heavily modified by: Leif Middelschulte */ - -#include "Ecore_X.h" -#include -#include -#include -#include - -/* TODO: - * - see other TODO's within this file. - */ - -#define ECORE_X_RANDR_EDID_VERSION_10 ((1 << 8) | 0) -#define ECORE_X_RANDR_EDID_VERSION_11 ((1 << 8) | 1) -#define ECORE_X_RANDR_EDID_VERSION_12 ((1 << 8) | 2) -#define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3) -#define ECORE_X_RANDR_EDID_VERSION_14 ((1 << 8) | 4) - -#define _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER 0x08 -#define _ECORE_X_RANDR_EDID_OFFSET_TYPE 0x14 -#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12 -#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13 -#define _ECORE_X_RANDR_EDID_OFFSET_DPMS 0x18 -#define _ECORE_X_RANDR_EDID_OFFSET_COLORSPACE 0x18 -#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36 -#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3 -#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5 -#define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED 15 -#define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO 14 - -#define _ECORE_X_RANDR_EDID_MASK_DIGITAL 0x80 -#define _ECORE_X_RANDR_EDID_MASK_DIGITAL_INTERFACE 0x0f -#define _ECORE_X_RANDR_EDID_MASK_DIGITAL_TMDS_DFP_10 0x01 -#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS 0x18 -#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444 0x10 -#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422 0x08 -#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED 0xe0 -#define _ECORE_X_RANDR_EDID_MASK_DPMS 0xE0 -#define _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY 0x80 -#define _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND 0x40 -#define _ECORE_X_RANDR_EDID_MASK_DPMS_OFF 0x20 -#define _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE 0x0f -#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3 0x80 -#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9 0x40 -#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10 0x20 -#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4 0x10 -#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9 0x08 - -#define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13 - -typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio_Preferred { - ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3 = 0x00, - ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9 = 0x01, - ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10 = 0x02, - ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4 = 0x03, - ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9 = 0x04 -} Ecore_X_Randr_Edid_Aspect_Ratio_Preferred; - -/* Some convenience loops */ -#define _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, extension_block_iter) \ - for (extension_block_iter = edid; extension_block_iter < (edid + edid_length); extension_block_iter += 128) - -#define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \ - _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, cea_block_iter) \ - if (cea_block_iter[0] == 0x02) - -/* The following macro is to be used with caution as it inherits another loop. - * Therefore using a 'break;' statement will lead to continuation in the - * inherent 'Extension block'-loop. - */ -#define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_DETAILED_BLOCK(edid, edid_length, cea_block_iter, detailed_block_iter) \ - _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \ - for (detailed_block_iter = cea_block_iter + cea_block_iter[2]; detailed_block_iter + 18 < cea_block_iter + 127; detailed_block_iter += 18) \ - if (detailed_block_iter[0]) - -#define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ - for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18) - -#define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \ - _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ - if ((block[0] == 0) && (block[1] == 0)) - -EAPI Eina_Bool -ecore_x_randr_edid_has_valid_header(unsigned char *edid, - unsigned long edid_length) -{ - const unsigned char header[] = - { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; - if (!edid) return EINA_FALSE; - if (edid_length < 8) return EINA_FALSE; - if (!memcmp(edid, header, 8)) return EINA_TRUE; - return EINA_FALSE; -} - -EAPI int -ecore_x_randr_edid_version_get(unsigned char *edid, - unsigned long edid_length) -{ - if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) && - (ecore_x_randr_edid_has_valid_header(edid, edid_length))) - return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) | - edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR]; - return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; -} - -EAPI int -ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, - unsigned long edid_length) -{ - if ((edid_length > 0x0b) && - (ecore_x_randr_edid_has_valid_header(edid, edid_length))) - return (int)(edid[0x0a] + (edid[0x0b] << 8)); - return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; -} - -EAPI int -ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, - unsigned long edid_length) -{ - if ((edid_length > 0x0f) && - (ecore_x_randr_edid_has_valid_header(edid, edid_length))) - return (int)(edid[0x0c] + (edid[0x0d] << 8) + - (edid[0x0e] << 16) + (edid[0x0f] << 24)); - return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; -} - -EAPI char * -ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, - unsigned long edid_length) -{ - if ((edid_length > (_ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER + 1)) && - (ecore_x_randr_edid_has_valid_header(edid, edid_length))) - { - unsigned char *x; - char *name; - - x = (edid + _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER); - name = malloc(sizeof(char) * 4); - if (!name) return NULL; - name[0] = ((x[0] & 0x7c) >> 2) + '@'; - name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xe0) >> 5) + '@'; - name[2] = (x[1] & 0x1f) + '@'; - name[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] = 0; - return name; - } - return NULL; -} - -EAPI char * -ecore_x_randr_edid_display_name_get(unsigned char *edid, - unsigned long edid_length) -{ - unsigned char *block = NULL; - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; - _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) - { - if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc) - { - char *name, *p; - const char *edid_name; - - edid_name = (const char *)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; - name = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); - if (!name) return NULL; - strncpy(name, edid_name, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); - name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; - for (p = name; *p; p++) - { - if ((*p < ' ') || (*p > '~')) *p = 0; - } - return name; - } - } - return NULL; -} - -EAPI Ecore_X_Randr_Edid_Aspect_Ratio -ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, - unsigned long edid_length) -{ - unsigned char *block = NULL; - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; - _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) - { - if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfd) && - (block[10] == 0x04)) - { - Ecore_X_Randr_Edid_Aspect_Ratio_Preferred preferred_ratio = - (Ecore_X_Randr_Edid_Aspect_Ratio_Preferred) - ((block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED] & - _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED) >> 5); - switch (preferred_ratio) - { - case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3: - return ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3; - - case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9: - return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9; - - case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10: - return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10; - - case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4: - return ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4; - - case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9: - return ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9; - - default: - return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; - } - } - } - return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; -} - -EAPI Ecore_X_Randr_Edid_Aspect_Ratio -ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, - unsigned long edid_length) -{ - Ecore_X_Randr_Edid_Aspect_Ratio ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; - unsigned char *block = NULL; - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; - _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) - { - if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfd) && - (block[10] == 0x04)) - { - if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3) - ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3; - if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9) - ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9; - if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10) - ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10; - if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4) - ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4; - if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9) - ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9; - } - } - return ret; -} - -EAPI char * -ecore_x_randr_edid_display_ascii_get(unsigned char *edid, - unsigned long edid_length) -{ - unsigned char *block = NULL; - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; - _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) - { - if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfe) - { - char *ascii, *p; - const char *edid_ascii = (const char *)block + - _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; - /* - * TODO: Two of these in a row, in the third and fourth slots, - * seems to be specified by SPWG: http://www.spwg.org/ - */ - ascii = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); - if (!ascii) return NULL; - strncpy(ascii, edid_ascii, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); - ascii[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; - for (p = ascii; *p; p++) - { - if ((*p < ' ') || (*p > '~')) *p = 0; - } - return ascii; - } - } - return NULL; -} - -EAPI char * -ecore_x_randr_edid_display_serial_get(unsigned char *edid, - unsigned long edid_length) -{ - unsigned char *block = NULL; - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; - _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) - { - if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xff) - { - char *serial, *p; - const char *edid_serial = (const char *)block + - _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; - /* - * TODO: Two of these in a row, in the third and fourth slots, - * seems to be specified by SPWG: http://www.spwg.org/ - */ - serial = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); - if (!serial) return NULL; - strncpy(serial, edid_serial, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); - serial[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; - for (p = serial; *p; p++) - { - if ((*p < ' ') || (*p > '~')) *p = 0; - } - return serial; - } - } - return NULL; -} - -EAPI Eina_Bool -ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, - unsigned long edid_length) -{ - unsigned char *cea_block_iter = NULL; - char sum = 0; - int i; - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; - if (edid_length < 128) return EINA_FALSE; - - /* Check the EDID block itself */ - for (i = 0; i < 128; i++) - sum += edid[i]; - if (sum) return EINA_FALSE; - - /* Check the cea extension blocks */ - _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) - { - for (i = 0, sum = 0; i < 128; i++) - sum += cea_block_iter[i]; - } - if (sum) return EINA_FALSE; - return EINA_TRUE; -} - -EAPI Eina_Bool -ecore_x_randr_edid_dpms_available_get(unsigned char *edid, - unsigned long edid_length) -{ - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; - return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & - _ECORE_X_RANDR_EDID_MASK_DPMS); -} - -EAPI Eina_Bool -ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, - unsigned long edid_length) -{ - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; - if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) - return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & - _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY); - return EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, - unsigned long edid_length) -{ - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; - if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) - return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & - _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND); - return EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, - unsigned long edid_length) -{ - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; - if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) - return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & - _ECORE_X_RANDR_EDID_MASK_DPMS_OFF); - return EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, - unsigned long edid_length) -{ - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; - return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] & - _ECORE_X_RANDR_EDID_MASK_DIGITAL); -} - -EAPI Ecore_X_Randr_Edid_Display_Colorscheme -ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, - unsigned long edid_length) -{ - Ecore_X_Randr_Edid_Display_Colorscheme colorscheme = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return colorscheme; - if (ecore_x_randr_edid_display_type_digital_get(edid, edid_length)) - { - colorscheme = ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4; - if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & - _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444) - colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4; - if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & - _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422) - colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2; - } - else - colorscheme = edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS; - return colorscheme; -} - -EAPI Ecore_X_Randr_Edid_Display_Interface_Type -ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, - unsigned long edid_length) -{ - Ecore_X_Randr_Edid_Display_Interface_Type type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; - int version = ecore_x_randr_edid_version_get(edid, edid_length); - - if (version < ECORE_X_RANDR_EDID_VERSION_13) return type; - type = edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] & - _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE; - if (type > ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT) - type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; - return type; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_13.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_13.c deleted file mode 100644 index 5d1c8e96db..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_randr_13.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2 - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "ecore_x_private.h" -#include "ecore_x_randr.h" -#include -#include -#include -#include - -#define Ecore_X_Randr_None 0 -#define Ecore_X_Randr_Unset -1 - -#ifdef ECORE_XRANDR - -#define RANDR_1_3 ((1 << 16) | 3) -#define RANDR_CHECK_1_3_RET(ret) if (_randr_version < RANDR_1_3) \ - return ret - -extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * - dpy, - Window - window); -extern int _randr_version; -#endif - -/* - * @param root window which's screen should be queried - * @return Ecore_X_Randr_Ouptut_Id or - if query failed or none is set - Ecore_X_Randr_None - */ -EAPI Ecore_X_Randr_Output -ecore_x_randr_primary_output_get(Ecore_X_Window root) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_3_RET(Ecore_X_Randr_None); - if (!_ecore_x_randr_root_validate(root)) - return Ecore_X_Randr_None; - - return XRRGetOutputPrimary(_ecore_x_disp, root); -#else - return Ecore_X_Randr_None; -#endif -} - -/* - * @param root window which's screen should be queried - * @param output that should be set as given root window's screen primary output - */ -EAPI void -ecore_x_randr_primary_output_set(Ecore_X_Window root, - Ecore_X_Randr_Output output) -{ -#ifdef ECORE_XRANDR - RANDR_CHECK_1_3_RET(); - - if (_ecore_x_randr_output_validate(root, output)) - { - XRRSetOutputPrimary(_ecore_x_disp, root, output); - } - -#endif -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_region.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_region.c deleted file mode 100644 index 81d7eea49c..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_region.c +++ /dev/null @@ -1,158 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#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 Eina_Bool -ecore_x_xregion_set(Ecore_X_XRegion *region, - Ecore_X_GC gc) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return XSetRegion(_ecore_x_disp, gc, (Region)region) ? EINA_TRUE : EINA_FALSE; -} - -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 Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -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) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_xregion_is_empty(Ecore_X_XRegion *region) -{ - if (!region) - return EINA_TRUE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return XEmptyRegion((Region)region) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, - Ecore_X_XRegion *r2) -{ - if (!r1 || !r2) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return XEqualRegion((Region)r1, (Region)r1) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_xregion_point_contain(Ecore_X_XRegion *region, - int x, - int y) -{ - if (!region) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return XPointInRegion((Region)region, x, y) ? EINA_TRUE : EINA_FALSE; -} - -EAPI Eina_Bool -ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, - Ecore_X_Rectangle *rect) -{ - if (!region || !rect) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return XRectInRegion((Region)region, - rect->x, - rect->y, - rect->width, - rect->height) ? EINA_TRUE : EINA_FALSE; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_screensaver.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_screensaver.c deleted file mode 100644 index 3688a44c56..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_screensaver.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Screensaver code - */ - -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include "Ecore.h" -#include "ecore_x_private.h" -#include "Ecore_X.h" -#include "Ecore_X_Atoms.h" - -static int _screensaver_available = -1; - -EAPI Eina_Bool -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 /* ifdef ECORE_XSS */ - _screensaver_available = 0; -#endif /* ifdef ECORE_XSS */ - 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; -#else - return 0; -#endif /* ifdef ECORE_XSS */ -} - -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(Eina_Bool 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 | ScreenSaverCycle); - else - XScreenSaverSelectInput(_ecore_x_disp, root, 0); -#else - return; - on = EINA_FALSE; -#endif /* ifdef ECORE_XSS */ -} - - -EAPI Eina_Bool -ecore_x_screensaver_custom_blanking_enable(void) -{ -#ifdef ECORE_XSS - XSetWindowAttributes attr; - - XScreenSaverSetAttributes(_ecore_x_disp, - DefaultRootWindow(_ecore_x_disp), - -9999, -9999, 1, 1, 0, - CopyFromParent, InputOnly, CopyFromParent, - 0, &attr); - return EINA_TRUE; -#else - return EINA_FALSE; -#endif /* ifdef ECORE_XSS */ -} - -EAPI Eina_Bool -ecore_x_screensaver_custom_blanking_disable(void) -{ -#ifdef ECORE_XSS - XScreenSaverUnsetAttributes(_ecore_x_disp, - DefaultRootWindow(_ecore_x_disp)); - return EINA_TRUE; -#else - return EINA_FALSE; -#endif /* ifdef ECORE_XSS */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_selection.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_selection.c deleted file mode 100644 index 3e1d2d34a2..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_selection.c +++ /dev/null @@ -1,1021 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_ALLOCA_H -# include -#elif !defined alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif !defined HAVE_ALLOCA -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#include -#include - -#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_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 /* ifdef X_HAVE_UTF8_STRING */ - 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; -} - -Eina_Bool -_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 EINA_FALSE; - - 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 EINA_FALSE; - - 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); - if (!buf) return EINA_FALSE; - 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 EINA_TRUE; -} - -/** - * 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 Eina_Bool -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 Eina_Bool -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 Eina_Bool -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 Eina_Bool -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 Eina_Bool -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 Eina_Bool -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 Eina_Bool -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 Eina_Bool -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, - Eina_Bool (*func)(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *ttype, - int *tsize)) -{ - 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)); - if (!cnv->next) return; - cnv = cnv->next; - } - else - { - converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); - if (!converters) return; - cnv = converters; - } - - cnv->target = target; - cnv->convert = func; -} - -EAPI void -ecore_x_selection_converter_add(char *target, - Eina_Bool (*func)(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *, - int *)) -{ - 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 Eina_Bool -ecore_x_selection_notify_send(Ecore_X_Window requestor, - Ecore_X_Atom selection, - Ecore_X_Atom target, - Ecore_X_Atom property, - Ecore_X_Time tim) -{ - 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 = tim; - xnotify.send_event = True; - xnotify.serial = 0; - - xev.xselection = xnotify; - return (XSendEvent(_ecore_x_disp, requestor, False, 0, &xev) > 0) ? EINA_TRUE : EINA_FALSE; -} - -/* Locate and run conversion callback for specified selection target */ -EAPI Eina_Bool -ecore_x_selection_convert(Ecore_X_Atom selection, - Ecore_X_Atom target, - void **data_ret, - int *size, - Ecore_X_Atom *targtype, - int *typesize) -{ - Ecore_X_Selection_Intern *sel; - Ecore_X_Selection_Converter *cnv; - void *data; - 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, - targtype, typesize); - free(tgt_str); - if (r) - { - *data_ret = data; - return r; - } - else - return EINA_FALSE; - } - } - - /* 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 EINA_FALSE; - - /* 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 */ -EAPI Eina_Bool -ecore_x_selection_converter_text(char *target, - void *data, - int size, - void **data_ret, - int *size_ret, - Ecore_X_Atom *targprop EINA_UNUSED, - int *s EINA_UNUSED) -{ - XTextProperty text_prop; - char *mystr; - XICCEncodingStyle style; - - if (!data || !size) - return EINA_FALSE; - - 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 /* ifdef X_HAVE_UTF8_STRING */ - else - return EINA_FALSE; - - mystr = alloca(size + 1); - memcpy(mystr, data, size); - mystr[size] = '\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); - if (!*data_ret) - { - return EINA_FALSE; - } - memcpy(*data_ret, text_prop.value, bufsize); - *size_ret = bufsize; - XFree(text_prop.value); - return EINA_TRUE; - } - -#else /* ifdef X_HAVE_UTF8_STRING */ - if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, - &text_prop) == Success) - { - int bufsize = strlen(text_prop.value) + 1; - *data_ret = malloc(bufsize); - if (!*data_ret) return EINA_FALSE; - memcpy(*data_ret, text_prop.value, bufsize); - *size_ret = bufsize; - XFree(text_prop.value); - return EINA_TRUE; - } - -#endif /* ifdef X_HAVE_UTF8_STRING */ - else - { - return EINA_TRUE; - } -} - -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)); - if (!prs->next) return; - prs = prs->next; - } - else - { - parsers = calloc(1, sizeof(Ecore_X_Selection_Parser)); - if (!parsers) return; - 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; - } -} - -/** - * Change the owner and last-change time for the specified selection. - * @param win The owner of the specified atom. - * @param atom The selection atom - * @param tim Specifies the time - * @since 1.1.0 - */ -EAPI void -ecore_x_selection_owner_set(Ecore_X_Window win, - Ecore_X_Atom atom, - Ecore_X_Time tim) -{ - XSetSelectionOwner(_ecore_x_disp, atom, win, tim); -} - -/** - * Return the window that currently owns the specified selection. - * - * @param atom The specified selection atom. - * - * @return The window that currently owns the specified selection. - * @since 1.1.0 - */ -EAPI Ecore_X_Window -ecore_x_selection_owner_get(Ecore_X_Atom atom) -{ - return XGetSelectionOwner(_ecore_x_disp, atom); -} - -/* 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); - if (sel) return sel; - } - } - - /* Default, just return the data */ - sel = calloc(1, sizeof(Ecore_X_Selection_Data)); - if (!sel) return NULL; - 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 EINA_UNUSED) -{ - Ecore_X_Selection_Data_Files *sel; - char *t, *data = _data; - int i, is; - char *tmp; - char **t2; - - if (strcmp(target, "text/uri-list") && - strcmp(target, "_NETSCAPE_URL")) - return NULL; - - sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files)); - if (!sel) return NULL; - ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free; - - if (data && data[size - 1]) - { - /* Isn't nul terminated */ - size++; - t = realloc(data, size); - if (!t) - { - free(sel); - return NULL; - } - data = t; - data[size - 1] = 0; - } - - tmp = malloc(size); - if (!tmp) - { - free(sel); - return NULL; - } - 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++; - t2 = realloc(sel->files, sel->num_files * sizeof(char *)); - if (t2) - { - sel->files = t2; - sel->files[sel->num_files - 1] = strdup(tmp); - } - tmp[0] = 0; - i = 0; - } - } - } - if (i > 0) - { - tmp[i] = 0; - sel->num_files++; - t2 = realloc(sel->files, sel->num_files * sizeof(char *)); - if (t2) - { - sel->files = t2; - 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 EINA_UNUSED, - void *_data, - int size, - int format EINA_UNUSED) -{ - Ecore_X_Selection_Data_Text *sel; - unsigned char *data = _data; - void *t; - - sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); - if (!sel) return NULL; - if (data && data[size - 1]) - { - /* Isn't nul terminated */ - size++; - t = realloc(data, size); - if (!t) - { - free(sel); - return NULL; - } - data = t; - 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)->data = data; - 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 EINA_UNUSED, - void *data, - int size, - int format EINA_UNUSED) -{ - Ecore_X_Selection_Data_Targets *sel; - unsigned long *targets; - int i; - - sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); - if (!sel) return NULL; - targets = (unsigned long *)data; - - sel->num_targets = size - 2; - sel->targets = malloc((size - 2) * sizeof(char *)); - if (!sel->targets) - { - free(sel); - return NULL; - } - for (i = 2; i < size; i++) - sel->targets[i - 2] = XGetAtomName(_ecore_x_disp, targets[i]); - - 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; - ECORE_X_SELECTION_DATA(sel)->data = data; - 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(ECORE_X_SELECTION_DATA(sel)->data); - free(sel); - return 1; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_sync.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_sync.c deleted file mode 100644 index 0c7f546f1a..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_sync.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * XSync code - */ - -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#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 Eina_Bool -ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - return XSyncDestroyAlarm(_ecore_x_disp, alarm); -} - -EAPI Eina_Bool -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 EINA_TRUE; - } - - return EINA_FALSE; -} - -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 -} - -EAPI void -ecore_x_sync_counter_set(Ecore_X_Sync_Counter counter, - int val) -{ - XSyncValue v; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XSyncIntToValue(&v, val); - XSyncSetCounter(_ecore_x_disp, counter, v); -} - -EAPI void -ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter, - int val_hi, - unsigned int val_lo) -{ - XSyncValue v; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XSyncIntsToValue(&v, val_lo, val_hi); - XSyncSetCounter(_ecore_x_disp, counter, v); -} - -EAPI Eina_Bool -ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter, - int *val_hi, - unsigned int *val_lo) -{ - XSyncValue value; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (XSyncQueryCounter(_ecore_x_disp, counter, &value)) - { - *val_lo = (unsigned int)XSyncValueLow32(value); - *val_hi = (int)XSyncValueHigh32(value); - return EINA_TRUE; - } - return EINA_FALSE; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_test.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_test.c deleted file mode 100644 index 4eec6b74b3..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_test.c +++ /dev/null @@ -1,167 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - -#ifdef ECORE_XTEST -# include -#endif /* ifdef ECORE_XTEST */ - -#include "ecore_x_private.h" -#include "Ecore_X.h" -#include - -EAPI Eina_Bool -#ifdef ECORE_XTEST -ecore_x_test_fake_key_down(const char *key) -#else -ecore_x_test_fake_key_down(const char *key EINA_UNUSED) -#endif -{ -#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 EINA_FALSE; - - keycode = XKeysymToKeycode(_ecore_x_disp, keysym); - } - - if (keycode == 0) - return EINA_FALSE; - - return XTestFakeKeyEvent(_ecore_x_disp, keycode, 1, 0) ? EINA_TRUE : EINA_FALSE; -#else /* ifdef ECORE_XTEST */ - return EINA_FALSE; -#endif /* ifdef ECORE_XTEST */ -} - -EAPI Eina_Bool -#ifdef ECORE_XTEST -ecore_x_test_fake_key_up(const char *key) -#else -ecore_x_test_fake_key_up(const char *key EINA_UNUSED) -#endif -{ -#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 EINA_FALSE; - - keycode = XKeysymToKeycode(_ecore_x_disp, keysym); - } - - if (keycode == 0) - return EINA_FALSE; - - return XTestFakeKeyEvent(_ecore_x_disp, keycode, 0, 0) ? EINA_TRUE : EINA_FALSE; -#else /* ifdef ECORE_XTEST */ - return EINA_FALSE; -#endif /* ifdef ECORE_XTEST */ -} - -EAPI Eina_Bool -#ifdef ECORE_XTEST -ecore_x_test_fake_key_press(const char *key) -#else -ecore_x_test_fake_key_press(const char *key EINA_UNUSED) -#endif -{ -#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 EINA_FALSE; - - keycode = XKeysymToKeycode(_ecore_x_disp, keysym); - if (_ecore_x_XKeycodeToKeysym(_ecore_x_disp, keycode, 0) != keysym) - { - if (_ecore_x_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 EINA_TRUE; -#else /* ifdef ECORE_XTEST */ - return EINA_FALSE; -#endif /* ifdef ECORE_XTEST */ -} - -EAPI const char * -ecore_x_keysym_string_get(int keysym) -{ - return XKeysymToString(keysym); -} - -EAPI int -ecore_x_keysym_keycode_get(const char *keyname) -{ - int keycode = 0; - - if (!strncmp(keyname, "Keycode-", 8)) - keycode = atoi(keyname + 8); - else - keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(keyname)); - - return keycode; -} diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_vsync.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_vsync.c deleted file mode 100644 index a316a33c45..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_vsync.c +++ /dev/null @@ -1,351 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include "Ecore.h" -#include "ecore_x_private.h" -#include "Ecore_X.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ECORE_X_VSYNC_DRI2 1 - -#ifdef ECORE_X_VSYNC_DRI2 -// relevant header bits of dri/drm inlined here to avoid needing external -// headers to build -/// drm -typedef unsigned int drm_magic_t; - -typedef enum -{ - DRM_VBLANK_ABSOLUTE = 0x00000000, - DRM_VBLANK_RELATIVE = 0x00000001, - DRM_VBLANK_EVENT = 0x04000000, - DRM_VBLANK_FLIP = 0x08000000, - DRM_VBLANK_NEXTONMISS = 0x10000000, - DRM_VBLANK_SECONDARY = 0x20000000, - DRM_VBLANK_SIGNAL = 0x40000000 -} -drmVBlankSeqType; - -typedef struct _drmVBlankReq -{ - drmVBlankSeqType type; - unsigned int sequence; - unsigned long signal; -} drmVBlankReq; - -typedef struct _drmVBlankReply -{ - drmVBlankSeqType type; - unsigned int sequence; - long tval_sec; - long tval_usec; -} drmVBlankReply; - -typedef union _drmVBlank -{ - drmVBlankReq request; - drmVBlankReply reply; -} drmVBlank; - -#define DRM_EVENT_CONTEXT_VERSION 2 - -typedef struct _drmEventContext -{ - int version; - void (*vblank_handler)(int fd, - unsigned int sequence, - unsigned int tv_sec, - unsigned int tv_usec, - void *user_data); - void (*page_flip_handler)(int fd, - unsigned int sequence, - unsigned int tv_sec, - unsigned int tv_usec, - void *user_data); -} drmEventContext; - -static int (*sym_drmClose)(int fd) = NULL; -static int (*sym_drmGetMagic)(int fd, - drm_magic_t *magic) = NULL; -static int (*sym_drmWaitVBlank)(int fd, - drmVBlank *vbl) = NULL; -static int (*sym_drmHandleEvent)(int fd, - drmEventContext *evctx) = NULL; - -//// dri - -static Bool (*sym_DRI2QueryExtension)(Display *display, - int *eventBase, - int *errorBase) = NULL; -static Bool (*sym_DRI2QueryVersion)(Display *display, - int *major, - int *minor) = NULL; -static Bool (*sym_DRI2Connect)(Display *display, - XID window, - char **driverName, - char **deviceName) = NULL; -static Bool (*sym_DRI2Authenticate)(Display *display, - XID window, - drm_magic_t magic) = NULL; - -//// dri/drm data needed -static int dri2_event = 0; -static int dri2_error = 0; -static int dri2_major = 0; -static int dri2_minor = 0; -static char *device_name = 0; -static char *driver_name = 0; -static drm_magic_t drm_magic; - -static int drm_fd = -1; -static int drm_event_is_busy = 0; -static int drm_animators_interval = 1; -static drmEventContext drm_evctx; -static Ecore_Fd_Handler *dri_drm_fdh = NULL; - -static void *dri_lib = NULL; -static void *drm_lib = NULL; - -static Window dri_drm_vsync_root = 0; - -static void -_dri_drm_tick_schedule(void) -{ - drmVBlank vbl; - - vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; - vbl.request.sequence = drm_animators_interval; - vbl.request.signal = 0; - sym_drmWaitVBlank(drm_fd, &vbl); -} - -static void -_dri_drm_tick_begin(void *data EINA_UNUSED) -{ - drm_event_is_busy = 1; - _dri_drm_tick_schedule(); -} - -static void -_dri_drm_tick_end(void *data EINA_UNUSED) -{ - drm_event_is_busy = 0; -} - -static void -_dri_drm_vblank_handler(int fd EINA_UNUSED, - unsigned int frame EINA_UNUSED, - unsigned int sec EINA_UNUSED, - unsigned int usec EINA_UNUSED, - void *data EINA_UNUSED) -{ - ecore_animator_custom_tick(); - if (drm_event_is_busy) _dri_drm_tick_schedule(); -} - -static Eina_Bool -_dri_drm_cb(void *data EINA_UNUSED, - Ecore_Fd_Handler *fd_handler EINA_UNUSED) -{ - sym_drmHandleEvent(drm_fd, &drm_evctx); - return ECORE_CALLBACK_RENEW; -} - -// yes. most evil. we dlopen libdrm and libGL etc. to manually find smbols -// so we can be as compatible as possible given the whole mess of the -// gl/dri/drm etc. world. and handle graceful failure at runtime not -// compile time -static int -_dri_drm_link(void) -{ - const char *drm_libs[] = - { - "libdrm.so.2", - "libdrm.so.1", - "libdrm.so.0", - "libdrm.so", - NULL, - }; - const char *dri_libs[] = - { - "libdri2.so.2", - "libdri2.so.1", - "libdri2.so.0", - "libdri2.so", - "libGL.so.4", - "libGL.so.3", - "libGL.so.2", - "libGL.so.1", - "libGL.so.0", - "libGL.so", - NULL, - }; - int i, fail; -#define SYM(lib, xx) \ - do { \ - sym_ ## xx = dlsym(lib, #xx); \ - if (!(sym_ ## xx)) { \ - fprintf(stderr, "%s\n", dlerror()); \ - fail = 1; \ - } \ - } while (0) - - if (dri_lib) return 1; - for (i = 0; drm_libs[i]; i++) - { - drm_lib = dlopen(drm_libs[i], RTLD_LOCAL | RTLD_LAZY); - if (drm_lib) - { - fail = 0; - SYM(drm_lib, drmClose); - SYM(drm_lib, drmWaitVBlank); - SYM(drm_lib, drmHandleEvent); - if (fail) - { - dlclose(drm_lib); - drm_lib = NULL; - } - else break; - } - } - if (!drm_lib) return 0; - for (i = 0; dri_libs[i]; i++) - { - dri_lib = dlopen(dri_libs[i], RTLD_LOCAL | RTLD_LAZY); - if (dri_lib) - { - fail = 0; - SYM(dri_lib, DRI2QueryExtension); - SYM(dri_lib, DRI2QueryVersion); - SYM(dri_lib, DRI2Connect); - SYM(dri_lib, DRI2Authenticate); - if (fail) - { - dlclose(dri_lib); - dri_lib = NULL; - } - else break; - } - } - if (!dri_lib) - { - dlclose(drm_lib); - drm_lib = NULL; - return 0; - } - return 1; -} - -static int -_dri_drm_init(void) -{ - if (!sym_DRI2QueryExtension(_ecore_x_disp, &dri2_event, &dri2_error)) - return 0; - if (!sym_DRI2QueryVersion(_ecore_x_disp, &dri2_major, &dri2_minor)) - return 0; - if (dri2_major < 2) - return 0; - if (!sym_DRI2Connect(_ecore_x_disp, dri_drm_vsync_root, &driver_name, &device_name)) - return 0; - drm_fd = open(device_name, O_RDWR); - if (drm_fd < 0) - return 0; - sym_drmGetMagic(drm_fd, &drm_magic); - if (!sym_DRI2Authenticate(_ecore_x_disp, dri_drm_vsync_root, drm_magic)) - { - close(drm_fd); - drm_fd = -1; - return 0; - } - memset(&drm_evctx, 0, sizeof(drm_evctx)); - drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; - drm_evctx.vblank_handler = _dri_drm_vblank_handler; - drm_evctx.page_flip_handler = NULL; - - dri_drm_fdh = ecore_main_fd_handler_add(drm_fd, ECORE_FD_READ, - _dri_drm_cb, NULL, NULL, NULL); - if (!dri_drm_fdh) - { - close(drm_fd); - drm_fd = -1; - return 0; - } - return 1; -} - -static void -_dri_drm_shutdown(void) -{ - if (drm_fd >= 0) - { - close(drm_fd); - drm_fd = -1; - } - if (dri_drm_fdh) - { - ecore_main_fd_handler_del(dri_drm_fdh); - dri_drm_fdh = NULL; - } -} - -#endif - -EAPI Eina_Bool -ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win) -{ -#ifdef ECORE_X_VSYNC_DRI2 - Ecore_X_Window root; - - root = ecore_x_window_root_get(win); - if (root != dri_drm_vsync_root) - { - dri_drm_vsync_root = root; - if (dri_drm_vsync_root) - { - if (!_dri_drm_link()) - { - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); - return EINA_FALSE; - } - _dri_drm_shutdown(); - if (!_dri_drm_init()) - { - dri_drm_vsync_root = 0; - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); - return EINA_FALSE; - } - ecore_animator_custom_source_tick_begin_callback_set - (_dri_drm_tick_begin, NULL); - ecore_animator_custom_source_tick_end_callback_set - (_dri_drm_tick_end, NULL); - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); - } - else - { - if (drm_fd >= 0) - { - _dri_drm_shutdown(); - ecore_animator_custom_source_tick_begin_callback_set - (NULL, NULL); - ecore_animator_custom_source_tick_end_callback_set - (NULL, NULL); - ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); - } - } - } - return EINA_TRUE; -#else - return EINA_FALSE; - win = 0; -#endif -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window.c deleted file mode 100644 index 36fc5cc53a..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window.c +++ /dev/null @@ -1,1727 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include -#include -#include - -#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_Group - */ -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, cnt; - Ecore_X_Window *t; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (ignore) - { - if (ignore_list) - { - for (i = 0; i < ignore_num; i++) - { - if (win == ignore_list[i]) - return; - } - t = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window)); - if (!t) return; - ignore_list = t; - ignore_list[ignore_num++] = win; - } - else - { - ignore_num = 0; - ignore_list = malloc(sizeof(Ecore_X_Window)); - if (ignore_list) - ignore_list[ignore_num++] = win; - } - } - else - { - if (!ignore_list) - return; - - for (cnt = ignore_num, i = 0, j = 0; i < cnt; i++) - { - if (win != ignore_list[i]) - ignore_list[j++] = ignore_list[i]; - else - ignore_num--; - } - - if (ignore_num <= 0) - { - free(ignore_list); - ignore_list = NULL; - return; - } - t = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window)); - if (t) ignore_list = t; - } -} - -/** - * 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); - - XUnmapWindow(_ecore_x_disp, win); - 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); -} - -/** - * @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 window that has focus. - * @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. - * - * Note that the x & y coordinates are relative to your parent. In - * particular for reparenting window managers - relative to you window border. - * If you want screen coordinates either walk the window tree to the root, - * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary - * applications can use elm_win_screen_position_get(). - * - * @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); -} - -/** - * @brief Show the cursor on a window of type Ecore_X_Window. - * @param win The window for which the cursor will be showed. - * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE. - */ -EAPI void -ecore_x_window_cursor_show(Ecore_X_Window win, - Eina_Bool 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 int -_inside_rects(Shadow *s, - int x, - int y, - int bx, - int by, - Ecore_X_Rectangle *rects, - int num) -{ - int i, inside; - - if (!rects) return 0; - inside = 0; - for (i = 0; i < num; i++) - { - if ((x >= s->x + bx + rects[i].x) && - (y >= s->y + by + rects[i].y) && - (x < (int)(s->x + bx + rects[i].x + rects[i].width)) && - (y < (int)(s->y + by + rects[i].y + rects[i].height))) - { - inside = 1; - break; - } - } - free(rects); - return inside; -} - -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; - - /* FIXME: get shape */ - { - int num; - Ecore_X_Rectangle *rects; - - num = 0; - rects = ecore_x_window_shape_rectangles_get(s->win, &num); - if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0; - num = 0; - rects = ecore_x_window_shape_input_rectangles_get(s->win, &num); - if (!_inside_rects(s, x, y, bx, by, rects, num)) 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. - * @param skip The list of windows to be skipped. - * @param skip_num The number of windows to be skipped. - * @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 EINA_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. - * @param skip The list of windows to be skipped. - * @param skip_num The number of windows to be skipped. - * @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, - Eina_Bool 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, - Eina_Bool override, - Eina_Bool 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) - 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 /* ifdef ECORE_XRENDER */ - -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 /* ifdef ECORE_XRENDER */ - return 0; -#endif /* ifdef ECORE_XRENDER */ -} - -/** - * 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 /* ifdef ECORE_XRENDER */ - return 0; -#endif /* ifdef ECORE_XRENDER */ -} - -/** - * 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 /* ifdef ECORE_XRENDER */ - return 0; -#endif /* ifdef ECORE_XRENDER */ -} - -/** - * 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 /* ifdef ECORE_XRENDER */ - return 0; -#endif /* ifdef ECORE_XRENDER */ -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window_prop.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window_prop.c deleted file mode 100644 index 535c521941..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window_prop.c +++ /dev/null @@ -1,760 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include -#include - -#include "Ecore.h" -#include "ecore_x_private.h" -#include "Ecore_X.h" -#include "Ecore_X_Atoms.h" -#include -#include - -#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 /* if SIZEOF_INT == SIZEOF_LONG */ - 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 /* if SIZEOF_INT == SIZEOF_LONG */ -} - -/* - * 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)); - if (!val) - { - if (prop_ret) XFree(prop_ret); - return -1; - } - 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 /* if SIZEOF_INT == SIZEOF_LONG */ - 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 /* if SIZEOF_INT == SIZEOF_LONG */ -} - -/* - * 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); -} - -EAPI Ecore_X_Atom -ecore_x_window_prop_any_type(void) -{ - return AnyPropertyType; -} - -/** - * @brief Set a property of Ecore_X_Window. - * @param win The window for which the property will be set. - * @param property The property of the window to be set. - * @param type The type of the property that will be set. - * @param size The size of the property that will be set. - * @param data The data of the property that will be set. - * @param number The size of data. - */ -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); - } - } -} - -/** - * @brief Get a property of Ecore_X_Window. - * @note If there aren't any data to be got the function return NULL. - * If the function can't allocate the memory then 0 is returned. - * @param win The window for which the property will be got. - * @param property The property of the window that will be gotten. - * @param type The type of the property that will be gotten. - * @param size This parameter isn't in use. - * @param data The data of the property that will be gotten. - * @param num The size of property. - * @return size_ret The size of array that contains the property. - */ -EAPI int -ecore_x_window_prop_property_get(Ecore_X_Window win, - Ecore_X_Atom property, - Ecore_X_Atom type, - int size EINA_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 /* ifdef X_HAVE_UTF8_STRING */ - s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp, - &list, &items); -#endif /* ifdef X_HAVE_UTF8_STRING */ - 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 Eina_Bool -ecore_x_window_prop_protocol_isset(Ecore_X_Window win, - Ecore_X_WM_Protocol protocol) -{ - Atom proto, *protos = NULL; - int i, protos_count = 0; - Eina_Bool ret = EINA_FALSE; - - /* check for invalid values */ - if (protocol >= ECORE_X_WM_PROTOCOL_NUM) - return EINA_FALSE; - - 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 = EINA_TRUE; - break; - } - - XFree(protos); - - return ret; -} - -/** - * @brief Get a array containing the protocols of @a win - * @note If there aren't any properties to be counted or any protocols to get - * then the function returns NULL. - * @param win The window for which protocol list will be got. - * @param num_ret Contains the number of elements of the array to be returned. - * @return The array that contains the protocols. - */ -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; -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window_shape.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window_shape.c deleted file mode 100644 index 71718cfa3a..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_window_shape.c +++ /dev/null @@ -1,658 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - -#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); -} - -/** - * Sets the input shape of the given window to that given by the pixmap @p mask. - * @param win The given window. - * @param mask A 1-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 /* ifdef ShapeInput */ - return; - win = mask = 0; -#endif /* ifdef ShapeInput */ -} - -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_input_window_set(Ecore_X_Window win, - Ecore_X_Window shape_win) -{ -#ifdef ShapeInput - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XShapeCombineShape(_ecore_x_disp, - win, - ShapeInput, - 0, - 0, - shape_win, - ShapeInput, - ShapeSet); -#else - return; - win = shape_win = 0; -#endif -} - -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_input_window_set_xy(Ecore_X_Window win, - Ecore_X_Window shape_win, - int x, - int y) -{ -#ifdef ShapeInput - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XShapeCombineShape(_ecore_x_disp, - win, - ShapeInput, - x, - y, - shape_win, - ShapeInput, - ShapeSet); -#else - return; - win = shape_win = x = y = 0; -#endif -} - -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_input_rectangle_set(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ShapeInput - XRectangle rect; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeInput, - 0, - 0, - &rect, - 1, - ShapeSet, - Unsorted); -#else - return; - win = x = y = w = h = 0; -#endif -} - -EAPI void -ecore_x_window_shape_rectangles_set(Ecore_X_Window win, - Ecore_X_Rectangle *rects, - int num) -{ -#ifdef ShapeInput - XRectangle *rect = NULL; - int i; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!rects) return; - if (num > 0) - { - rect = malloc(sizeof(XRectangle) * num); - if (!rect) return; - 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; - } - } - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeBounding, - 0, - 0, - rect, - num, - ShapeSet, - Unsorted); - if (rect) free(rect); -#else - return; - win = rects = num = 0; -#endif -} - -EAPI void -ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win, - Ecore_X_Rectangle *rects, - int num) -{ -#ifdef ShapeInput - XRectangle *rect = NULL; - int i; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!rects) return; - if (num > 0) - { - rect = malloc(sizeof(XRectangle) * num); - if (!rect) return; - 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; - } - } - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeInput, - 0, - 0, - rect, - num, - ShapeSet, - Unsorted); - if (rect) free(rect); -#else - return; - win = rects = num = 0; -#endif -} - -EAPI void -ecore_x_window_shape_rectangle_subtract(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, - ShapeSubtract, - Unsorted); -} - -EAPI void -ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ShapeInput - XRectangle rect; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeInput, - 0, - 0, - &rect, - 1, - ShapeSubtract, - Unsorted); -#else - return; - win = x = y = w = h = 0; -#endif -} - -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_input_window_add_xy(Ecore_X_Window win, - Ecore_X_Window shape_win, - int x, - int y) -{ -#ifdef ShapeInput - LOGFN(__FILE__, __LINE__, __FUNCTION__); - XShapeCombineShape(_ecore_x_disp, - win, - ShapeInput, - x, - y, - shape_win, - ShapeInput, - ShapeUnion); -#else - return; - win = shape_win = x = y = 0; -#endif -} - -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_input_rectangle_add(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ShapeInput - XRectangle rect; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeInput, - 0, - 0, - &rect, - 1, - ShapeUnion, - Unsorted); -#else - return; - win = x = y = w = h = 0; -#endif -} - -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_input_rectangle_clip(Ecore_X_Window win, - int x, - int y, - int w, - int h) -{ -#ifdef ShapeInput - XRectangle rect; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeInput, - 0, - 0, - &rect, - 1, - ShapeIntersect, - Unsorted); -#else - return; - win = x = y = w = h = 0; -#endif -} - -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) return; - 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; - } - } - - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeBounding, - 0, - 0, - rect, - num, - ShapeUnion, - Unsorted); - if (rect) free(rect); -} - -EAPI void -ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win, - Ecore_X_Rectangle *rects, - int num) -{ -#ifdef ShapeInput - XRectangle *rect = NULL; - int i; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (num > 0) - { - rect = malloc(sizeof(XRectangle) * num); - if (!rect) return; - 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; - } - } - - XShapeCombineRectangles(_ecore_x_disp, - win, - ShapeInput, - 0, - 0, - rect, - num, - ShapeUnion, - Unsorted); - if (rect) free(rect); -#else - return; - win = rects = num = 0; -#endif -} - -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) - { - if (num < 1) - { - XFree(rect); - if (num_ret) *num_ret = 0; - return NULL; - } - rects = malloc(sizeof(Ecore_X_Rectangle) * num); - if (!rects) - { - XFree(rect); - if (num_ret) *num_ret = 0; - return NULL; - } - 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 Ecore_X_Rectangle * -ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win, - int *num_ret) -{ - Ecore_X_Rectangle *rects = NULL; -#ifdef ShapeInput - XRectangle *rect; - int i, num = 0, ord; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeInput, &num, &ord); - if (rect) - { - if (num < 1) - { - XFree(rect); - if (num_ret) *num_ret = 0; - return NULL; - } - rects = malloc(sizeof(Ecore_X_Rectangle) * num); - if (!rects) - { - XFree(rect); - if (num_ret) *num_ret = 0; - return NULL; - } - 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; -#else - // have to return fake shape input rect of size of window - Window dw; - unsigned int di; - - if (num_ret) *num_ret = 0; - rects = malloc(sizeof(Ecore_X_Rectangle)); - if (!rects) return NULL; - if (!XGetGeometry(_ecore_x_disp, win, &dw, - &(rects[0].x), &(rects[0].y), - &(rects[0].width), &(rects[0].height), - &di, &di)) - { - free(rects); - return NULL; - } - if (num_ret) *num_ret = 1; - return rects; -#endif -} - -EAPI void -ecore_x_window_shape_events_select(Ecore_X_Window win, - Eina_Bool on) -{ - LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (on) - XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask); - else - XShapeSelectInput(_ecore_x_disp, win, 0); -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_xi2.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_xi2.c deleted file mode 100644 index 04d1023ec7..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_xi2.c +++ /dev/null @@ -1,336 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#include - -#include "Ecore.h" -#include "ecore_x_private.h" -#include "Ecore_X.h" - -#ifdef ECORE_XI2 -#include "Ecore_Input.h" -#endif /* ifdef ECORE_XI2 */ - -int _ecore_x_xi2_opcode = -1; - -#ifndef XIPointerEmulated -#define XIPointerEmulated (1 << 16) -#endif - -#ifdef ECORE_XI2 -static XIDeviceInfo *_ecore_x_xi2_devs = NULL; -static int _ecore_x_xi2_num = 0; -#endif /* ifdef ECORE_XI2 */ - -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 /* ifdef ECORE_XI2 */ -} - -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 /* ifdef ECORE_XI2 */ -} - -void -_ecore_x_input_handler(XEvent *xevent) -{ -#ifdef ECORE_XI2 - XIDeviceEvent *evd = (XIDeviceEvent *)(xevent->xcookie.data); - /* XIRawEvent *evr = (XIRawEvent *)(xevent->xcookie.data); */ - int devid = evd->deviceid; - int i; - - /* No filter for this events */ - switch (xevent->xcookie.evtype) - { -#ifdef XI_RawButtonPress - case XI_RawButtonPress: - ecore_event_add(ECORE_X_RAW_BUTTON_PRESS, NULL, NULL, NULL); - break; -#endif -#ifdef XI_RawButtonRelease - case XI_RawButtonRelease: - ecore_event_add(ECORE_X_RAW_BUTTON_RELEASE, NULL, NULL, NULL); - break; -#endif -#ifdef XI_RawMotion - case XI_RawMotion: - ecore_event_add(ECORE_X_RAW_MOTION, NULL, NULL, NULL); - break; -#endif - } - - if (_ecore_x_xi2_devs) - { - for (i = 0; i < _ecore_x_xi2_num; i++) - { - XIDeviceInfo *dev = &(_ecore_x_xi2_devs[i]); - - if (devid == dev->deviceid) - { - if (dev->use == XIMasterPointer) return; - if ((dev->use == XISlavePointer) && - (evd->flags & XIPointerEmulated)) return; - } - } - } - 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; - -#ifdef XI_TouchUpdate - case XI_TouchUpdate: - _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; - -#endif -#ifdef XI_TouchBegin - case XI_TouchBegin: - _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; - -#endif -#ifdef XI_TouchEnd - case XI_TouchEnd: - _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 - default: - break; - } -#endif /* ifdef ECORE_XI2 */ -} - -EAPI Eina_Bool -ecore_x_input_multi_select(Ecore_X_Window win) -{ -#ifdef ECORE_XI2 - int i; - Eina_Bool find = EINA_FALSE; - - 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[4] = { 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 = EINA_TRUE; - } - else if (dev->use == XISlavePointer) - { - XIDeviceInfo *atdev = NULL; - int j; - - for (j = 0; j < _ecore_x_xi2_num; j++) - { - if (_ecore_x_xi2_devs[j].deviceid == dev->attachment) - atdev = &(_ecore_x_xi2_devs[j]); - } - if (((atdev) && (atdev->use != XIMasterPointer)) || - (!atdev)) - { - XIEventMask eventmask; - unsigned char mask[4] = { 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); -# ifdef XI_TouchUpdate - XISetMask(mask, XI_TouchUpdate); -# endif -# ifdef XI_TouchBegin - XISetMask(mask, XI_TouchBegin); -# endif -# ifdef XI_TouchEnd - XISetMask(mask, XI_TouchEnd); -# endif - XISelectEvents(_ecore_x_disp, win, &eventmask, 1); - find = EINA_TRUE; - } - } - } - - return find; -#else /* ifdef ECORE_XI2 */ - return EINA_FALSE; -#endif /* ifdef ECORE_XI2 */ -} - -EAPI Eina_Bool -ecore_x_input_raw_select(Ecore_X_Window win) -{ -#ifdef ECORE_XI2 - XIEventMask emask; - unsigned char mask[4] = { 0 }; - - if (!_ecore_x_xi2_devs) - return EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - emask.deviceid = XIAllMasterDevices; - emask.mask_len = sizeof(mask); - emask.mask = mask; -#ifdef XI_RawButtonPress - XISetMask(emask.mask, XI_RawButtonPress); -#endif -#ifdef XI_RawButtonRelease - XISetMask(emask.mask, XI_RawButtonRelease); -#endif -#ifdef XI_RawMotion - XISetMask(emask.mask, XI_RawMotion); -#endif - - XISelectEvents(_ecore_x_disp, win, &emask, 1); - - return EINA_TRUE; -#else - return EINA_FALSE; -#endif -} - diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_xinerama.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_xinerama.c deleted file mode 100644 index f49a4d348f..0000000000 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_xinerama.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Xinerama code - */ - -#ifdef HAVE_CONFIG_H -# include -#endif /* ifdef HAVE_CONFIG_H */ - -#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 /* ifdef ECORE_XINERAMA */ - -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 /* ifdef ECORE_XINERAMA */ - return 0; -} - -EAPI Eina_Bool -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 EINA_TRUE; - } - } - } - -#endif /* ifdef ECORE_XINERAMA */ - 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 EINA_FALSE; - screen = 0; -} - diff --git a/legacy/ecore/src/modules/immodules/ibus/ibus_imcontext.c b/legacy/ecore/src/modules/immodules/ibus/ibus_imcontext.c deleted file mode 100644 index a5afed5574..0000000000 --- a/legacy/ecore/src/modules/immodules/ibus/ibus_imcontext.c +++ /dev/null @@ -1,822 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include "ibus_imcontext.h" - -struct _IBusIMContext -{ - /* instance members */ - Ecore_IMF_Context *ctx; - - /* enabled */ - Eina_Bool enable; - IBusInputContext *ibuscontext; - - /* preedit status */ - char *preedit_string; - Eina_List *preedit_attrs; - int preedit_cursor_pos; - Eina_Bool preedit_visible; - - int cursor_x; - int cursor_y; - int cursor_w; - int cursor_h; - - Eina_Bool has_focus; - - Ecore_X_Window client_window; - Evas *client_canvas; - - int caps; -}; - -typedef struct _KeyEvent KeyEvent; - -struct _KeyEvent -{ - int keysym; - int state; -}; - -static Eina_Bool _use_sync_mode = EINA_FALSE; - -static Ecore_IMF_Context *_focus_im_context = NULL; -static IBusBus *_bus = NULL; - -/* functions prototype */ -/* static methods*/ -static void _create_input_context (IBusIMContext *context); -static void _set_cursor_location_internal -(Ecore_IMF_Context *ctx); -static void _bus_connected_cb (IBusBus *bus, - IBusIMContext *context); -static XKeyEvent createXKeyEvent (Window win, Eina_Bool press, int keysym, int modifiers); - -static void -_window_to_screen_geometry_get(Ecore_X_Window client_win, int *x, int *y) -{ - Ecore_X_Window root_window, win; - int win_x, win_y; - int sum_x = 0, sum_y = 0; - - root_window = ecore_x_window_root_get(client_win); - win = client_win; - - while (root_window != win) - { - ecore_x_window_geometry_get(win, &win_x, &win_y, NULL, NULL); - sum_x += win_x; - sum_y += win_y; - win = ecore_x_window_parent_get(win); - } - - if (x) - *x = sum_x; - if (y) - *y = sum_y; -} - -static unsigned int -_ecore_imf_modifier_to_ibus_modifier(unsigned int modifier) -{ - unsigned int state = 0; - - /**< "Control" is pressed */ - if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) - state |= IBUS_CONTROL_MASK; - - /**< "Alt" is pressed */ - if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_ALT) - state |= IBUS_MOD1_MASK; - - /**< "Shift" is pressed */ - if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) - state |= IBUS_SHIFT_MASK; - - /**< "Win" (between "Ctrl" and "Alt") */ - if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_WIN) - state |= IBUS_SUPER_MASK; - - /**< "AltGr" is pressed */ - if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) - state |= IBUS_MOD5_MASK; - - return state; -} - -static void -key_event_put(int keysym, int state) -{ - // Find the window which has the current keyboard focus. - Window winFocus = 0; - int revert = RevertToParent; - - XGetInputFocus(ecore_x_display_get(), &winFocus, &revert); - - XKeyEvent event; - if (state & IBUS_RELEASE_MASK) - { - event = createXKeyEvent(winFocus, EINA_FALSE, keysym, state); - XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event); - } - else - { - event = createXKeyEvent(winFocus, EINA_TRUE, keysym, state); - XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); - } -} - -static KeyEvent * -key_event_copy(int keysym, int state) -{ - KeyEvent *kev = calloc(1, sizeof(KeyEvent)); - kev->keysym = keysym; - kev->state = state; - - return kev; -} - -IBusIMContext * -ibus_im_context_new(void) -{ - EINA_LOG_DBG("%s", __FUNCTION__); - - IBusIMContext *context = calloc(1, sizeof(IBusIMContext)); - - /* init bus object */ - if (_bus == NULL) - { - char *display_name = NULL; - - if ((display_name = getenv("DISPLAY"))) - ibus_set_display(display_name); - else - ibus_set_display(":0.0"); - - _bus = ibus_bus_new(); - } - - return context; -} - -static void -_process_key_event_done(GObject *object, - GAsyncResult *res, - gpointer user_data) -{ - IBusInputContext *context = (IBusInputContext *)object; - KeyEvent *event = (KeyEvent *)user_data; - - GError *error = NULL; - Eina_Bool retval = ibus_input_context_process_key_event_async_finish(context, - res, - &error); - - if (error != NULL) - { - g_warning("Process Key Event failed: %s.", error->message); - g_error_free(error); - } - - if (retval == EINA_FALSE) - { - key_event_put(event->keysym, event->state); - } - free(event); -} - -EAPI void -ibus_im_context_add(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("%s", __FUNCTION__); - - char *s = NULL; - IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - ibusimcontext->client_window = 0; - - // Init ibus status - ibusimcontext->enable = EINA_FALSE; - - // Init preedit status - ibusimcontext->preedit_string = NULL; - ibusimcontext->preedit_attrs = NULL; - ibusimcontext->preedit_cursor_pos = 0; - ibusimcontext->preedit_visible = EINA_FALSE; - - // Init cursor area - ibusimcontext->cursor_x = -1; - ibusimcontext->cursor_y = -1; - ibusimcontext->cursor_w = 0; - ibusimcontext->cursor_h = 0; - - ibusimcontext->ibuscontext = NULL; - ibusimcontext->has_focus = EINA_FALSE; - ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT; - ibusimcontext->ctx = ctx; - - s = getenv("IBUS_ENABLE_SYNC_MODE"); - if (s) - _use_sync_mode = !!atoi(s); - - if (ibus_bus_is_connected(_bus)) - _create_input_context (ibusimcontext); - - g_signal_connect(_bus, "connected", G_CALLBACK (_bus_connected_cb), ctx); -} - -EAPI void -ibus_im_context_del(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("%s", __FUNCTION__); - - IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - g_signal_handlers_disconnect_by_func(_bus, G_CALLBACK(_bus_connected_cb), ctx); - - if (ibusimcontext->ibuscontext) - ibus_proxy_destroy((IBusProxy *)ibusimcontext->ibuscontext); - - // release preedit - if (ibusimcontext->preedit_string) - free(ibusimcontext->preedit_string); - if (_focus_im_context == ctx) - _focus_im_context = NULL; -} - -EAPI Eina_Bool -ibus_im_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event) -{ - IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN_VAL(ibusimcontext, EINA_FALSE); - - if (type != ECORE_IMF_EVENT_KEY_UP && type != ECORE_IMF_EVENT_KEY_DOWN) - return EINA_FALSE; - - EINA_LOG_DBG("%s", __FUNCTION__); - - if (G_LIKELY(ibusimcontext->ibuscontext && ibusimcontext->has_focus)) - { - /* If context does not have focus, ibus will process key event in sync mode. - * It is a workaround for increase search in treeview. - */ - Eina_Bool retval = EINA_FALSE; - int keycode; - int keysym; - unsigned int state = 0; - - if (type == ECORE_IMF_EVENT_KEY_UP) - { - Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event; - if (ev->timestamp == 0) - return EINA_FALSE; - - keycode = ecore_x_keysym_keycode_get(ev->key); - keysym = XStringToKeysym(ev->key); - state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers) | IBUS_RELEASE_MASK; - - if (_use_sync_mode) - { - retval = ibus_input_context_process_key_event(ibusimcontext->ibuscontext, - keysym, - keycode - 8, - state); - } - else - { - ibus_input_context_process_key_event_async(ibusimcontext->ibuscontext, - keysym, - keycode - 8, - state, - -1, - NULL, - _process_key_event_done, - key_event_copy(keysym, state)); - retval = EINA_TRUE; - } - } - else if (type == ECORE_IMF_EVENT_KEY_DOWN) - { - Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; - if (ev->timestamp == 0) - return EINA_FALSE; - - keycode = ecore_x_keysym_keycode_get(ev->key); - keysym = XStringToKeysym(ev->key); - state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers); - if (_use_sync_mode) - { - retval = ibus_input_context_process_key_event(ibusimcontext->ibuscontext, - keysym, - keycode - 8, - state); - } - else - { - ibus_input_context_process_key_event_async(ibusimcontext->ibuscontext, - keysym, - keycode - 8, - state, - -1, - NULL, - _process_key_event_done, - key_event_copy(keysym, state)); - retval = EINA_TRUE; - } - } - else - retval = EINA_FALSE; - - if (retval) - return EINA_TRUE; - else - return EINA_FALSE; - } - else - return EINA_FALSE; -} - -EAPI void -ibus_im_context_focus_in(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("ctx : %p", ctx); - - IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->has_focus) - return; - - if (_focus_im_context != NULL) - ecore_imf_context_focus_out(_focus_im_context); - - ibusimcontext->has_focus = EINA_TRUE; - if (ibusimcontext->ibuscontext) - ibus_input_context_focus_in(ibusimcontext->ibuscontext); - - if (_focus_im_context != ctx) - _focus_im_context = ctx; -} - -EAPI void -ibus_im_context_focus_out(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("ctx : %p", ctx); - - IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->has_focus == EINA_FALSE) - return; - - if (_focus_im_context == ctx) - _focus_im_context = NULL; - - ibusimcontext->has_focus = EINA_FALSE; - if (ibusimcontext->ibuscontext) - ibus_input_context_focus_out(ibusimcontext->ibuscontext); -} - -EAPI void -ibus_im_context_reset(Ecore_IMF_Context *ctx) -{ - IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->ibuscontext) - ibus_input_context_reset(ibusimcontext->ibuscontext); -} - -EAPI void -ibus_im_context_preedit_string_get(Ecore_IMF_Context *ctx, - char **str, - int *cursor_pos) -{ - IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->enable && ibusimcontext->preedit_visible) - { - if (str) - *str = strdup(ibusimcontext->preedit_string ? ibusimcontext->preedit_string: ""); - - if (cursor_pos) - *cursor_pos = ibusimcontext->preedit_cursor_pos; - } - else - { - if (str) - *str = strdup(""); - - if (cursor_pos) - *cursor_pos = 0; - } - EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos); -} - -EAPI void -ibus_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, - char **str, - Eina_List **attr __UNUSED__, - int *cursor_pos) -{ - IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->enable && ibusimcontext->preedit_visible) - { - if (str) - *str = strdup(ibusimcontext->preedit_string ? ibusimcontext->preedit_string: ""); - - if (cursor_pos) - *cursor_pos = ibusimcontext->preedit_cursor_pos; - } - else - { - if (str) - *str = strdup(""); - - if (cursor_pos) - *cursor_pos = 0; - } - EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos); -} - -EAPI void -ibus_im_context_client_window_set(Ecore_IMF_Context *ctx, void *window) -{ - EINA_LOG_DBG("canvas : %p", window); - IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (window != NULL) - ibusimcontext->client_window = (Ecore_X_Window)(Ecore_Window)window; -} - -EAPI void -ibus_im_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas) -{ - EINA_LOG_DBG("canvas : %p", canvas); - IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (canvas != NULL) - ibusimcontext->client_canvas = canvas; -} - -static void -_set_cursor_location_internal(Ecore_IMF_Context *ctx) -{ - IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); - Ecore_Evas *ee; - int canvas_x, canvas_y; - - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->ibuscontext == NULL) - return; - - if (ibusimcontext->client_canvas) - { - ee = ecore_evas_ecore_evas_get(ibusimcontext->client_canvas); - if (!ee) return; - - ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL); - } - else - { - if (ibusimcontext->client_window) - _window_to_screen_geometry_get(ibusimcontext->client_window, &canvas_x, &canvas_y); - else - return; - } - - ibus_input_context_set_cursor_location(ibusimcontext->ibuscontext, - ibusimcontext->cursor_x + canvas_x, - ibusimcontext->cursor_y + canvas_y, - ibusimcontext->cursor_w, - ibusimcontext->cursor_h); -} - -EAPI void -ibus_im_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h) -{ - EINA_LOG_DBG("x : %d, y : %d, w, %d, h :%d", x, y, w, h); - IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->cursor_x != x || - ibusimcontext->cursor_y != y || - ibusimcontext->cursor_w != w || - ibusimcontext->cursor_h != h) - { - ibusimcontext->cursor_x = x; - ibusimcontext->cursor_y = y; - ibusimcontext->cursor_w = w; - ibusimcontext->cursor_h = h; - - _set_cursor_location_internal(ctx); - } -} - -EAPI void -ibus_im_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit) -{ - EINA_LOG_DBG("preedit : %d", use_preedit); - IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->ibuscontext) - { - if (use_preedit) - ibusimcontext->caps |= IBUS_CAP_PREEDIT_TEXT; - else - ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT; - - ibus_input_context_set_capabilities(ibusimcontext->ibuscontext, ibusimcontext->caps); - } -} - -static void -_bus_connected_cb(IBusBus *bus __UNUSED__, - IBusIMContext *ibusimcontext) -{ - EINA_LOG_DBG("ibus is connected"); - - if (ibusimcontext) - _create_input_context(ibusimcontext); -} - -static void -_ibus_context_commit_text_cb(IBusInputContext *ibuscontext __UNUSED__, - IBusText *text, - IBusIMContext *ibusimcontext) -{ - if (!ibusimcontext || !text) return; - char *commit_str = text->text ? text->text : ""; - - EINA_LOG_DBG("commit string : %s", commit_str); - - if (ibusimcontext->ctx) - { - ecore_imf_context_commit_event_add(ibusimcontext->ctx, text->text); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)commit_str); - } -} - -static XKeyEvent createXKeyEvent(Window win, Eina_Bool press, int keysym, int modifiers) -{ - XKeyEvent event; - Display *display = ecore_x_display_get(); - - event.display = display; - event.window = win; - event.root = ecore_x_window_root_get(win); - event.subwindow = None; - event.time = 0; - event.x = 1; - event.y = 1; - event.x_root = 1; - event.y_root = 1; - event.same_screen = EINA_TRUE; - event.state = modifiers; - event.keycode = XKeysymToKeycode(display, keysym); - if (press) - event.type = KeyPress; - else - event.type = KeyRelease; - event.send_event = EINA_FALSE; - event.serial = 0; - - return event; -} - -static void -_ibus_context_forward_key_event_cb(IBusInputContext *ibuscontext __UNUSED__, - guint keyval, - guint state, - IBusIMContext *ibusimcontext __UNUSED__) -{ - EINA_LOG_DBG("keyval : %d, state : %d", keyval, state); - - key_event_put(keyval, state); -} - -static void -_ibus_context_update_preedit_text_cb(IBusInputContext *ibuscontext __UNUSED__, - IBusText *text, - gint cursor_pos, - gboolean visible, - IBusIMContext *ibusimcontext) -{ - if (!ibusimcontext || !text) return; - - const char *str; - gboolean flag; - - if (ibusimcontext->preedit_string) - free (ibusimcontext->preedit_string); - - str = text->text; - - if (str) - ibusimcontext->preedit_string = strdup(str); - else - ibusimcontext->preedit_string = strdup(""); - - ibusimcontext->preedit_cursor_pos = cursor_pos; - - EINA_LOG_DBG("string : %s, cursor : %d", ibusimcontext->preedit_string, ibusimcontext->preedit_cursor_pos); - - flag = ibusimcontext->preedit_visible != visible; - ibusimcontext->preedit_visible = visible; - - if (ibusimcontext->preedit_visible) - { - if (flag) - { - ecore_imf_context_preedit_start_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); - } - - ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - else - { - if (flag) - { - ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - - ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); - } -} - -static void -_ibus_context_show_preedit_text_cb(IBusInputContext *ibuscontext __UNUSED__, - IBusIMContext *ibusimcontext) -{ - EINA_LOG_DBG("preedit visible : %d", ibusimcontext->preedit_visible); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->preedit_visible == EINA_TRUE) - return; - - ibusimcontext->preedit_visible = EINA_TRUE; - - // call preedit start - ecore_imf_context_preedit_start_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); - - // call preedit changed - ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); -} - -static void -_ibus_context_hide_preedit_text_cb(IBusInputContext *ibuscontext __UNUSED__, - IBusIMContext *ibusimcontext) -{ - EINA_LOG_DBG("%s", __FUNCTION__); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - if (ibusimcontext->preedit_visible == EINA_FALSE) - return; - - ibusimcontext->preedit_visible = EINA_FALSE; - - // call preedit changed - ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - - // call preedit end - ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); -} - -static void -_ibus_context_enabled_cb(IBusInputContext *ibuscontext __UNUSED__, - IBusIMContext *ibusimcontext) -{ - EINA_LOG_DBG("%s", __FUNCTION__); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - ibusimcontext->enable = EINA_TRUE; -} - -static void -_ibus_context_disabled_cb(IBusInputContext *ibuscontext __UNUSED__, - IBusIMContext *ibusimcontext) -{ - EINA_LOG_DBG("%s", __FUNCTION__); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - ibusimcontext->enable = EINA_FALSE; - - /* clear preedit */ - ibusimcontext->preedit_visible = EINA_FALSE; - ibusimcontext->preedit_cursor_pos = 0; - free (ibusimcontext->preedit_string); - ibusimcontext->preedit_string = NULL; - - // call preedit changed - ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - - // call preedit end - ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); -} - -static void -_ibus_context_destroy_cb(IBusInputContext *ibuscontext __UNUSED__, - IBusIMContext *ibusimcontext) -{ - EINA_LOG_DBG("%s", __FUNCTION__); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - ibusimcontext->ibuscontext = NULL; - ibusimcontext->enable = EINA_FALSE; - - /* clear preedit */ - ibusimcontext->preedit_visible = EINA_FALSE; - ibusimcontext->preedit_cursor_pos = 0; - free (ibusimcontext->preedit_string); - ibusimcontext->preedit_string = NULL; - - // call preedit changed - ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - - // call preedit end - ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx); - ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); -} - -static void -_create_input_context(IBusIMContext *ibusimcontext) -{ - EINA_LOG_DBG("%s", __FUNCTION__); - EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); - - ibusimcontext->ibuscontext = ibus_bus_create_input_context(_bus, "ecore"); - - g_return_if_fail(ibusimcontext->ibuscontext != NULL); - - g_signal_connect(ibusimcontext->ibuscontext, - "commit-text", - G_CALLBACK (_ibus_context_commit_text_cb), - ibusimcontext); - g_signal_connect(ibusimcontext->ibuscontext, - "forward-key-event", - G_CALLBACK (_ibus_context_forward_key_event_cb), - ibusimcontext); - g_signal_connect(ibusimcontext->ibuscontext, - "update-preedit-text", - G_CALLBACK (_ibus_context_update_preedit_text_cb), - ibusimcontext); - g_signal_connect(ibusimcontext->ibuscontext, - "show-preedit-text", - G_CALLBACK (_ibus_context_show_preedit_text_cb), - ibusimcontext); - g_signal_connect(ibusimcontext->ibuscontext, - "hide-preedit-text", - G_CALLBACK (_ibus_context_hide_preedit_text_cb), - ibusimcontext); - g_signal_connect(ibusimcontext->ibuscontext, - "enabled", - G_CALLBACK (_ibus_context_enabled_cb), - ibusimcontext); - g_signal_connect(ibusimcontext->ibuscontext, - "disabled", - G_CALLBACK (_ibus_context_disabled_cb), - ibusimcontext); - g_signal_connect(ibusimcontext->ibuscontext, "destroy", - G_CALLBACK (_ibus_context_destroy_cb), - ibusimcontext); - - ibus_input_context_set_capabilities(ibusimcontext->ibuscontext, ibusimcontext->caps); - - if (ibusimcontext->has_focus) - ibus_input_context_focus_in(ibusimcontext->ibuscontext); -} diff --git a/legacy/ecore/src/modules/immodules/ibus/ibus_imcontext.h b/legacy/ecore/src/modules/immodules/ibus/ibus_imcontext.h deleted file mode 100644 index ce5c075c3f..0000000000 --- a/legacy/ecore/src/modules/immodules/ibus/ibus_imcontext.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __IBUS_IM_CONTEXT_H_ -#define __IBUS_IM_CONTEXT_H_ - -#include - -typedef struct _IBusIMContext IBusIMContext; - -EAPI void ibus_im_context_add (Ecore_IMF_Context *ctx); -EAPI void ibus_im_context_del (Ecore_IMF_Context *ctx); -EAPI void ibus_im_context_reset (Ecore_IMF_Context *context); -EAPI void ibus_im_context_focus_in(Ecore_IMF_Context *context); -EAPI void ibus_im_context_focus_out(Ecore_IMF_Context *context); -EAPI void ibus_im_context_preedit_string_get - (Ecore_IMF_Context *context, - char **str, - int *cursor_pos); -EAPI void ibus_im_context_preedit_string_with_attributes_get - (Ecore_IMF_Context *context, - char **str, - Eina_List **attr, - int *cursor_pos); - -EAPI void ibus_im_context_cursor_location_set(Ecore_IMF_Context *context, - int x, int y, int w, int h); -EAPI void ibus_im_context_use_preedit_set(Ecore_IMF_Context *context, - Eina_Bool use_preedit); -EAPI void -ibus_im_context_client_window_set(Ecore_IMF_Context *context, void *window); -EAPI void -ibus_im_context_client_canvas_set(Ecore_IMF_Context *context, void *canvas); -EAPI Eina_Bool -ibus_im_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); - -IBusIMContext - *ibus_im_context_new (void); -#endif diff --git a/legacy/ecore/src/modules/immodules/ibus/ibus_module.c b/legacy/ecore/src/modules/immodules/ibus/ibus_module.c deleted file mode 100644 index a6e175c3ca..0000000000 --- a/legacy/ecore/src/modules/immodules/ibus/ibus_module.c +++ /dev/null @@ -1,109 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include -#include - -#include -#include "ibus_imcontext.h" - -#define IBUS_LOCALDIR "" -static const Ecore_IMF_Context_Info ibus_im_info = { - "ibus", - "IBus (Intelligent Input Bus)", - "*", - NULL, - 0 -}; - -static Ecore_IMF_Context_Class ibus_imf_class = { - ibus_im_context_add, /* add */ - ibus_im_context_del, /* del */ - ibus_im_context_client_window_set, /* client_window_set */ - ibus_im_context_client_canvas_set, /* client_canvas_set */ - NULL, /* input_panel_show */ - NULL, /* input_panel_hide */ - ibus_im_context_preedit_string_get, /* get_preedit_string */ - ibus_im_context_focus_in, /* focus_in */ - ibus_im_context_focus_out, /* focus_out */ - ibus_im_context_reset, /* reset */ - NULL, /* cursor_position_set */ - ibus_im_context_use_preedit_set, /* use_preedit_set */ - NULL, /* input_mode_set */ - ibus_im_context_filter_event, /* filter_event */ - ibus_im_context_preedit_string_with_attributes_get, /* preedit_string_with_attribute_get */ - NULL, /* prediction_allow_set */ - NULL, /* autocapital_type_set */ - NULL, /* control panel show */ - NULL, /* control panel hide */ - NULL, /* input_panel_layout_set */ - NULL, /* ibus_im_context_input_panel_layout_get, */ - NULL, /* ibus_im_context_input_panel_language_set, */ - NULL, /* ibus_im_context_input_panel_language_get, */ - ibus_im_context_cursor_location_set, /* cursor_location_set */ - NULL, /* input_panel_imdata_set */ - NULL, /* input_panel_imdata_get */ - NULL, /* input_panel_return_key_type_set */ - NULL, /* input_panel_return_key_disabled_set */ - NULL, /* input_panel_caps_lock_mode_set */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -static Ecore_IMF_Context *im_module_create (void); -static Ecore_IMF_Context *im_module_exit (void); - -static Eina_Bool -im_module_init(void) -{ - ecore_main_loop_glib_integrate(); - ibus_init(); - ecore_imf_module_register(&ibus_im_info, im_module_create, im_module_exit); - - return EINA_TRUE; -} - -static void im_module_shutdown(void) -{ -} - -static Ecore_IMF_Context * -im_module_exit(void) -{ - return NULL; -} - -static Ecore_IMF_Context * -im_module_create() -{ - Ecore_IMF_Context *ctx = NULL; - IBusIMContext *ctxd = NULL; - - ctxd = ibus_im_context_new(); - if (!ctxd) - { - return NULL; - } - - ctx = ecore_imf_context_new(&ibus_imf_class); - if (!ctx) - { - free(ctxd); - return NULL; - } - - ecore_imf_context_data_set(ctx, ctxd); - - return ctx; -} - -EINA_MODULE_INIT(im_module_init); -EINA_MODULE_SHUTDOWN(im_module_shutdown); - diff --git a/legacy/ecore/src/modules/immodules/scim/scim_imcontext.cpp b/legacy/ecore/src/modules/immodules/scim/scim_imcontext.cpp deleted file mode 100644 index d4d20b161a..0000000000 --- a/legacy/ecore/src/modules/immodules/scim/scim_imcontext.cpp +++ /dev/null @@ -1,2900 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include -#endif - -#define Uses_SCIM_DEBUG -#define Uses_SCIM_BACKEND -#define Uses_SCIM_IMENGINE_MODULE -#define Uses_SCIM_HOTKEY -#define Uses_SCIM_PANEL_CLIENT - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include "scim_imcontext.h" - -using namespace scim; - -struct _EcoreIMFContextISFImpl -{ - EcoreIMFContextISF *parent; - IMEngineInstancePointer si; - Ecore_X_Window client_window; - Evas *client_canvas; - Ecore_IMF_Input_Mode input_mode; - WideString preedit_string; - AttributeList preedit_attrlist; - Ecore_IMF_Autocapital_Type autocapital_type; - int preedit_caret; - int cursor_x; - int cursor_y; - int cursor_pos; - bool use_preedit; - bool is_on; - bool shared_si; - bool preedit_started; - bool preedit_updating; - bool need_commit_preedit; - bool uppercase; - bool prediction_allow; - - EcoreIMFContextISFImpl *next; -}; - -/* Input Context handling functions. */ -static EcoreIMFContextISFImpl *new_ic_impl (EcoreIMFContextISF *parent); -static void delete_ic_impl (EcoreIMFContextISFImpl *impl); -static void delete_all_ic_impl (void); - -static EcoreIMFContextISF *find_ic (int id); - - -/* private functions */ -static void panel_slot_reload_config (int context); -static void panel_slot_exit (int context); -static void panel_slot_update_lookup_table_page_size(int context, - int page_size); -static void panel_slot_lookup_table_page_up (int context); -static void panel_slot_lookup_table_page_down (int context); -static void panel_slot_trigger_property (int context, - const String &property); -static void panel_slot_process_helper_event (int context, - const String &target_uuid, - const String &helper_uuid, - const Transaction &trans); -static void panel_slot_move_preedit_caret (int context, - int caret_pos); -static void panel_slot_select_candidate (int context, - int cand_index); -static void panel_slot_process_key_event (int context, - const KeyEvent &key); -static void panel_slot_commit_string (int context, - const WideString &wstr); -static void panel_slot_forward_key_event (int context, - const KeyEvent &key); -static void panel_slot_request_help (int context); -static void panel_slot_request_factory_menu (int context); -static void panel_slot_change_factory (int context, - const String &uuid); - -static void panel_req_focus_in (EcoreIMFContextISF *ic); -static void panel_req_update_factory_info (EcoreIMFContextISF *ic); -static void panel_req_update_spot_location (EcoreIMFContextISF *ic); -static void panel_req_show_help (EcoreIMFContextISF *ic); -static void panel_req_show_factory_menu (EcoreIMFContextISF *ic); - -/* Panel iochannel handler*/ -static bool panel_initialize (void); -static void panel_finalize (void); -static Eina_Bool panel_iochannel_handler (void *data, - Ecore_Fd_Handler *fd_handler); - -/* utility functions */ -static bool filter_hotkeys (EcoreIMFContextISF *ic, - const KeyEvent &key); -static void turn_on_ic (EcoreIMFContextISF *ic); -static void turn_off_ic (EcoreIMFContextISF *ic); -static void set_ic_capabilities (EcoreIMFContextISF *ic); - -static void initialize (void); -static void finalize (void); - -static void open_next_factory (EcoreIMFContextISF *ic); -static void open_previous_factory (EcoreIMFContextISF *ic); -static void open_specific_factory (EcoreIMFContextISF *ic, - const String &uuid); -static void initialize_modifier_bits (Display *display); -static unsigned int scim_x11_keymask_scim_to_x11 (Display *display, uint16 scimkeymask); -static XKeyEvent createKeyEvent (Display *display, Window &win, - Window &winRoot, bool press, - int keycode, int modifiers); -static void _x_send_key_event (const KeyEvent &key); - -static void attach_instance (const IMEngineInstancePointer &si); - -/* slot functions */ -static void slot_show_preedit_string (IMEngineInstanceBase *si); -static void slot_show_aux_string (IMEngineInstanceBase *si); -static void slot_show_lookup_table (IMEngineInstanceBase *si); - -static void slot_hide_preedit_string (IMEngineInstanceBase *si); -static void slot_hide_aux_string (IMEngineInstanceBase *si); -static void slot_hide_lookup_table (IMEngineInstanceBase *si); - -static void slot_update_preedit_caret (IMEngineInstanceBase *si, - int caret); -static void slot_update_preedit_string (IMEngineInstanceBase *si, - const WideString &str, - const AttributeList &attrs); -static void slot_update_aux_string (IMEngineInstanceBase *si, - const WideString &str, - const AttributeList &attrs); -static void slot_commit_string (IMEngineInstanceBase *si, - const WideString &str); -static void slot_forward_key_event (IMEngineInstanceBase *si, - const KeyEvent &key); -static void slot_update_lookup_table (IMEngineInstanceBase *si, - const LookupTable &table); - -static void slot_register_properties (IMEngineInstanceBase *si, - const PropertyList &properties); -static void slot_update_property (IMEngineInstanceBase *si, - const Property &property); -static void slot_beep (IMEngineInstanceBase *si); -static void slot_start_helper (IMEngineInstanceBase *si, - const String &helper_uuid); -static void slot_stop_helper (IMEngineInstanceBase *si, - const String &helper_uuid); -static void slot_send_helper_event (IMEngineInstanceBase *si, - const String &helper_uuid, - const Transaction &trans); -static bool slot_get_surrounding_text (IMEngineInstanceBase *si, - WideString &text, - int &cursor, - int maxlen_before, - int maxlen_after); -static bool slot_delete_surrounding_text (IMEngineInstanceBase *si, - int offset, - int len); - -static void reload_config_callback (const ConfigPointer &config); - -static void fallback_commit_string_cb (IMEngineInstanceBase *si, - const WideString &str); - -static void caps_mode_check (Ecore_IMF_Context *ctx, Eina_Bool force); - -/* Local variables declaration */ -static String _language; -static EcoreIMFContextISFImpl *_used_ic_impl_list = 0; -static EcoreIMFContextISFImpl *_free_ic_impl_list = 0; -static EcoreIMFContextISF *_ic_list = 0; - -static KeyboardLayout _keyboard_layout = SCIM_KEYBOARD_Default; -static int _valid_key_mask = SCIM_KEY_AllMasks; - -static FrontEndHotkeyMatcher _frontend_hotkey_matcher; -static IMEngineHotkeyMatcher _imengine_hotkey_matcher; - -static IMEngineInstancePointer _default_instance; - -static ConfigModule *_config_module = 0; -static ConfigPointer _config; -static BackEndPointer _backend; - -static EcoreIMFContextISF *_focused_ic = 0; - -static bool _scim_initialized = false; - -static int _instance_count = 0; -static int _context_count = 0; - -static IMEngineFactoryPointer _fallback_factory; -static IMEngineInstancePointer _fallback_instance; -static PanelClient _panel_client; - -static Ecore_Fd_Handler *_panel_iochannel_read_handler = 0; -static Ecore_Fd_Handler *_panel_iochannel_err_handler = 0; - -static Ecore_X_Window _client_window = 0; - -static bool _on_the_spot = true; -static bool _shared_input_method = false; - -static Eina_Bool autocap_allow = EINA_FALSE; - -static Display *__current_display = 0; -static int __current_alt_mask = Mod1Mask; -static int __current_meta_mask = 0; -static int __current_super_mask = 0; -static int __current_hyper_mask = 0; -static int __current_numlock_mask = Mod2Mask; - -// A hack to shutdown the immodule cleanly even if im_module_exit() is not called when exiting. -class FinalizeHandler -{ -public: - FinalizeHandler() - { - SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::FinalizeHandler()\n"; - } - ~FinalizeHandler() - { - SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::~FinalizeHandler()\n"; - isf_imf_context_shutdown(); - } -}; - -static FinalizeHandler _finalize_handler; - -static unsigned int -utf8_offset_to_index(const char *str, int offset) -{ - int index = 0; - int i; - for (i = 0; i < offset; i++) - { - eina_unicode_utf8_get_next(str, &index); - } - - return index; -} - -static unsigned int -get_time(void) -{ - unsigned int tint; - struct timeval tv; - struct timezone tz; /* is not used since ages */ - gettimeofday(&tv, &tz); - tint = tv.tv_sec * 1000; - tint = tint / 1000 * 1000; - tint = tint + tv.tv_usec / 1000; - return tint; -} - -/* Function Implementations */ -static EcoreIMFContextISFImpl * -new_ic_impl(EcoreIMFContextISF *parent) -{ - EcoreIMFContextISFImpl *impl = NULL; - - if (_free_ic_impl_list != NULL) - { - impl = _free_ic_impl_list; - _free_ic_impl_list = _free_ic_impl_list->next; - } - else - { - impl = new EcoreIMFContextISFImpl; - if (impl == NULL) - return NULL; - } - - impl->uppercase = false; - impl->autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE; - impl->next = _used_ic_impl_list; - _used_ic_impl_list = impl; - - impl->parent = parent; - - return impl; -} - -static void -delete_ic_impl(EcoreIMFContextISFImpl *impl) -{ - EcoreIMFContextISFImpl *rec = _used_ic_impl_list, *last = 0; - - for (; rec != 0; last = rec, rec = rec->next) - { - if (rec == impl) - { - if (last != 0) - last->next = rec->next; - else - _used_ic_impl_list = rec->next; - - rec->next = _free_ic_impl_list; - _free_ic_impl_list = rec; - - rec->parent = 0; - rec->si.reset(); - rec->client_window = 0; - rec->preedit_string = WideString(); - rec->preedit_attrlist.clear(); - - return; - } - } -} - -static void -delete_all_ic_impl(void) -{ - EcoreIMFContextISFImpl *it = _used_ic_impl_list; - - while (it != 0) - { - _used_ic_impl_list = it->next; - delete it; - it = _used_ic_impl_list; - } - - it = _free_ic_impl_list; - while (it != 0) - { - _free_ic_impl_list = it->next; - delete it; - it = _free_ic_impl_list; - } -} - -static EcoreIMFContextISF * -find_ic(int id) -{ - EcoreIMFContextISFImpl *rec = _used_ic_impl_list; - - while (rec != 0) - { - if (rec->parent && rec->parent->id == id) - return rec->parent; - rec = rec->next; - } - - return 0; -} - -static Eina_Bool -analyze_surrounding_text(Ecore_IMF_Context *ctx) -{ - char *plain_str = NULL; - char *markup_str = NULL; - const char *puncs[] = {". ", "! ", "? "}; - Eina_Bool ret = EINA_FALSE; - int cursor_pos = 0; - int i = 0; - Eina_Unicode *tail = NULL; - Eina_Unicode *ustr = NULL; - const int punc_num = sizeof(puncs) / sizeof(puncs[0]); - Eina_Unicode *uni_puncs[punc_num]; - EcoreIMFContextISF *context_scim; - - if (!ctx) return EINA_FALSE; - context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - if (!context_scim || !context_scim->impl) return EINA_FALSE; - - switch (context_scim->impl->autocapital_type) - { - case ECORE_IMF_AUTOCAPITAL_TYPE_NONE: - return EINA_FALSE; - case ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER: - return EINA_TRUE; - default: - break; - } - - for (i = 0; i < punc_num; i++) - uni_puncs[i] = eina_unicode_utf8_to_unicode(puncs[i], NULL); - - ecore_imf_context_surrounding_get(ctx, &markup_str, &cursor_pos); - if (!markup_str) goto done; - - if (cursor_pos == 0) - { - ret = EINA_TRUE; - goto done; - } - - // Convert into plain string - plain_str = evas_textblock_text_markup_to_utf8(NULL, markup_str); - if (!plain_str) goto done; - - // Convert string from UTF-8 to unicode - ustr = eina_unicode_utf8_to_unicode(plain_str, NULL); - if (!ustr) goto done; - - if (cursor_pos >= 1) - { - if (context_scim->impl->autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_WORD) - { - if (ustr[cursor_pos-1] == ' ') - { - ret = EINA_TRUE; - goto done; - } - } - - // Check paragraph separator and carriage return
- if ((ustr[cursor_pos-1] == 0x2029) || (ustr[cursor_pos-1] == '\n')) - { - ret = EINA_TRUE; - goto done; - } - } - - // check punctuation - if (cursor_pos >= 2) - { - tail = eina_unicode_strndup(ustr+cursor_pos-2, 2); - - if (tail) - { - for (i = 0; i < punc_num; i++) - { - if (!eina_unicode_strcmp(tail, uni_puncs[i])) - { - ret = EINA_TRUE; - break; - } - } - free(tail); - tail = NULL; - } - } - -done: - if (ustr) free(ustr); - if (markup_str) free(markup_str); - if (plain_str) free(plain_str); - - for (i = 0; i < punc_num; i++) - if (uni_puncs[i]) free(uni_puncs[i]); - - return ret; -} - -static void -caps_mode_check(Ecore_IMF_Context *ctx, Eina_Bool force) -{ - Eina_Bool uppercase; - EcoreIMFContextISF *context_scim; - - if (!ctx) return; - context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (autocap_allow == EINA_FALSE) - return; - - // Check autocapital type - if (!context_scim || !context_scim->impl) - return; - - if (analyze_surrounding_text(ctx)) - uppercase = EINA_TRUE; - else - uppercase = EINA_FALSE; - - if (force) - context_scim->impl->uppercase = uppercase; - else - if (context_scim->impl->uppercase != uppercase) - context_scim->impl->uppercase = uppercase; -} - -static void -feed_key_event(Evas *evas, const char *str, Eina_Bool fake) -{ - char key_string[128] = {0}; - unsigned int timestamp = 0; - - if (!fake) - timestamp = get_time(); - - if (strncmp(str, "KeyRelease+", 11) == 0) - { - strncpy(key_string, str + 11, strlen(str)-11); - evas_event_feed_key_up(evas, key_string, key_string, NULL, NULL, timestamp, NULL); - SCIM_DEBUG_FRONTEND(1) << " evas_event_feed_key_up()...\n"; - } - else - { - strncpy(key_string, str, strlen(str)); - evas_event_feed_key_down(evas, key_string, key_string, NULL, NULL, timestamp, NULL); - SCIM_DEBUG_FRONTEND(1) << " evas_event_feed_key_down()...\n"; - } -} - -static void -window_to_screen_geometry_get(Ecore_X_Window client_win, int *x, int *y) -{ - Ecore_X_Window root_window, win; - int win_x, win_y; - int sum_x = 0, sum_y = 0; - - root_window = ecore_x_window_root_get(client_win); - win = client_win; - - while (root_window != win) - { - ecore_x_window_geometry_get(win, &win_x, &win_y, NULL, NULL); - sum_x += win_x; - sum_y += win_y; - win = ecore_x_window_parent_get(win); - } - - if (x) - *x = sum_x; - if (y) - *y = sum_y; -} - -/* Public functions */ -/** - * isf_imf_context_new - * - * This function will be called by Ecore IMF. - * Create a instance of type EcoreIMFContextISF. - * - * Return value: A pointer to the newly created EcoreIMFContextISF instance - */ -EAPI EcoreIMFContextISF * -isf_imf_context_new(void) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - char *env; - - EcoreIMFContextISF *context_scim = new EcoreIMFContextISF; - if (context_scim == NULL) - { - std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n"; - return NULL; - } - - context_scim->id = _context_count++; - - if (!_scim_initialized) - { - initialize(); - _scim_initialized = true; - } - - env = getenv("ECORE_IMF_AUTOCAPITAL_ALLOW"); - if (env) - autocap_allow = !!atoi(env); - - return context_scim; -} - -/** - * isf_imf_context_shutdown - * - * It will be called when the scim im module is unloaded by ecore. It will do some - * cleanup job. - */ -EAPI void -isf_imf_context_shutdown(void) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (_scim_initialized) - { - _scim_initialized = false; - finalize(); - } -} - -EAPI void -isf_imf_context_add(Ecore_IMF_Context *ctx) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - - if (!context_scim) return; - - context_scim->impl = NULL; - - if (_backend.null()) - return; - - IMEngineInstancePointer si; - - // Use the default instance if "shared input method" mode is enabled. - if (_shared_input_method && !_default_instance.null()) - { - si = _default_instance; - SCIM_DEBUG_FRONTEND(2) << "use default instance: " << si->get_id() << " " << si->get_factory_uuid() << "\n"; - } - - // Not in "shared input method" mode, or no default instance, create an instance. - if (si.null()) - { - IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8"); - if (factory.null()) return; - si = factory->create_instance("UTF-8", _instance_count++); - if (si.null()) return; - attach_instance(si); - SCIM_DEBUG_FRONTEND(2) << "create new instance: " << si->get_id() << " " << si->get_factory_uuid() << "\n"; - } - - // If "shared input method" mode is enabled, and there is no default instance, - // then store this instance as default one. - if (_shared_input_method && _default_instance.null()) - { - SCIM_DEBUG_FRONTEND(2) << "update default instance.\n"; - _default_instance = si; - } - - context_scim->ctx = ctx; - context_scim->impl = new_ic_impl(context_scim); - if (context_scim->impl == NULL) - { - std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n"; - return; - } - - context_scim->impl->si = si; - context_scim->impl->client_window = 0; - context_scim->impl->client_canvas = NULL; - context_scim->impl->preedit_caret = 0; - context_scim->impl->cursor_x = 0; - context_scim->impl->cursor_y = 0; - context_scim->impl->cursor_pos = -1; - context_scim->impl->is_on = false; - context_scim->impl->shared_si = _shared_input_method; - context_scim->impl->use_preedit = _on_the_spot; - context_scim->impl->preedit_started = false; - context_scim->impl->preedit_updating = false; - context_scim->impl->need_commit_preedit = false; - - if (!_ic_list) - context_scim->next = NULL; - else - context_scim->next = _ic_list; - _ic_list = context_scim; - - if (_shared_input_method) - context_scim->impl->is_on = _config->read(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on); - - _panel_client.prepare(context_scim->id); - _panel_client.register_input_context(context_scim->id, si->get_factory_uuid()); - set_ic_capabilities(context_scim); - _panel_client.send(); - - SCIM_DEBUG_FRONTEND(2) << "input context created: id = " << context_scim->id << "\n"; -} - -EAPI void -isf_imf_context_del(Ecore_IMF_Context *ctx) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (!_ic_list) return; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - - if (context_scim) - { - if (context_scim->id != _ic_list->id) - { - EcoreIMFContextISF * pre = _ic_list; - EcoreIMFContextISF * cur = _ic_list->next; - while (cur != NULL) - { - if (cur->id == context_scim->id) - { - pre->next = cur->next; - break; - } - pre = cur; - cur = cur->next; - } - } - else - _ic_list = _ic_list->next; - } - - if (context_scim && context_scim->impl) - { - _panel_client.prepare(context_scim->id); - - if (context_scim == _focused_ic) - context_scim->impl->si->focus_out(); - - // Delete the instance. - EcoreIMFContextISF *old_focused = _focused_ic; - _focused_ic = context_scim; - context_scim->impl->si.reset(); - _focused_ic = old_focused; - - if (context_scim == _focused_ic) - { - _panel_client.turn_off(context_scim->id); - _panel_client.focus_out(context_scim->id); - } - - _panel_client.remove_input_context(context_scim->id); - _panel_client.send(); - - if (context_scim->impl->client_window) - isf_imf_context_client_window_set(ctx, NULL); - - if (context_scim->impl) - { - delete_ic_impl(context_scim->impl); - context_scim->impl = 0; - } - } - - if (context_scim == _focused_ic) - _focused_ic = 0; - - if (context_scim) - { - delete context_scim; - context_scim = 0; - } -} - -/** - * isf_imf_context_client_canvas_set - * @ctx: a #Ecore_IMF_Context - * @canvas: the client canvas - * - * This function will be called by Ecore IMF. - * - * 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. - */ -EAPI void -isf_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (context_scim && context_scim->impl && context_scim->impl->client_canvas != (Evas*) canvas) - context_scim->impl->client_canvas = (Evas*)canvas; -} - -/** - * isf_imf_context_client_window_set - * @ctx: a #Ecore_IMF_Context - * @window: the client window - * - * This function will be called by Ecore IMF. - * - * 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. - */ -EAPI void -isf_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (context_scim && context_scim->impl && context_scim->impl->client_window != (Ecore_X_Window)((Ecore_Window)window)) - { - context_scim->impl->client_window = (Ecore_X_Window)((Ecore_Window)window); - - if ((context_scim->impl->client_window != 0) && - (context_scim->impl->client_window != _client_window)) - _client_window = context_scim->impl->client_window; - } -} - -/** - * isf_imf_context_reset - * @ctx: a #Ecore_IMF_Context - * - * This function will be called by Ecore IMF. - * - * 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. - */ -EAPI void -isf_imf_context_reset(Ecore_IMF_Context *ctx) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (context_scim && context_scim->impl && context_scim == _focused_ic) - { - WideString wstr = context_scim->impl->preedit_string; - - _panel_client.prepare(context_scim->id); - context_scim->impl->si->reset(); - _panel_client.send(); - - if (context_scim->impl->need_commit_preedit) - { - if (wstr.length()) - { - ecore_imf_context_commit_event_add(context_scim->ctx, utf8_wcstombs(wstr).c_str()); - ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); - } - _panel_client.prepare(context_scim->id); - _panel_client.send(); - } - } -} - -/** - * isf_imf_context_focus_in - * @ctx: a #Ecore_IMF_Context - * - * This function will be called by Ecore IMF. - * - * Notify the Input Method Context that the widget to which its correspond has gained focus. - */ -EAPI void -isf_imf_context_focus_in(Ecore_IMF_Context *ctx) -{ - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (!context_scim) - return; - - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__<< "(" << context_scim->id << ")...\n"; - - if (_focused_ic) - { - if (_focused_ic == context_scim) - { - SCIM_DEBUG_FRONTEND(1) << "It's already focused.\n"; - return; - } - SCIM_DEBUG_FRONTEND(1) << "Focus out previous IC first: " << _focused_ic->id << "\n"; - if (_focused_ic->ctx) - isf_imf_context_focus_out(_focused_ic->ctx); - } - - bool need_cap = false; - bool need_reset = false; - bool need_reg = false; - - if (context_scim && context_scim->impl) - { - _focused_ic = context_scim; - _panel_client.prepare(context_scim->id); - - // Handle the "Shared Input Method" mode. - if (_shared_input_method) - { - SCIM_DEBUG_FRONTEND(2) << "shared input method.\n"; - IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8"); - if (!factory.null()) - { - if (_default_instance.null() || _default_instance->get_factory_uuid() != factory->get_uuid()) - { - _default_instance = factory->create_instance("UTF-8", _default_instance.null() ? _instance_count++ : _default_instance->get_id()); - attach_instance(_default_instance); - SCIM_DEBUG_FRONTEND(2) << "create new default instance: " << _default_instance->get_id() << " " << _default_instance->get_factory_uuid() << "\n"; - } - - context_scim->impl->shared_si = true; - context_scim->impl->si = _default_instance; - - context_scim->impl->is_on = _config->read(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on); - context_scim->impl->preedit_string.clear(); - context_scim->impl->preedit_attrlist.clear(); - context_scim->impl->preedit_caret = 0; - context_scim->impl->preedit_started = false; - need_cap = true; - need_reset = true; - need_reg = true; - } - } - else if (context_scim->impl->shared_si) - { - SCIM_DEBUG_FRONTEND(2) << "exit shared input method.\n"; - IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8"); - if (!factory.null()) - { - context_scim->impl->si = factory->create_instance("UTF-8", _instance_count++); - context_scim->impl->preedit_string.clear(); - context_scim->impl->preedit_attrlist.clear(); - context_scim->impl->preedit_caret = 0; - context_scim->impl->preedit_started = false; - attach_instance(context_scim->impl->si); - need_cap = true; - need_reg = true; - context_scim->impl->shared_si = false; - SCIM_DEBUG_FRONTEND(2) << "create new instance: " << context_scim->impl->si->get_id() << " " << context_scim->impl->si->get_factory_uuid() << "\n"; - } - } - - context_scim->impl->si->set_frontend_data(static_cast (context_scim)); - - if (need_reg) _panel_client.register_input_context(context_scim->id, context_scim->impl->si->get_factory_uuid()); - if (need_cap) set_ic_capabilities(context_scim); - if (need_reset) context_scim->impl->si->reset(); - - panel_req_focus_in(context_scim); - panel_req_update_spot_location(context_scim); - panel_req_update_factory_info(context_scim); - - if (context_scim->impl->is_on) - { - _panel_client.turn_on(context_scim->id); - _panel_client.hide_preedit_string(context_scim->id); - _panel_client.hide_aux_string(context_scim->id); - _panel_client.hide_lookup_table(context_scim->id); - context_scim->impl->si->focus_in(); - } - else - { - _panel_client.turn_off(context_scim->id); - } - - _panel_client.send(); - } - - if (ecore_imf_context_input_panel_enabled_get(ctx)) - ecore_imf_context_input_panel_show(ctx); -} - -/** - * isf_imf_context_focus_out - * @ctx: a #Ecore_IMF_Context - * - * This function will be called by Ecore IMF. - * - * Notify the Input Method Context that the widget to which its correspond has lost focus. - */ -EAPI void -isf_imf_context_focus_out(Ecore_IMF_Context *ctx) -{ - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (!context_scim) return; - - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "(" << context_scim->id << ")...\n"; - - if (context_scim && context_scim->impl && context_scim == _focused_ic) - { - WideString wstr = context_scim->impl->preedit_string; - - if (context_scim->impl->need_commit_preedit) - { - if (wstr.length()) - { - ecore_imf_context_commit_event_add(context_scim->ctx, utf8_wcstombs(wstr).c_str()); - ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); - } - _panel_client.prepare(context_scim->id); - _panel_client.send(); - } - - _panel_client.prepare(context_scim->id); - context_scim->impl->si->focus_out(); - context_scim->impl->si->reset(); - _panel_client.turn_off(context_scim->id); - _panel_client.focus_out(context_scim->id); - _panel_client.send(); - _focused_ic = 0; - } - - if (ecore_imf_context_input_panel_enabled_get(ctx)) - ecore_imf_context_input_panel_hide(ctx); -} - -/** - * isf_imf_context_cursor_location_set - * @ctx: a #Ecore_IMF_Context - * @x: x position of New cursor. - * @y: y position of New cursor. - * @w: the width of New cursor. - * @h: the height of New cursor. - * - * This function will be called by Ecore IMF. - * - * Notify the Input Method Context that a change in the cursor location has been made. - */ -EAPI void -isf_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int cx, int cy, int cw, int ch) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - Ecore_Evas *ee; - int canvas_x, canvas_y; - int new_cursor_x, new_cursor_y; - - if (cw == 0 && ch == 0) - return; - - if (context_scim && context_scim->impl && context_scim == _focused_ic) - { - if (context_scim->impl->client_canvas) - { - ee = ecore_evas_ecore_evas_get(context_scim->impl->client_canvas); - if (!ee) return; - - ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL); - } - else - { - if (context_scim->impl->client_window) - window_to_screen_geometry_get(context_scim->impl->client_window, &canvas_x, &canvas_y); - else - return; - } - - new_cursor_x = canvas_x + cx; - new_cursor_y = canvas_y + cy + ch; - - // Don't update spot location while updating preedit string. - if (context_scim->impl->preedit_updating && (context_scim->impl->cursor_y == new_cursor_y)) - return; - - if (context_scim->impl->cursor_x != new_cursor_x || context_scim->impl->cursor_y != new_cursor_y) - { - context_scim->impl->cursor_x = new_cursor_x; - context_scim->impl->cursor_y = new_cursor_y; - _panel_client.prepare(context_scim->id); - panel_req_update_spot_location(context_scim); - _panel_client.send(); - SCIM_DEBUG_FRONTEND(2) << "new cursor location = " << context_scim->impl->cursor_x << "," << context_scim->impl->cursor_y << "\n"; - } - } -} - -/** - * isf_imf_context_use_preedit_set - * @ctx: a #Ecore_IMF_Context - * @use_preedit: Whether the IM context should use the preedit string. - * - * This function will be called by Ecore IMF. - * - * Set whether the IM context should use the preedit string to display feedback. - * If 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. - */ -EAPI void -isf_imf_context_use_preedit_set(Ecore_IMF_Context* ctx, Eina_Bool use_preedit) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (use_preedit ? "true" : "false") << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - - if (!_on_the_spot) return; - - if (context_scim && context_scim->impl) - { - bool old = context_scim->impl->use_preedit; - context_scim->impl->use_preedit = use_preedit; - if (context_scim == _focused_ic) - { - _panel_client.prepare(context_scim->id); - - if (old != use_preedit) - set_ic_capabilities(context_scim); - - if (context_scim->impl->preedit_string.length()) - slot_show_preedit_string(context_scim->impl->si); - - _panel_client.send(); - } - } -} - -EAPI void -isf_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - - if (context_scim && context_scim->impl && context_scim->impl->is_on) - { - String mbs = utf8_wcstombs(context_scim->impl->preedit_string); - - if (str) - { - if (mbs.length()) - *str = strdup(mbs.c_str()); - else - *str = strdup(""); - } - - if (cursor_pos) - { - *cursor_pos = context_scim->impl->preedit_caret; - } - - if (attrs) - { - if (mbs.length()) - { - int start_index, end_index; - int wlen = context_scim->impl->preedit_string.length(); - - Ecore_IMF_Preedit_Attr *attr = NULL; - AttributeList::const_iterator i; - bool *attrs_flag = new bool [mbs.length()]; - memset(attrs_flag, 0, mbs.length() *sizeof(bool)); - - for (i = context_scim->impl->preedit_attrlist.begin(); - i != context_scim->impl->preedit_attrlist.end(); ++i) - { - start_index = i->get_start(); - end_index = i->get_end(); - - if (end_index <= wlen && start_index < end_index && i->get_type() != SCIM_ATTR_DECORATE_NONE) - { - start_index = utf8_offset_to_index(mbs.c_str(), i->get_start()); - end_index = utf8_offset_to_index(mbs.c_str(), i->get_end()); - - if (i->get_type() == SCIM_ATTR_DECORATE) - { - attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr)); - if (attr == NULL) - continue; - attr->start_index = start_index; - attr->end_index = end_index; - - if (i->get_value() == SCIM_ATTR_DECORATE_UNDERLINE) - { - attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1; - *attrs = eina_list_append(*attrs, (void *)attr); - } - else if (i->get_value() == SCIM_ATTR_DECORATE_REVERSE) - { - attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; - *attrs = eina_list_append(*attrs, (void *)attr); - } - else if (i->get_value() == SCIM_ATTR_DECORATE_HIGHLIGHT) - { - attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3; - *attrs = eina_list_append(*attrs, (void *)attr); - } - else - { - free(attr); - } - - switch(i->get_value()) - { - case SCIM_ATTR_DECORATE_UNDERLINE: - case SCIM_ATTR_DECORATE_REVERSE: - case SCIM_ATTR_DECORATE_HIGHLIGHT: - // Record which character has attribute. - for (int pos = start_index; pos < end_index; ++pos) - attrs_flag [pos] = 1; - break; - default: - break; - } - } - else if (i->get_type() == SCIM_ATTR_FOREGROUND) - { - SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_FOREGROUND\n"; - } - else if (i->get_type() == SCIM_ATTR_BACKGROUND) - { - SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_BACKGROUND\n"; - } - } - } - - // Add underline for all characters which don't have attribute. - for (unsigned int pos = 0; pos < mbs.length(); ++pos) - { - if (!attrs_flag [pos]) - { - int begin_pos = pos; - - while (pos < mbs.length() && !attrs_flag[pos]) - ++pos; - - // use REVERSE style as default - attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr)); - if (attr == NULL) - continue; - attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; - attr->start_index = begin_pos; - attr->end_index = pos; - *attrs = eina_list_append(*attrs, (void *)attr); - } - } - - delete [] attrs_flag; - } - } - } - else - { - if (str) - *str = strdup(""); - - if (cursor_pos) - *cursor_pos = 0; - - if (attrs) - *attrs = NULL; - } -} - -/** - * isf_imf_context_preedit_string_get - * @ctx: a #Ecore_IMF_Context - * @str: the preedit string - * @cursor_pos: the cursor position - * - * This function will be called by Ecore IMF. - * - * To get the preedit string of the input method. - */ -EAPI void -isf_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char** str, int *cursor_pos) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - - if (context_scim && context_scim->impl && context_scim->impl->is_on) - { - String mbs = utf8_wcstombs(context_scim->impl->preedit_string); - - if (str) - { - if (mbs.length()) - *str = strdup(mbs.c_str()); - else - *str = strdup(""); - } - - if (cursor_pos) - *cursor_pos = context_scim->impl->preedit_caret; - } - else - { - if (str) - *str = strdup(""); - - if (cursor_pos) - *cursor_pos = 0; - } -} - -/** - * isf_imf_context_cursor_position_set - * @ctx: a #Ecore_IMF_Context - * @cursor_pos: New cursor position in characters. - * - * This function will be called by Ecore IMF. - * - * Notify the Input Method Context that a change in the cursor position has been made. - */ -EAPI void -isf_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (context_scim && context_scim->impl && context_scim == _focused_ic) - { - // Don't update spot location while updating preedit string. - if (context_scim->impl->preedit_updating) - return; - - if (context_scim->impl->cursor_pos != cursor_pos) - { - context_scim->impl->cursor_pos = cursor_pos; - caps_mode_check(ctx, EINA_FALSE); - } - } -} - -/** - * isf_imf_context_input_mode_set - * @ctx: a #Ecore_IMF_Context - * @input_mode: the input mode - * - * This function will be called by Ecore IMF. - * - * To set the input mode of input method. The definition of Ecore_IMF_Input_Mode - * is in Ecore_IMF.h. - */ -EAPI void -isf_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - if (context_scim && context_scim->impl) - context_scim->impl->input_mode = input_mode; -} - -/** - * isf_imf_context_prediction_allow_set - * @ctx: a #Ecore_IMF_Context - * @use_prediction: Whether the IM context should use the prediction. - * - * This function will be called by Ecore IMF. - * - * Set whether the IM context should use the prediction. - */ -EAPI void -isf_imf_context_prediction_allow_set(Ecore_IMF_Context* ctx, Eina_Bool prediction) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (prediction ? "true" : "false") << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (context_scim && context_scim->impl && context_scim->impl->prediction_allow != prediction) - context_scim->impl->prediction_allow = prediction; -} - -EAPI void -isf_imf_context_autocapital_type_set(Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << autocapital_type << "...\n"; - - EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); - - if (context_scim && context_scim->impl && context_scim->impl->autocapital_type != autocapital_type) - context_scim->impl->autocapital_type = autocapital_type; -} - -/** - * isf_imf_context_filter_event - * @ctx: a #Ecore_IMF_Context - * @type: The type of event defined by Ecore_IMF_Event_Type. - * @event: The event itself. - * Return value: %TRUE if the input method handled the key event. - * - * This function will be called by Ecore IMF. - * - * 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. - */ -EAPI Eina_Bool -isf_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - Eina_Bool ret = EINA_FALSE; - - if (ic == NULL || ic->impl == NULL) - return ret; - - KeyEvent key; - - if (type == ECORE_IMF_EVENT_KEY_DOWN) - { - Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; - scim_string_to_key(key, ev->key); - if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask; - if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask; - if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask; - if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask; - if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask; - if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask; - } - else if (type == ECORE_IMF_EVENT_KEY_UP) - { - Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event; - scim_string_to_key(key, ev->key); - key.mask = SCIM_KEY_ReleaseMask; - if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask; - if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask; - if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask; - if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask; - if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask; - if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask; - } - else - { - return ret; - } - - key.mask &= _valid_key_mask; - - _panel_client.prepare(ic->id); - - ret = EINA_TRUE; - if (!filter_hotkeys(ic, key)) - { - if (!_focused_ic || !_focused_ic->impl->is_on || - !_focused_ic->impl->si->process_key_event(key)) - ret = EINA_FALSE; - } - - _panel_client.send(); - - return ret; -} - -EAPI void -isf_imf_context_input_panel_show(Ecore_IMF_Context *ctx) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - if (ic == NULL || ic->impl == NULL) - return; - - ecore_x_e_virtual_keyboard_state_set - (ic->impl->client_window, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON); -} - -EAPI void -isf_imf_context_input_panel_hide(Ecore_IMF_Context *ctx) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); - if (ic == NULL || ic->impl == NULL) - return; - - ecore_x_e_virtual_keyboard_state_set - (ic->impl->client_window, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF); -} - -/* Panel Slot functions */ -static void -panel_slot_reload_config(int context __UNUSED__) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - _config->reload(); -} - -static void -panel_slot_exit(int /* context */) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - finalize(); -} - -static void -panel_slot_update_lookup_table_page_size(int context, int page_size) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " page_size=" << page_size << " ic=" << ic << "\n"; - if (ic && ic->impl) - { - _panel_client.prepare(ic->id); - ic->impl->si->update_lookup_table_page_size(page_size); - _panel_client.send(); - } -} - -static void -panel_slot_lookup_table_page_up(int context) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; - if (ic && ic->impl) - { - _panel_client.prepare(ic->id); - ic->impl->si->lookup_table_page_up(); - _panel_client.send(); - } -} - -static void -panel_slot_lookup_table_page_down(int context) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; - if (ic && ic->impl) - { - _panel_client.prepare(ic->id); - ic->impl->si->lookup_table_page_down(); - _panel_client.send(); - } -} - -static void -panel_slot_trigger_property(int context, const String &property) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " property=" << property << " ic=" << ic << "\n"; - if (ic && ic->impl) - { - _panel_client.prepare(ic->id); - ic->impl->si->trigger_property(property); - _panel_client.send(); - } -} - -static void -panel_slot_process_helper_event(int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " target=" << target_uuid - << " helper=" << helper_uuid << " ic=" << ic << " ic->impl=" << (ic ? ic->impl : 0) << " ic-uuid=" - << ((ic && ic->impl) ? ic->impl->si->get_factory_uuid() : "" ) << "\n"; - if (ic && ic->impl && ic->impl->si->get_factory_uuid() == target_uuid) - { - _panel_client.prepare(ic->id); - SCIM_DEBUG_FRONTEND(2) << "call process_helper_event\n"; - ic->impl->si->process_helper_event(helper_uuid, trans); - _panel_client.send(); - } -} - -static void -panel_slot_move_preedit_caret(int context, int caret_pos) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " caret=" << caret_pos << " ic=" << ic << "\n"; - if (ic && ic->impl) - { - _panel_client.prepare(ic->id); - ic->impl->si->move_preedit_caret(caret_pos); - _panel_client.send(); - } -} - -static void -panel_slot_select_candidate(int context, int cand_index) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " candidate=" << cand_index << " ic=" << ic << "\n"; - if (ic && ic->impl) - { - _panel_client.prepare(ic->id); - ic->impl->si->select_candidate(cand_index); - _panel_client.send(); - } -} - -static void -panel_slot_process_key_event(int context, const KeyEvent &key) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string() << " ic=" << ic << "\n"; - - if (key.is_key_press()) - ecore_x_test_fake_key_press(key.get_key_string().c_str()); -} - -static void -panel_slot_commit_string(int context, const WideString &wstr) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " str=" << utf8_wcstombs(wstr) << " ic=" << ic << "\n"; - - if (ic && ic->impl) - { - if (_focused_ic != ic) - return; - - ecore_imf_context_commit_event_add(ic->ctx, utf8_wcstombs(wstr).c_str()); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); - } -} - -static void -panel_slot_forward_key_event(int context, const KeyEvent &key) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string() << " ic=" << ic << "\n"; - - if (ic && ic->impl && ic->impl->client_canvas) - feed_key_event(ic->impl->client_canvas, key.get_key_string().c_str(), EINA_TRUE); -} - -static void -panel_slot_request_help(int context) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; - - if (ic && ic->impl) - { - _panel_client.prepare(ic->id); - panel_req_show_help(ic); - _panel_client.send(); - } -} - -static void -panel_slot_request_factory_menu(int context) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; - - if (ic && ic->impl) - { - _panel_client.prepare(ic->id); - panel_req_show_factory_menu(ic); - _panel_client.send(); - } -} - -static void -panel_slot_change_factory(int context, const String &uuid) -{ - EcoreIMFContextISF *ic = find_ic(context); - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " factory=" << uuid << " ic=" << ic << "\n"; - - if (ic && ic->impl) - { - ic->impl->si->reset(); - _panel_client.prepare(ic->id); - open_specific_factory(ic, uuid); - _panel_client.send(); - } -} - -/* Panel Requestion functions. */ -static void -panel_req_show_help(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - String help; - - help = String("Smart Common Input Method platform ") + - //String(SCIM_VERSION) + - String("\n(C) 2002-2005 James Su \n\n"); - - if (ic && ic->impl) - { - IMEngineFactoryPointer sf = _backend->get_factory(ic->impl->si->get_factory_uuid()); - if (sf) - { - help += utf8_wcstombs(sf->get_name()); - help += String(":\n\n"); - - help += utf8_wcstombs(sf->get_help()); - help += String("\n\n"); - - help += utf8_wcstombs(sf->get_credits()); - } - _panel_client.show_help(ic->id, help); - } -} - -static void -panel_req_show_factory_menu(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - std::vector factories; - std::vector menu; - - _backend->get_factories_for_encoding(factories, "UTF-8"); - - for (size_t i = 0; i < factories.size(); ++ i) - { - menu.push_back(PanelFactoryInfo( - factories [i]->get_uuid(), - utf8_wcstombs(factories [i]->get_name()), - factories [i]->get_language(), - factories [i]->get_icon_file())); - } - - if (menu.size()) - _panel_client.show_factory_menu(ic->id, menu); -} - -static void -panel_req_update_factory_info(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (ic && ic->impl && ic == _focused_ic) - { - PanelFactoryInfo info; - if (ic->impl->is_on) - { - IMEngineFactoryPointer sf = _backend->get_factory(ic->impl->si->get_factory_uuid()); - if (sf) - info = PanelFactoryInfo(sf->get_uuid(), utf8_wcstombs(sf->get_name()), sf->get_language(), sf->get_icon_file()); - } - else - { - info = PanelFactoryInfo(String(""), String("English/Keyboard"), String("C"), ""); - } - _panel_client.update_factory_info(ic->id, info); - } -} - -static void -panel_req_focus_in(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - _panel_client.focus_in(ic->id, ic->impl->si->get_factory_uuid()); -} - -static void -panel_req_update_spot_location(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - _panel_client.update_spot_location(ic->id, ic->impl->cursor_x, ic->impl->cursor_y); -} - -static bool -filter_hotkeys(EcoreIMFContextISF *ic, const KeyEvent &key) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - bool ret = false; - - _frontend_hotkey_matcher.push_key_event(key); - _imengine_hotkey_matcher.push_key_event(key); - - FrontEndHotkeyAction hotkey_action = _frontend_hotkey_matcher.get_match_result(); - - if (hotkey_action == SCIM_FRONTEND_HOTKEY_TRIGGER) - { - if (!ic->impl->is_on) - turn_on_ic(ic); - else - turn_off_ic(ic); - ret = true; - } - else if (hotkey_action == SCIM_FRONTEND_HOTKEY_ON) - { - if (!ic->impl->is_on) - turn_on_ic(ic); - ret = true; - } - else if (hotkey_action == SCIM_FRONTEND_HOTKEY_OFF) - { - if (ic->impl->is_on) - turn_off_ic(ic); - ret = true; - } - else if (hotkey_action == SCIM_FRONTEND_HOTKEY_NEXT_FACTORY) - { - open_next_factory(ic); - ret = true; - } - else if (hotkey_action == SCIM_FRONTEND_HOTKEY_PREVIOUS_FACTORY) - { - open_previous_factory(ic); - ret = true; - } - else if (hotkey_action == SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU) - { - panel_req_show_factory_menu(ic); - ret = true; - } - else if (_imengine_hotkey_matcher.is_matched()) - { - String sfid = _imengine_hotkey_matcher.get_match_result(); - open_specific_factory(ic, sfid); - ret = true; - } - return ret; -} - -static bool -panel_initialize(void) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - String display_name; - { - const char *p = getenv("DISPLAY"); - if (p) display_name = String(p); - } - - if (_panel_client.open_connection(_config->get_name(), display_name) >= 0) - { - int fd = _panel_client.get_connection_number(); - - _panel_iochannel_read_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, panel_iochannel_handler, NULL, NULL, NULL); - - SCIM_DEBUG_FRONTEND(2) << " Panel FD= " << fd << "\n"; - - return true; - } - std::cerr << "panel_initialize() failed!!!\n"; - return false; -} - -static void -panel_finalize(void) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - _panel_client.close_connection(); - - if (_panel_iochannel_read_handler) - { - ecore_main_fd_handler_del(_panel_iochannel_read_handler); - _panel_iochannel_read_handler = 0; - } - - if (_panel_iochannel_err_handler) - { - ecore_main_fd_handler_del(_panel_iochannel_err_handler); - _panel_iochannel_err_handler = 0; - } -} - -static Eina_Bool -panel_iochannel_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (fd_handler == _panel_iochannel_read_handler) - { - if (!_panel_client.filter_event()) - { - panel_finalize(); - panel_initialize(); - return ECORE_CALLBACK_CANCEL; - } - } - else if (fd_handler == _panel_iochannel_err_handler) - { - panel_finalize(); - panel_initialize(); - return ECORE_CALLBACK_CANCEL; - } - return ECORE_CALLBACK_RENEW; -} - -static void -turn_on_ic(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (ic && ic->impl && !ic->impl->is_on) - { - ic->impl->is_on = true; - - if (ic == _focused_ic) - { - panel_req_focus_in(ic); - panel_req_update_spot_location(ic); - panel_req_update_factory_info(ic); - _panel_client.turn_on(ic->id); - _panel_client.hide_preedit_string(ic->id); - _panel_client.hide_aux_string(ic->id); - _panel_client.hide_lookup_table(ic->id); - ic->impl->si->focus_in(); - } - - //Record the IC on/off status - if (_shared_input_method) - _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), true); - - if (ic->impl->use_preedit && ic->impl->preedit_string.length()) - { - ecore_imf_context_preedit_start_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); - ecore_imf_context_preedit_changed_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - ic->impl->preedit_started = true; - } - } -} - -static void -turn_off_ic(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (ic && ic->impl && ic->impl->is_on) - { - ic->impl->is_on = false; - - if (ic == _focused_ic) - { - ic->impl->si->focus_out(); - - panel_req_update_factory_info(ic); - _panel_client.turn_off(ic->id); - } - - //Record the IC on/off status - if (_shared_input_method) - _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); - - if (ic->impl->use_preedit && ic->impl->preedit_string.length()) - { - ecore_imf_context_preedit_changed_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - ecore_imf_context_preedit_end_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); - ic->impl->preedit_started = false; - } - } -} - -static void -set_ic_capabilities(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (ic && ic->impl) - { - unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES; - - if (!_on_the_spot || !ic->impl->use_preedit) - cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT; - - ic->impl->si->update_client_capabilities(cap); - } -} - -static bool -check_socket_frontend(void) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - SocketAddress address; - SocketClient client; - - uint32 magic; - - address.set_address(scim_get_default_socket_frontend_address()); - - if (!client.connect(address)) - return false; - - if (!scim_socket_open_connection(magic, - String("ConnectionTester"), - String("SocketFrontEnd"), - client, - 1000)) - return false; - - return true; -} - -void -initialize(void) -{ - std::vector config_list; - std::vector engine_list; - std::vector load_engine_list; - - std::vector::iterator it; - - bool manual = false; - - bool socket = true; - - String config_module_name = "simple"; - - printf("Initializing Ecore SCIM IMModule...\n"); - - SCIM_DEBUG_FRONTEND(1) << "Initializing Ecore SCIM IMModule...\n"; - - // Get system language. - _language = scim_get_locale_language(scim_get_current_locale()); - - if (socket) - { - // If no Socket FrontEnd is running, then launch one. - // And set manual to false. - bool check_result = check_socket_frontend(); - if (!check_result) - { - std::cerr << "Launching a SCIM daemon with Socket FrontEnd...\n"; - //get modules list - scim_get_imengine_module_list(engine_list); - - for (it = engine_list.begin(); it != engine_list.end(); it++) - { - if (*it != "socket") - load_engine_list.push_back(*it); - } - - const char *new_argv [] = { "--no-stay", 0 }; - scim_launch(true, - config_module_name, - (load_engine_list.size() ? scim_combine_string_list(load_engine_list, ',') : "none"), - "socket", - (char **)new_argv); - manual = false; - } - - // If there is one Socket FrontEnd running and it's not manual mode, - // then just use this Socket Frontend. - if (!manual) - { - for (int i = 0; i < 200; ++i) - { - if (check_result) - { - config_module_name = "socket"; - load_engine_list.clear(); - load_engine_list.push_back("socket"); - break; - } - scim_usleep(50000); - check_result = check_socket_frontend(); - } - } - } - - if (config_module_name != "dummy") - { - //load config module - SCIM_DEBUG_FRONTEND(1) << "Loading Config module: " << config_module_name << "...\n"; - _config_module = new ConfigModule(config_module_name); - - //create config instance - if (_config_module != NULL && _config_module->valid()) - _config = _config_module->create_config(); - } - - if (_config.null()) - { - SCIM_DEBUG_FRONTEND(1) << "Config module cannot be loaded, using dummy Config.\n"; - - if (_config_module) delete _config_module; - _config_module = NULL; - - _config = new DummyConfig(); - config_module_name = "dummy"; - } - - reload_config_callback(_config); - _config->signal_connect_reload(slot(reload_config_callback)); - - // create backend - _backend = new CommonBackEnd(_config, load_engine_list.size() ? load_engine_list : engine_list); - - if (_backend.null()) - std::cerr << "Cannot create BackEnd Object!\n"; - else - _fallback_factory = _backend->get_factory(SCIM_COMPOSE_KEY_FACTORY_UUID); - - if (_fallback_factory.null()) - _fallback_factory = new DummyIMEngineFactory(); - - _fallback_instance = _fallback_factory->create_instance(String("UTF-8"), 0); - _fallback_instance->signal_connect_commit_string(slot(fallback_commit_string_cb)); - - // Attach Panel Client signal. - _panel_client.signal_connect_reload_config (slot(panel_slot_reload_config)); - _panel_client.signal_connect_exit (slot(panel_slot_exit)); - _panel_client.signal_connect_update_lookup_table_page_size(slot(panel_slot_update_lookup_table_page_size)); - _panel_client.signal_connect_lookup_table_page_up (slot(panel_slot_lookup_table_page_up)); - _panel_client.signal_connect_lookup_table_page_down (slot(panel_slot_lookup_table_page_down)); - _panel_client.signal_connect_trigger_property (slot(panel_slot_trigger_property)); - _panel_client.signal_connect_process_helper_event (slot(panel_slot_process_helper_event)); - _panel_client.signal_connect_move_preedit_caret (slot(panel_slot_move_preedit_caret)); - _panel_client.signal_connect_select_candidate (slot(panel_slot_select_candidate)); - _panel_client.signal_connect_process_key_event (slot(panel_slot_process_key_event)); - _panel_client.signal_connect_commit_string (slot(panel_slot_commit_string)); - _panel_client.signal_connect_forward_key_event (slot(panel_slot_forward_key_event)); - _panel_client.signal_connect_request_help (slot(panel_slot_request_help)); - _panel_client.signal_connect_request_factory_menu (slot(panel_slot_request_factory_menu)); - _panel_client.signal_connect_change_factory (slot(panel_slot_change_factory)); - - if (!panel_initialize()) - std::cerr << "Ecore IM Module: Cannot connect to Panel!\n"; -} - -static void -finalize(void) -{ - SCIM_DEBUG_FRONTEND(1) << "Finalizing Ecore ISF IMModule...\n"; - - // Reset this first so that the shared instance could be released correctly afterwards. - _default_instance.reset(); - - SCIM_DEBUG_FRONTEND(2) << "Finalize all IC partially.\n"; - while (_used_ic_impl_list) - { - // In case in "shared input method" mode, - // all contexts share only one instance, - // so we need point the reference pointer correctly before finalizing. - _used_ic_impl_list->si->set_frontend_data(static_cast (_used_ic_impl_list->parent)); - isf_imf_context_del(_used_ic_impl_list->parent->ctx); - } - - delete_all_ic_impl(); - - _fallback_instance.reset(); - _fallback_factory.reset(); - - SCIM_DEBUG_FRONTEND(2) << " Releasing BackEnd...\n"; - _backend.reset(); - - SCIM_DEBUG_FRONTEND(2) << " Releasing Config...\n"; - _config.reset(); - - if (_config_module) - { - SCIM_DEBUG_FRONTEND(2) << " Deleting _config_module...\n"; - delete _config_module; - _config_module = 0; - } - - _focused_ic = NULL; - _ic_list = NULL; - - _scim_initialized = false; - - panel_finalize(); -} - -static void -open_next_factory(EcoreIMFContextISF *ic) -{ - SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; - IMEngineFactoryPointer sf = _backend->get_next_factory("", "UTF-8", ic->impl->si->get_factory_uuid()); - - if (!sf.null()) - { - turn_off_ic(ic); - ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id()); - ic->impl->si->set_frontend_data(static_cast (ic)); - ic->impl->preedit_string = WideString(); - ic->impl->preedit_caret = 0; - attach_instance(ic->impl->si); - _backend->set_default_factory(_language, sf->get_uuid()); - _panel_client.register_input_context(ic->id, sf->get_uuid()); - set_ic_capabilities(ic); - turn_on_ic(ic); - - if (_shared_input_method) - { - _default_instance = ic->impl->si; - ic->impl->shared_si = true; - } - } -} - -static void -open_previous_factory(EcoreIMFContextISF *ic) -{ - if (ic == NULL) - return; - - SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; - IMEngineFactoryPointer sf = _backend->get_previous_factory("", "UTF-8", ic->impl->si->get_factory_uuid()); - - if (!sf.null()) - { - turn_off_ic(ic); - ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id()); - ic->impl->si->set_frontend_data(static_cast (ic)); - ic->impl->preedit_string = WideString(); - ic->impl->preedit_caret = 0; - attach_instance(ic->impl->si); - _backend->set_default_factory(_language, sf->get_uuid()); - _panel_client.register_input_context(ic->id, sf->get_uuid()); - set_ic_capabilities(ic); - turn_on_ic(ic); - - if (_shared_input_method) - { - _default_instance = ic->impl->si; - ic->impl->shared_si = true; - } - } -} - -static void -open_specific_factory(EcoreIMFContextISF *ic, - const String &uuid) -{ - if (ic == NULL) - return; - - SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; - - // The same input method is selected, just turn on the IC. - if (ic->impl->si->get_factory_uuid() == uuid) - { - turn_on_ic(ic); - return; - } - - IMEngineFactoryPointer sf = _backend->get_factory(uuid); - - if (uuid.length() && !sf.null()) - { - turn_off_ic(ic); - ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id()); - ic->impl->si->set_frontend_data(static_cast (ic)); - ic->impl->preedit_string = WideString(); - ic->impl->preedit_caret = 0; - attach_instance(ic->impl->si); - _backend->set_default_factory(_language, sf->get_uuid()); - _panel_client.register_input_context(ic->id, sf->get_uuid()); - set_ic_capabilities(ic); - turn_on_ic(ic); - - if (_shared_input_method) - { - _default_instance = ic->impl->si; - ic->impl->shared_si = true; - } - } - else - { - // turn_off_ic comment out panel_req_update_factory_info() - turn_off_ic(ic); - if (ic && ic->impl->is_on) - { - ic->impl->is_on = false; - - if (ic == _focused_ic) - { - ic->impl->si->focus_out(); - - panel_req_update_factory_info(ic); - _panel_client.turn_off(ic->id); - } - - //Record the IC on/off status - if (_shared_input_method) - _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); - - if (ic->impl->use_preedit && ic->impl->preedit_string.length()) - { - ecore_imf_context_preedit_changed_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - ecore_imf_context_preedit_end_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); - ic->impl->preedit_started = false; - } - } - } -} - -static void initialize_modifier_bits(Display *display) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (__current_display == display) - return; - - __current_display = display; - - if (display == 0) - { - __current_alt_mask = Mod1Mask; - __current_meta_mask = ShiftMask | Mod1Mask; - __current_super_mask = 0; - __current_hyper_mask = 0; - __current_numlock_mask = Mod2Mask; - return; - } - - XModifierKeymap *mods = NULL; - - ::KeyCode ctrl_l = XKeysymToKeycode(display, XK_Control_L); - ::KeyCode ctrl_r = XKeysymToKeycode(display, XK_Control_R); - ::KeyCode meta_l = XKeysymToKeycode(display, XK_Meta_L); - ::KeyCode meta_r = XKeysymToKeycode(display, XK_Meta_R); - ::KeyCode alt_l = XKeysymToKeycode(display, XK_Alt_L); - ::KeyCode alt_r = XKeysymToKeycode(display, XK_Alt_R); - ::KeyCode super_l = XKeysymToKeycode(display, XK_Super_L); - ::KeyCode super_r = XKeysymToKeycode(display, XK_Super_R); - ::KeyCode hyper_l = XKeysymToKeycode(display, XK_Hyper_L); - ::KeyCode hyper_r = XKeysymToKeycode(display, XK_Hyper_R); - ::KeyCode numlock = XKeysymToKeycode(display, XK_Num_Lock); - - int i, j; - - mods = XGetModifierMapping(display); - if (mods == NULL) - return; - - __current_alt_mask = 0; - __current_meta_mask = 0; - __current_super_mask = 0; - __current_hyper_mask = 0; - __current_numlock_mask = 0; - - /* We skip the first three sets for Shift, Lock, and Control. The - remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */ - for (i = 3; i < 8; i++) - { - for (j = 0; j < mods->max_keypermod; j++) - { - ::KeyCode code = mods->modifiermap [i * mods->max_keypermod + j]; - if (! code) continue; - if (code == alt_l || code == alt_r) - __current_alt_mask |= (1 << i); - else if (code == meta_l || code == meta_r) - __current_meta_mask |= (1 << i); - else if (code == super_l || code == super_r) - __current_super_mask |= (1 << i); - else if (code == hyper_l || code == hyper_r) - __current_hyper_mask |= (1 << i); - else if (code == numlock) - __current_numlock_mask |= (1 << i); - } - } - - /* Check whether there is a combine keys mapped to Meta */ - if (__current_meta_mask == 0) - { - char buf [32]; - XKeyEvent xkey; - KeySym keysym_l, keysym_r; - - xkey.type = KeyPress; - xkey.display = display; - xkey.serial = 0L; - xkey.send_event = False; - xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0; - xkey.time = 0; - xkey.same_screen = False; - xkey.subwindow = None; - xkey.window = None; - xkey.root = DefaultRootWindow(display); - xkey.state = ShiftMask; - - xkey.keycode = meta_l; - XLookupString(&xkey, buf, 32, &keysym_l, 0); - xkey.keycode = meta_r; - XLookupString(&xkey, buf, 32, &keysym_r, 0); - - if ((meta_l == alt_l && keysym_l == XK_Meta_L) || (meta_r == alt_r && keysym_r == XK_Meta_R)) - __current_meta_mask = ShiftMask + __current_alt_mask; - else if ((meta_l == ctrl_l && keysym_l == XK_Meta_L) || (meta_r == ctrl_r && keysym_r == XK_Meta_R)) - __current_meta_mask = ShiftMask + ControlMask; - } - - XFreeModifiermap(mods); -} - -static unsigned int scim_x11_keymask_scim_to_x11(Display *display, uint16 scimkeymask) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - unsigned int state = 0; - - initialize_modifier_bits(display); - - if (scimkeymask & SCIM_KEY_ShiftMask) state |= ShiftMask; - if (scimkeymask & SCIM_KEY_CapsLockMask) state |= LockMask; - if (scimkeymask & SCIM_KEY_ControlMask) state |= ControlMask; - if (scimkeymask & SCIM_KEY_AltMask) state |= __current_alt_mask; - if (scimkeymask & SCIM_KEY_MetaMask) state |= __current_meta_mask; - if (scimkeymask & SCIM_KEY_SuperMask) state |= __current_super_mask; - if (scimkeymask & SCIM_KEY_HyperMask) state |= __current_hyper_mask; - if (scimkeymask & SCIM_KEY_NumLockMask) state |= __current_numlock_mask; - - return state; -} - -static XKeyEvent createKeyEvent(Display *display, Window &win, - Window &winRoot, bool press, - int keycode, int modifiers) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - XKeyEvent event; - - event.display = display; - event.window = win; - event.root = winRoot; - event.subwindow = None; - event.time = CurrentTime; - event.x = 1; - event.y = 1; - event.x_root = 1; - event.y_root = 1; - event.same_screen = EINA_TRUE; - event.state = modifiers; - event.keycode = XKeysymToKeycode(display, keycode); - if (press) - event.type = KeyPress; - else - event.type = KeyRelease; - event.send_event = EINA_FALSE; - event.serial = 0; - - return event; -} - -static void _x_send_key_event(const KeyEvent &key) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - // Obtain the X11 display. - Display *display = XOpenDisplay(NULL); - if (display == NULL) - { - std::cerr << "XOpenDisplay failed\n"; - return; - } - - // Get the root window for the current display. - Window winRoot = 0; - - // Find the window which has the current keyboard focus. - Window winFocus = 0; - int revert = RevertToParent; - - XGetInputFocus(display, &winFocus, &revert); - - // Send a fake key press event to the window. - XSelectInput(display, winFocus, FocusChangeMask|KeyPressMask|KeyReleaseMask); - XMapWindow(display, winFocus); - - unsigned int modifier = scim_x11_keymask_scim_to_x11(display, key.mask); - XKeyEvent event; - if (key.is_key_press()) - { - event = createKeyEvent(display, winFocus, winRoot, true, key.code, modifier); - XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); - } - else - { - event = createKeyEvent(display, winFocus, winRoot, false, key.code, modifier); - XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event); - } - - XCloseDisplay(display); -} - -static void -attach_instance(const IMEngineInstancePointer &si) -{ - si->signal_connect_show_preedit_string( - slot(slot_show_preedit_string)); - si->signal_connect_show_aux_string( - slot(slot_show_aux_string)); - si->signal_connect_show_lookup_table( - slot(slot_show_lookup_table)); - - si->signal_connect_hide_preedit_string( - slot(slot_hide_preedit_string)); - si->signal_connect_hide_aux_string( - slot(slot_hide_aux_string)); - si->signal_connect_hide_lookup_table( - slot(slot_hide_lookup_table)); - - si->signal_connect_update_preedit_caret( - slot(slot_update_preedit_caret)); - si->signal_connect_update_preedit_string( - slot(slot_update_preedit_string)); - si->signal_connect_update_aux_string( - slot(slot_update_aux_string)); - si->signal_connect_update_lookup_table( - slot(slot_update_lookup_table)); - - si->signal_connect_commit_string( - slot(slot_commit_string)); - - si->signal_connect_forward_key_event( - slot(slot_forward_key_event)); - - si->signal_connect_register_properties( - slot(slot_register_properties)); - - si->signal_connect_update_property( - slot(slot_update_property)); - - si->signal_connect_beep( - slot(slot_beep)); - - si->signal_connect_start_helper( - slot(slot_start_helper)); - - si->signal_connect_stop_helper( - slot(slot_stop_helper)); - - si->signal_connect_send_helper_event( - slot(slot_send_helper_event)); - - si->signal_connect_get_surrounding_text( - slot(slot_get_surrounding_text)); - - si->signal_connect_delete_surrounding_text( - slot(slot_delete_surrounding_text)); -} - -// Implementation of slot functions -static void -slot_show_preedit_string(IMEngineInstanceBase *si) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - { - if (ic->impl->use_preedit) - { - if (!ic->impl->preedit_started) - { - ecore_imf_context_preedit_start_event_add(_focused_ic->ctx); - ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); - ic->impl->preedit_started = true; - } - } - else - _panel_client.show_preedit_string(ic->id); - } -} - -static void -slot_show_aux_string(IMEngineInstanceBase *si) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - _panel_client.show_aux_string(ic->id); -} - -static void -slot_show_lookup_table(IMEngineInstanceBase *si) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - _panel_client.show_lookup_table(ic->id); -} - -static void -slot_hide_preedit_string(IMEngineInstanceBase *si) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - { - bool emit = false; - if (ic->impl->preedit_string.length()) - { - ic->impl->preedit_string = WideString(); - ic->impl->preedit_caret = 0; - ic->impl->preedit_attrlist.clear(); - emit = true; - } - if (ic->impl->use_preedit) - { - if (emit) - { - ecore_imf_context_preedit_changed_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - if (ic->impl->preedit_started) - { - ecore_imf_context_preedit_end_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); - ic->impl->preedit_started = false; - } - } - else - _panel_client.hide_preedit_string(ic->id); - } -} - -static void -slot_hide_aux_string(IMEngineInstanceBase *si) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - _panel_client.hide_aux_string(ic->id); -} - -static void -slot_hide_lookup_table(IMEngineInstanceBase *si) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - _panel_client.hide_lookup_table(ic->id); -} - -static void -slot_update_preedit_caret(IMEngineInstanceBase *si, int caret) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret) - { - ic->impl->preedit_caret = caret; - if (ic->impl->use_preedit) - { - if (!ic->impl->preedit_started) - { - ecore_imf_context_preedit_start_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); - ic->impl->preedit_started = true; - } - ecore_imf_context_preedit_changed_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - else - _panel_client.update_preedit_caret(ic->id, caret); - } -} - -static void -slot_update_preedit_string(IMEngineInstanceBase *si, - const WideString & str, - const AttributeList & attrs) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic && (ic->impl->preedit_string != str || str.length())) - { - ic->impl->preedit_string = str; - ic->impl->preedit_attrlist = attrs; - if (ic->impl->use_preedit) - { - if (!ic->impl->preedit_started) - { - ecore_imf_context_preedit_start_event_add(_focused_ic->ctx); - ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); - ic->impl->preedit_started = true; - } - ic->impl->preedit_caret = str.length(); - ic->impl->preedit_updating = true; - ecore_imf_context_preedit_changed_event_add(ic->ctx); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - ic->impl->preedit_updating = false; - } - else - { - _panel_client.update_preedit_string(ic->id, str, attrs); - } - } -} - -static void -slot_update_aux_string(IMEngineInstanceBase *si, - const WideString & str, - const AttributeList & attrs) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - _panel_client.update_aux_string(ic->id, str, attrs); -} - -static void -slot_commit_string(IMEngineInstanceBase *si, - const WideString & str) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->ctx) - { - ecore_imf_context_commit_event_add(ic->ctx, utf8_wcstombs(str).c_str()); - ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str()); - } -} - -static void -slot_forward_key_event(IMEngineInstanceBase *si, - const KeyEvent & key) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && _focused_ic == ic) - { - if (!_fallback_instance->process_key_event(key)) - _x_send_key_event(key); - } -} - -static void -slot_update_lookup_table(IMEngineInstanceBase *si, - const LookupTable & table) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - _panel_client.update_lookup_table(ic->id, table); -} - -static void -slot_register_properties(IMEngineInstanceBase *si, - const PropertyList & properties) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - _panel_client.register_properties(ic->id, properties); -} - -static void -slot_update_property(IMEngineInstanceBase *si, - const Property & property) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - _panel_client.update_property(ic->id, property); -} - -static void -slot_beep(IMEngineInstanceBase *si __UNUSED__) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; -} - -static void -slot_start_helper(IMEngineInstanceBase *si, - const String &helper_uuid) -{ - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" - << (ic ? ic->id : -1) << " ic=" << ic - << " ic-uuid=" << ((ic ) ? ic->impl->si->get_factory_uuid() : "") << "...\n"; - - if (ic && ic->impl) - _panel_client.start_helper(ic->id, helper_uuid); -} - -static void -slot_stop_helper(IMEngineInstanceBase *si, - const String &helper_uuid) -{ - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" << (ic ? ic->id : -1) << " ic=" << ic << "...\n"; - - if (ic && ic->impl) - _panel_client.stop_helper(ic->id, helper_uuid); -} - -static void -slot_send_helper_event(IMEngineInstanceBase *si, - const String &helper_uuid, - const Transaction &trans) -{ - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" - << (ic ? ic->id : -1) << " ic=" << ic - << " ic-uuid=" << ((ic) ? ic->impl->si->get_factory_uuid() : "") << "...\n"; - - if (ic && ic->impl) - _panel_client.send_helper_event(ic->id, helper_uuid, trans); -} - -static bool -slot_get_surrounding_text(IMEngineInstanceBase *si, - WideString &text, - int &cursor, - int maxlen_before, - int maxlen_after) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - { - char *surrounding = NULL; - int cursor_index; - if (ecore_imf_context_surrounding_get(_focused_ic->ctx, &surrounding, &cursor_index)) - { - SCIM_DEBUG_FRONTEND(2) << "Surrounding text: " << surrounding <<"\n"; - SCIM_DEBUG_FRONTEND(2) << "Cursor Index : " << cursor_index <<"\n"; - WideString before(utf8_mbstowcs(String(surrounding, surrounding + cursor_index))); - WideString after(utf8_mbstowcs(String(surrounding + cursor_index))); - if (maxlen_before > 0 && ((unsigned int)maxlen_before) < before.length()) - before = WideString(before.begin() + (before.length() - maxlen_before), before.end()); - else if (maxlen_before == 0) before = WideString(); - if (maxlen_after > 0 && ((unsigned int)maxlen_after) < after.length()) - after = WideString(after.begin(), after.begin() + maxlen_after); - else if (maxlen_after == 0) after = WideString(); - text = before + after; - cursor = before.length(); - return true; - } - } - return false; -} - -static bool -slot_delete_surrounding_text(IMEngineInstanceBase *si, - int offset, - int len) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); - - if (ic && ic->impl && _focused_ic == ic) - { - Ecore_IMF_Event_Delete_Surrounding ev; - ev.ctx = _focused_ic->ctx; - ev.n_chars = len; - ev.offset = offset; - ecore_imf_context_delete_surrounding_event_add(_focused_ic->ctx, offset, len); - ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev); - return true; - } - return false; -} - -static void -reload_config_callback(const ConfigPointer &config) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - _frontend_hotkey_matcher.load_hotkeys(config); - _imengine_hotkey_matcher.load_hotkeys(config); - - KeyEvent key; - - scim_string_to_key(key, - config->read(String(SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK), - String("Shift+Control+Alt+Lock"))); - - _valid_key_mask = (key.mask > 0)?(key.mask):0xFFFF; - _valid_key_mask |= SCIM_KEY_ReleaseMask; - // Special treatment for two backslash keys on jp106 keyboard. - _valid_key_mask |= SCIM_KEY_QuirkKanaRoMask; - - _on_the_spot = config->read(String(SCIM_CONFIG_FRONTEND_ON_THE_SPOT), _on_the_spot); - _shared_input_method = config->read(String(SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), _shared_input_method); - - // Get keyboard layout setting - // Flush the global config first, in order to load the new configs from disk. - scim_global_config_flush(); - - _keyboard_layout = scim_get_default_keyboard_layout(); -} - -static void -fallback_commit_string_cb(IMEngineInstanceBase *si __UNUSED__, - const WideString &str) -{ - SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; - - if (_focused_ic && _focused_ic->impl) - { - ecore_imf_context_commit_event_add(_focused_ic->ctx, utf8_wcstombs(str).c_str()); - ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str()); - } -} - diff --git a/legacy/ecore/src/modules/immodules/scim/scim_imcontext.h b/legacy/ecore/src/modules/immodules/scim/scim_imcontext.h deleted file mode 100644 index 72533e245d..0000000000 --- a/legacy/ecore/src/modules/immodules/scim/scim_imcontext.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __ISF_IMF_CONTEXT_H -#define __ISF_IMF_CONTEXT_H - -#include - -typedef struct _EcoreIMFContextISF EcoreIMFContextISF; -typedef struct _EcoreIMFContextISFImpl EcoreIMFContextISFImpl; - -struct _EcoreIMFContextISF { - Ecore_IMF_Context *ctx; - - EcoreIMFContextISFImpl *impl; - - int id; /* Input Context id*/ - struct _EcoreIMFContextISF *next; -}; - -void isf_imf_context_add (Ecore_IMF_Context *ctx); -void isf_imf_context_del (Ecore_IMF_Context *ctx); -void isf_imf_context_client_window_set (Ecore_IMF_Context *ctx, void *window); -void isf_imf_context_client_canvas_set (Ecore_IMF_Context *ctx, void *window); -void isf_imf_context_focus_in (Ecore_IMF_Context *ctx); -void isf_imf_context_focus_out (Ecore_IMF_Context *ctx); -void isf_imf_context_reset (Ecore_IMF_Context *ctx); -void isf_imf_context_cursor_position_set (Ecore_IMF_Context *ctx, int cursor_pos); -void isf_imf_context_cursor_location_set (Ecore_IMF_Context *ctx, int x, int y, int w, int h); -void isf_imf_context_input_mode_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); -void isf_imf_context_preedit_string_get (Ecore_IMF_Context *ctx, char** str, int *cursor_pos); -void isf_imf_context_preedit_string_with_attributes_get (Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos); -void isf_imf_context_use_preedit_set (Ecore_IMF_Context* ctx, Eina_Bool use_preedit); -Eina_Bool isf_imf_context_filter_event (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); -void isf_imf_context_prediction_allow_set (Ecore_IMF_Context* ctx, Eina_Bool prediction); -void isf_imf_context_autocapital_type_set (Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type); -void isf_imf_context_input_panel_layout_set (Ecore_IMF_Context* ctx, Ecore_IMF_Input_Panel_Layout layout); -void isf_imf_context_input_panel_show(Ecore_IMF_Context *ctx); -void isf_imf_context_input_panel_hide(Ecore_IMF_Context *ctx); - -EcoreIMFContextISF* isf_imf_context_new (void); -void isf_imf_context_shutdown (void); - -#endif /* __ISF_IMF_CONTEXT_H */ - diff --git a/legacy/ecore/src/modules/immodules/scim/scim_module.cpp b/legacy/ecore/src/modules/immodules/scim/scim_module.cpp deleted file mode 100644 index d77fb11f3a..0000000000 --- a/legacy/ecore/src/modules/immodules/scim/scim_module.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include "scim_imcontext.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - - static const Ecore_IMF_Context_Info isf_imf_info = { - "scim", /* ID */ - "SCIM immodule for Ecore", /* Description */ - "*", /* Default locales */ - NULL, /* Canvas type */ - 0 /* Canvas required */ - }; - - static Ecore_IMF_Context_Class isf_imf_class = { - isf_imf_context_add, /* add */ - isf_imf_context_del, /* del */ - isf_imf_context_client_window_set, /* client_window_set */ - isf_imf_context_client_canvas_set, /* client_canvas_set */ - isf_imf_context_input_panel_show, /* input_panel_show, - show */ - isf_imf_context_input_panel_hide, /* input_panel_hide, - hide */ - isf_imf_context_preedit_string_get, /* get_preedit_string */ - isf_imf_context_focus_in, /* focus_in */ - isf_imf_context_focus_out, /* focus_out */ - isf_imf_context_reset, /* reset */ - isf_imf_context_cursor_position_set, /* cursor_position_set */ - isf_imf_context_use_preedit_set, /* use_preedit_set */ - isf_imf_context_input_mode_set, /* input_mode_set */ - isf_imf_context_filter_event, /* filter_event */ - isf_imf_context_preedit_string_with_attributes_get, /* preedit_string_with_attribute_get */ - isf_imf_context_prediction_allow_set, /* prediction_allow_set */ - isf_imf_context_autocapital_type_set, /* autocapital_type_set */ - NULL, /* control panel show */ - NULL, /* control panel hide */ - NULL, /* input_panel_layout_set */ - NULL, /* isf_imf_context_input_panel_layout_get, */ - NULL, /* isf_imf_context_input_panel_language_set, */ - NULL, /* isf_imf_context_input_panel_language_get, */ - isf_imf_context_cursor_location_set, /* cursor_location_set */ - NULL, /* input_panel_imdata_set */ - NULL, /* input_panel_imdata_get */ - NULL, /* input_panel_return_key_type_set */ - NULL, /* input_panel_return_key_disabled_set */ - NULL, /* input_panel_caps_lock_mode_set */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - }; - - static Ecore_IMF_Context *imf_module_create (void); - static Ecore_IMF_Context *imf_module_exit (void); - - static Eina_Bool imf_module_init (void) - { - ecore_imf_module_register (&isf_imf_info, imf_module_create, imf_module_exit); - return EINA_TRUE; - } - - static void imf_module_shutdown (void) - { - isf_imf_context_shutdown (); - } - - static Ecore_IMF_Context *imf_module_create (void) - { - Ecore_IMF_Context *ctx = NULL; - EcoreIMFContextISF *ctxd = NULL; - - ctxd = isf_imf_context_new (); - if (!ctxd) - { - printf ("isf_imf_context_new () failed!!!\n"); - return NULL; - } - - ctx = ecore_imf_context_new (&isf_imf_class); - if (!ctx) - { - delete ctxd; - return NULL; - } - - ecore_imf_context_data_set (ctx, ctxd); - - return ctx; - } - - static Ecore_IMF_Context *imf_module_exit (void) - { - return NULL; - } - - EINA_MODULE_INIT(imf_module_init); - EINA_MODULE_SHUTDOWN(imf_module_shutdown); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - diff --git a/legacy/ecore/src/modules/immodules/xim/ecore_imf_xim.c b/legacy/ecore/src/modules/immodules/xim/ecore_imf_xim.c deleted file mode 100644 index bab1aa7cee..0000000000 --- a/legacy/ecore/src/modules/immodules/xim/ecore_imf_xim.c +++ /dev/null @@ -1,1555 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CLAMP(x, low, high) (x > high) ? high : (x < low) ? low : x -#define _(x) x - -#ifdef ENABLE_XIM -static Eina_List *open_ims = NULL; -#endif - -#define FEEDBACK_MASK (XIMReverse | XIMUnderline | XIMHighlight) - -typedef struct _XIM_Im_Info XIM_Im_Info; - -typedef struct _Ecore_IMF_Context_Data Ecore_IMF_Context_Data; - -struct _XIM_Im_Info -{ - Ecore_X_Window win; - Ecore_IMF_Context_Data *user; - char *locale; - XIM im; - Eina_List *ics; - Eina_Bool reconnecting; - XIMStyles *xim_styles; - Eina_Bool supports_string_conversion : 1; - Eina_Bool supports_cursor : 1; -}; - -struct _Ecore_IMF_Context_Data -{ - Ecore_X_Window win; - long mask; - XIC ic; /* Input context for composed characters */ - char *locale; - XIM_Im_Info *im_info; - int preedit_length; - int preedit_cursor; - Eina_Unicode *preedit_chars; - Eina_Bool use_preedit; - Eina_Bool finalizing; - Eina_Bool has_focus; - Eina_Bool in_toplevel; - XIMFeedback *feedbacks; - - XIMCallback destroy_cb; - - XIMCallback preedit_start_cb; - XIMCallback preedit_done_cb; - XIMCallback preedit_draw_cb; - XIMCallback preedit_caret_cb; -}; - -/* prototype */ -Ecore_IMF_Context_Data *imf_context_data_new(); -void imf_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data); - -#ifdef ENABLE_XIM -static void add_feedback_attr(Eina_List **attrs, - const char *str, - XIMFeedback feedback, - int start_pos, - int end_pos); - -static void reinitialize_ic(Ecore_IMF_Context *ctx); -static void set_ic_client_window(Ecore_IMF_Context *ctx, - Ecore_X_Window window); -static int preedit_start_callback(XIC xic, - XPointer client_data, - XPointer call_data); -static void preedit_done_callback(XIC xic, - XPointer client_data, - XPointer call_data); -static int xim_text_to_utf8(Ecore_IMF_Context *ctx, - XIMText *xim_text, - char **text); -static void preedit_draw_callback(XIC xic, - XPointer client_data, - XIMPreeditDrawCallbackStruct *call_data); -static void preedit_caret_callback(XIC xic, - XPointer client_data, - XIMPreeditCaretCallbackStruct *call_data); -static XVaNestedList preedit_callback_set(Ecore_IMF_Context *ctx); -static XIC get_ic(Ecore_IMF_Context *ctx); -static XIM_Im_Info *get_im(Ecore_X_Window window, - char *locale); -static void xim_info_try_im(XIM_Im_Info *info); -static void xim_info_display_closed(Ecore_X_Display *display, - int is_error, - XIM_Im_Info *info); -static void xim_instantiate_callback(Display *display, - XPointer client_data, - XPointer call_data); -static void setup_im(XIM_Im_Info *info); -static void xim_destroy_callback(XIM xim, - XPointer client_data, - XPointer call_data); -#endif - -#ifdef ENABLE_XIM -static unsigned int -utf8_offset_to_index(const char *str, int offset) -{ - int idx = 0; - int i; - for (i = 0; i < offset; i++) - { - eina_unicode_utf8_get_next(str, &idx); - } - - return idx; -} - -#endif - -static void -_ecore_imf_context_xim_add(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("in"); -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data = NULL; - - imf_context_data = imf_context_data_new(); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - imf_context_data->use_preedit = EINA_TRUE; - imf_context_data->finalizing = EINA_FALSE; - imf_context_data->has_focus = EINA_FALSE; - imf_context_data->in_toplevel = EINA_FALSE; - - ecore_imf_context_data_set(ctx, imf_context_data); -#else - (void)ctx; -#endif -} - -static void -_ecore_imf_context_xim_del(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("in"); -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - imf_context_data->finalizing = EINA_TRUE; - if (imf_context_data->im_info && !imf_context_data->im_info->ics->next) - { - if (imf_context_data->im_info->reconnecting == EINA_TRUE) - { - Ecore_X_Display *dsp; - dsp = ecore_x_display_get(); - XUnregisterIMInstantiateCallback(dsp, - NULL, NULL, NULL, - xim_instantiate_callback, - (XPointer)imf_context_data->im_info); - } - else if (imf_context_data->im_info->im) - { - XIMCallback im_destroy_callback; - im_destroy_callback.client_data = NULL; - im_destroy_callback.callback = NULL; - XSetIMValues(imf_context_data->im_info->im, - XNDestroyCallback, &im_destroy_callback, - NULL); - } - } - - set_ic_client_window(ctx, 0); - - imf_context_data_destroy(imf_context_data); -#else - (void)ctx; -#endif -} - -static void -_ecore_imf_context_xim_client_window_set(Ecore_IMF_Context *ctx, - void *window) -{ - EINA_LOG_DBG("in"); -#ifdef ENABLE_XIM - set_ic_client_window(ctx, (Ecore_X_Window)((Ecore_Window)window)); -#else - (void)ctx; - (void)window; -#endif -} - -static void -_ecore_imf_context_xim_preedit_string_get(Ecore_IMF_Context *ctx, - char **str, - int *cursor_pos) -{ - EINA_LOG_DBG("in"); -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data; - char *utf8; - int len; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - if (imf_context_data->preedit_chars) - { - utf8 = eina_unicode_unicode_to_utf8(imf_context_data->preedit_chars, - &len); - if (str) - *str = utf8; - else - free(utf8); - } - else - { - if (str) - *str = NULL; - if (cursor_pos) - *cursor_pos = 0; - } - - if (cursor_pos) - *cursor_pos = imf_context_data->preedit_cursor; -#else - (void)ctx; - if (str) - *str = NULL; - if (cursor_pos) - *cursor_pos = 0; -#endif -} - -static void -_ecore_imf_context_xim_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, - char **str, - Eina_List **attrs, - int *cursor_pos) -{ - EINA_LOG_DBG("in"); - -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); - - _ecore_imf_context_xim_preedit_string_get(ctx, str, cursor_pos); - - if (!attrs) return; - if (!imf_context_data || !imf_context_data->feedbacks) return; - - int i = 0; - XIMFeedback last_feedback = 0; - int start = -1; - - for (i = 0; i < imf_context_data->preedit_length; i++) - { - XIMFeedback new_feedback = imf_context_data->feedbacks[i] & FEEDBACK_MASK; - - if (new_feedback != last_feedback) - { - if (start >= 0) - add_feedback_attr(attrs, *str, last_feedback, start, i); - - last_feedback = new_feedback; - start = i; - } - } - - if (start >= 0) - add_feedback_attr(attrs, *str, last_feedback, start, i); -#else - (void)ctx; - if (str) - *str = NULL; - if (attrs) - *attrs = NULL; - if (cursor_pos) - *cursor_pos = 0; -#endif -} - -static void -_ecore_imf_context_xim_focus_in(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("in"); -#ifdef ENABLE_XIM - XIC ic; - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - ic = imf_context_data->ic; - imf_context_data->has_focus = EINA_TRUE; - - if (ecore_imf_context_input_panel_enabled_get(ctx)) - ecore_imf_context_input_panel_show(ctx); - - if (ic) - { - char *str; - -#ifdef X_HAVE_UTF8_STRING - if ((str = Xutf8ResetIC(ic))) -#else - if ((str = XmbResetIC(ic))) -#endif - XFree(str); - - XSetICFocus(ic); - } -#else - (void)ctx; -#endif -} - -static void -_ecore_imf_context_xim_focus_out(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("%s in", __FUNCTION__); -#ifdef ENABLE_XIM - XIC ic; - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - if (imf_context_data->has_focus == EINA_TRUE) - { - imf_context_data->has_focus = EINA_FALSE; - ic = imf_context_data->ic; - if (ic) - XUnsetICFocus(ic); - - if (ecore_imf_context_input_panel_enabled_get(ctx)) - ecore_imf_context_input_panel_hide(ctx); - } -#else - (void)ctx; -#endif -} - -static void -_ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("%s in", __FUNCTION__); -#ifdef ENABLE_XIM - XIC ic; - Ecore_IMF_Context_Data *imf_context_data; - char *result; - - /* restore conversion state after resetting ic later */ - XIMPreeditState preedit_state = XIMPreeditUnKnown; - XVaNestedList preedit_attr; - Eina_Bool have_preedit_state = EINA_FALSE; - - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - ic = imf_context_data->ic; - if (!ic) - return; - - if (imf_context_data->preedit_length == 0) - return; - - preedit_attr = XVaCreateNestedList(0, - XNPreeditState, &preedit_state, - NULL); - if (!XGetICValues(ic, - XNPreeditAttributes, preedit_attr, - NULL)) - have_preedit_state = EINA_TRUE; - - XFree(preedit_attr); - - result = XmbResetIC(ic); - - preedit_attr = XVaCreateNestedList(0, - XNPreeditState, preedit_state, - NULL); - if (have_preedit_state) - XSetICValues(ic, - XNPreeditAttributes, preedit_attr, - NULL); - - XFree(preedit_attr); - - if (imf_context_data->feedbacks) - { - free(imf_context_data->feedbacks); - imf_context_data->feedbacks = NULL; - } - - if (imf_context_data->preedit_length) - { - imf_context_data->preedit_length = 0; - free(imf_context_data->preedit_chars); - imf_context_data->preedit_chars = NULL; - - ecore_imf_context_preedit_changed_event_add(ctx); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - - if (result) - { - char *result_utf8 = strdup(result); - if (result_utf8) - { - ecore_imf_context_commit_event_add(ctx, result_utf8); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, result_utf8); - free(result_utf8); - } - } - - XFree(result); -#else - (void)ctx; -#endif -} - -static void -_ecore_imf_context_xim_use_preedit_set(Ecore_IMF_Context *ctx, - Eina_Bool use_preedit) -{ - EINA_LOG_DBG("in"); -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - use_preedit = use_preedit != EINA_FALSE; - - if (imf_context_data->use_preedit != use_preedit) - { - imf_context_data->use_preedit = use_preedit; - reinitialize_ic(ctx); - } -#else - (void)ctx; - (void)use_preedit; -#endif -} - -#ifdef ENABLE_XIM -static void -add_feedback_attr(Eina_List **attrs, - const char *str, - XIMFeedback feedback, - int start_pos, - int end_pos) -{ - Ecore_IMF_Preedit_Attr *attr = NULL; - - unsigned int start_index = utf8_offset_to_index(str, start_pos); - unsigned int end_index = utf8_offset_to_index(str, end_pos); - - if (feedback & FEEDBACK_MASK) - { - attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr)); - attr->start_index = start_index; - attr->end_index = end_index; - *attrs = eina_list_append(*attrs, (void *)attr); - } - - if (feedback & XIMUnderline) - attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1; - - if (feedback & XIMReverse) - attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; - - if (feedback & XIMHighlight) - attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3; -} - -#endif - -static void -_ecore_imf_context_xim_cursor_location_set(Ecore_IMF_Context *ctx, - int x, int y, int w, int h) -{ - EINA_LOG_DBG("%s in", __FUNCTION__); - -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data; - XIC ic; - XVaNestedList preedit_attr; - XPoint spot; - - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - ic = imf_context_data->ic; - if (!ic) - return; - - spot.x = x; - spot.y = y + h; - - preedit_attr = XVaCreateNestedList(0, - XNSpotLocation, &spot, - NULL); - XSetICValues(ic, - XNPreeditAttributes, preedit_attr, - NULL); - - XFree(preedit_attr); -#else - (void)ctx; - (void)x; - (void)y; - (void)h; -#endif - (void)(w); // yes w is unused, but only a bi-product of the algorithm -} - -static void -_ecore_imf_context_xim_input_panel_show(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("%s in", __FUNCTION__); - -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - ecore_x_e_virtual_keyboard_state_set - (imf_context_data->win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON); -#else - (void)ctx; -#endif -} - -static void -_ecore_imf_context_xim_input_panel_hide(Ecore_IMF_Context *ctx) -{ - EINA_LOG_DBG("%s in", __FUNCTION__); - -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - ecore_x_e_virtual_keyboard_state_set - (imf_context_data->win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF); -#else - (void)ctx; -#endif -} - -#ifdef ENABLE_XIM -static unsigned int -_ecore_x_event_reverse_modifiers(unsigned int state) -{ - unsigned int modifiers = 0; - - /**< "Control" is pressed */ - if (state & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) - modifiers |= ECORE_X_MODIFIER_CTRL; - - /**< "Alt" is pressed */ - if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALT) - modifiers |= ECORE_X_MODIFIER_ALT; - - /**< "Shift" is pressed */ - if (state & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) - modifiers |= ECORE_X_MODIFIER_SHIFT; - - /**< "Win" (between "Ctrl" and "Alt") is pressed */ - if (state & ECORE_IMF_KEYBOARD_MODIFIER_WIN) - modifiers |= ECORE_X_MODIFIER_WIN; - - /**< "AltGr" is pressed */ - if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) - modifiers |= ECORE_X_MODIFIER_ALTGR; - - return modifiers; -} - -static unsigned int -_ecore_x_event_reverse_locks(unsigned int state) -{ - unsigned int locks = 0; - - /**< "Num" lock is active */ - if (state & ECORE_IMF_KEYBOARD_LOCK_NUM) - locks |= ECORE_X_LOCK_NUM; - - if (state & ECORE_IMF_KEYBOARD_LOCK_CAPS) - locks |= ECORE_X_LOCK_CAPS; - - if (state & ECORE_IMF_KEYBOARD_LOCK_SCROLL) - locks |= ECORE_X_LOCK_SCROLL; - - return locks; -} - -static KeyCode -_keycode_get(Ecore_X_Display *dsp, - const char *keyname) -{ - KeyCode keycode; - - // EINA_LOG_DBG("keyname:%s keysym:%lu", keyname, XStringToKeysym(keyname)); - if (strcmp(keyname, "Keycode-0") == 0) - keycode = 0; - else - keycode = XKeysymToKeycode(dsp, XStringToKeysym(keyname)); - - return keycode; -} - -#endif - -static Eina_Bool -_ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, - Ecore_IMF_Event_Type type, - Ecore_IMF_Event *event) -{ - EINA_LOG_DBG("%s in", __FUNCTION__); -#ifdef ENABLE_XIM - Ecore_IMF_Context_Data *imf_context_data; - XIC ic; - - Ecore_X_Display *dsp; - Ecore_X_Window win; - - int val; - char compose_buffer[256]; - KeySym sym; - char *compose = NULL; - char *tmp = NULL; - Eina_Bool result = EINA_FALSE; - - imf_context_data = ecore_imf_context_data_get(ctx); - if (!imf_context_data) return EINA_FALSE; - ic = imf_context_data->ic; - if (!ic) - ic = get_ic(ctx); - - if (type == ECORE_IMF_EVENT_KEY_DOWN) - { - XKeyPressedEvent xev; - Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; - EINA_LOG_DBG("ECORE_IMF_EVENT_KEY_DOWN"); - - dsp = ecore_x_display_get(); - win = imf_context_data->win; - - xev.type = KeyPress; - xev.serial = 0; /* hope it doesn't matter */ - xev.send_event = 0; - xev.display = dsp; - xev.window = win; - xev.root = ecore_x_window_root_get(win); - xev.subwindow = win; - xev.time = ev->timestamp; - xev.x = xev.x_root = 0; - xev.y = xev.y_root = 0; - xev.state = 0; - xev.state |= _ecore_x_event_reverse_modifiers(ev->modifiers); - xev.state |= _ecore_x_event_reverse_locks(ev->locks); - xev.keycode = _keycode_get(dsp, ev->keyname); - xev.same_screen = True; - - if (ic) - { - Status mbstatus; -#ifdef X_HAVE_UTF8_STRING - val = Xutf8LookupString(ic, - &xev, - compose_buffer, - sizeof(compose_buffer) - 1, - &sym, - &mbstatus); -#else /* ifdef X_HAVE_UTF8_STRING */ - val = XmbLookupString(ic, - &xev, - compose_buffer, - sizeof(compose_buffer) - 1, - &sym, - &mbstatus); -#endif /* ifdef X_HAVE_UTF8_STRING */ - if (mbstatus == XBufferOverflow) - { - tmp = malloc(sizeof (char) * (val + 1)); - if (!tmp) - return EINA_FALSE; - - compose = tmp; - -#ifdef X_HAVE_UTF8_STRING - val = Xutf8LookupString(ic, - &xev, - tmp, - val, - &sym, - &mbstatus); -#else /* ifdef X_HAVE_UTF8_STRING */ - val = XmbLookupString(ic, - &xev, - tmp, - val, - &sym, - &mbstatus); -#endif /* ifdef X_HAVE_UTF8_STRING */ - 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 /* ifndef X_HAVE_UTF8_STRING */ - } - else - compose = NULL; - } - else if (val > 0) - { - compose_buffer[val] = '\0'; -#ifdef X_HAVE_UTF8_STRING - compose = strdup(compose_buffer); -#else /* ifdef X_HAVE_UTF8_STRING */ - compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", - compose_buffer); -#endif /* ifdef X_HAVE_UTF8_STRING */ - } - } - else - { - compose = strdup(ev->compose); - } - - if (compose) - { - Eina_Unicode *unicode; - int len; - unicode = eina_unicode_utf8_to_unicode(compose, &len); - if (!unicode) abort(); - if (unicode[0] >= 0x20 && unicode[0] != 0x7f) - { - ecore_imf_context_commit_event_add(ctx, compose); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, compose); - result = EINA_TRUE; - } - free(compose); - free(unicode); - } - } - - return result; -#else - (void)ctx; - (void)type; - (void)event; - return EINA_FALSE; -#endif -} - -static const Ecore_IMF_Context_Info xim_info = { - .id = "xim", - .description = _("X input method"), - .default_locales = "ko:ja:th:zh", - .canvas_type = "evas", - .canvas_required = 1, -}; - -static Ecore_IMF_Context_Class xim_class = { - .add = _ecore_imf_context_xim_add, - .del = _ecore_imf_context_xim_del, - .client_window_set = _ecore_imf_context_xim_client_window_set, - .client_canvas_set = NULL, - .show = _ecore_imf_context_xim_input_panel_show, - .hide = _ecore_imf_context_xim_input_panel_hide, - .preedit_string_get = _ecore_imf_context_xim_preedit_string_get, - .focus_in = _ecore_imf_context_xim_focus_in, - .focus_out = _ecore_imf_context_xim_focus_out, - .reset = _ecore_imf_context_xim_reset, - .cursor_position_set = NULL, - .use_preedit_set = _ecore_imf_context_xim_use_preedit_set, - .input_mode_set = NULL, - .filter_event = _ecore_imf_context_xim_filter_event, - .preedit_string_with_attributes_get = _ecore_imf_context_xim_preedit_string_with_attributes_get, - .prediction_allow_set = NULL, - .autocapital_type_set = NULL, - .control_panel_show = NULL, - .control_panel_hide = NULL, - .input_panel_layout_set = NULL, - .input_panel_layout_get = NULL, - .input_panel_language_set = NULL, - .input_panel_language_get = NULL, - .cursor_location_set = _ecore_imf_context_xim_cursor_location_set, - .input_panel_imdata_set = NULL, - .input_panel_imdata_get = NULL, - .input_panel_return_key_type_set = NULL, - .input_panel_return_key_disabled_set = NULL, - .input_panel_caps_lock_mode_set = NULL -}; - -static Ecore_IMF_Context * -xim_imf_module_create(void) -{ - EINA_LOG_DBG("%s in", __FUNCTION__); - Ecore_IMF_Context *ctx = NULL; - - ctx = ecore_imf_context_new(&xim_class); - if (!ctx) - goto error; - - return ctx; - -error: - free(ctx); - return NULL; -} - -static Ecore_IMF_Context * -xim_imf_module_exit(void) -{ - return NULL; -} - -Eina_Bool -ecore_imf_xim_init(void) -{ - EINA_LOG_DBG("%s in", __FUNCTION__); - eina_init(); - ecore_x_init(NULL); - ecore_imf_module_register(&xim_info, - xim_imf_module_create, - xim_imf_module_exit); - - return EINA_TRUE; -} - -void -ecore_imf_xim_shutdown(void) -{ -#ifdef ENABLE_XIM - while (open_ims) - { - XIM_Im_Info *info = open_ims->data; - Ecore_X_Display *display = ecore_x_display_get(); - - xim_info_display_closed(display, EINA_FALSE, info); - } -#endif - - ecore_x_shutdown(); - eina_shutdown(); -} - -EINA_MODULE_INIT(ecore_imf_xim_init); -EINA_MODULE_SHUTDOWN(ecore_imf_xim_shutdown); - -#ifdef ENABLE_XIM -/* - * internal functions - */ -Ecore_IMF_Context_Data * -imf_context_data_new() -{ - Ecore_IMF_Context_Data *imf_context_data = NULL; - char *locale; - - locale = setlocale(LC_CTYPE, ""); - if (!locale) return NULL; - - if (!XSupportsLocale()) return NULL; - - imf_context_data = calloc(1, sizeof(Ecore_IMF_Context_Data)); - EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, NULL); - - imf_context_data->locale = strdup(locale); - if (!imf_context_data->locale) goto error; - - return imf_context_data; -error: - imf_context_data_destroy(imf_context_data); - return NULL; -} - -void -imf_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data) -{ - if (!imf_context_data) - return; - - if (imf_context_data->ic) - XDestroyIC(imf_context_data->ic); - - free(imf_context_data->preedit_chars); - - if (imf_context_data->feedbacks) - { - free(imf_context_data->feedbacks); - imf_context_data->feedbacks = NULL; - } - - free(imf_context_data->locale); - free(imf_context_data); -} - -static int -preedit_start_callback(XIC xic __UNUSED__, - XPointer client_data, - XPointer call_data __UNUSED__) -{ - EINA_LOG_DBG("in"); - Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - if (!imf_context_data) return -1; - - if (imf_context_data->finalizing == EINA_FALSE) - { - ecore_imf_context_preedit_start_event_add(ctx); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); - } - return -1; -} - -static void -preedit_done_callback(XIC xic __UNUSED__, - XPointer client_data, - XPointer call_data __UNUSED__) -{ - EINA_LOG_DBG("in"); - Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - if (imf_context_data->preedit_length) - { - imf_context_data->preedit_length = 0; - free(imf_context_data->preedit_chars); - imf_context_data->preedit_chars = NULL; - ecore_imf_context_preedit_changed_event_add(ctx); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - - if (imf_context_data->finalizing == EINA_FALSE) - { - ecore_imf_context_preedit_end_event_add(ctx); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); - } -} - -/* FIXME */ -static int -xim_text_to_utf8(Ecore_IMF_Context *ctx __UNUSED__, - XIMText *xim_text, - char **text) -{ - int text_length = 0; - char *result = NULL; - - if (xim_text && xim_text->string.multi_byte) - { - if (xim_text->encoding_is_wchar) - { - EINA_LOG_WARN("Wide character return from Xlib not currently supported"); - *text = NULL; - return 0; - } - - /* XXX Convert to UTF-8 */ - result = strdup(xim_text->string.multi_byte); - if (result) - { - text_length = eina_unicode_utf8_get_len(result); - if (text_length != xim_text->length) - { - EINA_LOG_WARN("Size mismatch when converting text from input method: supplied length = %d\n, result length = %d", xim_text->length, text_length); - } - } - else - { - EINA_LOG_WARN("Error converting text from IM to UCS-4"); - *text = NULL; - return 0; - } - - *text = result; - return text_length; - } - else - { - *text = NULL; - return 0; - } -} - -static void -preedit_draw_callback(XIC xic __UNUSED__, - XPointer client_data, - XIMPreeditDrawCallbackStruct *call_data) -{ - EINA_LOG_DBG("in"); - Eina_Bool ret = EINA_FALSE; - Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; - Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); - XIMText *t = call_data->text; - char *tmp; - Eina_Unicode *new_text = NULL; - Eina_UStrbuf *preedit_bufs = NULL; - int new_text_length; - int i = 0; - - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - preedit_bufs = eina_ustrbuf_new(); - if (imf_context_data->preedit_chars) - { - ret = eina_ustrbuf_append(preedit_bufs, imf_context_data->preedit_chars); - if (ret == EINA_FALSE) goto done; - } - - new_text_length = xim_text_to_utf8(ctx, t, &tmp); - if (tmp) - { - int tmp_len; - new_text = eina_unicode_utf8_to_unicode((const char *)tmp, &tmp_len); - free(tmp); - } - - if (t == NULL) - { - /* delete string */ - ret = eina_ustrbuf_remove(preedit_bufs, - call_data->chg_first, call_data->chg_length); - } - else if (call_data->chg_length == 0) - { - /* insert string */ - ret = eina_ustrbuf_insert(preedit_bufs, new_text, call_data->chg_first); - } - else if (call_data->chg_length > 0) - { - /* replace string */ - ret = eina_ustrbuf_remove(preedit_bufs, - call_data->chg_first, call_data->chg_length); - if (ret == EINA_FALSE) goto done; - - ret = eina_ustrbuf_insert_n(preedit_bufs, new_text, - new_text_length, call_data->chg_first); - if (ret == EINA_FALSE) goto done; - } - else - { - ret = EINA_FALSE; - } - -done: - if (ret == EINA_TRUE) - { - free(imf_context_data->preedit_chars); - imf_context_data->preedit_chars = - eina_ustrbuf_string_steal(preedit_bufs); - imf_context_data->preedit_length = - eina_unicode_strlen(imf_context_data->preedit_chars); - - if (imf_context_data->feedbacks) - { - free(imf_context_data->feedbacks); - imf_context_data->feedbacks = NULL; - } - - if (imf_context_data->preedit_length > 0) - { - imf_context_data->feedbacks = calloc(imf_context_data->preedit_length, sizeof(XIMFeedback)); - - for (i = 0; i < imf_context_data->preedit_length; i++) - imf_context_data->feedbacks[i] = t->feedback[i]; - } - - ecore_imf_context_preedit_changed_event_add(ctx); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - - free(new_text); - eina_ustrbuf_free(preedit_bufs); -} - -static void -preedit_caret_callback(XIC xic __UNUSED__, - XPointer client_data, - XIMPreeditCaretCallbackStruct *call_data) -{ - EINA_LOG_DBG("in"); - Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - if (call_data->direction == XIMAbsolutePosition) - { - // printf("call_data->position:%d\n", call_data->position); - imf_context_data->preedit_cursor = call_data->position; - if (imf_context_data->finalizing == EINA_FALSE) - { - ecore_imf_context_preedit_changed_event_add(ctx); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - } -} - -static XVaNestedList -preedit_callback_set(Ecore_IMF_Context *ctx) -{ - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - - imf_context_data->preedit_start_cb.client_data = (XPointer)ctx; - imf_context_data->preedit_start_cb.callback = (XIMProc)preedit_start_callback; - - imf_context_data->preedit_done_cb.client_data = (XPointer)ctx; - imf_context_data->preedit_done_cb.callback = (XIMProc)preedit_done_callback; - - imf_context_data->preedit_draw_cb.client_data = (XPointer)ctx; - imf_context_data->preedit_draw_cb.callback = (XIMProc)preedit_draw_callback; - - imf_context_data->preedit_caret_cb.client_data = (XPointer)ctx; - imf_context_data->preedit_caret_cb.callback = (XIMProc)preedit_caret_callback; - - return XVaCreateNestedList(0, - XNPreeditStartCallback, - &imf_context_data->preedit_start_cb, - XNPreeditDoneCallback, - &imf_context_data->preedit_done_cb, - XNPreeditDrawCallback, - &imf_context_data->preedit_draw_cb, - XNPreeditCaretCallback, - &imf_context_data->preedit_caret_cb, - NULL); -} - -static XIC -get_ic(Ecore_IMF_Context *ctx) -{ - Ecore_IMF_Context_Data *imf_context_data; - XIC ic; - imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, NULL); - - ic = imf_context_data->ic; - if (!ic) - { - XIM_Im_Info *im_info = imf_context_data->im_info; - XVaNestedList preedit_attr = NULL; - XIMStyle im_style = 0; - XPoint spot = { 0, 0 }; - char *name = NULL; - - if (!im_info) - { - EINA_LOG_WARN("Doesn't open XIM."); - return NULL; - } - - // supported styles -#if 0 - int i; - if (im_info->xim_styles) - { - for (i = 0; i < im_info->xim_styles->count_styles; i++) - { - printf("%i: ", i); - if (im_info->xim_styles->supported_styles[i] & XIMPreeditCallbacks) - printf("XIMPreeditCallbacks | "); - if (im_info->xim_styles->supported_styles[i] & XIMPreeditPosition) - printf("XIMPreeditPosition | "); - if (im_info->xim_styles->supported_styles[i] & XIMPreeditArea) - printf("XIMPreeditArea | "); - if (im_info->xim_styles->supported_styles[i] & XIMPreeditNothing) - printf("XIMPreeditNothing | "); - if (im_info->xim_styles->supported_styles[i] & XIMPreeditNone) - printf("XIMPreeditNone | "); - if (im_info->xim_styles->supported_styles[i] & XIMStatusArea) - printf("XIMStatusArea | "); - if (im_info->xim_styles->supported_styles[i] & XIMStatusCallbacks) - printf("XIMStatusCallbacks | "); - if (im_info->xim_styles->supported_styles[i] & XIMStatusNothing) - printf("XIMStatusNothing | "); - if (im_info->xim_styles->supported_styles[i] & XIMStatusNone) - printf("XIMStatusNone | "); - printf("\n"); - } - } -#endif - // "OverTheSpot" = XIMPreeditPosition | XIMStatusNothing - // "OffTheSpot" = XIMPreeditArea | XIMStatusArea - // "Root" = XIMPreeditNothing | XIMStatusNothing - - if (imf_context_data->use_preedit == EINA_TRUE) - { - if (im_info->supports_cursor) - { - // kinput2 DOES do this... - XFontSet fs; - char **missing_charset_list; - int missing_charset_count; - char *def_string; - - im_style |= XIMPreeditPosition; - im_style |= XIMStatusNothing; - fs = XCreateFontSet(ecore_x_display_get(), - "fixed", - &missing_charset_list, - &missing_charset_count, - &def_string); - preedit_attr = XVaCreateNestedList(0, - XNSpotLocation, &spot, - XNFontSet, fs, - NULL); - } - else - { - im_style |= XIMPreeditCallbacks; - im_style |= XIMStatusNothing; - preedit_attr = preedit_callback_set(ctx); - } - name = XNPreeditAttributes; - } - else - { - im_style |= XIMPreeditNothing; - im_style |= XIMStatusNothing; - } - - if (!im_info->xim_styles) - { - EINA_LOG_WARN("No XIM styles supported! Wanted %#llx", - (unsigned long long)im_style); - im_style = 0; - } - else - { - XIMStyle fallback = 0; - int i; - - for (i = 0; i < im_info->xim_styles->count_styles; i++) - { - XIMStyle cur = im_info->xim_styles->supported_styles[i]; - if (cur == im_style) - break; - else if (cur == (XIMPreeditNothing | XIMStatusNothing)) - /* TODO: fallback is just that or the anyone? */ - fallback = cur; - } - - if (i == im_info->xim_styles->count_styles) - { - if (fallback) - { - EINA_LOG_WARN("Wanted XIM style %#llx not found, " - "using fallback %#llx instead.", - (unsigned long long)im_style, - (unsigned long long)fallback); - im_style = fallback; - } - else - { - EINA_LOG_WARN("Wanted XIM style %#llx not found, " - "no fallback supported.", - (unsigned long long)im_style); - im_style = 0; - } - } - } - - if ((im_info->im) && (im_style)) - { - ic = XCreateIC(im_info->im, - XNInputStyle, im_style, - XNClientWindow, imf_context_data->win, - name, preedit_attr, NULL); - } - XFree(preedit_attr); - if (ic) - { - unsigned long mask = 0xaaaaaaaa; - XGetICValues(ic, - XNFilterEvents, &mask, - NULL); - imf_context_data->mask = mask; - ecore_x_event_mask_set(imf_context_data->win, mask); - } - - imf_context_data->ic = ic; - if (ic && imf_context_data->has_focus == EINA_TRUE) - XSetICFocus(ic); - } - - return ic; -} - -static void -reinitialize_ic(Ecore_IMF_Context *ctx) -{ - Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - XIC ic = imf_context_data->ic; - if (ic) - { - XDestroyIC(ic); - imf_context_data->ic = NULL; - if (imf_context_data->preedit_length) - { - imf_context_data->preedit_length = 0; - free(imf_context_data->preedit_chars); - imf_context_data->preedit_chars = NULL; - ecore_imf_context_preedit_changed_event_add(ctx); - ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); - } - } -} - -static void -set_ic_client_window(Ecore_IMF_Context *ctx, - Ecore_X_Window window) -{ - EINA_LOG_DBG("in"); - Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); - Ecore_X_Window old_win; - - EINA_SAFETY_ON_NULL_RETURN(imf_context_data); - - /* reinitialize IC */ - reinitialize_ic(ctx); - - old_win = imf_context_data->win; - EINA_LOG_DBG("old_win:%d window:%d ", old_win, window); - if (old_win != 0 && old_win != window) /* XXX how do check window... */ - { - XIM_Im_Info *info; - info = imf_context_data->im_info; - info->ics = eina_list_remove(info->ics, imf_context_data); - if (imf_context_data->im_info) - imf_context_data->im_info->user = NULL; - imf_context_data->im_info = NULL; - } - - imf_context_data->win = window; - - if (window) /* XXX */ - { - XIM_Im_Info *info = NULL; - info = get_im(window, imf_context_data->locale); - imf_context_data->im_info = info; - imf_context_data->im_info->ics = - eina_list_prepend(imf_context_data->im_info->ics, - imf_context_data); - if (imf_context_data->im_info) - imf_context_data->im_info->user = imf_context_data; - } -} - -static XIM_Im_Info * -get_im(Ecore_X_Window window, - char *locale) -{ - EINA_LOG_DBG("in"); - - Eina_List *l; - XIM_Im_Info *im_info = NULL; - XIM_Im_Info *info = NULL; - EINA_LIST_FOREACH (open_ims, l, im_info) - { - if (strcmp(im_info->locale, locale) == 0) - { - if (im_info->im) - { - return im_info; - } - else - { - info = im_info; - break; - } - } - } - - if (!info) - { - info = calloc(1, sizeof(XIM_Im_Info)); - if (!info) return NULL; - open_ims = eina_list_prepend(open_ims, info); - info->win = window; - info->locale = strdup(locale); - info->reconnecting = EINA_FALSE; - } - - xim_info_try_im(info); - return info; -} - -/* initialize info->im */ -static void -xim_info_try_im(XIM_Im_Info *info) -{ - Ecore_X_Display *dsp; - - assert(info->im == NULL); - if (info->reconnecting == EINA_TRUE) - return; - - if (XSupportsLocale()) - { - if (!XSetLocaleModifiers("")) - EINA_LOG_WARN("Unable to set locale modifiers with XSetLocaleModifiers()"); - dsp = ecore_x_display_get(); - info->im = XOpenIM(dsp, NULL, NULL, NULL); - if (!info->im) - { - XRegisterIMInstantiateCallback(dsp, - NULL, NULL, NULL, - xim_instantiate_callback, - (XPointer)info); - info->reconnecting = EINA_TRUE; - return; - } - setup_im(info); - } -} - -static void -xim_info_display_closed(Ecore_X_Display *display __UNUSED__, - int is_error __UNUSED__, - XIM_Im_Info *info) -{ - Eina_List *ics, *tmp_list; - Ecore_IMF_Context *ctx; - - open_ims = eina_list_remove(open_ims, info); - - ics = info->ics; - info->ics = NULL; - - EINA_LIST_FOREACH (ics, tmp_list, ctx) - set_ic_client_window(ctx, 0); - - EINA_LIST_FREE (ics, ctx) - { - Ecore_IMF_Context_Data *imf_context_data; - imf_context_data = ecore_imf_context_data_get(ctx); - imf_context_data_destroy(imf_context_data); - } - - free(info->locale); - - if (info->im) - XCloseIM(info->im); - - free(info); -} - -static void -xim_instantiate_callback(Display *display, - XPointer client_data, - XPointer call_data __UNUSED__) -{ - XIM_Im_Info *info = (XIM_Im_Info *)client_data; - XIM im = NULL; - - im = XOpenIM(display, NULL, NULL, NULL); - - if (!im) - { - fprintf(stderr, "Failed to connect to IM\n"); - return; - } - - info->im = im; - setup_im(info); - - XUnregisterIMInstantiateCallback(display, NULL, NULL, NULL, - xim_instantiate_callback, - (XPointer)info); - info->reconnecting = EINA_FALSE; -} - -static void -setup_im(XIM_Im_Info *info) -{ - XIMValuesList *ic_values = NULL; - XIMCallback im_destroy_callback; - - if (!info->im) - return; - - im_destroy_callback.client_data = (XPointer)info; - im_destroy_callback.callback = (XIMProc)xim_destroy_callback; - XSetIMValues(info->im, - XNDestroyCallback, &im_destroy_callback, - NULL); - - XGetIMValues(info->im, - XNQueryInputStyle, &info->xim_styles, - XNQueryICValuesList, &ic_values, - NULL); - - if (ic_values) - { - int i; - - for (i = 0; i < ic_values->count_values; i++) - { - if (!strcmp(ic_values->supported_values[i], - XNStringConversionCallback)) - info->supports_string_conversion = EINA_TRUE; - if (!strcmp(ic_values->supported_values[i], - XNCursor)) - info->supports_cursor = EINA_TRUE; - } -#if 0 - printf("values........\n"); - for (i = 0; i < ic_values->count_values; i++) - printf("%s\n", ic_values->supported_values[i]); - printf("styles........\n"); - for (i = 0; i < info->xim_styles->count_styles; i++) - printf("%lx\n", info->xim_styles->supported_styles[i]); -#endif - XFree(ic_values); - } -} - -static void -xim_destroy_callback(XIM xim __UNUSED__, - XPointer client_data, - XPointer call_data __UNUSED__) -{ - XIM_Im_Info *info = (XIM_Im_Info *)client_data; - - if (info->user) info->user->ic = NULL; - info->im = NULL; -// reinitialize_ic(ctx); - xim_info_try_im(info); - - return; -} - -#endif /* ENABLE_XIM */ diff --git a/legacy/ecore/src/util/makekeys.c b/legacy/ecore/src/util/makekeys.c deleted file mode 100644 index a057fa2c65..0000000000 --- a/legacy/ecore/src/util/makekeys.c +++ /dev/null @@ -1,326 +0,0 @@ -/* Portions of this code are Copyright 1990, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -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 OPEN GROUP 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. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - -#include -#include -#include -#include - -#define TBLNUM 4000 -#define MIN_REHASH 15 -#define MATCHES 10 - -typedef struct _Info Info; -static struct _Info -{ - char *name; - long unsigned int val; -} info[TBLNUM]; - -/* local function prototypes */ -static int _parseline(const char *buf, char *key, long unsigned int *val, char *prefix); - -/* local variables */ -static char tab[TBLNUM]; -static unsigned short offsets[TBLNUM]; -static unsigned short indexes[TBLNUM]; -static long unsigned int values[TBLNUM]; -static char buf[1024]; -static int ksnum = 0; - -int -main(int argc, char **argv) -{ - int max_rehash = 0; - unsigned long sig; - int i = 0, j = 0, k = 0, l = 0, z = 0; - FILE *fptr; - char *name = NULL, c; - int first = 0, num_found = 0; - int best_max_rehash = 0, best_z = 0; - long unsigned int val; - char key[128], prefix[128]; - - for (l = 1; l < argc; l++) - { - if (!(fptr = fopen(argv[l], "r"))) - { - fprintf(stderr, "Could not open %s\n", argv[l]); - continue; - } - - while (fgets(buf, sizeof(buf), fptr)) - { - if (!_parseline(buf, key, &val, prefix)) - continue; - - if (val == XK_VoidSymbol) val = 0; - if (val > 0x1fffffff) - { - fprintf(stderr, "Ignoring illegal keysym (%s %lx)\n", - key, val); - continue; - } - - if (!(name = malloc(strlen(prefix) + strlen(key) + 1))) - { - fprintf(stderr, "Makekeys: Out Of Memory !!\n"); - exit(EXIT_FAILURE); - } - - sprintf(name, "%s%s", prefix, key); - info[ksnum].name = name; - info[ksnum].val = val; - ksnum++; - if (ksnum == TBLNUM) - { - fprintf(stderr, "Makekeys: Too Many Keysyms!!\n"); - exit(EXIT_FAILURE); - } - } - - fclose(fptr); - } - - printf("/* This file is generated from keysymdef.h. */\n"); - printf("/* Do Not Edit !! */\n\n"); - - best_max_rehash = ksnum; - num_found = 0; - for (z = ksnum; z < TBLNUM; z++) - { - max_rehash = 0; - for (name = tab, i = z; --i >= 0;) - *name++ = 0; - for (i = 0; i < ksnum; i++) - { - name = info[i].name; - sig = 0; - while ((c = *name++)) - sig = (sig << 1) + c; - first = j = sig % z; - for (k = 0; tab[j]; k++) - { - j += (first + 1); - if (j >= z) j -= z; - if (j == first) goto next1; - } - tab[j] = 1; - if (k > max_rehash) max_rehash = k; - } - if (max_rehash < MIN_REHASH) - { - if (max_rehash < best_max_rehash) - { - best_max_rehash = max_rehash; - best_z = z; - } - num_found++; - if (num_found >= MATCHES) - break; - } -next1: ; - } - - z = best_z; - if (z == 0) - { - fprintf(stderr, "Makekeys: Failed to find small enough hash !!\n" - "Try increasing TBLNUM in makekeys.c\n"); - exit(EXIT_FAILURE); - } - - printf("#ifdef NEED_KEYSYM_TABLE\n"); - printf("const unsigned char _ecore_xcb_keytable[] = {\n"); - printf("0,\n"); - k = 1; - for (i = 0; i < ksnum; i++) - { - name = info[i].name; - sig = 0; - while ((c = *name++)) - sig = (sig << 1) + c; - first = j = sig % z; - while (offsets[j]) - { - j += (first + 1); - if (j >= z) j -= z; - } - offsets[j] = k; - indexes[i] = k; - val = info[i].val; - printf("0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, ", - (sig >> 8) & 0xff, sig & 0xff, - (val >> 24) & 0xff, (val >> 16) & 0xff, - (val >> 8) & 0xff, val & 0xff); - for (name = info[i].name, k += 7; (c = *name++); k++) - printf("'%c',", c); - printf((i == (ksnum - 1)) ? "0\n" : "0,\n"); - } - - printf("};\n\n"); - printf("#define KTABLESIZE %d\n", z); - printf("#define KMAXHASH %d\n", (best_max_rehash + 1)); - printf("\n"); - printf("static const unsigned short hashString[KTABLESIZE] = {\n"); - - for (i = 0; i < z;) - { - printf("0x%.4x", offsets[i]); - i++; - if (i == z) break; - printf((i & 7) ? ", " : ",\n"); - } - - printf("\n"); - printf("};\n"); - printf("#endif\n"); - - best_max_rehash = ksnum; - num_found = 0; - for (z = ksnum; z < TBLNUM; z++) - { - max_rehash = 0; - for (name = tab, i = z; --i >= 0;) - *name++ = 0; - for (i = 0; i < ksnum; i++) - { - val = info[i].val; - first = j = val % z; - for (k = 0; tab[j]; k++) - { - if (values[j] == val) goto skip1; - j += (first + 1); - if (j >= z) j -= z; - if (j == first) goto next2; - } - tab[j] = 1; - values[j] = val; - if (k > max_rehash) max_rehash = k; -skip1: ; - } - if (max_rehash < MIN_REHASH) - { - if (max_rehash < best_max_rehash) - { - best_max_rehash = max_rehash; - best_z = z; - } - num_found++; - if (num_found >= MATCHES) break; - } -next2: ; - } - - z = best_z; - if (z == 0) - { - fprintf(stderr, "Makekeys: Failed to find small enough hash !!\n" - "Try increasing TBLNUM in makekeys.c\n"); - exit(EXIT_FAILURE); - } - for (i = z; --i >= 0;) - offsets[i] = 0; - - for (i = 0; i < ksnum; i++) - { - val = info[i].val; - first = j = val % z; - while (offsets[j]) - { - if (values[j] == val) goto skip2; - j += (first + 1); - if (j >= z) j -= z; - } - offsets[j] = indexes[i] + 2; - values[j] = val; -skip2: ; - } - - printf("\n"); - printf("#ifdef NEED_VTABLE\n"); - printf("#define VTABLESIZE %d\n", z); - printf("#define VMAXHASH %d\n", best_max_rehash + 1); - printf("\n"); - printf("static const unsigned short hashKeysym[VTABLESIZE] = {\n"); - for (i = 0; i < z;) - { - printf("0x%.4x", offsets[i]); - i++; - if (i == z) break; - printf((i & 7) ? ", " : ",\n"); - } - printf("\n"); - printf("};\n"); - printf("#endif\n"); - - return 0; -} - -/* local functions */ -static int -_parseline(const char *buf, char *key, long unsigned int *val, char *prefix) -{ - int i = 0; - char alias[128]; - char *tmp = NULL, *tmpa = NULL; - - /* try to match XK_foo first */ - i = sscanf(buf, "#define %127s 0x%lx", key, val); - if ((i == 2) && (tmp = strstr(key, "XK_"))) - { - memcpy(prefix, key, (tmp - key)); - prefix[tmp - key] = '\0'; - tmp += 3; - memmove(key, tmp, strlen(tmp) + 1); - return 1; - } - - /* try to match an alias */ - i = sscanf(buf, "#define %127s %127s", key, alias); - if (((i == 2) && (tmp = strstr(key, "XK_"))) && - (tmpa = strstr(alias, "XK_"))) - { - memcpy(prefix, key, (tmp - key)); - prefix[tmp - key] = '\0'; - tmp += 3; - memmove(key, tmp, strlen(tmp) + 1); - memmove(tmpa, tmpa + 3, strlen(tmpa + 3) + 1); - - for (i = ksnum - 1; i >= 0; i--) - { - if (!strcmp(info[i].name, alias)) - { - *val = info[i].val; - return 1; - } - } - fprintf(stderr, "Cannot find matching definition %s for keysym %s%s\n", - alias, prefix, key); - } - - return 0; -} diff --git a/legacy/ecore/src/util/mkks.sh b/legacy/ecore/src/util/mkks.sh deleted file mode 100755 index 666924258a..0000000000 --- a/legacy/ecore/src/util/mkks.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -cat $* | awk 'BEGIN { \ - printf "/*\n * This file is generated from %s. Do not edit.\n */\n", \ - "$(INCLUDESRC)/keysymdef.h";\ -} \ -/^#define/ { \ - len = length($2)-3; \ - printf("{ \"%s\", %s },\n", substr($2,4,len), $3); \ -}' diff --git a/legacy/emotion/COPYING b/legacy/emotion/COPYING deleted file mode 100644 index aab836272d..0000000000 --- a/legacy/emotion/COPYING +++ /dev/null @@ -1,25 +0,0 @@ -Copyright notice for Emotion: - -Copyright (C) 2004-2011 Carsten Haitzler and various contributors (see AUTHORS) - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/legacy/escape/ChangeLog b/legacy/escape/ChangeLog deleted file mode 100644 index 8b13789179..0000000000 --- a/legacy/escape/ChangeLog +++ /dev/null @@ -1 +0,0 @@ - diff --git a/legacy/escape/README b/legacy/escape/README deleted file mode 100644 index d45099f00d..0000000000 --- a/legacy/escape/README +++ /dev/null @@ -1,4 +0,0 @@ - The Escape library is a library that acts implements some of the missing - function from the PS3 GameOS system that are needed for the proper - functioning of the EFL. - diff --git a/legacy/escape/escape.pc.in b/legacy/escape/escape.pc.in deleted file mode 100644 index 5d18d8008e..0000000000 --- a/legacy/escape/escape.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: escape -Description: Library that ports on the PS3 some specific Unix functions. -Version: @VERSION@ -Libs: -L${libdir} -lescape -Libs.private: -lm -lnet -lsysmodule -liberty -Cflags: -I${includedir}/escape-@VMAJ@ diff --git a/legacy/escape/src/lib/Escape.h b/legacy/escape/src/lib/Escape.h deleted file mode 100644 index ca728b50b7..0000000000 --- a/legacy/escape/src/lib/Escape.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __ESCAPE_H__ -#define __ESCAPE_H__ - -#ifndef EAPI -#define EAPI -#endif /* EAPI */ -#define __UNUSED__ __attribute__((unused)) - -#include - -#ifdef CLOCK_REALTIME -#undef CLOCK_REALTIME -#endif -#ifdef CLOCK_PROF -#undef CLOCK_PROF -#endif -#ifdef CLOCK_PROCESS_CPUTIME_ID -#undef CLOCK_PROCESS_CPUTIME_ID -#endif - -/** - * @mainpage Escape - * @image html e_big.png - * @author Youness Alaoui - * @date 2011 - * - * @section intro_sec Introduction - * - * The Escape library is a library that acts implements some of the missing - * function from the PS3 GameOS system that are needed for the proper - * functioning of the EFL. - * - * @section escape_sec Escape API Documentation - * - * Take a look at the documentation of @ref mmap/munmap. - * - */ - -#include "escape_libgen.h" -#include "escape_unistd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Nothing to see here */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ESCAPE_H__ */ diff --git a/legacy/escape/src/lib/escape_libgen.c b/legacy/escape/src/lib/escape_libgen.c deleted file mode 100644 index 796708978e..0000000000 --- a/legacy/escape/src/lib/escape_libgen.c +++ /dev/null @@ -1,90 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include - -#include "Escape.h" - -static char _escape_basename_buf[PATH_MAX]; -static char _escape_dirname_buf[PATH_MAX]; - -char * -escape_basename(char *path) -{ - char *p1; - char *p2; - size_t length; - - /* path must begin by "?:\" or "?:/" */ - if (!path || strlen(path) <= 1) - { - memcpy(_escape_basename_buf, path, PATH_MAX); - return _escape_basename_buf; - } - - length = strlen(path); - p1 = strdup(path); - if (!p1) - { - memcpy(_escape_basename_buf, path, PATH_MAX); - return _escape_basename_buf; - } - - /* remove trailing backslashes */ - p2 = p1 + (length - 1); - if (*p2 == '/') - { - while (*p2 == '/') - p2--; - } - *(p2 + 1) = '\0'; - - p2 = strrchr(p1, '/'); - memcpy(_escape_basename_buf, p2 + 1, (p1 + length + 1) - p2); - - free(p1); - - return _escape_basename_buf; -} - -char * -escape_dirname(char *path) -{ - char *p1; - char *p2; - size_t length; - - /* path must begin by "?:\" or "?:/" */ - if (!path || strlen(path) <= 1) - { - memcpy(_escape_dirname_buf, path, PATH_MAX); - return _escape_dirname_buf; - } - - length = strlen(path); - p1 = strdup(path); - if (!p1) - { - memcpy(_escape_dirname_buf, path, PATH_MAX); - return _escape_dirname_buf; - } - /* remove trailing backslashes */ - p2 = p1 + (length - 1); - if (*p2 == '/') - { - while (*p2 == '/') - p2--; - } - *(p2 + 1) = '\0'; - - p2 = strrchr(p1, '/'); - *p2 = '\0'; - memcpy(_escape_dirname_buf, p1, strlen(p1) + 1); - - free(p1); - - return _escape_dirname_buf; -} - diff --git a/legacy/escape/src/lib/escape_libgen.h b/legacy/escape/src/lib/escape_libgen.h deleted file mode 100644 index 0c23a76821..0000000000 --- a/legacy/escape/src/lib/escape_libgen.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __ESCAPE_LIBGEN_H__ -#define __ESCAPE_LIBGEN_H__ - -/** - * @file escape_libgen.h - * @brief The file that provides functions ported from Unix in libgen.h. - * @defgroup Escape_Libgen_Group Libgen.h functions. - * - * This header provides functions ported from Unix in libgen.h. - * - * @{ - */ - -EAPI char *escape_basename(char *path); - -#ifdef basename -#undef basename -#endif -#define basename(p) escape_basename(p) - -EAPI char *escape_dirname(char *path); - -#ifdef dirname -#undef dirname -#endif -#define dirname(p) escape_dirname(p) - -/** - * @} - */ - -#endif /* __ESCAPE_LIBGEN_H__ */ diff --git a/legacy/escape/src/lib/escape_mman.c b/legacy/escape/src/lib/escape_mman.c deleted file mode 100644 index 995c72e7f4..0000000000 --- a/legacy/escape/src/lib/escape_mman.c +++ /dev/null @@ -1,67 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include -#include - -#include "sys/mman.h" - -/***** API *****/ - -void * -mmap(void *addr __UNUSED__, - size_t len, - int prot, - int flags, - int fd, - off_t offset) -{ - void *data; - size_t size; - - data = malloc(len); - if (!data) - { - fprintf (stderr, "[Escape] [mmap] malloc failed\n"); - return MAP_FAILED; - } - - size = read(fd, data, len); - if (size != len) - { - fprintf (stderr, "[Escape] [mmap] read failed\n"); - free(data); - return MAP_FAILED; - } - - if (lseek(fd, -len, SEEK_CUR) == -1) - { - fprintf (stderr, "[Escape] [mmap] lseek failed\n"); - free(data); - return MAP_FAILED; - } - - return data; -} - -int -munmap(void *addr, - size_t len __UNUSED__) -{ - if (addr && (addr != MAP_FAILED)) - free(addr); - - return 0; -} - -int -madvise(void *addr __UNUSED__, - size_t length __UNUSED__, - int advice __UNUSED__) -{ - return 0; -} - diff --git a/legacy/escape/src/lib/escape_unistd.c b/legacy/escape/src/lib/escape_unistd.c deleted file mode 100644 index 5dbbb18634..0000000000 --- a/legacy/escape/src/lib/escape_unistd.c +++ /dev/null @@ -1,186 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif /* HAVE_CONFIG_H */ - -#ifdef HAVE_ERRNO_H -#include -#endif /* HAVE_ERRNO_H */ - -#include /* See NOTES */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Escape.h" - -char * -escape_realpath(const char *path, char *resolved_path) -{ - char *real = lrealpath (path); - - if (real) - { - if (resolved_path) - { - memcpy (resolved_path, real, PATH_MAX); - free (real); - return resolved_path; - } - else - { - return real; - } - } - - return NULL; -} - -int -escape_access(const char *pathname, int mode) -{ - struct stat stat_buf; - - if (stat(pathname, &stat_buf) != 0) - return -1; - - if (mode == F_OK) - return 0; - if (mode == R_OK) - { - if (stat_buf.st_mode & S_IRUSR) - return 0; - errno = EACCES; - return -1; - } - if (mode == W_OK) - { - if (stat_buf.st_mode & S_IWUSR) - return 0; - errno = EROFS; - return -1; - } - if (mode == X_OK) - { - if (stat_buf.st_mode & S_IXUSR) - return 0; - errno = EACCES; - return -1; - } - - return 0; -} - -EAPI ssize_t -escape_readlink(const char *path, - char *buf, - size_t bufsize) -{ - errno = EINVAL; - return -1; -} - -EAPI int -escape_symlink(const char *path1, const char *path2) -{ - errno = EINVAL; - return -1; -} - -/* - * The code of the following functions has been kindly offered - * by Tor Lillqvist. - */ -int -escape_pipe(int *fds) -{ - struct sockaddr_in saddr; - int temp; - int socket1 = -1; - int socket2 = -1; - fd_set read_set; - fd_set write_set; - int len; - - temp = socket (AF_INET, SOCK_STREAM, 0); - - if (temp == -1) - goto out0; - - memset (&saddr, 0, sizeof (saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = 0; - saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - - if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr))) - goto out0; - - if (listen (temp, 1) == -1) - goto out0; - - len = sizeof (saddr); - if (getsockname (temp, (struct sockaddr *)&saddr, &len)) - goto out0; - - socket1 = socket (AF_INET, SOCK_STREAM, 0); - - if (socket1 == -1) - goto out0; - - if ((connect (socket1, (struct sockaddr *)&saddr, len) == -1) && - (errno != EAGAIN)) - goto out1; - - FD_ZERO (&read_set); - FD_SET (temp, &read_set); - - if (select (0, &read_set, NULL, NULL, NULL) == -1) - goto out1; - - if (!FD_ISSET (temp, &read_set)) - goto out1; - - socket2 = accept (temp, (struct sockaddr *)&saddr, &len); - if (socket2 == -1) - goto out1; - - FD_ZERO (&write_set); - FD_SET (socket1, &write_set); - - if (select (0, NULL, &write_set, NULL, NULL) == -1) - goto out2; - - if (!FD_ISSET (socket1, &write_set)) - goto out2; - - fds[0] = socket1; - fds[1] = socket2; - - closesocket (temp); - - return 0; - -out2: - closesocket (socket2); -out1: - closesocket (socket1); -out0: - closesocket (temp); - - fds[0] = -1; - fds[1] = -1; - - return -1; -} - -#undef access -int -access(const char *pathname, int mode) -{ - return escape_access (pathname, mode); -} - diff --git a/legacy/escape/src/lib/escape_unistd.h b/legacy/escape/src/lib/escape_unistd.h deleted file mode 100644 index 0e96d3f3cb..0000000000 --- a/legacy/escape/src/lib/escape_unistd.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef __ESCAPE_UNISTD_H__ -#define __ESCAPE_UNISTD_H__ - -/** - * @file escape_unistd.h - * @brief The file that provides functions ported from Unix in unistd.h. - * @defgroup Escape_Unistd_Group Unistd.h functions - * - * This header provides functions ported from Unix in unistd.h. - * - * @{ - */ - -#include - -/* Path function */ -/** - * @brief return the canonicalized absolute pathname - * - * @param path A path to canonicalize - * @param resolved_path A pointer of size PATH_MAX where to store the result - * - * realpath() expands all symbolic links and resolves references to /./, /../ - * and extra '/' characters in the null-terminated string named by path to - * produce a canonicalized absolute pathname. The resulting pathname is - * stored as a null-terminated string, up to a maximum of PATH_MAX bytes, - * in the buffer pointed to by resolved_path. The resulting path will have - * no symbolic link, /./ or /../ components. - * - * If resolved_path is specified as NULL, then realpath() uses malloc(3) - * to allocate a buffer of up to PATH_MAX bytes to hold the resolved pathname, - * and returns a pointer to this buffer. - * The caller should deallocate this buffer using free(3). - * - */ -EAPI char *escape_realpath(const char *path, char *resolved_path); -#ifdef realpath -#undef realpath -#endif -#define realpath escape_realpath - -EAPI ssize_t -escape_readlink(const char *path, - char *buf, - size_t bufsize); -#ifdef readlink -#undef readlink -#endif -#define readlink escape_readlink - -EAPI int -escape_symlink(const char *path1, const char *path2); -#ifdef symlink -#undef symlink -#endif -#define symlink escape_symlink - -/** - * @brief check real user's permissions for a file - * - * @param pathname The path to check - * @param mode the permission to check - * - * access() checks whether the calling process can access the file pathname. - * If pathname is a symbolic link, it is dereferenced. - * The mode specifies the accessibility check(s) to be performed, and is either - * the value F_OK, or a mask consisting of the bitwise OR of one or more - * of R_OK, W_OK, and X_OK. F_OK tests for the existence of the file. - * R_OK, W_OK, and X_OK test whether the file exists and grants read, write, - * and execute permissions, respectively. - * - */ -EAPI int -escape_access(const char *pathname, int mode); -#ifdef access -#undef access -#endif -#define access escape_access - -/** - * @brief Create a pair of sockets. - * - * @param fds A pointer that contains two sockets. - * - * Create a pair of sockets that can be use with select(). - * Contrary to Unix, that functions does not - * create a pair of file descriptors. - * - * Conformity: Not applicable. - */ -EAPI int -escape_pipe(int *fds); - -/** - * @def pipe(fds) - * - * Wrapper around escape_pipe(). - */ -#define pipe(fds) escape_pipe(fds) - -//#define sync() - -/** - * @} - */ - -#endif /* __ESCAPE_UNISTD_H__ */ diff --git a/legacy/escape/src/lib/sys/mman.h b/legacy/escape/src/lib/sys/mman.h deleted file mode 100644 index 98ef7fa5fc..0000000000 --- a/legacy/escape/src/lib/sys/mman.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef __ESCAPE_SYS_MMAN_H__ -#define __ESCAPE_SYS_MMAN_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @def PROT_NONE - * Data can not be accessed. - */ - -/** - * @def PROT_READ - * Data can be read. - */ - -/** - * @def PROT_WRITE - * Data can be written. - */ - -/** - * @def PROT_EXEC - * Data can be executed. - */ - -#define PROT_NONE 0x00 -#define PROT_READ 0x01 -#define PROT_WRITE 0x02 -#define PROT_EXEC 0x04 - -/** - * @def MAP_SHARED - * Changes are shared. - */ - -/** - * @def MAP_PRIVATE - * Changes are private. - */ - -/** - * @def MAP_FIXED - * Interpret the address (addr) exactly. - */ - -/** - * @def MAP_FAILED - * Error return from mmap(). - */ - -#define MAP_SHARED 0x0001 -#define MAP_PRIVATE 0x0002 -#define MAP_FIXED 0x0010 - -#define MAP_FAILED ((void *)-1) - -/** - * @file mman.h - * @brief The file that provides the memory map functions - * @defgroup Mman Functions that manage memory mappping. - * - * This header provides the meomry map functions mmap and munmap. - * - */ - -/** - * Creates or opens a named or unnamed file mapping object for a - * specified file and maps a view of a file mapping into the - * address space of a calling process. - * - * @param addr Unused - * @param len Number of bytes to be mapped. - * @param prot Protections. - * @param flags Type of the mapped object. - * @param fd File descriptor that describes the object to map. - * @param offset Number of bytes from which to start the mapping. - * @return The starting address of the mapped view on success, -1 otherwise. - * - * Create or open an unnamed file mapping object for a specified - * file described by the file descriptor @p fd. The number of - * bytes that are mapped is given by @p len and start after - * @p offset bytes. The parameter @p addr is unused. - * - * The only type of the mapped object that is supported is - * @c MAP_SHARED. If another value if given, -1 is returned. - * - * @p prot specifies the protection of the mapped region. If - * PROT_EXEC is used, it set the execute access. If PROT_READ - * is used, it sets the read access. If PROT_WRITE is used, it - * sets the write access. - * - * If the map view of file can not be created, -1 is returned. - * If the mappping can not be done, -1 is returned. - * - * If no error occured, the starting address of the mapped view - * is returned. - * - * Conformity: None. - * - * @ingroup Mman - */ -EAPI void *mmap(void *addr, - size_t len, - int prot, - int flags, - int fd, - off_t offset); - -/** - * Unmaps a mapped view of a file from the calling process's - * address space. - * - * @param addr Pointer to the base address. - * @param len Unused. - * @return 0 on success, -1 otherwise. - * - * Unmaps a mapped view of a file from the calling process's - * address space. @p addr is the pointer to the base address. - * This value must be identical to the value returned by a - * previous call to mmap(). The parameter @p len is unsed. - * - * Conformity: None. - * - * @ingroup Mman - */ -EAPI int -munmap(void *addr, - size_t len); - -# define MADV_NORMAL 0 /* No further special treatment. */ -# define MADV_RANDOM 1 /* Expect random page references. */ -# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ -# define MADV_WILLNEED 3 /* Will need these pages. */ -# define MADV_DONTNEED 4 /* Don't need these pages. */ -# define MADV_REMOVE 9 /* Remove these pages and resources. */ -# define MADV_DONTFORK 10 /* Do not inherit across fork. */ -# define MADV_DOFORK 11 /* Do inherit across fork. */ -# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */ -# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */ -# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */ -# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */ -# define MADV_HWPOISON 100 /* Poison a page for testing. */ - -/** - * give advice about use of memory - * - * @param addr Unused. - * @param length Unused. - * @param advice Unused. - * @return 0 on success, -1 otherwise. - * - * The madvise() system call advises the kernel about how to handle - * paging input/output in the address range beginning at address addr and - * with size length bytes. It allows an application to tell the kernel - * how it expects to use some mapped or shared memory areas, so that - * the kernel can choose appropriate read-ahead and caching techniques. - * This call does not influence the semantics of the application (except - * in the case of MADV_DONTNEED), but may influence its performance. - * The kernel is free to ignore the advice. - - * Conformity: None. - * - * @ingroup Mman - */ -EAPI int -madvise(void *addr, - size_t length, - int advice); - -#ifdef __cplusplus -} -#endif - -#endif /* __ESCAPE_SYS_MMAN_H__ */ - diff --git a/licenses/COPYING.SMALL b/licenses/COPYING.SMALL new file mode 100644 index 0000000000..26d6208129 --- /dev/null +++ b/licenses/COPYING.SMALL @@ -0,0 +1,47 @@ +Copyright notice for Embryo: + +Copyright (C) 2004-2011 Carsten Haitzler and various contributors (see AUTHORS) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Large parts of this source come under the following license from the +original Small (renamed to Pawn afterwards, but was named Small when +Embryo split off). See the source files that are clearly marked as below: + +Copyright (c) ITB CompuPhase, 1997-2003 + +This software is provided "as-is", without any express or implied warranty. +In no event will the authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software in + a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. diff --git a/m4/ecore_check_c_extension.m4 b/m4/ecore_check_c_extension.m4 new file mode 100644 index 0000000000..1ef3bd2f91 --- /dev/null +++ b/m4/ecore_check_c_extension.m4 @@ -0,0 +1,42 @@ +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 ] + ) + CFLAGS=$SAVE_CFLAGS +else + use_[]DOWN="no" + AC_MSG_NOTICE([$1 support disabled]) +fi + +ECORE_X_LIBS="${ECORE_X_LIBS} ${UP[]_LIBS}" + +AC_SUBST(UP[]_CFLAGS) +AC_SUBST(UP[]_LIBS) + +popdef([UP]) +popdef([DOWN]) +]) diff --git a/m4/ecore_check_module.m4 b/m4/ecore_check_module.m4 new file mode 100644 index 0000000000..8d0d76bf3c --- /dev/null +++ b/m4/ecore_check_module.m4 @@ -0,0 +1,95 @@ +dnl use: ECORE_CHECK_MODULE(Foo, default-enabled, description[, dependency[, 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_FULL(foo-bar, evas-module, want, description, backend[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +AC_DEFUN([ECORE_EVAS_CHECK_MODULE_FULL], +[ +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="$3" + +AC_ARG_ENABLE(ecore-evas-$1, + [AC_HELP_STRING( + [--enable-ecore-evas-$1], + [enable $4 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 $4 support is to be built]) +AC_MSG_RESULT([${want_module}]) + +if test "x$2" = "xyes" && \ + test "x$5" = "xyes" && \ + test "x$have_ecore_evas" = "xyes" && \ + test "x$want_module" = "xyes" ; then + AC_DEFINE([BUILD_ECORE_EVAS_]m4_defn([UP]), [1], [Support for $4 Engine in Ecore_Evas]) + have_ecore_evas_[]m4_defn([DOWN])="yes" +fi + +AC_MSG_CHECKING([whether ecore_evas $4 support is built]) +AC_MSG_RESULT([$have_ecore_evas_]m4_defn([DOWN])) + +AS_IF([test "x$have_ecore_evas_[]m4_defn([DOWN])" = "xyes"], [$6], [$7]) + +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], +[ECORE_EVAS_CHECK_MODULE_FULL([$1], [$1], [$2], [$3], [$4], [$5], [$6])]) diff --git a/m4/efl_check_libs.m4 b/m4/efl_check_libs.m4 index cbdb11b795..c43e8d0187 100644 --- a/m4/efl_check_libs.m4 +++ b/m4/efl_check_libs.m4 @@ -26,7 +26,6 @@ if test "x${have_dep}" = "xyes" ; then [ have_dep="yes" requirements_libs_[]m4_defn([DOWNEFL])="${requirements_libs_[]m4_defn([DOWNEFL])} -ljpeg" - requirements_libs_deps_[]m4_defn([DOWNEFL])="${requirements_libs_deps_[]m4_defn([DOWNEFL])} -ljpeg" ], [ AC_MSG_ERROR("Cannot find libjpeg library. Make sure your LDFLAGS environment variable contains include lines for the location of this file") @@ -66,7 +65,6 @@ else [ _efl_have_lib="yes" requirements_libs_[]m4_defn([DOWNEFL])="${requirements_libs_[]m4_defn([DOWNEFL])} -lz" - requirements_libs_deps_[]m4_defn([DOWNEFL])="${requirements_libs_deps_[]m4_defn([DOWNEFL])} -lz" ], [ AC_MSG_ERROR(["Cannot find libjpeg library. Make sure your LDFLAGS environment variable contains include lines for the location of this file"]) diff --git a/m4/efl_threads.m4 b/m4/efl_threads.m4 index bba617f955..a657500434 100644 --- a/m4/efl_threads.m4 +++ b/m4/efl_threads.m4 @@ -28,15 +28,10 @@ case "$host_os" in AC_DEFINE([EFL_HAVE_WIN32_THREADS], [1], [Define to mention that Win32 threads are supported]) AC_DEFINE([EFL_HAVE_THREADS], [1], [Define to mention that POSIX or Win32 threads are supported]) ;; - solaris*) - _efl_enable_posix_threads="yes" - _efl_threads_cflags="-mt" - _efl_threads_libs="-mt" - ;; *) _efl_enable_posix_threads="yes" - _efl_threads_cflags="-pthread" - _efl_threads_libs="-pthread" + _efl_threads_cflags="-D_REENTRANT" + _efl_threads_libs="-lpthread" ;; esac diff --git a/m4/evas_check_engine.m4 b/m4/evas_check_engine.m4 index b3803941cc..599cb3370d 100644 --- a/m4/evas_check_engine.m4 +++ b/m4/evas_check_engine.m4 @@ -51,7 +51,6 @@ fi if test "x$3" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_engine_$1_cflags]) @@ -174,7 +173,6 @@ fi if test "x$3" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_engine_$1_cflags]) @@ -346,7 +344,6 @@ fi if test "x$3" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_deps_evas}" requirements_pc_evas="${requirement} ${requirements_pc_evas}" requirements_pc_deps_evas="${requirement} ${requirements_pc_deps_evas}" fi @@ -376,7 +373,6 @@ AC_CHECK_HEADER([windows.h], if test "x$3" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_engine_$1_cflags]) @@ -403,7 +399,6 @@ AC_CHECK_HEADER([ddraw.h], if test "x$3" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_engine_$1_cflags]) @@ -430,7 +425,6 @@ AC_CHECK_HEADERS([d3d9.h d3dx9.h], if test "x$3" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_engine_$1_cflags]) @@ -479,7 +473,6 @@ AC_LANG_POP([Objective C]) if test "x$3" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_engine_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_engine_$1_cflags]) diff --git a/m4/evas_check_loader.m4 b/m4/evas_check_loader.m4 index 66cb98087e..5dc01d2fe0 100644 --- a/m4/evas_check_loader.m4 +++ b/m4/evas_check_loader.m4 @@ -84,7 +84,6 @@ fi if test "x$2" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_image_loader_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_image_loader_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_image_loader_$1_cflags]) @@ -149,7 +148,6 @@ fi if test "x$2" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_image_loader_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_image_loader_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_image_loader_$1_cflags]) @@ -350,7 +348,6 @@ fi if test "x$2" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_image_loader_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_image_loader_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_image_loader_$1_cflags]) @@ -399,7 +396,6 @@ fi if test "x$2" = "xstatic" && test "x${have_dep}" = "xyes" ; then requirements_libs_evas="${evas_image_loader_[]$1[]_libs} ${requirements_libs_evas}" - requirements_libs_deps_evas="${evas_image_loader_[]$1[]_libs} ${requirements_libs_deps_evas}" fi AC_SUBST([evas_image_loader_$1_cflags]) diff --git a/old/ChangeLog.escape b/old/ChangeLog.escape new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/old/ChangeLog.escape @@ -0,0 +1 @@ + diff --git a/old/NEWS.escape b/old/NEWS.escape new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/old/NEWS.escape @@ -0,0 +1 @@ + diff --git a/old/README.escape b/old/README.escape new file mode 100644 index 0000000000..d45099f00d --- /dev/null +++ b/old/README.escape @@ -0,0 +1,4 @@ + The Escape library is a library that acts implements some of the missing + function from the PS3 GameOS system that are needed for the proper + functioning of the EFL. + diff --git a/pc/ecore-cocoa.pc.in b/pc/ecore-cocoa.pc.in new file mode 100644 index 0000000000..fc3607768e --- /dev/null +++ b/pc/ecore-cocoa.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-cocoa +Description: E core library, Cocoa module +Requires.private: @requirements_pc_ecore_cocoa@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_cocoa +Libs.private: @requirements_libs_ecore_cocoa@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-con.pc.in b/pc/ecore-con.pc.in new file mode 100644 index 0000000000..ecf7b257a9 --- /dev/null +++ b/pc/ecore-con.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-con +Description: E core library, Con module +Requires.private: @requirements_pc_ecore_con@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_con +Libs.private: @requirements_libs_ecore_con@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-directfb.pc.in b/pc/ecore-directfb.pc.in new file mode 100644 index 0000000000..b02870b80a --- /dev/null +++ b/pc/ecore-directfb.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-directfb +Description: E core library, DirectFB module +Requires.private: @requirements_pc_ecore_directfb@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_directfb +Libs.private: @requirements_libs_ecore_directfb@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-evas.pc.in b/pc/ecore-evas.pc.in new file mode 100644 index 0000000000..02a30ac63f --- /dev/null +++ b/pc/ecore-evas.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-evas +Description: E core library, Evas module +Requires.private: @requirements_pc_ecore_evas@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_evas +Libs.private: @requirements_libs_ecore_evas@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-fb.pc.in b/pc/ecore-fb.pc.in new file mode 100644 index 0000000000..f37881662b --- /dev/null +++ b/pc/ecore-fb.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-fb +Description: E core library, FB module +Requires.private: @requirements_pc_ecore_fb@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_fb +Libs.private: @requirements_libs_ecore_fb@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-file.pc.in b/pc/ecore-file.pc.in new file mode 100644 index 0000000000..b0c210dacd --- /dev/null +++ b/pc/ecore-file.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-file +Description: E core library, File module +Requires.private: @requirements_pc_ecore_file@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_file +Libs.private: @requirements_libs_ecore_file@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-imf-evas.pc.in b/pc/ecore-imf-evas.pc.in new file mode 100644 index 0000000000..23451c80e5 --- /dev/null +++ b/pc/ecore-imf-evas.pc.in @@ -0,0 +1,11 @@ +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}/ecore-@VMAJ@ diff --git a/pc/ecore-imf.pc.in b/pc/ecore-imf.pc.in new file mode 100644 index 0000000000..cc155ed29a --- /dev/null +++ b/pc/ecore-imf.pc.in @@ -0,0 +1,11 @@ +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}/ecore-@VMAJ@ diff --git a/pc/ecore-input-evas.pc.in b/pc/ecore-input-evas.pc.in new file mode 100644 index 0000000000..39912d32d2 --- /dev/null +++ b/pc/ecore-input-evas.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-input-evas +Description: E core library, Input module Evas extension +Requires.private: @requirements_pc_ecore_input_evas@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_input_evas +Libs.private: @requirements_libs_ecore_input_evas@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-input.pc.in b/pc/ecore-input.pc.in new file mode 100644 index 0000000000..4fc5d86f48 --- /dev/null +++ b/pc/ecore-input.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-input +Description: E core library, Input module +Requires.private: @requirements_pc_ecore_input@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_input +Libs.private: @requirements_libs_ecore_input@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-ipc.pc.in b/pc/ecore-ipc.pc.in new file mode 100644 index 0000000000..541de2170d --- /dev/null +++ b/pc/ecore-ipc.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-ipc +Description: E core library, IPC module +Requires.private: @requirements_pc_ecore_ipc@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_ipc +Libs.private: @requirements_libs_ecore_ipc@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-psl1ght.pc.in b/pc/ecore-psl1ght.pc.in new file mode 100644 index 0000000000..0b53362985 --- /dev/null +++ b/pc/ecore-psl1ght.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-psl1ght +Description: E core library, PSL1GHT module +Requires.private: @requirements_pc_ecore_psl1ght@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_psl1ght +Libs.private: @requirements_libs_ecore_psl1ght@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-sdl.pc.in b/pc/ecore-sdl.pc.in new file mode 100644 index 0000000000..78170c1c41 --- /dev/null +++ b/pc/ecore-sdl.pc.in @@ -0,0 +1,11 @@ +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}/ecore-@VMAJ@ diff --git a/pc/ecore-wayland.pc.in b/pc/ecore-wayland.pc.in new file mode 100644 index 0000000000..5a123cf498 --- /dev/null +++ b/pc/ecore-wayland.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-wayland +Description: E core library, Wayland module +Requires.private: @requirements_pc_ecore_wayland@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_wayland +Libs.private: @requirements_libs_ecore_wayland@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-win32.pc.in b/pc/ecore-win32.pc.in new file mode 100644 index 0000000000..09383d645d --- /dev/null +++ b/pc/ecore-win32.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-win32 +Description: E core library, Win32 module +Requires.private: @requirements_pc_ecore_win32@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_win32 +Libs.private: @requirements_libs_ecore_win32@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-wince.pc.in b/pc/ecore-wince.pc.in new file mode 100644 index 0000000000..344f29a622 --- /dev/null +++ b/pc/ecore-wince.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-wince +Description: E core library, WinCE module +Requires.private: @requirements_pc_ecore_wince@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_wince +Libs.private: @requirements_libs_ecore_wince@ +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/ecore-x.pc.in b/pc/ecore-x.pc.in new file mode 100644 index 0000000000..ec7fae7916 --- /dev/null +++ b/pc/ecore-x.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-x +Description: E core library, X module +Requires.private: @requirements_pc_ecore_x@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_x +Libs.private: @requirements_libs_ecore_x@ +Cflags: -I${includedir}/ecore-@VMAJ@ @have_ecore_x_xcb_define@ diff --git a/pc/ecore.pc.in b/pc/ecore.pc.in new file mode 100644 index 0000000000..f141c4cad7 --- /dev/null +++ b/pc/ecore.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore +Description: Ecore event abstraction library +Requires.private: @requirements_pc_ecore@ +Version: @VERSION@ +Libs: -L${libdir} -lecore +Libs.private: @requirements_libs_ecore@ -lm +Cflags: -I${includedir}/ecore-@VMAJ@ diff --git a/pc/escape.pc.in b/pc/escape.pc.in new file mode 100644 index 0000000000..5d18d8008e --- /dev/null +++ b/pc/escape.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: escape +Description: Library that ports on the PS3 some specific Unix functions. +Version: @VERSION@ +Libs: -L${libdir} -lescape +Libs.private: -lm -lnet -lsysmodule -liberty +Cflags: -I${includedir}/escape-@VMAJ@ diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 0000000000..e69de29bb2 diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 0000000000..3ea2f05548 --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,2 @@ +cs de el es fr gl it ko nl pt sl + diff --git a/po/Makevars b/po/Makevars new file mode 100644 index 0000000000..22837aba49 --- /dev/null +++ b/po/Makevars @@ -0,0 +1,41 @@ +# 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 = diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000000..5014aa2e92 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1 @@ +src/lib/ecore/ecore_getopt.c diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000000..4aa405d85c --- /dev/null +++ b/po/cs.po @@ -0,0 +1,174 @@ +# ecore czech translation +# quaker66@gmail.com +# Vít Pelčák , 2011. +msgid "" +msgstr "" +"Project-Id-Version: ecore\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2011-10-23 01:28+0100\n" +"Last-Translator: Daniel Kolesa \n" +"Language-Team: Czech \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#: src/lib/ecore/ecore_getopt.c:104 +msgid "Version:" +msgstr "Verze:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Použití:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [volby]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Copyright:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Licence:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Typ: " + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Výchozí: " + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Možnosti: " + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Volby:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "CHYBA: neznámá volba --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "CHYBA: neznámá volba -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "CHYBA: " + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "hodnota nemá nastaven pointer.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "neznámá boolean hodnota %s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "neznámý číselný formát %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "neznámá volba \"%s\". Možné hodnoty jsou: " + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "chybějící parametr k připojení.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "nemůžu parsovat hodnotu.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "chybějící parametr.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "chybějící callback funkce!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "nebyla definována verze.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "nebyl definován copyright.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "nebyla definována licence.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "CHYBA: neznámá volba --%s, ignoruji.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "CHYBA: volba --%s vyžaduje argument!\n" + +#: src/lib/ecore/ecore_getopt.c:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "CHYBA: neznámá volba -%c, ignoruji.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "CHYBA: volba -%c vyžaduje argument!\n" + +#: src/lib/ecore/ecore_getopt.c:1802 +msgid "ERROR: no parser provided.\n" +msgstr "CHYBA: nebyl poskytnut parser.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "CHYBA: nebyly poskytnuty hodnoty.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "CHYBA: nebyly poskytnuty argumenty.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "CHYBA: nalezeny neplatné volby." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr " Viz --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr " Viz -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "CHYBA: neplatná hodnota geometrie '%s'\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "CHYBA: neplatná hodnota velikosti '%s'\n" diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000000..e389a835a9 --- /dev/null +++ b/po/de.po @@ -0,0 +1,175 @@ +# 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 , 2009. +# Fabian Nowak , 2010. +# +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: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2010-01-03 21:52+GMT\n" +"Last-Translator: Fabian Nowak \n" +"Language-Team: German \n" +"Language: de\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:104 +msgid "Version:" +msgstr "Version:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Aufruf:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [Optionen]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Copyright:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Lizenz:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Typ: " + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Standard: " + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Auswahlmöglichkeiten: " + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Optionen:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "FEHLER: Unbekannte Option --%s\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "FEHLER: Unbekannte Option -%c\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "FEHLER: " + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "kein Zeiger auf Wert gesetzt\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "unbekannter boolescher Wert %s\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "ungültiges Zahlenformat %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "ungültige Auswahl \"%s\". Gültige Werte sind: " + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "fehlender Parameter zum Anhängen.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "Wert kann nicht ausgewertet werden.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "fehlender Parameter.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "fehlende Rückruffunktion!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "es wurde keine Version angegeben.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "es wurde kein Copyright angegeben.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "es wurde keine Lizenz angegeben.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "FEHLER: Unbekannte Option --%s, ignoriert\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, 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:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "FEHLER: Unbekannte Option -%c, ignoriert\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, 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:1802 +msgid "ERROR: no parser provided.\n" +msgstr "FEHLER: Kein Parser bereitgestellt.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "FEHLER: Keine Werte bereitgestellt.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "FEHLER: Keine Argumente bereitgestellt.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "FEHLER: Ungültige Optionen gefunden." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr " Siehe --%s\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr " Siehe -%c\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "FEHLER: Falscher Geometriewert \"%s\"\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "FEHLER: Falscher Größenwert \"%s\"\n" diff --git a/po/el.po b/po/el.po new file mode 100644 index 0000000000..945251b6d0 --- /dev/null +++ b/po/el.po @@ -0,0 +1,205 @@ +# Greek translation for Ecore. +# This file is put in the public domain. +# ragecryx , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: Ecore\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2011-11-20 22:42+0200\n" +"Last-Translator: George Rizopoulos \n" +"Language-Team: Greek\n" +"Language: \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:104 +msgid "Version:" +msgstr "Έκδοση:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Χρήση:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [επιλογές]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Πνευματικά δικαιώματα:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Άδεια:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Τύπος:" + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Προκαθορισμένο:" + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Επιλογές:" + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Επιλογές:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "ΣΦΑΛΜΑ: άγνωστη επιλογή --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "ΣΦΑΛΜΑ: άγνωστη επιλογή -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "ΣΦΑΛΜΑ:" + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "η τιμή δεν έχει δείκτη ορισμένο.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "άγνωστη τιμή boolean %s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "άγνωστη μορφή αριθμού %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "μη έγκυρη επιλογή \"%s\". Οι έγκυρες τιμές είναι: " + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "ελλιπής παράμετρος προς επισύναψη.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "αδυναμία ανάλυσης τιμών.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "ελλιπής παράμετρος.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "λείπει η λειτουργία επανάκλησης!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "δεν έχει οριστεί έκδοση.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "δεν έχουν οριστεί πνευματικά δικαιώματα.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "δεν έχει οριστεί άδεια.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "ΣΦΑΛΜΑ:άγνωστη επιλογή --%s, αγνοήθηκε.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "ΣΦΑΛΜΑ: η επιλογή --%s απαιτεί παραμέτρους!\n" + +#: src/lib/ecore/ecore_getopt.c:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "ΣΦΑΛΜΑ: άγνωστη επιλογή -%c, αγνοήθηκε.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "ΣΦAΛΜΑ: η επιλογή -%c απαιτεί μία παράμετρο!\n" + +#: src/lib/ecore/ecore_getopt.c:1802 +#, fuzzy +msgid "ERROR: no parser provided.\n" +msgstr "ΣΦΑΛΜΑ:δεν παρέχεται αναλυτής.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "ΣΦΑΛΜΑ:δεν έχουν δοθεί τιμές.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "ΣΦΑΛΜΑ:δεν έχουν δοθεί παράμετροι.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "ΣΦΑΛΜΑ: βρέθηκαν μη έγκυρες επιλογές." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr " Δείτε --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr " Δείτε -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "ΣΦΑΛΜΑ: μη έγκυρη γεωμετρική τιμή '%s'\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "ΣΦΑΛΜΑ: μη έγκυρη τιμή μεγέθους '%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" diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000000..4a55b3e1fc --- /dev/null +++ b/po/es.po @@ -0,0 +1,173 @@ +# Spanish translation for ecore. +# Copyright (C) YEAR Enlightenment development team +# This file is distributed under the same license as the PACKAGE package. +# Aníbal Garrido , 2012. +msgid "" +msgstr "" +"Project-Id-Version: ecore\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2012-11-08 02:06+0100\n" +"Last-Translator: Aníbal Garrido \n" +"Language-Team: Enlightenment Team\n" +"Language: es\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:104 +msgid "Version:" +msgstr "Versión:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Uso:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [opciones]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Copyright:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Licencia:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Tipo:" + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Predeterminado" + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Elecciones:" + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Opciones:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "ERROR: opción desconocida --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "ERROR: opción desconocida -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "ERROR: " + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "no se definió el valor.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "valor booleano desconocido %s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "formato numérico inválido %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "Elección inválida \"%s\". Los valores válidos son:" + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "faltan los parámetros a anexar.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "incapaz de procesar el valor.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "parámetro ausente.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "¡función de invocación desaparecida!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "no se definió la versión.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "no se definió el copyright.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "no se definió la licencia.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "ERROR: opción desconocida --%s, ignorada.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "ERROR: opción --%s ¡requiere un argumento!\n" + +#: src/lib/ecore/ecore_getopt.c:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "ERROR: opción desconocida -%c, ignorada.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "ERROR: opción -%c ¡requiere un argumento!\n" + +#: src/lib/ecore/ecore_getopt.c:1802 +msgid "ERROR: no parser provided.\n" +msgstr "ERROR: no se proporcionó ningún procesador.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "ERROR: no se proporcionó ningún valor.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "ERROR: no se proporcionó ningún argumento.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "ERROR: encontradas opciones inválidas." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr " Vea --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr " Vea -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "ERROR: valor geométrico incorrecto '%s'\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "ERROR: valor del tamaño incorrecto '%s'\n" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000000..1dd79fddb2 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,208 @@ +# French translation for Ecore. +# This file is put in the public domain. +# batden , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: Ecore\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2010-07-11 11:01+0400\n" +"Last-Translator: batden \n" +"Language-Team: Enlightenment French Team \n" +"Language: \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:104 +msgid "Version:" +msgstr "Version :" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Usage :" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [options]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Copyright :" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Licence :" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Type : " + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Par défaut :" + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Choix :" + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Options :\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "ERREUR : option inconnue --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "ERREUR : option inconnue -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "ERREUR :" + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "la valeur n'a aucun pointeur défini.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "valeur booléenne inconnue %s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "format du nombre non valide %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "choix non valide « %s ». Les valeurs valides sont : " + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "paramètre manquant à ajouter.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "analyse de la valeur impossible.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "paramètre manquant.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "fonction de rappel manquante !\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "aucune version n'est définie.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "aucun copyright n'est défini.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "aucune licence n'est définie.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, 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:1511 +#, 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:1553 +#, 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:1591 +#, 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:1802 +msgid "ERROR: no parser provided.\n" +msgstr "ERREUR : aucun analyseur n'est fourni.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "ERREUR : aucune valeur n'est fournie.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "ERREUR : aucun argument n'est fourni.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "ERREUR : options non valides détectées." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr " Voir --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr " Voir -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "ERREUR : valeur géométrique incorrecte « %s »\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, 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" diff --git a/po/gl.po b/po/gl.po new file mode 100644 index 0000000000..d1eeb91399 --- /dev/null +++ b/po/gl.po @@ -0,0 +1,173 @@ +# Galician translation of ecore +# This file is put in the public domain. +# Aníbal Garrido , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: ecore\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2012-10-16 09:53+0200\n" +"Last-Translator: Aníbal Garrido \n" +"Language-Team: http://trasno.net/ \n" +"Language: gl\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:104 +msgid "Version:" +msgstr "Versión:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Uso:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [opcións]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Dereitos de autor:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Licenza" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Tipo:" + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Predeterminado:" + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Eleccións:" + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Opcións:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "ERRO: opción descoñecida --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "ERRO: opción descoñecida -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "ERRO: " + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "non se definiu o valor.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "valor booleano descoñecido %s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "formato numérico inválido %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "Elección inválida \"%s\". Os valores válidos son:" + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "faltan os parámetros a anexar.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "incapaz de procesar o valor.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "parámetro ausente.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "Función de invocación desaparecida!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "non se definiu a versión.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "non se definiron os dereitos de autor.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "non se definiu a licenza.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "ERRO: opción descoñecida --%s, ignorada.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "ERRO: opción --%s require un argumento!\n" + +#: src/lib/ecore/ecore_getopt.c:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "ERRO: opción descoñecida -%c, ignorada.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "ERRO: opción -%c require un argumento!\n" + +#: src/lib/ecore/ecore_getopt.c:1802 +msgid "ERROR: no parser provided.\n" +msgstr "ERRO: non se forneceu ningún procesador.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "ERRO: non se forneceu ningún valor.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "ERRO: non se forneceu ningún argumento.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "ERRO: atopadas opcións inválidas." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr " Consulte --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr " Consulte -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "ERRO: valor xeométrico incorrecto '%s'\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "ERRO: valor do tamaño incorrecto '%s'\n" diff --git a/po/it.po b/po/it.po new file mode 100644 index 0000000000..93d26c74b2 --- /dev/null +++ b/po/it.po @@ -0,0 +1,204 @@ +# Italian translation for Ecore. +# This file is put in the public domain. +# Massimo Maiurana , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: Ecore\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2009-10-27 19:36+0100\n" +"Last-Translator: quaker66 \n" +"Language-Team: none\n" +"Language: \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:104 +msgid "Version:" +msgstr "Versione:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Uso:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [opzioni]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Copyright:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Licenza:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Tipo: " + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Predefinito:" + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Scelte:" + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Opzioni:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "ERRORE: opzione sconosciuta --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "ERRORE: opzione sconosciuta -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "ERRORE:" + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "il valore non ha puntatori impostati.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "valore booleano sconosciuto %s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "formato numero non valido %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "scelta non valida \"%s\". I valori ammessi sono: " + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "parametro da appendere mancante.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "impossibile il parsing del valore.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "parametro mancante.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "funzione callback mancante!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "nessuna versione definita.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "nessun copyright definito.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "nessuna licenza definita.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "ERRORE: opzione sconosciuta --%s, ignorata.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, 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:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "ERRORE: opzione sconosciuta -%c, ignorata.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, 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:1802 +msgid "ERROR: no parser provided.\n" +msgstr "ERRORE: nessun parser fornito.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "ERRORE: nessun valore fornito.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "ERRORE: nessun argomento fornito.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "ERRORE: trovate opzioni non valide." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr " Vedere --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr " Vedere -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "ERRORE: valore geometrico non corretto '%s'\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, 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" diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000000..877964aadb --- /dev/null +++ b/po/ko.po @@ -0,0 +1,179 @@ +# Korean translation for the Enlightenment ecore. +# Copyright (C) 2000-2012 Enlightenment development team +# This file is distributed under the same license as the Enlightenment package. +# Seong-ho Cho , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: Enlightenment Ecore 1.7.0\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2012-08-30 22:50+0900\n" +"Last-Translator: Seong-ho Cho \n" +"Language-Team: Enlightenment-Intl \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Poedit-Language: Korean\n" +"X-Poedit-Country: KOREA, REPUBLIC OF\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: src/lib/ecore/ecore_getopt.c:104 +msgid "Version:" +msgstr "버전:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "사용법:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s <옵션>\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "저작권 정보:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "라이선스:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "형식: " + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "기본값: " + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "선택: " + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "옵션:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "오류: 알 수 없는 옵션 --%s 입니다.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "오류: 알 수 없는 옵션 -%c 입니다.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "오류: " + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "값에 포인터 집합이 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "알 수 없는 부울린 값 %s 입니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "잘못된 숫자 형식 %s 입니다\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "잘못된 선택 \"%s\" 입니다. 유효한 값은 다음과 같습니다: " + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "붙일 매개변수가 빠졌습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "값을 해석할 수 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "매개변수가 빠졌습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "콜백 함수가 빠졌습니다!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "정의한 버전이 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "정의한 저작권 정보가 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "정의한 라이선스가 없습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "오류: 알 수 없는 --%s 옵션을 무시합니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "오류: --%s 옵션에 인자가 필요합니다!\n" + +#: src/lib/ecore/ecore_getopt.c:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "오류: 알 수 없는 -%c 옵션을 무시합니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "오류: -%c 옵션에 인자가 필요합니다!\n" + +#: src/lib/ecore/ecore_getopt.c:1802 +msgid "ERROR: no parser provided.\n" +msgstr "오류: 해석 프로그램이 존재하지 않습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "오류: 값이 존재하지 않습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "인자가 존재하지 않습니다.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "오류: 잘못된 옵션이 있습니다." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr " --%s을(를) 참조하십시오.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr " -%c을(를) 참조하십시오.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "오류: '%s' 값의 좌표가 올바르지 않습니다\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "오류: '%s' 값의 크기가 올바르지 않습니다\n" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000000..64a8d99976 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,175 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Ecore\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2011-09-03 15:48+0100\n" +"Last-Translator: Heimen Stoffels \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: NL\n" +"X-Poedit-Country: Nederland\n" + +#: src/lib/ecore/ecore_getopt.c:104 +msgid "Version:" +msgstr "Versie:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Gebruik:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [opties]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Copyright:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Licentie:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Type:" + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Standaard:" + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Keuzes:" + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Opties:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "FOUT: onbekende optie --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "FOUT: onbekende optie -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "FOUT:" + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "waarde heeft geen pointer ingsteld.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "onbekende boolean-waarde %s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "ongeldig nummerformaat %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "ongeldige keuze \"%s\". Geldige waardes zijn:" + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "parameter om toe te wijzen ontbreekt.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "kon waarde niet doorvoeren.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "paramater ontbreekt.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "ontbrekende terugroep-functie!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "geen versie was gedefinieerd.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "geen copyright was gedefinieerd.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "geen licentie was gedefinieerd.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "FOUT: onbekende optie --%s, genegeerd.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "FOUT: optie --%s vereist een argument!\n" + +#: src/lib/ecore/ecore_getopt.c:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "FOUT: onbekende opties -%c, genegeerd.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "FOUT: optie -%c vereist een argument!\n" + +#: src/lib/ecore/ecore_getopt.c:1802 +msgid "ERROR: no parser provided.\n" +msgstr "FOUT: geen doorvoerder beschikbaar gesteld.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "FOUT: geen waarden beschikbaar gesteld.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "FOUT: geen argumenten beschibaar gesteld.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "FOUT: ongeldige opties gevonden." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr "Zie --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr "Zie -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "Fout: foutieve wiskundige waarde '%s'\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "FOUT: foutieve grootte-waarden '%s'\n" diff --git a/po/pt.po b/po/pt.po new file mode 100644 index 0000000000..794a654b79 --- /dev/null +++ b/po/pt.po @@ -0,0 +1,176 @@ +# Portuguese translation for ecore +# This file is distributed under the same license as the enlightenment package. +# Sérgio Marques , 2010 +# +msgid "" +msgstr "" +"Project-Id-Version: ecore\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2012-08-23 00:30+0100\n" +"Last-Translator: Sérgio Marques \n" +"Language-Team: \n" +"Language: \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: Portuguese\n" +"X-Poedit-Country: Portugal\n" + +#: src/lib/ecore/ecore_getopt.c:104 +msgid "Version:" +msgstr "Versão:" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Utilização:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s [opções]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Direitos de autor:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Licença:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Tipo:" + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Padrão:" + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Escolhas:" + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Opções:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "ERRO: opção desconhecida --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "ERRO: opção desconhecida -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "ERRO: " + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "o valor não está definido.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "valor booleano desconhecido %s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "formato numérico inválido %s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "escolha inválida \"%s\". O valores possíveis são:" + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "faltam os parâmetros a anexar.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "incapaz de processar o valor.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "parâmetro em falta.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "função de invocação em falta!\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "nenhuma versão definida.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "direitos de autor não definidos.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "licença não definida.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "ERRO: opção desconhecida --%s, ignorada.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "ERRO: a opção --%s requer um argumento!\n" + +#: src/lib/ecore/ecore_getopt.c:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "ERRO: opção desconhecida --%c, ignorada.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "ERRO: a opção --%c requer um argumento!\n" + +#: src/lib/ecore/ecore_getopt.c:1802 +msgid "ERROR: no parser provided.\n" +msgstr "ERRO: nenhum processador fornecido.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "ERRO: nenhum valor fornecido.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "ERRO: nenhum argumento fornecido.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "ERRO: encontradas opções inválidas." + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr "Consulte --%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr "Consulte -%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "ERRO: valor geométrico incorreto \"%s\"\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "ERRO: tamanho incorreto \"%s\"\n" diff --git a/po/sl.po b/po/sl.po new file mode 100644 index 0000000000..ea20e0d2ff --- /dev/null +++ b/po/sl.po @@ -0,0 +1,175 @@ +# Slovenian translation of ecore. +# This file is put in the public domain. +# r1to , 2011. +# , fuzzy +# +# +msgid "" +msgstr "" +"Project-Id-Version: ecore 1.0\n" +"Report-Msgid-Bugs-To: enlightenment-devel@lists.sourceforge.net\n" +"POT-Creation-Date: 2012-11-21 13:41+0100\n" +"PO-Revision-Date: 2011-02-24 16:54+0100\n" +"Last-Translator: r1to \n" +"Language-Team: Slovenian \n" +"Language: sl\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:104 +msgid "Version:" +msgstr "Različica" + +#: src/lib/ecore/ecore_getopt.c:113 +msgid "Usage:" +msgstr "Uporaba:" + +#: src/lib/ecore/ecore_getopt.c:118 +#, c-format +msgid "%s [options]\n" +msgstr "%s·[možnosti]\n" + +#: src/lib/ecore/ecore_getopt.c:273 +msgid "Copyright:" +msgstr "Avtorstvo:" + +#: src/lib/ecore/ecore_getopt.c:285 +msgid "License:" +msgstr "Licenca:" + +#: src/lib/ecore/ecore_getopt.c:466 +msgid "Type: " +msgstr "Vrsta:·" + +#: src/lib/ecore/ecore_getopt.c:542 +msgid "Default: " +msgstr "Privzeto:·" + +#: src/lib/ecore/ecore_getopt.c:569 +msgid "Choices: " +msgstr "Izbire:·" + +#: src/lib/ecore/ecore_getopt.c:670 +msgid "Options:\n" +msgstr "Možnosti:\n" + +#: src/lib/ecore/ecore_getopt.c:797 +#, c-format +msgid "ERROR: unknown option --%s.\n" +msgstr "NAPAKA:·Neznana možnost·--%s.\n" + +#: src/lib/ecore/ecore_getopt.c:799 +#, c-format +msgid "ERROR: unknown option -%c.\n" +msgstr "NAPAKA:·neznana možnost·-%c.\n" + +#: src/lib/ecore/ecore_getopt.c:857 +msgid "ERROR: " +msgstr "NAPAKA:" + +#: src/lib/ecore/ecore_getopt.c:940 src/lib/ecore/ecore_getopt.c:1077 +#: src/lib/ecore/ecore_getopt.c:1093 src/lib/ecore/ecore_getopt.c:1108 +#: src/lib/ecore/ecore_getopt.c:1125 src/lib/ecore/ecore_getopt.c:1172 +#: src/lib/ecore/ecore_getopt.c:1292 src/lib/ecore/ecore_getopt.c:1333 +msgid "value has no pointer set.\n" +msgstr "vrednost nima nastavljenega kazalnika.\n" + +#: src/lib/ecore/ecore_getopt.c:972 src/lib/ecore/ecore_getopt.c:1192 +#, c-format +msgid "unknown boolean value %s.\n" +msgstr "neznana Boolova vrednost·%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1023 src/lib/ecore/ecore_getopt.c:1280 +#, c-format +msgid "invalid number format %s\n" +msgstr "napačen·format Å¡tevila·%s\n" + +#: src/lib/ecore/ecore_getopt.c:1138 +#, c-format +msgid "invalid choice \"%s\". Valid values are: " +msgstr "napačna izbira·\"%s\".·Pravilne izbire so:·" + +#: src/lib/ecore/ecore_getopt.c:1166 +msgid "missing parameter to append.\n" +msgstr "manjka·parameter·za dodajo.\n" + +#: src/lib/ecore/ecore_getopt.c:1270 +msgid "could not parse value.\n" +msgstr "vrednosti ni bilo možno razčleniti.\n" + +#: src/lib/ecore/ecore_getopt.c:1327 +msgid "missing parameter.\n" +msgstr "manjkajoči·parameter.\n" + +#: src/lib/ecore/ecore_getopt.c:1340 +msgid "missing callback function!\n" +msgstr "manjkajoča povratno-zasilna funkcija !\n" + +#: src/lib/ecore/ecore_getopt.c:1369 +msgid "no version was defined.\n" +msgstr "definirana ni bila nobena različica.\n" + +#: src/lib/ecore/ecore_getopt.c:1386 +msgid "no copyright was defined.\n" +msgstr "definirano ni bilo nobeno avtorstvo.\n" + +#: src/lib/ecore/ecore_getopt.c:1403 +msgid "no license was defined.\n" +msgstr "definirana ni bila nobena licenca.\n" + +#: src/lib/ecore/ecore_getopt.c:1478 +#, c-format +msgid "ERROR: unknown option --%s, ignored.\n" +msgstr "NAPAKA:·neznana možnost·--%s,·prezrto.\n" + +#: src/lib/ecore/ecore_getopt.c:1511 +#, c-format +msgid "ERROR: option --%s requires an argument!\n" +msgstr "NAPAKA:·možnost·--%s·zahteva argument!\n" + +#: src/lib/ecore/ecore_getopt.c:1553 +#, c-format +msgid "ERROR: unknown option -%c, ignored.\n" +msgstr "NAPAKA:·neznana možnost·-%c,·prezrto.\n" + +#: src/lib/ecore/ecore_getopt.c:1591 +#, c-format +msgid "ERROR: option -%c requires an argument!\n" +msgstr "NAPAKA:·možnost·-%c zahteva argument!\n" + +#: src/lib/ecore/ecore_getopt.c:1802 +msgid "ERROR: no parser provided.\n" +msgstr "NAPAKA:·ni podan razčlenjevalnik.\n" + +#: src/lib/ecore/ecore_getopt.c:1807 +msgid "ERROR: no values provided.\n" +msgstr "NAPAKA::·ni podanih vrednosti.\n" + +#: src/lib/ecore/ecore_getopt.c:1816 +msgid "ERROR: no arguments provided.\n" +msgstr "NAPAKA::·ni podanih argumentov.\n" + +#: src/lib/ecore/ecore_getopt.c:1842 +msgid "ERROR: invalid options found." +msgstr "NAPAKA::·najdene nepravilne možnosti" + +#: src/lib/ecore/ecore_getopt.c:1848 +#, c-format +msgid " See --%s.\n" +msgstr "·Glej·--%s.\n" + +#: src/lib/ecore/ecore_getopt.c:1850 +#, c-format +msgid " See -%c.\n" +msgstr "·Glej·-%c.\n" + +#: src/lib/ecore/ecore_getopt.c:1896 +#, c-format +msgid "ERROR: incorrect geometry value '%s'\n" +msgstr "NAPAKA::·nepravilna geometrijska vrednost·'%s'\n" + +#: src/lib/ecore/ecore_getopt.c:1928 +#, c-format +msgid "ERROR: incorrect size value '%s'\n" +msgstr "NAPAKA::·nepravilna vrednost velikosti·'%s'\n" diff --git a/src/Makefile.am b/src/Makefile.am index 68b83fc598..e9c5a9bdbe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,10 +13,47 @@ if HAVE_WINDOWS include Makefile_Evil.am endif +if HAVE_PS3 +include Makefile_Escape.am +endif + include Makefile_Eina.am include Makefile_Eo.am include Makefile_Eet.am include Makefile_Evas.am +include Makefile_Ecore.am +include Makefile_Ecore_Con.am +include Makefile_Ecore_Ipc.am +include Makefile_Ecore_File.am +include Makefile_Ecore_Input.am +if HAVE_ECORE_COCOA +include Makefile_Ecore_Cocoa.am +endif +if HAVE_ECORE_DIRECTFB +include Makefile_Ecore_DirectFB.am +endif +if HAVE_ECORE_FB +include Makefile_Ecore_FB.am +endif +if HAVE_PS3 +include Makefile_Ecore_Psl1ght.am +endif +if HAVE_ECORE_SDL +include Makefile_Ecore_SDL.am +endif +if HAVE_ECORE_WAYLAND +include Makefile_Ecore_Wayland.am +endif +if HAVE_WIN32 +include Makefile_Ecore_Win32.am +endif +if HAVE_WINCE +include Makefile_Ecore_WinCE.am +endif +if HAVE_ECORE_X +include Makefile_Ecore_X.am +endif +include Makefile_Ecore_Imf.am include Makefile_Embryo.am .PHONY: benchmark examples diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am new file mode 100644 index 0000000000..eabe603558 --- /dev/null +++ b/src/Makefile_Ecore.am @@ -0,0 +1,88 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore/libecore.la + +installed_ecoremainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoremainheaders_DATA = \ +lib/ecore/Ecore.h \ +lib/ecore/Ecore_Getopt.h + +lib_ecore_libecore_la_SOURCES = \ +lib/ecore/ecore.c \ +lib/ecore/ecore_alloc.c \ +lib/ecore/ecore_anim.c \ +lib/ecore/ecore_app.c \ +lib/ecore/ecore_events.c \ +lib/ecore/ecore_getopt.c \ +lib/ecore/ecore_glib.c \ +lib/ecore/ecore_idle_enterer.c \ +lib/ecore/ecore_idle_exiter.c \ +lib/ecore/ecore_idler.c \ +lib/ecore/ecore_job.c \ +lib/ecore/ecore_main.c \ +lib/ecore/ecore_pipe.c \ +lib/ecore/ecore_poll.c \ +lib/ecore/ecore_time.c \ +lib/ecore/ecore_timer.c \ +lib/ecore/ecore_thread.c \ +lib/ecore/ecore_throttle.c \ +lib/ecore/ecore_private.h + +if HAVE_WIN32 +lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_exe_win32.c +else +if HAVE_WINCE +lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_exe_wince.c +else +#if ECORE_HAVE_PS3 +#libecore_la_SOURCES += ecore_exe_ps3.c +#else +#if ECORE_HAVE_EXOTIC +#libecore_la_SOURCES += +#else +lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_signal.c lib/ecore/ecore_exe.c +#endif +#endif +endif +endif + +lib_ecore_libecore_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-DEFL_ECORE_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@ECORE_CFLAGS@ + +if HAVE_WINDOWS +lib_ecore_libecore_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/evil \ +-I$(top_builddir)/src/lib/evil +endif + +if HAVE_PS3 +lib_ecore_libecore_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/escape \ +-I$(top_builddir)/src/lib/escape +endif + +lib_ecore_libecore_la_LIBADD = \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +if HAVE_WINDOWS +lib_ecore_libecore_la_LIBADD += lib/evil/libevil.la +endif + +if HAVE_PS3 +lib_ecore_libecore_la_LIBADD += lib/escape/libescape.la +endif + +lib_ecore_libecore_la_LIBADD += @ECORE_LIBS@ @EFL_COV_LIBS@ -lm + +lib_ecore_libecore_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_Cocoa.am b/src/Makefile_Ecore_Cocoa.am new file mode 100644 index 0000000000..f7f82918a1 --- /dev/null +++ b/src/Makefile_Ecore_Cocoa.am @@ -0,0 +1,37 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_cocoa/libecore_cocoa.la + +installed_ecorecocoamainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecorecocoamainheaders_DATA = \ +lib/ecore_cocoa/Ecore_Cocoa.h \ +lib/ecore_cocoa/Ecore_Cocoa_Keys.h + +lib_ecore_cocoa_libecore_cocoa_la_SOURCES = \ +lib/ecore_cocoa/ecore_cocoa.m \ +lib/ecore_cocoa/ecore_cocoa_window.m \ +lib/ecore_cocoa/ecore_cocoa_private.h + +lib_ecore_cocoa_libecore_cocoa_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_cocoa \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_cocoa \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_cocoa_libecore_cocoa_la_LIBADD = \ +lib/ecore_input/libecore_input.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@ECORE_COCOA_LIBS@ + +lib_ecore_cocoa_libecore_cocoa_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_Con.am b/src/Makefile_Ecore_Con.am new file mode 100644 index 0000000000..f2e6ee8537 --- /dev/null +++ b/src/Makefile_Ecore_Con.am @@ -0,0 +1,70 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_con/libecore_con.la + +installed_ecoreconmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoreconmainheaders_DATA = \ +lib/ecore_con/Ecore_Con.h \ +lib/ecore_con/Ecore_Con_Eet.h + +lib_ecore_con_libecore_con_la_SOURCES = \ +lib/ecore_con/ecore_con_alloc.c \ +lib/ecore_con/ecore_con.c \ +lib/ecore_con/ecore_con_eet.c \ +lib/ecore_con/ecore_con_socks.c \ +lib/ecore_con/ecore_con_ssl.c \ +lib/ecore_con/ecore_con_url.c \ +lib/ecore_con/ecore_con_private.h + +if HAVE_WINDOWS +lib_ecore_con_libecore_con_la_SOURCES += lib/ecore_con/ecore_con_local_win32.c +else +lib_ecore_con_libecore_con_la_SOURCES += lib/ecore_con/ecore_con_local.c +endif + +if HAVE_CARES +lib_ecore_con_libecore_con_la_SOURCES += lib/ecore_con/ecore_con_ares.c +else +if HAVE_IPV6 +lib_ecore_con_libecore_con_la_SOURCES += lib/ecore_con/ecore_con_dns.c lib/ecore_con/dns.c lib/ecore_con/dns.h +else +lib_ecore_con_libecore_con_la_SOURCES += lib/ecore_con/ecore_con_info.c +endif +endif + +lib_ecore_con_libecore_con_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/eet \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_con \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/eet \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_con \ +-DEFL_ECORE_CON_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@ECORE_CON_CFLAGS@ + +if HAVE_WINDOWS +lib_ecore_con_libecore_con_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/evil \ +-I$(top_builddir)/src/lib/evil +endif + +lib_ecore_con_libecore_con_la_LIBADD = \ +lib/ecore/libecore.la \ +lib/eet/libeet.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +if HAVE_WINDOWS +lib_ecore_con_libecore_con_la_LIBADD += lib/evil/libevil.la +endif + +lib_ecore_con_libecore_con_la_LIBADD += @ECORE_CON_LIBS@ @EFL_COV_LIBS@ -lm + +lib_ecore_con_libecore_con_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_DirectFB.am b/src/Makefile_Ecore_DirectFB.am new file mode 100644 index 0000000000..6e2d54c27a --- /dev/null +++ b/src/Makefile_Ecore_DirectFB.am @@ -0,0 +1,34 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_directfb/libecore_directfb.la + +installed_ecoredirectfbmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoredirectfbmainheaders_DATA = \ +lib/ecore_directfb/Ecore_DirectFB.h + +lib_ecore_directfb_libecore_directfb_la_SOURCES = \ +lib/ecore_directfb/ecore_directfb.c \ +lib/ecore_directfb/ecore_directfb_keys.h \ +lib/ecore_directfb/ecore_directfb_private.h + +lib_ecore_directfb_libecore_directfb_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_directfb \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_directfb \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@ECORE_DIRECTFB_CFLAGS@ + +lib_ecore_directfb_libecore_directfb_la_LIBADD = \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@ECORE_DIRECTFB_LIBS@ + +lib_ecore_directfb_libecore_directfb_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_Evas.am b/src/Makefile_Ecore_Evas.am new file mode 100644 index 0000000000..595cd25f0f --- /dev/null +++ b/src/Makefile_Ecore_Evas.am @@ -0,0 +1,160 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_evas/libecore_evas.la + +installed_ecoreevasmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoreevasmainheaders_DATA = \ +lib/ecore_evas/Ecore_Evas.h + +lib_ecore_evas_libecore_evas_la_SOURCES = \ +lib/ecore_evas/ecore_evas.c \ +lib/ecore_evas/ecore_evas_util.c \ +lib/ecore_evas/ecore_evas_x.c \ +lib/ecore_evas/ecore_evas_fb.c \ +lib/ecore_evas/ecore_evas_buffer.c \ +lib/ecore_evas/ecore_evas_directfb.c \ +lib/ecore_evas/ecore_evas_win32.c \ +lib/ecore_evas/ecore_evas_sdl.c \ +lib/ecore_evas/ecore_evas_cocoa.c \ +lib/ecore_evas/ecore_evas_wince.c \ +lib/ecore_evas/ecore_evas_ews.c \ +lib/ecore_evas/ecore_evas_psl1ght.c \ +lib/ecore_evas/ecore_evas_wayland_shm.c \ +lib/ecore_evas/ecore_evas_wayland_egl.c \ +lib/ecore_evas/ecore_evas_extn.c \ +lib/ecore_evas/ecore_evas_private.h + +if BUILD_ECORE_WAYLAND +lib_ecore_evas_libecore_evas_la_SOURCES += \ +lib/ecore_evas/ecore_evas_wayland_common.c +endif + +lib_ecore_evas_libecore_evas_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_ipc \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_input_evas \ +-I$(top_srcdir)/src/lib/ecore_evas \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_ipc \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_input_evas \ +-I$(top_builddir)/src/lib/ecore_evas \ +-DEFL_ECORE_EVAS_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +if BUILD_ECORE_COCOA +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_cocoa \ +-I$(top_builddir)/src/lib/ecore_cocoa +endif + +if BUILD_ECORE_DIRECTFB +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_directfb \ +-I$(top_builddir)/src/lib/ecore_directfb +endif + +if BUILD_ECORE_FB +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_fb \ +-I$(top_builddir)/src/lib/ecore_fb +endif + +if BUILD_ECORE_PSL1GHT +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_psl1ght \ +-I$(top_builddir)/src/lib/ecore_psl1ght +endif + +if BUILD_ECORE_SDL +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_sdl \ +-I$(top_builddir)/src/lib/ecore_sdl +endif + +if BUILD_ECORE_WAYLAND +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_wayland \ +-I$(top_builddir)/src/lib/ecore_wayland +endif + +if BUILD_ECORE_WIN32 +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_win32 \ +-I$(top_builddir)/src/lib/ecore_win32 +endif + +if BUILD_ECORE_WINCE +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_wince \ +-I$(top_builddir)/src/lib/ecore_wince +endif + +if BUILD_ECORE_X +lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ +-I$(top_srcdir)/src/lib/ecore_x \ +-I$(top_builddir)/src/lib/ecore_x +endif + +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_input_evas/libecore_input_evas.la \ +lib/ecore_input/libecore_input.la \ +lib/ecore_ipc/libecore_ipc.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@ECORE_EVAS_LIBS@ + +if BUILD_ECORE_COCOA +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_cocoa/libecore_cocoa.la +endif + +if BUILD_ECORE_DIRECTFB +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_directfb/libecore_directfb.la +endif + +if BUILD_ECORE_FB +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_fb/libecore_fb.la +endif + +if BUILD_ECORE_PSL1GHT +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_psl1ght/libecore_psl1ght.la +endif + +if BUILD_ECORE_SDL +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_sdl/libecore_sdl.la +endif + +if BUILD_ECORE_WAYLAND +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_wayland/libecore_wayland.la +endif + +if BUILD_ECORE_WIN32 +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_win32/libecore_win32.la +endif + +if BUILD_ECORE_WINCE +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_wince/libecore_wince.la +endif + +if BUILD_ECORE_X +lib_ecore_evas_libecore_evas_la_LIBADD = \ +lib/ecore_x/libecore_x.la +endif + +lib_ecore_evas_libecore_evas_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_FB.am b/src/Makefile_Ecore_FB.am new file mode 100644 index 0000000000..adcc5ebdc6 --- /dev/null +++ b/src/Makefile_Ecore_FB.am @@ -0,0 +1,42 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_fb/libecore_fb.la + +installed_ecorefbmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecorefbmainheaders_DATA = \ +lib/ecore_fb/Ecore_Fb.h + +lib_ecore_fb_libecore_fb_la_SOURCES = \ +lib/ecore_fb/ecore_fb.c \ +lib/ecore_fb/ecore_fb_li.c \ +lib/ecore_fb/ecore_fb_ts.c \ +lib/ecore_fb/ecore_fb_vt.c \ +lib/ecore_fb/ecore_fb_keytable.h \ +lib/ecore_fb/ecore_fb_private.h +# deprecated sources (might not compile): +# lib/ecore_fb/ecore_fb_kbd.c +# lib/ecore_fb/ecore_fb_ps2.c + +lib_ecore_fb_libecore_fb_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_fb \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_fb \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@ECORE_FB_CFLAGS@ + +lib_ecore_fb_libecore_fb_la_LIBADD = \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@ECORE_FB_LIBS@ + +lib_ecore_fb_libecore_fb_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_File.am b/src/Makefile_Ecore_File.am new file mode 100644 index 0000000000..2172245342 --- /dev/null +++ b/src/Makefile_Ecore_File.am @@ -0,0 +1,41 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_file/libecore_file.la + +installed_ecorefilemainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecorefilemainheaders_DATA = \ +lib/ecore_file/Ecore_File.h + +lib_ecore_file_libecore_file_la_SOURCES = \ +lib/ecore_file/ecore_file.c \ +lib/ecore_file/ecore_file_download.c \ +lib/ecore_file/ecore_file_monitor.c \ +lib/ecore_file/ecore_file_monitor_inotify.c \ +lib/ecore_file/ecore_file_monitor_poll.c \ +lib/ecore_file/ecore_file_monitor_win32.c \ +lib/ecore_file/ecore_file_path.c \ +lib/ecore_file/ecore_file_private.h + +lib_ecore_file_libecore_file_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_con \ +-I$(top_srcdir)/src/lib/ecore_file \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_con \ +-I$(top_builddir)/src/lib/ecore_file \ +-DEFL_ECORE_FILE_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_file_libecore_file_la_LIBADD = \ +lib/ecore_con/libecore_con.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +lib_ecore_file_libecore_file_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_Imf.am b/src/Makefile_Ecore_Imf.am new file mode 100644 index 0000000000..820ae2b12a --- /dev/null +++ b/src/Makefile_Ecore_Imf.am @@ -0,0 +1,186 @@ + +### Library + +lib_LTLIBRARIES += \ +lib/ecore_imf/libecore_imf.la \ +lib/ecore_imf/libecore_imf_evas.la + +installed_ecoreimfmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoreimfmainheaders_DATA = \ +lib/ecore_imf/Ecore_IMF.h + +lib_ecore_imf_libecore_imf_la_SOURCES = \ +lib/ecore_imf/ecore_imf.c \ +lib/ecore_imf/ecore_imf_context.c \ +lib/ecore_imf/ecore_imf_module.c \ +lib/ecore_imf/ecore_imf_private.h + +lib_ecore_imf_libecore_imf_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_imf \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_imf \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DEFL_ECORE_IMF_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_imf_libecore_imf_la_LIBADD = \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +lib_ecore_imf_libecore_imf_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ + +installed_ecoreimfevasmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoreimfevasmainheaders_DATA = \ +lib/ecore_imf/Ecore_IMF_Evas.h + +lib_ecore_imf_libecore_imf_evas_la_SOURCES = \ +lib/ecore_imf/ecore_imf_evas.c + +lib_ecore_imf_libecore_imf_evas_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/evas \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_imf \ +-I$(top_srcdir)/src/lib/ecore_imf_evas \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/evas \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_imf \ +-I$(top_builddir)/src/lib/ecore_imf_evas \ +-DEFL_ECORE_IMF_EVAS_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_imf_libecore_imf_evas_la_LIBADD = \ +lib/ecore_imf/libecore_imf.la \ +lib/ecore/libecore.la \ +lib/evas/libevas.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +lib_ecore_imf_libecore_imf_evas_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ + + +### Modules + +# Ibus + +if BUILD_ECORE_IMF_IBUS +ecoreimfibuspkgdir = $(libdir)/ecore/immodules +ecoreimfibuspkg_LTLIBRARIES = modules/ecore/immodules/ibus/ibus.la +modules_ecore_immodules_ibus_ibus_la_SOURCES = \ +modules/ecore/immodules/ibus/ibus_module.c \ +modules/ecore/immodules/ibus/ibus_imcontext.c \ +modules/ecore/immodules/ibus/ibus_imcontext.h +modules_ecore_immodules_ibus_ibus_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_x \ +-I$(top_srcdir)/src/lib/ecore_imf \ +-I$(top_srcdir)/src/lib/ecore_evas \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_x \ +-I$(top_builddir)/src/lib/ecore_imf \ +-I$(top_builddir)/src/lib/ecore_evas \ +-DEFL_ECORE_IMF_EVAS_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@IBUS_CFLAGS@ +modules_ecore_immodules_ibus_ibus_la_LIBADD = \ +lib/ecore_imf/libecore_evas.la \ +lib/ecore_imf/libecore_imf.la \ +lib/ecore_x/libecore_x.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@IBUS_LIBS@ +modules_ecore_immodules_ibus_ibus_la_LDFLAGS = -no-undefined -module -avoid-version +modules_ecore_immodules_ibus_ibus_la_LIBTOOLFLAGS = --tag=disable-static +endif + +# Scim + +if BUILD_ECORE_IMF_SCIM +ecoreimfscimpkgdir = $(libdir)/ecore/immodules +ecoreimfscimpkg_LTLIBRARIES = modules/ecore/immodules/scim/scim.la +modules_ecore_immodules_scim_scim_la_SOURCES = \ +modules/ecore/immodules/scim/scim_module.cpp \ +modules/ecore/immodules/scim/scim_imcontext.cpp \ +modules/ecore/immodules/scim/scim_imcontext.h +modules_ecore_immodules_scim_scim_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_x \ +-I$(top_srcdir)/src/lib/ecore_imf \ +-I$(top_srcdir)/src/lib/ecore_evas \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_x \ +-I$(top_builddir)/src/lib/ecore_imf \ +-I$(top_builddir)/src/lib/ecore_evas \ +-DEFL_ECORE_IMF_EVAS_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@SCIM_CFLAGS@ +modules_ecore_immodules_scim_scim_la_LIBADD = \ +lib/ecore_imf/libecore_evas.la \ +lib/ecore_imf/libecore_imf.la \ +lib/ecore_x/libecore_x.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@SCIM_LIBS@ +modules_ecore_immodules_scim_scim_la_LDFLAGS = -no-undefined -module -avoid-version +modules_ecore_immodules_scim_scim_la_LIBTOOLFLAGS = --tag=disable-static +endif + +# Xim + +if BUILD_ECORE_IMF_XIM +ecoreimfximpkgdir = $(libdir)/ecore/immodules +ecoreimfximpkg_LTLIBRARIES = modules/ecore/immodules/xim/xim.la +modules_ecore_immodules_xim_xim_la_SOURCES = \ +modules/ecore/immodules/xim/ecore_imf_xim.c +modules_ecore_immodules_xim_xim_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_x \ +-I$(top_srcdir)/src/lib/ecore_imf \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_x \ +-I$(top_builddir)/src/lib/ecore_imf \ +-DEFL_ECORE_IMF_EVAS_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ +modules_ecore_immodules_xim_xim_la_LIBADD = \ +lib/ecore_imf/libecore_imf.la \ +lib/ecore_x/libecore_x.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la +modules_ecore_immodules_xim_xim_la_LDFLAGS = -no-undefined -module -avoid-version +modules_ecore_immodules_xim_xim_la_LIBTOOLFLAGS = --tag=disable-static +endif diff --git a/src/Makefile_Ecore_Input.am b/src/Makefile_Ecore_Input.am new file mode 100644 index 0000000000..29aa449f45 --- /dev/null +++ b/src/Makefile_Ecore_Input.am @@ -0,0 +1,70 @@ + +### Library + +lib_LTLIBRARIES += \ +lib/ecore_input/libecore_input.la \ +lib/ecore_input/libecore_input_evas.la + +installed_ecoreinputmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoreinputmainheaders_DATA = \ +lib/ecore_input/Ecore_Input.h + +lib_ecore_input_libecore_input_la_SOURCES = \ +lib/ecore_input/ecore_input.c \ +lib/ecore_input/ecore_input_compose.c \ +lib/ecore_input/ecore_input_compose.h \ +lib/ecore_input/ecore_input_private.h + +lib_ecore_input_libecore_input_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-DEFL_ECORE_INPUT_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_input_libecore_input_la_LIBADD = \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +lib_ecore_input_libecore_input_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ + +installed_ecoreinputevasmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoreinputevasmainheaders_DATA = \ +lib/ecore_input/Ecore_Input_Evas.h + +lib_ecore_input_libecore_input_evas_la_SOURCES = \ +lib/ecore_input/ecore_input_evas.c \ +lib/ecore_input/ecore_input_evas_private.h + +lib_ecore_input_libecore_input_evas_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/evas \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_input_evas \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/evas \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_input_evas \ +-DEFL_ECORE_INPUT_EVAS_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_input_libecore_input_evas_la_LIBADD = \ +lib/ecore_input/libecore_input.la \ +lib/ecore/libecore.la \ +lib/evas/libevas.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +lib_ecore_input_libecore_input_evas_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_Ipc.am b/src/Makefile_Ecore_Ipc.am new file mode 100644 index 0000000000..ba09f374b7 --- /dev/null +++ b/src/Makefile_Ecore_Ipc.am @@ -0,0 +1,37 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_ipc/libecore_ipc.la + +installed_ecoreipcmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoreipcmainheaders_DATA = \ +lib/ecore_ipc/Ecore_Ipc.h + +lib_ecore_ipc_libecore_ipc_la_SOURCES = \ +lib/ecore_ipc/ecore_ipc.c \ +lib/ecore_ipc/ecore_ipc_private.h + +lib_ecore_ipc_libecore_ipc_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_con \ +-I$(top_srcdir)/src/lib/ecore_ipc \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_con \ +-I$(top_builddir)/src/lib/ecore_ipc \ +-DEFL_ECORE_IPC_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_ipc_libecore_ipc_la_LIBADD = \ +lib/ecore_con/libecore_con.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +lib_ecore_ipc_libecore_ipc_la_LIBADD += @EFL_COV_LIBS@ -lm + +lib_ecore_ipc_libecore_ipc_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_Psl1ght.am b/src/Makefile_Ecore_Psl1ght.am new file mode 100644 index 0000000000..9ac146c63d --- /dev/null +++ b/src/Makefile_Ecore_Psl1ght.am @@ -0,0 +1,38 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_psl1ght/libecore_psl1ght.la + +installed_ecorepsl1ghtmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecorepsl1ghtmainheaders_DATA = \ +lib/ecore_psl1ght/Ecore_Psl1ght.h + +lib_ecore_psl1ght_libecore_psl1ght_la_SOURCES = \ +lib/ecore_psl1ght/ecore_psl1ght.c \ +lib/ecore_psl1ght/moveutil.c \ +lib/ecore_psl1ght/spursutil.c \ +lib/ecore_psl1ght/Ecore_Psl1ght_Keys.h \ +lib/ecore_psl1ght/ecore_psl1ght_private.h + +lib_ecore_psl1ght_libecore_psl1ght_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_psl1ght \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_psl1ght \ +-DEFL_ECORE_PSL1GHT_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_psl1ght_libecore_psl1ght_la_LIBADD = \ +lib/ecore_input/libecore_input.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la + +lib_ecore_psl1ght_libecore_psl1ght_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_SDL.am b/src/Makefile_Ecore_SDL.am new file mode 100644 index 0000000000..62e7a10266 --- /dev/null +++ b/src/Makefile_Ecore_SDL.am @@ -0,0 +1,38 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_sdl/libecore_sdl.la + +installed_ecoresdlmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecoresdlmainheaders_DATA = \ +lib/ecore_sdl/Ecore_Sdl.h + +lib_ecore_sdl_libecore_sdl_la_SOURCES = \ +lib/ecore_sdl/ecore_sdl.c \ +lib/ecore_sdl/Ecore_Sdl_Keys.h \ +lib/ecore_sdl/ecore_sdl_private.h + +lib_ecore_sdl_libecore_sdl_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_sdl \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_sdl \ +-DEFL_ECORE_SDL_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@ECORE_SDL_CFLAGS@ + +lib_ecore_sdl_libecore_sdl_la_LIBADD = \ +lib/ecore_input/libecore_input.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@ECORE_SDL_LIBS@ + +lib_ecore_sdl_libecore_sdl_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_Wayland.am b/src/Makefile_Ecore_Wayland.am new file mode 100644 index 0000000000..4923a1abf4 --- /dev/null +++ b/src/Makefile_Ecore_Wayland.am @@ -0,0 +1,40 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_wayland/libecore_wayland.la + +installed_ecorewaylandmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecorewaylandmainheaders_DATA = \ +lib/ecore_wayland/Ecore_Wayland.h + +lib_ecore_wayland_libecore_wayland_la_SOURCES = \ +lib/ecore_wayland/ecore_wayland.c \ +lib/ecore_wayland/ecore_wl_dnd.c \ +lib/ecore_wayland/ecore_wl_input.c \ +lib/ecore_wayland/ecore_wl_output.c \ +lib/ecore_wayland/ecore_wl_window.c \ +lib/ecore_wayland/ecore_wayland_private.h + +lib_ecore_wayland_libecore_wayland_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_wayland \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_wayland \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@ECORE_WAYLAND_CFLAGS@ + +lib_ecore_wayland_libecore_wayland_la_LIBADD = \ +lib/ecore/libecore_input.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@ECORE_WAYLAND_LIBS@ + +lib_ecore_wayland_libecore_wayland_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_Win32.am b/src/Makefile_Ecore_Win32.am new file mode 100644 index 0000000000..2491ca5aa7 --- /dev/null +++ b/src/Makefile_Ecore_Win32.am @@ -0,0 +1,51 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_win32/libecore_win32.la + +installed_ecorewin32mainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecorewin32mainheaders_DATA = \ +lib/ecore_win32/Ecore_Win32.h + +lib_ecore_win32_libecore_win32_la_SOURCES = \ +lib/ecore_win32/ecore_win32.c \ +lib/ecore_win32/ecore_win32_cursor.c \ +lib/ecore_win32/ecore_win32_dnd.c \ +lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp \ +lib/ecore_win32/ecore_win32_dnd_data_object.cpp \ +lib/ecore_win32/ecore_win32_dnd_drop_source.cpp \ +lib/ecore_win32/ecore_win32_dnd_drop_target.cpp \ +lib/ecore_win32/ecore_win32_event.c \ +lib/ecore_win32/ecore_win32_window.c \ +lib/ecore_win32/ecore_win32_private.h \ +lib/ecore_win32/ecore_win32_dnd_enumformatetc.h \ +lib/ecore_win32/ecore_win32_dnd_data_object.h \ +lib/ecore_win32/ecore_win32_dnd_drop_source.h \ +lib/ecore_win32/ecore_win32_dnd_drop_target.h + +lib_ecore_win32_libecore_win32_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/evil \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_win32 \ +-I$(top_builddir)/src/lib/evil \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_win32 \ +-DEFL_ECORE_WIN32_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_win32_libecore_win32_la_LIBADD = \ +lib/ecore_input/libecore_input.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +lib/evil/libevil.la \ +@ECORE_WIN32_LIBS@ + +lib_ecore_win32_libecore_win32_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_WinCE.am b/src/Makefile_Ecore_WinCE.am new file mode 100644 index 0000000000..29122ab8c0 --- /dev/null +++ b/src/Makefile_Ecore_WinCE.am @@ -0,0 +1,41 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_wince/libecore_wince.la + +installed_ecorewincemainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecorewincemainheaders_DATA = \ +lib/ecore_wince/Ecore_Wince.h + +lib_ecore_wince_libecore_wince_la_SOURCES = \ +lib/ecore_wince/ecore_wince.c \ +lib/ecore_wince/ecore_wince_event.c \ +lib/ecore_wince/ecore_wince_window.c \ +lib/ecore_wince/ecore_wince_private.h + +lib_ecore_wince_libecore_wince_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/evil \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_wince \ +-I$(top_builddir)/src/lib/evil \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_wince \ +-DEFL_ECORE_WINCE_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ + +lib_ecore_wince_libecore_wince_la_LIBADD = \ +lib/ecore_input/libecore_input.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +lib/evil/libevil.la \ +@ECORE_WINCE_LIBS@ + +lib_ecore_wince_libecore_wince_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ diff --git a/src/Makefile_Ecore_X.am b/src/Makefile_Ecore_X.am new file mode 100644 index 0000000000..cda857bd59 --- /dev/null +++ b/src/Makefile_Ecore_X.am @@ -0,0 +1,126 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_x/libecore_x.la + +installed_ecorexmainheadersdir = $(includedir)/ecore-@VMAJ@ +dist_installed_ecorexmainheaders_DATA = \ +lib/ecore_x/Ecore_X.h \ +lib/ecore_x/Ecore_X_Atoms.h \ +lib/ecore_x/Ecore_X_Cursor.h + +if HAVE_ECORE_X_XCB +lib_ecore_x_libecore_x_la_SOURCES = \ +lib/ecore_x/xcb/ecore_xcb.c \ +lib/ecore_x/xcb/ecore_xcb_atoms.c \ +lib/ecore_x/xcb/ecore_xcb_extensions.c \ +lib/ecore_x/xcb/ecore_xcb_shape.c \ +lib/ecore_x/xcb/ecore_xcb_screensaver.c \ +lib/ecore_x/xcb/ecore_xcb_sync.c \ +lib/ecore_x/xcb/ecore_xcb_render.c \ +lib/ecore_x/xcb/ecore_xcb_randr.c \ +lib/ecore_x/xcb/ecore_xcb_xfixes.c \ +lib/ecore_x/xcb/ecore_xcb_composite.c \ +lib/ecore_x/xcb/ecore_xcb_cursor.c \ +lib/ecore_x/xcb/ecore_xcb_damage.c \ +lib/ecore_x/xcb/ecore_xcb_dnd.c \ +lib/ecore_x/xcb/ecore_xcb_dpms.c \ +lib/ecore_x/xcb/ecore_xcb_drawable.c \ +lib/ecore_x/xcb/ecore_xcb_e.c \ +lib/ecore_x/xcb/ecore_xcb_gc.c \ +lib/ecore_x/xcb/ecore_xcb_image.c \ +lib/ecore_x/xcb/ecore_xcb_input.c \ +lib/ecore_x/xcb/ecore_xcb_gesture.c \ +lib/ecore_x/xcb/ecore_xcb_mwm.c \ +lib/ecore_x/xcb/ecore_xcb_pixmap.c \ +lib/ecore_x/xcb/ecore_xcb_region.c \ +lib/ecore_x/xcb/ecore_xcb_selection.c \ +lib/ecore_x/xcb/ecore_xcb_textlist.c \ +lib/ecore_x/xcb/ecore_xcb_events.c \ +lib/ecore_x/xcb/ecore_xcb_keymap.c \ +lib/ecore_x/xcb/ecore_xcb_netwm.c \ +lib/ecore_x/xcb/ecore_xcb_icccm.c \ +lib/ecore_x/xcb/ecore_xcb_window.c \ +lib/ecore_x/xcb/ecore_xcb_window_prop.c \ +lib/ecore_x/xcb/ecore_xcb_window_shape.c \ +lib/ecore_x/xcb/ecore_xcb_window_shadow.c \ +lib/ecore_x/xcb/ecore_xcb_xinerama.c \ +lib/ecore_x/xcb/ecore_xcb_error.c \ +lib/ecore_x/xcb/ecore_xcb_xtest.c \ +lib/ecore_x/xcb/ecore_xcb_vsync.c \ +lib/ecore_x/xcb/ecore_xcb_xdefaults.c \ +lib/ecore_x/xcb/ecore_xcb_private.h +else +lib_ecore_x_libecore_x_la_SOURCES = \ +lib/ecore_x/xlib/ecore_x.c \ +lib/ecore_x/xlib/ecore_x_dnd.c \ +lib/ecore_x/xlib/ecore_x_sync.c \ +lib/ecore_x/xlib/ecore_x_randr.c \ +lib/ecore_x/xlib/ecore_x_randr_11.c \ +lib/ecore_x/xlib/ecore_x_randr_12.c \ +lib/ecore_x/xlib/ecore_x_randr_12_edid.c \ +lib/ecore_x/xlib/ecore_x_randr_13.c \ +lib/ecore_x/xlib/ecore_x_fixes.c \ +lib/ecore_x/xlib/ecore_x_damage.c \ +lib/ecore_x/xlib/ecore_x_composite.c \ +lib/ecore_x/xlib/ecore_x_error.c \ +lib/ecore_x/xlib/ecore_x_events.c \ +lib/ecore_x/xlib/ecore_x_icccm.c \ +lib/ecore_x/xlib/ecore_x_netwm.c \ +lib/ecore_x/xlib/ecore_x_mwm.c \ +lib/ecore_x/xlib/ecore_x_e.c \ +lib/ecore_x/xlib/ecore_x_selection.c \ +lib/ecore_x/xlib/ecore_x_window.c \ +lib/ecore_x/xlib/ecore_x_window_prop.c \ +lib/ecore_x/xlib/ecore_x_window_shape.c \ +lib/ecore_x/xlib/ecore_x_pixmap.c \ +lib/ecore_x/xlib/ecore_x_gc.c \ +lib/ecore_x/xlib/ecore_x_xinerama.c \ +lib/ecore_x/xlib/ecore_x_screensaver.c \ +lib/ecore_x/xlib/ecore_x_dpms.c \ +lib/ecore_x/xlib/ecore_x_drawable.c \ +lib/ecore_x/xlib/ecore_x_cursor.c \ +lib/ecore_x/xlib/ecore_x_test.c \ +lib/ecore_x/xlib/ecore_x_atoms.c \ +lib/ecore_x/xlib/ecore_x_region.c \ +lib/ecore_x/xlib/ecore_x_image.c \ +lib/ecore_x/xlib/ecore_x_xi2.c \ +lib/ecore_x/xlib/ecore_x_vsync.c \ +lib/ecore_x/xlib/ecore_x_randr.h \ +lib/ecore_x/xlib/ecore_x_gesture.c \ +lib/ecore_x/xlib/ecore_x_private.h +endif + +lib_ecore_x_libecore_x_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_srcdir)/src/lib/ecore_x \ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore_x \ +-DEFL_ECORE_X_BUILD \ +@EFL_CFLAGS@ \ +@EFL_COV_CFLAGS@ \ +@ECORE_X_CFLAGS@ + +lib_ecore_x_libecore_x_la_LIBADD = \ +lib/ecore_input/libecore_input.la \ +lib/ecore/libecore.la \ +lib/eo/libeo.la \ +lib/eina/libeina.la \ +@ECORE_X_LIBS@ + +lib_ecore_x_libecore_x_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ + +### Utils + +noinst_PROGRAMS = utils/ecore/makekeys + +utils_ecore_makekeys_SOURCES = utils/ecore/makekeys.c + +EXTRA_DIST += utils/ecore/mkks.sh + diff --git a/src/Makefile_Escape.am b/src/Makefile_Escape.am new file mode 100644 index 0000000000..d237d184a2 --- /dev/null +++ b/src/Makefile_Escape.am @@ -0,0 +1,25 @@ + +### Library + +lib_LTLIBRARIES += lib/escape/libescape.la + +install_escapeheadersdir = $(includedir)/escape-@VMAJ@ +dist_install_escapeheaders_DATA = \ +lib/escape/Escape.h \ +lib/escape/escape_libgen.h \ +lib/escape/escape_unistd.h + +escapemmanheadersdir = $(includedir)/escape-@VMAJ@/sys +dist_escapemmanheaders_DATA = \ +lib/escape/sys/mman.h + +lib_escape_libescape_la_SOURCES = \ +lib/escape/escape_libgen.c \ +lib/escape/escape_mman.c \ +lib/escape/escape_unistd.c + +lib_escape_libescape_la_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/escape \ +-I$(top_builddir)/src/lib/escape +lib_escape_libescape_la_LIBADD = @ESCAPE_LIBS@ +lib_escape_libescape_la_LDFLAGS = -no-undefined -version-info @version_info@ diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 616c466b4e..62b86c0f14 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -439,70 +439,6 @@ modules_evas_engines_buffer_module_la_LIBTOOLFLAGS = --tag=disable-static endif endif -if BUILD_ENGINE_DIRECT3D -dist_installed_evasmainheaders_DATA += modules/evas/engines/direct3d/Evas_Engine_Direct3D.h -DIRECT3D_SOURCES = \ -modules/evas/engines/direct3d/evas_engine.c \ -modules/evas/engines/direct3d/evas_direct3d_context.cpp \ -modules/evas/engines/direct3d/evas_direct3d_device.cpp \ -modules/evas/engines/direct3d/evas_direct3d_image_cache.cpp \ -modules/evas/engines/direct3d/evas_direct3d_main.cpp \ -modules/evas/engines/direct3d/evas_direct3d_object.cpp \ -modules/evas/engines/direct3d/evas_direct3d_object_font.cpp \ -modules/evas/engines/direct3d/evas_direct3d_object_image.cpp \ -modules/evas/engines/direct3d/evas_direct3d_object_line.cpp \ -modules/evas/engines/direct3d/evas_direct3d_object_rect.cpp \ -modules/evas/engines/direct3d/evas_direct3d_scene.cpp \ -modules/evas/engines/direct3d/evas_direct3d_shader_pack.cpp \ -modules/evas/engines/direct3d/evas_direct3d_vertex_buffer_cache.cpp \ -modules/evas/engines/direct3d/array.h \ -modules/evas/engines/direct3d/evas_direct3d_context.h \ -modules/evas/engines/direct3d/evas_direct3d_device.h \ -modules/evas/engines/direct3d/evas_direct3d_image_cache.h \ -modules/evas/engines/direct3d/evas_direct3d_object.h \ -modules/evas/engines/direct3d/evas_direct3d_object_font.h \ -modules/evas/engines/direct3d/evas_direct3d_object_image.h \ -modules/evas/engines/direct3d/evas_direct3d_object_line.h \ -modules/evas/engines/direct3d/evas_direct3d_object_rect.h \ -modules/evas/engines/direct3d/evas_direct3d_scene.h \ -modules/evas/engines/direct3d/evas_direct3d_shader_pack.h \ -modules/evas/engines/direct3d/evas_direct3d_vertex_buffer_cache.h \ -modules/evas/engines/direct3d/evas_engine.h \ -modules/evas/engines/direct3d/ref.h -if EVAS_STATIC_BUILD_DIRECT3D -lib_evas_libevas_la_SOURCES += $(DIRECT3D_SOURCES) -lib_evas_libevas_la_CPPFLAGS += @evas_engine_direct3d_cflags@ -lib_evas_libevas_la_CXXFLAGS += -fno-rtti -fno-exceptions -lib_evas_libevas_la_LIBADD += @evas_engine_direct3d_libs@ -else -enginedirect3dpkgdir = $(libdir)/evas/modules/engines/direct3d/$(MODULE_ARCH) -enginedirect3dpkg_LTLIBRARIES = modules/evas/engines/direct3d/module.la -modules_evas_engines_direct3d_module_la_SOURCES = $(DIRECT3D_SOURCES) -modules_evas_engines_direct3d_module_la_CPPFLAGS = \ --I$(top_srcdir)/src/lib/eina \ --I$(top_builddir)/src/lib/eina \ --I$(top_srcdir)/src/lib/eo \ --I$(top_builddir)/src/lib/eo \ --I$(top_srcdir)/src/lib/evas \ --I$(top_builddir)/src/lib/evas \ --I$(top_srcdir)/src/lib/evas/include \ --I$(top_builddir)/src/lib/evas/include \ --I$(top_srcdir)/src/lib/evas/cserve2 \ --I$(top_builddir)/src/lib/evas/cserve2 \ --DEFL_EVAS_BUILD \ -@evas_engine_direct3d_cflags@ \ -@EFL_CFLAGS@ \ -@EVAS_CFLAGS@ -modules_evas_engines_direct3d_module_la_CXXFLAGS = -fno-rtti -fno-exceptions -modules_evas_engines_direct3d_module_la_LIBADD = \ -lib/evas/libevas.la \ -@EFL_LIBS@ \ -@evas_engine_direct3d_libs@ -modules_evas_engines_direct3d_module_la_LDFLAGS = -no-undefined -module -avoid-version -modules_evas_engines_direct3d_module_la_LIBTOOLFLAGS = --tag=disable-static -endif -endif - if BUILD_ENGINE_DIRECTFB dist_installed_evasmainheaders_DATA += modules/evas/engines/directfb/Evas_Engine_DirectFB.h DIRECTFB_SOURCES = \ diff --git a/src/lib/ecore/Ecore.h b/src/lib/ecore/Ecore.h new file mode 100644 index 0000000000..5a02211526 --- /dev/null +++ b/src/lib/ecore/Ecore.h @@ -0,0 +1,2954 @@ +/** + @brief Ecore Library Public API Calls + + These routines are used for Ecore Library interaction + */ + +/** + + @mainpage Ecore + + @version 1.7 + @date 2000-2012 + + Please see the @ref authors page for contact details. + + @section intro Introduction + + Ecore is a library of convenience functions. A brief explanation of how to use + it can be found in @ref Ecore_Main_Loop_Page. + + The Ecore library provides the following modules: + @li @ref Ecore_Main_Loop_Group + @li @ref Ecore_File_Group + @li @ref Ecore_Con_Group + @li @ref Ecore_Evas_Group + @li @ref Ecore_FB_Group + @li @ref Ecore_IMF_Lib_Group + @li @ref Ecore_IMF_Context_Group + @li @ref Ecore_IMF_Context_Module_Group + @li @ref Ecore_IMF_Evas_Group + @li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink + @li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink + @li @ref Ecore_Win32_Group + @li @ref Ecore_WinCE_Group + + For more info on Ecore usage, there are these @ref Examples. + + @section compiling How to compile using Ecore? + pkgconfig (.pc) files are installed for every ecore module. + Thus, to compile using any of them, you can use something like the following: + +@verbatim +gcc *.c $(pkg-config ecore ecore-$x ecore-$y [...] --cflags --libs) +@endverbatim + + @section install How is it installed? + + Suggested configure options for ecore for a Linux desktop X display + with OpenGL and Software support, communication (networking) and + IPC (inter process communication): + +@verbatim +./configure \ + --enable-ecore-con \ + --enable-ecore-ipc \ + --enable-ecore-file \ + --enable-ecore-input \ + --enable-ecore-input-evas \ + --enable-ecore-x \ + --enable-ecore-evas \ + --enable-ecore-evas-software-buffer \ + --enable-ecore-evas-software-x11 \ + --enable-ecore-evas-opengl-x11 +make +sudo make install +@endverbatim + + */ + +/** + @page authors Authors + @author Carsten Haitzler + @author Tom Gilbert + @author Burra + @author Chris Ross + @author Term + @author Tilman Sauerbeck + @author Ibukun Olumuyiwa + @author Yuri + @author Nicholas Curran + @author Howell Tam + @author Nathan Ingersoll + @author Andrew Elcock + @author Kim Woelders + @author Sebastian Dransfeld + @author Simon Poole + @author Jorge Luis Zapata Muga + @author dan sinclair + @author Michael 'Mickey' Lauer + @author David 'onefang' Seikel + @author Hisham 'CodeWarrior' Mardam Bey + @author Brian 'rephorm' Mattern + @author Tim Horton + @author Arnaud de Turckheim 'quarium' + @author Matt Barclay + @author Peter Wehrfritz + @author Albin "Lutin" Tonnerre + @author Vincent Torri + @author Lars Munch + @author Andre Dieb + @author Mathieu Taillefumier + @author Rui Miguel Silva Seabra + @author Samsung Electronics + @author Samsung SAIT + @author Nicolas Aguirre + @author Brett Nash + @author Mike Blumenkrantz + @author Leif Middelschulte + @author Mike McCormack + @author Sangho Park + @author Jihoon Kim + @author PnB + @author Daniel Juyung Seo + @author Christopher 'devilhorns' Michael + @author ChunEon Park + @author xlopez@igalia.com + @author Rafael Antognolli + @author Kim Yunhan + @author Youness Alaoui + @author Bluezery + @author Doyoun Kang + @author Haifeng Deng + @author Jérémy Zurcher + @author Vikram Narayanan + + Please contact to get in + contact with the developers and maintainers. + */ + +/** + * @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 from embedded systems all the way up to large and + * powerful multi-cpu workstations. The main loop has a number of primitives to + * be used with its main loop. It serializes all the primitives and allows for + * great responsiveness without the need for threads(or any other concurrency). + * + * @subsection timers Timers + * + * Timers serve two main purposes: doing something at a specified time and + * repeatedly doing something with a set interval. + * @see Ecore_Timer_Group + * + * @subsection pollers Pollers + * + * Pollers allow for polling to be centralized into a single place therefore + * alleviating the need for different parts of the program to wake up at + * different times to do polling, thereby making the code simpler and more + * efficient. + * @see Ecore_Poller_Group + * + * @subsection idler Idlers + * + * There are three types of idlers, enterers, idlers(proper) and exiters, they + * are called, respectively, when the program is about to enter an idle state, + * when the program is idle and when the program is leaving an idle state. Idler + * enterers are usually a good place to update the program state. Proper idlers + * are the appropriate place to do heavy computational tasks thereby using what + * would otherwise be wasted CPU cycles. Exiters are the perfect place to do + * anything your program should do just before processing events(also timers, + * poolers, file descriptor handlers and animators) + * @see Ecore_Idle_Group + * + * @subsection fd_handler File descriptor handlers + * + * File descriptor handlers allow you to monitor when there is data available to + * read on file descriptors, when writing will not block or if there was an + * error. Any valid file descriptor can be used with this API, regardless of if + * was gotten with an OS specific API or from ecore. + * @see Ecore_FD_Handler_Group + * + * @subsection animators Animators + * + * Ecore provides a facility called animators, so named since the intended use + * was in animations, that facilitates knowing what percentage of a given + * interval has elapsed. This is perfect for performing animations, but is not + * limited to that use, it can, for example, also be used to create a progress + * bar. + * @see Ecore_Animator_Group + * + * @subsection ev_handlers Event handlers + * + * Event handlers are, arguably, the most important feature of the ecore main + * loop, they are what allows the programmer to easily handle user interaction. + * Events however are not only things the user does, events can represent + * anything for which a type is created. + * @see Ecore_Event_Group + * + * All of these primitives are discussed in more detail in their respective + * pages linked above. + * + * Here is a diagram of the main loop flow of a simple program: + * + * @image html prog_flow.png + * @image latex prog_flow.eps width=\textwidth + * + * + * + * @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 + * + * 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 doesn'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_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 abstraction + 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 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. + */ + +#ifndef _ECORE_H +#define _ECORE_H + +#ifdef _MSC_VER +# include +#endif + +#include + +/* This include has been added to support Eo in Ecore */ +#include + +#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 */ + +#ifdef _WIN32 +# include +#elif defined (__FreeBSD__) || defined (__OpenBSD__) +# include +# include +#elif defined (__ANDROID__) +# include +#else +# include +# if !defined (EXOTIC_NO_SIGNAL) +# include +# endif +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Ecore_Init_Group Ecore initialization, shutdown functions and reset on fork. + * + * @{ + */ + +EAPI int ecore_init(void); +EAPI int ecore_shutdown(void); +/** + * @} + */ + +/** + * @defgroup Ecore_Main_Loop_Group Ecore main loop + * + * This group discusses functions that are acting on Ecore's main loop itself or + * on events and infrastructure directly linked to it. Most programs only need + * to start and end the main loop, the rest of the function discussed here are + * meant to be used in special situations, and with great care. + * + * For details on the usage of ecore's main loop and how it interacts with other + * ecore facilities see: @ref Ecore_Main_Loop_Page. + * + * @{ + */ + +#define ECORE_VERSION_MAJOR 1 +#define ECORE_VERSION_MINOR 8 + +typedef struct _Ecore_Version +{ + int major; + int minor; + int micro; + int revision; +} Ecore_Version; + +EAPI extern Ecore_Version *ecore_version; + +#define ECORE_CALLBACK_CANCEL EINA_FALSE /**< Return value to remove a callback */ +#define ECORE_CALLBACK_RENEW EINA_TRUE /**< Return value to keep a callback */ + +#define ECORE_CALLBACK_PASS_ON EINA_TRUE /**< Return value to pass event to next handler */ +#define ECORE_CALLBACK_DONE EINA_FALSE /**< Return value to stop event handling */ + +/** + * @typedef Ecore_Task_Cb Ecore_Task_Cb + * A callback run for a task (timer, idler, poller, animator, etc) + */ +typedef Eina_Bool (*Ecore_Task_Cb)(void *data); + +/** + * @typedef Ecore_Select_Function + * A function which can be used to replace select() in the main loop + */ +typedef int (*Ecore_Select_Function)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); + +EAPI void ecore_main_loop_iterate(void); + +EAPI void ecore_main_loop_select_func_set(Ecore_Select_Function func); +EAPI Ecore_Select_Function 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); + +/** + * @typedef Ecore_Cb Ecore_Cb + * A generic callback called as a hook when a certain point in + * execution is reached. + */ +typedef void (*Ecore_Cb)(void *data); + +/** + * @typedef Ecore_Data_Cb Ecore_Data_Cb + * A callback which is used to return data to the main function + */ +typedef void *(*Ecore_Data_Cb)(void *data); + +/** + * Add a function to be called by ecore_fork_reset() + * + * This queues @p func to be called (and passed @p data as its argument) when + * ecore_fork_reset() is called. This allows other libraries and subsystems + * to also reset their internal state after a fork. + * + * @since 1.7 + */ +EAPI Eina_Bool ecore_fork_reset_callback_add(Ecore_Cb func, const void *data); + +/** + * This removes the callback specified + * + * This deletes the callback added by ecore_fork_reset_callback_add() using + * the function and data pointer to specify which to remove. + * + * @since 1.7 + */ +EAPI Eina_Bool ecore_fork_reset_callback_del(Ecore_Cb func, const void *data); + +/** + * Reset the ecore internal state after a fork + * + * Ecore maintains internal data that can be affected by the fork() system call + * which creates a duplicate of the current process. This also duplicates + * file descriptors which is problematic in that these file descriptors still + * point to their original sources. This function makes ecore reset internal + * state (e.g. pipes used for signalling between threads) so they function + * correctly afterwards. + * + * It is highly suggested that you call this function after any fork() + * system call inside the child process if you intend to use ecore features + * after this point and not call any exec() family functions. Not doing so + * will cause possible misbehaviour. + * + * @since 1.7 + */ +EAPI void ecore_fork_reset(void); + +/** + * @brief Call callback asynchronously in the main loop. + * @since 1.1.0 + * + * @param callback The callback to call in the main loop + * @param data The data to give to that call back + * + * For all calls that need to happen in the main loop (most EFL functions do), + * this helper function provides the infrastructure needed to do it safely + * by avoiding dead lock, race condition and properly wake up the main loop. + * + * Remember after that function call, you should never touch again the @p data + * in the thread, it is owned by the main loop and your callback should take + * care of freeing it if necessary. + */ +EAPI void ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, void *data); + +/** + * @brief Call callback synchronously in the main loop. + * @since 1.1.0 + * + * @param callback The callback to call in the main loop + * @param data The data to give to that call back + * @return the value returned by the callback in the main loop + * + * For all calls that need to happen in the main loop (most EFL functions do), + * this helper function provides the infrastructure needed to do it safely + * by avoiding dead lock, race condition and properly wake up the main loop. + * + * Remember this function will block until the callback is executed in the + * main loop. It can take time and you have no guaranty about the timeline. + */ +EAPI void *ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, void *data); + +/** + * @brief This function suspend the main loop in a know state + * @since 1.1.0 + * + * @result the number of time ecore_thread_main_loop_begin() has been called + * in this thread, if the main loop was suspended correctly. If not, it return @c -1. + * + * This function suspend the main loop in a know state, this let you + * use any EFL call you want after it return. Be carefully, the main loop + * is blocked until you call ecore_thread_main_loop_end(). This is + * the only sane way to achieve pseudo thread safety. + * + * Notice that until the main loop is blocked, the thread is blocked + * and their is noway around that. + * + * We still advise you, when possible, to use ecore_main_loop_thread_safe_call_async() + * as it will not block the thread nor the main loop. + */ +EAPI int ecore_thread_main_loop_begin(void); + +/** + * @brief Unlock the main loop. + * @since 1.1.0 + * + * @result the number of time ecore_thread_main_loop_end() need to be called before + * the main loop is unlocked again. @c -1 will be returned if you are trying to unlock + * when there wasn't enough call to ecore_thread_main_loop_begin(). + * + * After a call to ecore_thread_main_loop_begin(), you need to absolutely + * call ecore_thread_main_loop_end(), or you application will stay frozen. + */ +EAPI int ecore_thread_main_loop_end(void); + +/** + * @} + */ + +/** + * @defgroup Ecore_Event_Group Ecore Event functions + * + * Ecore events provide two main features that are of use to those using ecore: + * creating events and being notified of events. Those two will usually be used + * in different contexts, creating events is mainly done by libraries wrapping + * some system functionality while being notified of events is mainly a + * necessity of applications. + * + * For a program to be notified of events it's interested in it needs to have a + * function to process the event and to register that function as the callback + * to the event, that's all: + * @code + * ecore_event_handler_add(EVENT_TYPE, _my_event_handler, some_data); + * ... + * static Eina_Bool + * _my_event_handler(void *data, int type, void *event) + * { + * //data is some_data + * //event is provided by whoever created the event + * //Do really cool stuff with event + * } + * @endcode + * + * One very important thing to note here is the @c EVENT_TYPE, to register a + * handler for an event you must know its type before hand. Ecore provides + * the following events which are emitted in response to POSIX + * signals(https://en.wikipedia.org/wiki/Signal_%28computing%29): + * @li @b ECORE_EVENT_SIGNAL_USER + * @li @b ECORE_EVENT_SIGNAL_HUP + * @li @b ECORE_EVENT_SIGNAL_POWER + * @li @b ECORE_EVENT_SIGNAL_EXIT + * + * @warning Don't override these using the @c signal or @c sigaction calls. + * These, however, aren't the only signals one can handle. Many + * libraries(including ecore modules) have their own signals that can be + * listened for and handled, to do that one only needs to know the type of the + * event. This information can be found on the documentation of the library + * emitting the signal, so, for example, for events related to windowing one + * would look in @ref Ecore_Evas_Group. + * + * Examples of libraries that integrate into ecore's main loop by providing + * events are @ref Ecore_Con_Group, @ref Ecore_Evas_Group and @ref + * Ecore_Exe_Group, amongst others. This usage can be divided into two parts, + * setup and adding events. The setup is very simple, all that needs doing is + * getting a type id for the event: + * @code + * int MY_EV_TYPE = ecore_event_type_new(); + * @endcode + * @note This variable should be declared in the header since it'll be needed by + * anyone wishing to register a handler to your event. + * + * The complexity of adding of an event to the queue depends on whether that + * event sends uses @c event, if it doesn't it a one-liner: + * @code + * ecore_event_add(MY_EV_TYPE, NULL, NULL, NULL); + * @endcode + * The usage when an @c event is needed is not that much more complex and can be + * seen in @ref ecore_event_add. + * + * Examples that deals with events: + * @li @ref ecore_event_example_01_c + * @li @ref ecore_event_example_02_c + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +#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 + +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_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 Ecore_Filter_Cb + * A callback used for filtering events from the main loop. + */ +typedef Eina_Bool (*Ecore_Filter_Cb)(void *data, void *loop_data, int type, void *event); + +/** + * @typedef Ecore_End_Cb Ecore_End_Cb + * This is the callback which is called at the end of a function, + * usually for cleanup purposes. + */ +typedef void (*Ecore_End_Cb)(void *user_data, void *func_data); + +/** + * @typedef Ecore_Event_Handler_Cb Ecore_Event_Handler_Cb + * A callback used by the main loop to handle events of a specified + * type. + */ +typedef Eina_Bool (*Ecore_Event_Handler_Cb)(void *data, int type, void *event); + +struct _Ecore_Event_Signal_User /** User signal event */ +{ + int number; /**< The signal number. Either 1 or 2 */ + void *ext_data; /**< Extension data - not used */ + +#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) + siginfo_t data; /**< Signal info */ +#endif +}; + +struct _Ecore_Event_Signal_Hup /** Hup signal event */ +{ + void *ext_data; /**< Extension data - not used */ + +#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) + siginfo_t data; /**< Signal info */ +#endif +}; + +struct _Ecore_Event_Signal_Exit /** Exit request event */ +{ + Eina_Bool interrupt : 1; /**< Set if the exit request was an interrupt signal*/ + Eina_Bool quit : 1; /**< set if the exit request was a quit signal */ + Eina_Bool terminate : 1; /**< Set if the exit request was a terminate signal */ + void *ext_data; /**< Extension data - not used */ + +#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) + siginfo_t data; /**< Signal info */ +#endif +}; + +struct _Ecore_Event_Signal_Power /** Power event */ +{ + void *ext_data; /**< Extension data - not used */ + +#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) + siginfo_t data; /**< Signal info */ +#endif +}; + +struct _Ecore_Event_Signal_Realtime /** Realtime event */ +{ + int num; /**< The realtime signal's number */ + +#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) + siginfo_t data; /**< Signal info */ +#endif +}; + +/** + * @brief 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 @c 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_PASS_ON), It will keep being called as per normal, for + * each handler set up for that event type. If it returns 0 (or + * ECORE_CALLBACK_DONE), 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, Ecore_Event_Handler_Cb func, const void *data); +/** + * @brief 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 @c 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); +/** + * @brief Add an event to the event queue. + * @param type The event type to add to the end of the event queue + * @param ev The data structure passed as @c event to event handlers + * @param func_free The function to be called to free @a ev + * @param data The data pointer to be passed to the free function + * @return A Handle for that event on success, otherwise NULL + * + * If it succeeds, an event of type @a type will be added to the queue for + * processing by event handlers added by ecore_event_handler_add(). The @a ev + * parameter will be passed as the @c event parameter of the handler. When the + * event is no longer needed, @a func_free will be called and passed @a ev for + * cleaning up. If @p func_free is NULL, free() will be called with the private + * structure pointer. + */ +EAPI Ecore_Event *ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data); +/** + * @brief 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 parameter 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); +/** + * @brief Get the data associated with an #Ecore_Event_Handler + * @param eh The event handler + * @return The data + * + * This function returns the data previously associated with @p eh by + * ecore_event_handler_add(). + */ +EAPI void *ecore_event_handler_data_get(Ecore_Event_Handler *eh); +/** + * @brief Set the data associated with an #Ecore_Event_Handler + * @param eh The event handler + * @param data The data to associate + * @return The previous data + * + * This function sets @p data to @p eh and returns the old data pointer + * which was previously associated with @p eh by ecore_event_handler_add(). + */ +EAPI void *ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data); +/** + * @brief 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); +/** + * @brief 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 queue has been filtered + * @param data Data to pass to the filter functions + * @return A filter handle on success, @c NULL otherwise. + * + * Adds a callback to filter events from the event queue. Filters are called on + * the queue just before Event handler processing to try and remove redundant + * events. Just as processing is about to start @a func_start is called and + * passed the @a data pointer, the return value of this functions is passed to + * @a func_filter as loop_data. @a func_filter is also passed @a data and the + * event type and event structure. If this @a func_filter returns + * @c EINA_FALSE, the event is removed from the queue, if it returns + * @c EINA_TRUE, the event is kept. When processing is finished @p func_end is + * called and is passed the loop_data(returned by @c func_start) and @p data + * pointer to clean up. + */ +EAPI Ecore_Event_Filter *ecore_event_filter_add(Ecore_Data_Cb func_start, Ecore_Filter_Cb func_filter, Ecore_End_Cb func_end, const void *data); +/** + * @brief Delete an event filter. + * @param ef The event filter handle + * @return The data set for the filter on success, @c NULL otherwise. + * + * Delete a filter that has been added by its @p ef handle. + */ +EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef); +/** + * @brief Return the current event type being handled. + * @return The current event type being handled if inside a handler callback, + * ECORE_EVENT_NONE otherwise + * + * If the program is currently inside an Ecore event handler callback this + * will return the type of the current event being processed. + * + * 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); +/** + * @brief Return the current event type pointer handled. + * @return The current event pointer being handled if inside a handler callback, + * @c NULL otherwise. + * + * If the program is currently inside an Ecore event handler callback this + * will return the pointer of the current event being processed. + * + * 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); + +/** + * @} + */ + +/** + * @defgroup Ecore_Exe_Group Process Spawning Functions + * + * This module is responsible for managing portable processes using Ecore. + * With this module you're able to spawn processes and you also can pause, + * quit your spawned processes. + * An interaction between your process and those spawned is possible + * using pipes or signals. + * + * Example + * @li @ref Ecore_exe_simple_example_c + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +/** Inherit priority from parent process */ +#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 consistent 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_Exe_Flags + * Flags for executing a child with its stdin and/or stdout piped back. + */ +enum _Ecore_Exe_Flags /* flags for executing a child with its stdin and/or stdout piped back */ +{ + ECORE_EXE_NONE = 0, /**< No exe flags at all */ + 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 split 1 line per Ecore_Exe_Event_Data_Line */ + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16, /**< Errors are buffered until a newline and split 1 line per Ecore_Exe_Event_Data_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 */ + ECORE_EXE_TERM_WITH_PARENT = 512 /**< Makes child receive SIGTERM when parent dies. */ +}; +typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags; + +/** + * @enum _Ecore_Exe_Win32_Priority + * Defines the priority of the proccess. + */ +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; + +typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */ + +/** + * @typedef Ecore_Exe_Cb Ecore_Exe_Cb + * A callback to run with the associated @ref Ecore_Exe, usually + * for cleanup purposes. + */ +typedef void (*Ecore_Exe_Cb)(void *data, const Ecore_Exe *exe); + +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 */ + +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 @c NULL if not found */ + int exit_signal; /** < The signal that caused the process to exit */ + Eina_Bool exited : 1; /** < set to 1 if the process exited of its own accord */ + Eina_Bool signalled : 1; /** < set to 1 id the process exited due to uncaught signal */ + void *ext_data; /**< Extension data - not used */ +#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL) + siginfo_t data; /**< Signal info */ +#endif +}; + +struct _Ecore_Exe_Event_Data_Line /**< Lines from a child process */ +{ + char *line; /**< The bytes of a line of buffered data */ + int size; /**< The size of the line buffer in bytes */ +}; + +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 received */ + 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 @c NULL */ +}; + +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, Ecore_Exe_Cb func); +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 void *ecore_exe_data_set(Ecore_Exe *exe, void *data); +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); + +/** + * @} + */ + +/** + * @defgroup Ecore_FD_Handler_Group File Descriptor Handling Functions + * + * @brief Functions that deal with file descriptor handlers. + * + * File descriptor handlers facilitate reading, writing and checking for errors + * without blocking the program or doing expensive pooling. This can be used to + * monitor a socket, pipe, or other stream for which an FD can be had. + * + * @warning File descriptor handlers can't be used to monitor for file creation, + * modification or deletion, see @ref Ecore_File_Group for this. + * + * One common FD to be monitored is the standard input(stdin), monitoring it for + * reading requires a single call: + * @code + * static Eina_Bool + * _my_cb_func(void *data, Ecore_Fd_Handler *handler) + * { + * char c; + * scanf("%c", &c); //Guaranteed not to block + * ... do stuff with c ... + * } + * ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ, _my_cb_func, NULL, NULL, NULL); + * @endcode + * + * When using a socket, pipe or other stream it's important to remember that + * errors may occur and as such to monitor not only for reading/writing but also + * for errors using the @ref ECORE_FD_ERROR flag. + * + * Example of use of a file descriptor handler: + * @li @ref ecore_fd_handler_example_c + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; /**< A handle for Fd handlers */ + +/** + * @enum _Ecore_Fd_Handler_Flags + * What to monitor the file descriptor for: reading, writing or error. + */ +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; + +/** + * @typedef Ecore_Fd_Cb Ecore_Fd_Cb + * A callback used by an @ref Ecore_Fd_Handler. + */ +typedef Eina_Bool (*Ecore_Fd_Cb)(void *data, Ecore_Fd_Handler *fd_handler); + +/** + * @typedef Ecore_Fd_Prep_Cb Ecore_Fd_Prep_Cb + * A callback used by an @ref Ecore_Fd_Handler. + */ +typedef void (*Ecore_Fd_Prep_Cb)(void *data, Ecore_Fd_Handler *fd_handler); + +/** + * @typedef Ecore_Win32_Handle_Cb Ecore_Win32_Handle_Cb + * A callback used by an @ref Ecore_Win32_Handler. + */ +typedef Eina_Bool (*Ecore_Win32_Handle_Cb)(void *data, Ecore_Win32_Handler *wh); + +/** + * @brief Adds a callback for activity on the given file descriptor. + * + * @param fd The file descriptor to watch. + * @param flags To monitor it for reading use @c ECORE_FD_READ, for writing @c + * ECORE_FD_WRITE, and for error @c ECORE_FD_ERROR. Values by |(ored). + * @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. May be @c NULL. + * @param buf_data The data to pass to the @p buf_func function. + * @return A fd handler handle on success, @c NULL otherwise. + * + * @a func will be called during the execution of @ref Ecore_Main_Loop_Page + * when the file descriptor is available for reading, writing, or there has been + * an error(depending on the given @a flags). + * + * When @a func returns ECORE_CALLBACK_CANCEL, it indicates that the + * handler should be marked for deletion (identical to calling @ref + * ecore_main_fd_handler_del). + * + * @warning @a buf_func is meant for @b internal use only and should be @b + * avoided. + * + * The return value of @a buf_func has a different meaning, when it returns + * ECORE_CALLBACK_CANCEL, it indicates that @a func @b shouldn't be called, and + * when it returns ECORE_CALLBACK_RENEW it indicates @a func should be called. + * The return value of @a buf_func will not cause the FD handler to be deleted. + * + * @a 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 @a buf_func. This is a + * most annoying hack, only ecore_x uses it, so refer to that for an example. + * + * @warning This function should @b not be used for monitoring "normal" files, like text files. + * + */ +EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, Ecore_Fd_Cb buf_func, const void *buf_data); + +/** + * @brief Adds a callback for activity on the given file descriptor. + * + * @param fd The file descriptor to watch. + * @param flags To monitor it for reading use @c ECORE_FD_READ, for writing @c + * ECORE_FD_WRITE, and for error @c ECORE_FD_ERROR. Values by |(ored). + * @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. May be @c NULL. + * @param buf_data The data to pass to the @p buf_func function. + * @return A fd handler handle on success, @c NULL otherwise. + * + * This function is identical to ecore_main_fd_handler_add, except that it supports regular files. + * @warning This function should ONLY be called with ECORE_FD_ERROR, otherwise it will call the fd + * handler constantly. + * @warning Do not use this function unless you know what you are doing. + * + * @since 1.7 + */ +EAPI Ecore_Fd_Handler *ecore_main_fd_handler_file_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, Ecore_Fd_Cb buf_func, const void *buf_data); + +/** + * @brief Set the prepare callback with data for a given #Ecore_Fd_Handler + * + * @param fd_handler The fd handler + * @param func The prep function + * @param data The data to pass to the prep function + * + * This function will be called prior to any fd handler's callback function + * (even the other fd handlers), before entering the main loop select function. + * + * @note Once a prepare callback is set for a fd handler, it cannot be changed. + * You need to delete the fd handler and create a new one, to set another + * callback. + * @note You probably don't need this function. It is only necessary for very + * uncommon cases that need special behavior. + */ +EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data); +/** + * @brief Marks an FD handler for deletion. + * @param fd_handler The FD handler. + * @return The data pointer set using @ref ecore_main_fd_handler_add, for + * @a fd_handler on success, @c NULL otherwise. + * This function marks an fd handler to be deleted during an iteration of the + * main loop. It does NOT close the associated fd! + * + * @warning If the underlying fd is already closed ecore may complain if the + * main loop is using epoll internally, and also in some rare cases this may + * cause crashes and instability. Remember to delete your fd handlers before the + * fds they listen to are closed. + */ +EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); +/** + * @brief 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. + */ +EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler); +/** + * @brief Gets which flags are active on an 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 EINA_TRUE if any of the given flags are active, @c EINA_FALSE + * otherwise. + */ +EAPI Eina_Bool ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); +/** + * @brief 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. + */ +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, Ecore_Win32_Handle_Cb func, const void *data); +EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler); + +/** + * @} + */ + +/** + * @defgroup Ecore_Poller_Group Ecore Poll functions + * + * Ecore poller provides infrastructure for the creation of pollers. Pollers + * are, in essence, callbacks that share a single timer per type. Because not + * all pollers need to be called at the same frequency the user may specify the + * frequency in ticks(each expiration of the shared timer is called a tick, in + * ecore poller parlance) for each added poller. Ecore pollers should only be + * used when the poller doesn't have specific requirements on the exact times + * to poll. + * + * This architecture means that the main loop is only woken up once to handle + * all pollers of that type, 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 in situations where power usage is a concern. + * + * For now only 1 core poller type is supported: ECORE_POLLER_CORE, the default + * interval for ECORE_POLLER_CORE is 0.125(or 1/8th) second. + * + * The creation of a poller is extremely simple and only requires one line: + * @code + * ecore_poller_add(ECORE_POLLER_CORE, 1, my_poller_function, NULL); + * @endcode + * This sample creates a poller to call @c my_poller_function at every tick with + * @c NULL as data. + * + * Example: + * @li @ref ecore_poller_example_c + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +/** + * @enum _Ecore_Poller_Type + * Defines the frequency of ticks for the poller. + */ +enum _Ecore_Poller_Type /* Poller types */ +{ + ECORE_POLLER_CORE = 0 /**< The core poller interval */ +}; +typedef enum _Ecore_Poller_Type Ecore_Poller_Type; + +/* + * @since 1.8 + */ + +typedef Eo Ecore_Poller; /**< A handle for pollers */ + +#define ECORE_POLLER_CLASS ecore_poller_class_get() +const Eo_Class *ecore_poller_class_get(void) EINA_CONST; +extern EAPI Eo_Op ECORE_POLLER_BASE_ID; + +enum +{ + ECORE_POLLER_SUB_ID_CONSTRUCTOR, + ECORE_POLLER_SUB_ID_INTERVAL_SET, + ECORE_POLLER_SUB_ID_INTERVAL_GET, + ECORE_POLLER_SUB_ID_LAST, +}; + +#define ECORE_POLLER_ID(sub_id) (ECORE_POLLER_BASE_ID + sub_id) + +/** + * @def ecore_poller_constructor + * @since 1.8 + * + * Contructor with parameters for Ecore Poller. + * + * @param[in] type + * @param[in] interval + * @param[in] func + * @param[in] data + * + */ +#define ecore_poller_constructor(type, interval, func, data) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Poller_Type, type), EO_TYPECHECK(int, interval), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * @def ecore_poller_interval_set + * @since 1.8 + * + * Changes the polling interval rate of poller. + * + * @param[in] interval + * @param[out] ret + * + * @see ecore_poller_poller_interval_set + */ +#define ecore_poller_interval_set(interval, ret) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_SET), EO_TYPECHECK(int, interval), EO_TYPECHECK(Eina_Bool *, ret) + +/** + * @def ecore_poller_interval_get + * @since 1.8 + * + * Gets the polling interval rate of poller. + * + * @param[out] ret + * + * @see ecore_poller_poller_interval_get + */ +#define ecore_poller_interval_get(ret) ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_GET), EO_TYPECHECK(int *, ret) + + +/** + * @brief Sets the time(in seconds) between ticks for the given poller type. + * @param type The poller type to adjust. + * @param poll_time The time(in seconds) between ticks of the timer. + * + * This will adjust the time between ticks of the given timer 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, double poll_time); +/** + * @brief Gets the time(in seconds) between ticks for the given poller type. + * @param type The poller type to query. + * @return The time in seconds between ticks of the poller timer. + * + * This will get the time between ticks of the specified poller timer. + */ +EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type); +/** + * @brief Changes the polling interval rate of @p poller. + * @param poller The Ecore_Poller to change the interval of. + * @param interval The tick interval to set; must be a power of 2 and <= 32768. + * @return Returns true on success, false on failure. + * + * This allows the changing of a poller's polling interval. It is useful when + * you want to alter a poll rate without deleting and re-creating a poller. + */ +EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval); +/** + * @brief Gets the polling interval rate of @p poller. + * @param poller The Ecore_Poller to change the interval of. + * @return Returns the interval, in ticks, that @p poller polls at. + * + * This returns a poller's polling interval, or 0 on error. + */ +EAPI int ecore_poller_poller_interval_get(Ecore_Poller *poller); +/** + * @brief Creates a poller to call the given function at a particular tick interval. + * @param type The ticker type to attach the poller to. Must be ECORE_POLLER_CORE. + * @param interval The poll interval. + * @param func The poller function. + * @param data Data to pass to @a func when it is called. + * @return A poller object on success, @c NULL otherwise. + * + * This function adds @a func as a poller callback that will be called every @a + * interval ticks together with other pollers of type @a type. @a func will be + * passed the @p data pointer as a parameter. + * + * The @p interval must be between 1 and 32768 inclusive, and must be a power of + * 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768). The exact tick in which @a func + * will be called is undefined, as only the interval between calls can be + * defined. Ecore will endeavor to keep pollers synchronized and to call as + * many in 1 wakeup event as possible. If @a interval is not a power of two, the + * closest power of 2 greater than @a interval will be used. + * + * When the poller @p func is called, it must return a value of either + * ECORE_CALLBACK_RENEW(or 1) or ECORE_CALLBACK_CANCEL(or 0). 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, int interval, Ecore_Task_Cb func, const void *data); +/** + * @brief 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 on success, @c NULL otherwise. + * + * @note @a 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 deleted). + */ +EAPI void *ecore_poller_del(Ecore_Poller *poller); + +/** + * @} + */ + +/** + * @defgroup Ecore_Animator_Group Ecore Animator functions + * + * @brief Ecore animators are a helper to simplify creating + * animations. + * + * Creating an animation is as simple as saying for how long it + * should be run and having a callback that does the animation, + * something like this: + * @code + * static Eina_Bool + * _do_animation(void *data, double pos) + * { + * evas_object_move(data, 100 * pos, 100 * pos); + * ... do some more animating ... + * } + * ... + *ecore_animator_timeline_add(2, _do_animation, my_evas_object); + * @endcode + * In the sample above we create an animation to move + * @c my_evas_object from position (0,0) to (100,100) in 2 seconds. + * + * If your animation will run for an unspecified amount of time you + * can use ecore_animator_add(), which is like using + *ecore_timer_add() with the interval being the + * @ref ecore_animator_frametime_set "framerate". Note that this has + * tangible benefits to creating a timer for each animation in terms + * of performance. + * + * For a more detailed example that show several animation see + * @ref tutorial_ecore_animator. + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +/* + * @since 1.8 + */ +typedef Eo Ecore_Animator; /**< A handle for animators */ +#define ECORE_ANIMATOR_CLASS ecore_animator_class_get() +const Eo_Class *ecore_animator_class_get(void) EINA_CONST; + +extern EAPI Eo_Op ECORE_ANIMATOR_BASE_ID; + +enum +{ + ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR, + ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR, + ECORE_ANIMATOR_SUB_ID_LAST +}; + +#define ECORE_ANIMATOR_ID(sub_id) (ECORE_ANIMATOR_BASE_ID + sub_id) + +/** + * @def ecore_animator_constructor + * @since 1.8 + * + * Contructor. + * + * @param[in] func + * @param[in] data + * + */ +#define ecore_animator_constructor(func, data) ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * @def ecore_animator_timeline_constructor + * @since 1.8 + * + * Contructor. + * + * @param[in] runtime + * @param[in] func + * @param[in] data + * + */ +#define ecore_animator_timeline_constructor(runtime, func, data) ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR), EO_TYPECHECK(double, runtime), EO_TYPECHECK(Ecore_Timeline_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * @enum _Ecore_Pos_Map + * Defines the position mappings for the animation. + */ +enum _Ecore_Pos_Map /* Position mappings */ +{ + ECORE_POS_MAP_LINEAR, /**< Linear 0.0 -> 1.0 */ + ECORE_POS_MAP_ACCELERATE, /**< Start slow then speed up */ + ECORE_POS_MAP_DECELERATE, /**< Start fast then slow down */ + ECORE_POS_MAP_SINUSOIDAL, /**< Start slow, speed up then slow down at end */ + ECORE_POS_MAP_ACCELERATE_FACTOR, /**< Start slow then speed up, v1 being a power factor, 0.0 being linear, 1.0 being normal accelerate, 2.0 being much more pronounced accelerate (squared), 3.0 being cubed, etc. */ + ECORE_POS_MAP_DECELERATE_FACTOR, /**< Start fast then slow down, v1 being a power factor, 0.0 being linear, 1.0 being normal decelerate, 2.0 being much more pronounced decelerate (squared), 3.0 being cubed, etc. */ + ECORE_POS_MAP_SINUSOIDAL_FACTOR, /**< Start slow, speed up then slow down at end, v1 being a power factor, 0.0 being linear, 1.0 being normal sinusoidal, 2.0 being much more pronounced sinusoidal (squared), 3.0 being cubed, etc. */ + ECORE_POS_MAP_DIVISOR_INTERP, /**< Start at gradient * v1, interpolated via power of v2 curve */ + ECORE_POS_MAP_BOUNCE, /**< Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1 */ + ECORE_POS_MAP_SPRING /**< Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1 */ +}; +typedef enum _Ecore_Pos_Map Ecore_Pos_Map; + +/** + * @enum _Ecore_Animator_Source + * Defines the timing sources for animators. + */ +enum _Ecore_Animator_Source /* Timing sources for animators */ +{ + ECORE_ANIMATOR_SOURCE_TIMER, /**< The default system clock/timer based animator that ticks every "frametime" seconds */ + ECORE_ANIMATOR_SOURCE_CUSTOM /**< A custom animator trigger that you need to call ecore_animator_trigger() to make it tick */ +}; +typedef enum _Ecore_Animator_Source Ecore_Animator_Source; + +/** + * @typedef Ecore_Timeline_Cb Ecore_Timeline_Cb + * A callback run for a task (animators with runtimes) + */ +typedef Eina_Bool (*Ecore_Timeline_Cb)(void *data, double pos); + +/** + * @brief Add an animator to call @p func at every animation 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 + * + * This function adds a animator and returns its handle on success and @c NULL + * on failure. The function @p func will be called every N seconds where N is + * the @p 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. + * + * @note The default @p frametime value is 1/30th of a second. + * + * @see ecore_animator_timeline_add() + * @see ecore_animator_frametime_set() + */ +EAPI Ecore_Animator *ecore_animator_add(Ecore_Task_Cb func, const void *data); +/** + * @brief Add a animator that runs for a limited time + * + * @param runtime The time to run in seconds + * @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 + * + * This function is just like ecore_animator_add() except the animator only + * runs for a limited time specified in seconds by @p runtime. Once the + * runtime the animator has elapsed (animator finished) it will automatically + * be deleted. The callback function @p func can return ECORE_CALLBACK_RENEW + * to keep the animator running or ECORE_CALLBACK_CANCEL ro stop it and have + * it be deleted automatically at any time. + * + * The @p func will ALSO be passed a position parameter that will be in value + * from 0.0 to 1.0 to indicate where along the timeline (0.0 start, 1.0 end) + * the animator run is at. If the callback wishes not to have a linear + * transition it can "map" this value to one of several curves and mappings + * via ecore_animator_pos_map(). + * + * @note The default @p frametime value is 1/30th of a second. + * + * @see ecore_animator_add() + * @see ecore_animator_pos_map() + * @since 1.1.0 + */ +EAPI Ecore_Animator *ecore_animator_timeline_add(double runtime, Ecore_Timeline_Cb func, const void *data); +/** + * @brief Delete the specified animator from the animator list. + * + * @param animator The animator to delete + * @return The data pointer set for the animator on add + * + * Delete the specified @p animator 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 @c 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); +/** + * @brief Suspend the specified animator. + * + * @param animator The animator to delete + * + * The specified @p animator will be temporarily removed from the set of + * animators that are executed during main loop. + * + * @warning Freezing an animator doesn't freeze accounting of how long that + * animator has been running. Therefore if the animator was created with + *ecore_animator_timeline_add() the @p pos argument given to the callback + * will increase as if the animator hadn't been frozen and the animator may + * have it's execution halted if @p runtime elapsed. + */ +EAPI void ecore_animator_freeze(Ecore_Animator *animator); +/** + * @brief Restore execution of the specified animator. + * + * @param animator The animator to delete + * + * The specified @p animator will be put back in the set of animators that are + * executed during main loop. + */ +EAPI void ecore_animator_thaw(Ecore_Animator *animator); +/** + * @brief 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) between animator ticks. + * At every tick the callback of every existing animator will be called. + * + * @warning Too small a value may cause performance issues and too high a + * value may cause your animation to seem "jerky". + * + * @note The default @p frametime value is 1/30th of a second. + */ +EAPI void ecore_animator_frametime_set(double frametime); +/** + * @brief Get the animator call interval in seconds. + * + * @return The time in second in between animator ticks. + * + * This function retrieves the time in seconds between animator ticks. + * + * @see ecore_animator_frametime_set() + */ +EAPI double ecore_animator_frametime_get(void); +/** + * @brief Maps an input position from 0.0 to 1.0 along a timeline to a + * position in a different curve. + * + * @param pos The input position to map + * @param map The mapping to use + * @param v1 A parameter use by the mapping (pass 0.0 if not used) + * @param v2 A parameter use by the mapping (pass 0.0 if not used) + * @return The mapped value + * + * Takes an input position (0.0 to 1.0) and maps to a new position (normally + * between 0.0 and 1.0, but it may go above/below 0.0 or 1.0 to show that it + * has "overshot" the mark) using some interpolation (mapping) algorithm. + * + * This function useful to create non-linear animations. It offers a variety + * of possible animation curves to be used: + * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos + * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up + * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down + * @li ECORE_POS_MAP_SINUSOIDAL - Start slow, speed up then slow down at end + * @li ECORE_POS_MAP_ACCELERATE_FACTOR - Start slow then speed up, v1 being a + * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_ACCELERATE, 2.0 + * being much more pronounced accelerate (squared), 3.0 being cubed, etc. + * @li ECORE_POS_MAP_DECELERATE_FACTOR - Start fast then slow down, v1 being a + * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_DECELERATE, 2.0 + * being much more pronounced decelerate (squared), 3.0 being cubed, etc. + * @li ECORE_POS_MAP_SINUSOIDAL_FACTOR - Start slow, speed up then slow down + * at end, v1 being a power factor, 0.0 being linear, 1.0 being + * ECORE_POS_MAP_SINUSOIDAL, 2.0 being much more pronounced sinusoidal + * (squared), 3.0 being cubed, etc. + * @li ECORE_POS_MAP_DIVISOR_INTERP - Start at gradient * v1, interpolated via + * power of v2 curve + * @li ECORE_POS_MAP_BOUNCE - Start at 0.0 then "drop" like a ball bouncing to + * the ground at 1.0, and bounce v2 times, with decay factor of v1 + * @li ECORE_POS_MAP_SPRING - Start at 0.0 then "wobble" like a spring rest + * position 1.0, and wobble v2 times, with decay factor of v1 + * @note When not listed v1 and v2 have no effect. + * + * @image html ecore-pos-map.png + * @image latex ecore-pos-map.eps width=\textwidth + * + * One way to use this would be: + * @code + * double pos; // input position in a timeline from 0.0 to 1.0 + * double out; // output position after mapping + * int x1, y1, x2, y2; // x1 & y1 are start position, x2 & y2 are end position + * int x, y; // x & y are the calculated position + * + * out = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 1.8, 7); + * x = (x1 * out) + (x2 * (1.0 - out)); + * y = (y1 * out) + (y2 * (1.0 - out)); + * move_my_object_to(myobject, x, y); + * @endcode + * This will make an animation that bounces 7 each times diminishing by a + * factor of 1.8. + * + * @see _Ecore_Pos_Map + * + * @since 1.1.0 + */ +EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2); +/** + * @brief Set the source of animator ticks for the mainloop + * + * @param source The source of animator ticks to use + * + * This sets the source of animator ticks. When an animator is active the + * mainloop will "tick" over frame by frame calling all animators that are + * registered until none are. The mainloop will tick at a given rate based + * on the animator source. The default source is the system clock timer + * source - ECORE_ANIMATOR_SOURCE_TIMER. This source uses the system clock + * to tick over every N seconds (specified by ecore_animator_frametime_set(), + * with the default being 1/30th of a second unless set otherwise). You can + * set a custom tick source by setting the source to + * ECORE_ANIMATOR_SOURCE_CUSTOM and then drive it yourself based on some input + * tick source (like another application via ipc, some vertical blanking + * interrupt interrupt etc.) using + *ecore_animator_custom_source_tick_begin_callback_set() and + *ecore_animator_custom_source_tick_end_callback_set() to set the functions + * that will be called to start and stop the ticking source, which when it + * gets a "tick" should call ecore_animator_custom_tick() to make the "tick" over 1 + * frame. + */ +EAPI void ecore_animator_source_set(Ecore_Animator_Source source); +/** + * @brief Get the animator source currently set. + * + * @return The current animator source + * + * This gets the current animator source. + * + * @see ecore_animator_source_set() + */ +EAPI Ecore_Animator_Source ecore_animator_source_get(void); +/** + * @brief Set the function that begins a custom animator tick source + * + * @param func The function to call when ticking is to begin + * @param data The data passed to the tick begin function as its parameter + * + * The Ecore Animator infrastructure handles tracking if animators are needed + * or not and which ones need to be called and when, but when the tick source + * is custom, you have to provide a tick source by calling + *ecore_animator_custom_tick() to indicate a frame tick happened. In order + * to allow the source of ticks to be dynamically enabled or disabled as + * needed, the @p func when set is called to enable the tick source to + * produce tick events that call ecore_animator_custom_tick(). If @p func + * is @c NULL then no function is called to begin custom ticking. + * + * @see ecore_animator_source_set() + * @see ecore_animator_custom_source_tick_end_callback_set() + * @see ecore_animator_custom_tick() + */ +EAPI void ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data); +/** + * @brief Set the function that ends a custom animator tick source + * + * @param func The function to call when ticking is to end + * @param data The data passed to the tick end function as its parameter + * + * This function is a matching pair to the function set by + * ecore_animator_custom_source_tick_begin_callback_set() and is called + * when ticking is to stop. If @p func is @c NULL then no function will be + * called to stop ticking. For more information please see + * ecore_animator_custom_source_tick_begin_callback_set(). + * + * @see ecore_animator_source_set() + * @see ecore_animator_custom_source_tick_begin_callback_set() + * @see ecore_animator_custom_tick() + */ +EAPI void ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data); +/** + * @brief Trigger a custom animator tick + * + * When animator source is set to ECORE_ANIMATOR_SOURCE_CUSTOM, then calling + * this function triggers a run of all animators currently registered with + * Ecore as this indicates a "frame tick" happened. This will do nothing if + * the animator source(set by ecore_animator_source_set()) is not set to + * ECORE_ANIMATOR_SOURCE_CUSTOM. + * + * @see ecore_animator_source_set() + * @see ecore_animator_custom_source_tick_begin_callback_set + * @see ecore_animator_custom_source_tick_end_callback_set()() + */ +EAPI void ecore_animator_custom_tick(void); + +/** + * @} + */ + +/** + * @defgroup Ecore_Time_Group Ecore time functions + * + * These are function to retrieve time in a given format. + * + * Examples: + * @li @ref ecore_time_functions_example_c + * @{ + */ +EAPI double ecore_time_get(void); +EAPI double ecore_time_unix_get(void); +EAPI double ecore_loop_time_get(void); + +/** + * @} + */ + +/** + * @defgroup Ecore_Timer_Group Ecore Timer functions + * + * Ecore provides very flexible timer functionality. The basic usage of timers, + * to call a certain function at a certain interval can be achieved with a + * single line: + * @code + * Eina_Bool my_func(void *data) { + * do_funky_stuff_with_data(data); + * return EINA_TRUE; + * } + * ecore_timer_add(interval_in_seconds, my_func, data_given_to_function); + * @endcode + * @note If the function was to be executed only once simply return + * @c EINA_FALSE instead. + * + * An example that shows the usage of a lot of these: + * @li @ref ecore_timer_example_c + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +/* + * @since 1.8 + */ +typedef Eo Ecore_Timer; /**< A handle for timers */ + +#define ECORE_TIMER_CLASS ecore_timer_class_get() +const Eo_Class *ecore_timer_class_get(void) EINA_CONST; +extern EAPI Eo_Op ECORE_TIMER_BASE_ID; + +enum +{ + ECORE_TIMER_SUB_ID_CONSTRUCTOR, + ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR, + ECORE_TIMER_SUB_ID_INTERVAL_SET, + ECORE_TIMER_SUB_ID_INTERVAL_GET, + ECORE_TIMER_SUB_ID_DELAY, + ECORE_TIMER_SUB_ID_RESET, + ECORE_TIMER_SUB_ID_PENDING_GET, + ECORE_TIMER_SUB_ID_LAST, +}; + +#define ECORE_TIMER_ID(sub_id) (ECORE_TIMER_BASE_ID + sub_id) + +/** + * @def ecore_timer_constructor + * @since 1.8 + * + * Contructor. + * + * @param[in] in + * @param[in] func + * @param[in] data + * + */ +#define ecore_timer_constructor(in, func, data) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(double, in), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * @def ecore_timer_loop_constructor + * @since 1.8 + * + * Contructor. + * + * @param[in] in + * @param[in] func + * @param[in] data + * + */ +#define ecore_timer_loop_constructor(in, func, data) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR), EO_TYPECHECK(double, in), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * @def ecore_obj_timer_interval_set + * @since 1.8 + * + * Change the interval the timer ticks of. + * + * @param[in] in + * + * @see ecore_timer_interval_set + */ +#define ecore_obj_timer_interval_set(in) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_SET), EO_TYPECHECK(double, in) + +/** + * @def ecore_obj_timer_interval_get + * @since 1.8 + * + * Get the interval the timer ticks on. + * + * @param[out] ret + * + * @see ecore_timer_interval_get + */ +#define ecore_obj_timer_interval_get(ret) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_GET), EO_TYPECHECK(double *, ret) + +/** + * @def ecore_obj_timer_delay + * @since 1.8 + * + * Add some delay for the next occurrence of a timer. + * + * @param[in] add + * + * @see ecore_timer_delay + */ +#define ecore_obj_timer_delay(add) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_DELAY), EO_TYPECHECK(double, add) + +/** + * @def ecore_obj_timer_reset + * @since 1.8 + * + * Reset a timer to its full interval. + * + * @see ecore_timer_reset + */ +#define ecore_obj_timer_reset() ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_RESET) + +/** + * @def ecore_obj_timer_pending_get + * @since 1.8 + * + * Get the pending time regarding a timer. + * + * @param[out] ret + * + * @see ecore_timer_pending_get + */ +#define ecore_obj_timer_pending_get(ret) ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_PENDING_GET), EO_TYPECHECK(double *, ret) + +EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data); +EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, 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 void ecore_timer_reset(Ecore_Timer *timer); +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 char *ecore_timer_dump(void); + +/** + * @} + */ + +/** + * @defgroup Ecore_Idle_Group Ecore Idle functions + * + * The idler functionality in Ecore allows for callbacks to be called when the + * program isn't handling @ref Ecore_Event_Group "events", @ref Ecore_Timer_Group + * "timers" or @ref Ecore_FD_Handler_Group "fd handlers". + * + * There are three types of idlers: Enterers, Idlers(proper) and Exiters. They + * are called, respectively, when the program is about to enter an idle state, + * when the program is in an idle state and when the program has just left an + * idle state and will begin processing @ref Ecore_Event_Group "events", @ref + * Ecore_Timer_Group "timers" or @ref Ecore_FD_Handler_Group "fd handlers". + * + * 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. + * + * Exiter callbacks are called when the main loop wakes up from an idle state. + * + * 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. + * + * @note Idle state doesn't mean that the @b program is idle, but + * that the main loop is idle. It doesn't have any timers, + * events, fd handlers or anything else to process (which in most + * event driven programs also means that the @b program is + * idle too, but it's not a rule). The program itself may be doing + * a lot of processing in the idler, or in another thread, for + * example. + * + * Example with functions that deal with idle state: + * + * @li @ref ecore_idler_example_c + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +/* + * @since 1.8 + */ +typedef Eo Ecore_Idler; /**< A handle for idlers */ +#define ECORE_IDLER_CLASS ecore_idler_class_get() +const Eo_Class *ecore_idler_class_get(void) EINA_CONST; + +extern EAPI Eo_Op ECORE_IDLER_BASE_ID; + +enum +{ + ECORE_IDLER_SUB_ID_CONSTRUCTOR, + ECORE_IDLER_SUB_ID_LAST +}; + +#define ECORE_IDLER_ID(sub_id) (ECORE_IDLER_BASE_ID + sub_id) + +/** + * @def ecore_idler_constructor + * @since 1.8 + * + * Contructor. + * + * @param[in] func + * @param[in] data + * + */ +#define ecore_idler_constructor(func, data) ECORE_IDLER_ID(ECORE_IDLER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * + */ + +typedef Eo Ecore_Idle_Enterer; /**< A handle for idle enterers */ +#define ECORE_IDLE_ENTERER_CLASS ecore_idle_enterer_class_get() +const Eo_Class *ecore_idle_enterer_class_get(void) EINA_CONST; + +extern EAPI Eo_Op ECORE_IDLE_ENTERER_BASE_ID; + +enum +{ + ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR, + ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR, + ECORE_IDLE_ENTERER_SUB_ID_LAST +}; + +#define ECORE_IDLE_ENTERER_ID(sub_id) (ECORE_IDLE_ENTERER_BASE_ID + sub_id) + +/** + * @def ecore_idle_enterer_after_constructor + * @since 1.8 + * + * Contructor. Will insert the handler at the end of the list. + * + * @param[in] func + * @param[in] data + * + */ +#define ecore_idle_enterer_after_constructor(func, data) ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * @def ecore_idle_enterer_before_constructor + * @since 1.8 + * + * Contructor. Will insert the handler at the beginning of the list. + * + * @param[in] func + * @param[in] data + * + */ +#define ecore_idle_enterer_before_constructor(func, data) ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * + */ + +/* + * @since 1.8 + */ +typedef Eo Ecore_Idle_Exiter; /**< A handle for idle exiters */ +#define ECORE_IDLE_EXITER_CLASS ecore_idle_exiter_class_get() +const Eo_Class *ecore_idle_exiter_class_get(void) EINA_CONST; + +extern EAPI Eo_Op ECORE_IDLE_EXITER_BASE_ID; + +enum +{ + ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR, + ECORE_IDLE_EXITER_SUB_ID_LAST +}; + +#define ECORE_IDLE_EXITER_ID(sub_id) (ECORE_IDLE_EXITER_BASE_ID + sub_id) + +/** + * @def ecore_idle_exiter_constructor + * @since 1.8 + * + * Contructor. + * + * @param[in] func + * @param[in] data + * + */ +#define ecore_idle_exiter_constructor(func, data) ECORE_IDLE_EXITER_ID(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Task_Cb, func), EO_TYPECHECK(const void *, data) + +/** + * 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, @c NULL otherwise. + * + * Add an idler handle to the event loop, returning a handle on + * success and @c NULL otherwise. The function @p func will be called + * repeatedly while no other events are ready to be processed, as + * long as it returns @c 1 (or ECORE_CALLBACK_RENEW). A return of @c 0 + * (or ECORE_CALLBACK_CANCEL) deletes the idler. + * + * Idlers are useful for progressively prossessing data without blocking. + */ +EAPI Ecore_Idler *ecore_idler_add(Ecore_Task_Cb func, const void *data); + +/** + * 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, @c NULL + * otherwise. + */ +EAPI void *ecore_idler_del(Ecore_Idler *idler); + +EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data); +EAPI Ecore_Idle_Enterer *ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data); +EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer); + +EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data); +EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter); + +/** + * @} + */ + +/** + * @defgroup Ecore_Thread_Group Ecore Thread functions + * + * Facilities to run heavy tasks in different threads to avoid blocking + * the main loop. + * + * The EFL is, for the most part, not thread safe. This means that if you + * have some task running in another thread and you have, for example, an + * Evas object to show the status progress of this task, you cannot update + * the object from within the thread. This can only be done from the main + * thread, the one running the main loop. This problem can be solved + * by running a thread that sends messages to the main one using an + * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other + * things like cancelling the thread, your code grows in complexity and gets + * much harder to maintain. + * + * Ecore Thread is here to solve that problem. It is @b not a simple wrapper + * around standard POSIX threads (or the equivalent in other systems) and + * it's not meant to be used to run parallel tasks throughout the entire + * duration of the program, especially when these tasks are performance + * critical, as Ecore manages these tasks using a pool of threads based on + * system configuration. + * + * What Ecore Thread does, is make it a lot easier to dispatch a worker + * function to perform some heavy task and then get the result once it + * completes, without blocking the application's UI. In addition, cancelling + * and rescheduling comes practically for free and the developer needs not + * worry about how many threads are launched, since Ecore will schedule + * them according to the number of processors the system has and maximum + * amount of concurrent threads set for the application. + * + * At the system level, Ecore will start a new thread on an as-needed basis + * until the maximum set is reached. When no more threads can be launched, + * new worker functions will be queued in a waiting list until a thread + * becomes available. This way, system threads will be shared throughout + * different worker functions, but running only one at a time. At the same + * time, a worker function that is rescheduled may be run on a different + * thread the next time. + * + * The ::Ecore_Thread handler has two meanings, depending on what context + * it is on. The one returned when starting a worker with any of the + * functions ecore_thread_run() or ecore_thread_feedback_run() is an + * identifier of that specific instance of the function and can be used from + * the main loop with the ecore_thread_cancel() and ecore_thread_check() + * functions. This handler must not be shared with the worker function + * function running in the thread. This same handler will be the one received + * on the @c end, @c cancel and @c feedback callbacks. + * + * The worker function, that's the one running in the thread, also receives + * an ::Ecore_Thread handler that can be used with ecore_thread_cancel() and + *ecore_thread_check(), sharing the flag with the main loop. But this + * handler is also associated with the thread where the function is running. + * This has strong implications when working with thread local data. + * + * There are two kinds of worker threads Ecore handles: simple, or short, + * workers and feedback workers. + * + * The first kind is for simple functions that perform a + * usually small but time consuming task. Ecore will run this function in + * a thread as soon as one becomes available and notify the calling user of + * its completion once the task is done. + * + * The following image shows the flow of a program running four tasks on + * a pool of two threads. + * + * @image html ecore_thread.png + * @image rtf ecore_thread.png + * @image latex ecore_thread.eps width=\textwidth + * + * For larger tasks that may require continuous communication with the main + * program, the feedback workers provide the same functionality plus a way + * for the function running in the thread to send messages to the main + * thread. + * + * The next diagram omits some details shown in the previous one regarding + * how threads are spawned and tasks are queued, but illustrates how feedback + * jobs communicate with the main loop and the special case of threads + * running out of pool. + * + * @image html ecore_thread_feedback.png + * @image rtf ecore_thread_feedback.png + * @image latex ecore_thread_feedback.eps width=\textwidth + * + * See an overview example in @ref ecore_thread_example_c. + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +typedef struct _Ecore_Thread Ecore_Thread; /**< A handle for threaded jobs */ + +/** + * @typedef Ecore_Thread_Cb Ecore_Thread_Cb + * A callback used by Ecore_Thread helper. + */ +typedef void (*Ecore_Thread_Cb)(void *data, Ecore_Thread *thread); +/** + * @typedef Ecore_Thread_Notify_Cb Ecore_Thread_Notify_Cb + * A callback used by the main loop to receive data sent by an + * @ref Ecore_Thread_Group. + */ +typedef void (*Ecore_Thread_Notify_Cb)(void *data, Ecore_Thread *thread, void *msg_data); + +/** + * Schedule a task to run in a parallel thread to avoid locking the main loop + * + * @param func_blocking The function that should run in another thread. + * @param func_end Function to call from main loop when @p func_blocking + * completes its task successfully (may be NULL) + * @param func_cancel Function to call from main loop if the thread running + * @p func_blocking is cancelled or fails to start (may be NULL) + * @param data User context data to pass to all callbacks. + * @return A new thread handler, or @c NULL on failure. + * + * This function will try to create a new thread to run @p func_blocking in, + * or if the maximum number of concurrent threads has been reached, will + * add it to the pending list, where it will wait until a thread becomes + * available. The return value will be an ::Ecore_Thread handle that can + * be used to cancel the thread before its completion. + * + * @note This function should always return immediately, but in the rare + * case that Ecore is built with no thread support, @p func_blocking will + * be called here, actually blocking the main loop. + * + * Once a thread becomes available, @p func_blocking will be run in it until + * it finishes, then @p func_end is called from the thread containing the + * main loop to inform the user of its completion. While in @p func_blocking, + * no functions from the EFL can be used, except for those from Eina that are + * marked to be thread-safe. Even for the latter, caution needs to be taken + * if the data is shared across several threads. + * + * @p func_end will be called from the main thread when @p func_blocking ends, + * so here it's safe to use anything from the EFL freely. + * + * The thread can also be cancelled before its completion calling + *ecore_thread_cancel(), either from the main thread or @p func_blocking. + * In this case, @p func_cancel will be called, also from the main thread + * to inform of this happening. If the thread could not be created, this + * function will be called and it's @c thread parameter will be NULL. It's + * also safe to call any EFL function here, as it will be running in the + * main thread. + * + * Inside @p func_blocking, it's possible to call ecore_thread_reschedule() + * to tell Ecore that this function should be called again. + * + * Be aware that no assumptions can be made about the order in which the + * @p func_end callbacks for each task will be called. Once the function is + * running in a different thread, it's the OS that will handle its running + * schedule, and different functions may take longer to finish than others. + * Also remember that just starting several tasks together doesn't mean they + * will be running at the same time. Ecore will schedule them based on the + * number of threads available for the particular system it's running in, + * so some of the jobs started may be waiting until another one finishes + * before it can execute its own @p func_blocking. + * + * @see ecore_thread_feedback_run() + * @see ecore_thread_cancel() + * @see ecore_thread_reschedule() + * @see ecore_thread_max_set() + */ +EAPI Ecore_Thread *ecore_thread_run(Ecore_Thread_Cb func_blocking, Ecore_Thread_Cb func_end, Ecore_Thread_Cb func_cancel, const void *data); +/** + * Launch a thread to run a task that can talk back to the main thread + * + * @param func_heavy The function that should run in another thread. + * @param func_notify Function that receives the data sent from the thread + * @param func_end Function to call from main loop when @p func_heavy + * completes its task successfully + * @param func_cancel Function to call from main loop if the thread running + * @p func_heavy is cancelled or fails to start + * @param data User context data to pass to all callback. + * @param try_no_queue If you want to run outside of the thread pool. + * @return A new thread handler, or @c NULL on failure. + * + * See ecore_thread_run() for a general description of this function. + * + * The difference with the above is that ecore_thread_run() is meant for + * tasks that don't need to communicate anything until they finish, while + * this function is provided with a new callback, @p func_notify, that will + * be called from the main thread for every message sent from @p func_heavy + * with ecore_thread_feedback(). + * + * Like with ecore_thread_run(), a new thread will be launched to run + * @p func_heavy unless the maximum number of simultaneous threads has been + * reached, in which case the function will be scheduled to run whenever a + * running task ends and a thread becomes free. But if @p try_no_queue is + * set, Ecore will first try to launch a thread outside of the pool to run + * the task. If it fails, it will revert to the normal behaviour of using a + * thread from the pool as if @p try_no_queue had not been set. + * + * Keep in mind that Ecore handles the thread pool based on the number of + * CPUs available, but running a thread outside of the pool doesn't count for + * this, so having too many of them may have drastic effects over the + * program's performance. + * + * @see ecore_thread_feedback() + * @see ecore_thread_run() + * @see ecore_thread_cancel() + * @see ecore_thread_reschedule() + * @see ecore_thread_max_set() + */ +EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, Ecore_Thread_Notify_Cb func_notify, + Ecore_Thread_Cb func_end, Ecore_Thread_Cb func_cancel, + const void *data, Eina_Bool try_no_queue); +/** + * Cancel a running thread. + * + * @param thread The thread to cancel. + * @return Will return @c EINA_TRUE if the thread has been cancelled, + * @c EINA_FALSE if it is pending. + * + * This function can be called both in the main loop or in the running thread. + * + * This function cancels a running thread. If @p thread can be immediately + * cancelled (it's still pending execution after creation or rescheduling), + * then the @c cancel callback will be called, @p thread will be freed and + * the function will return @c EINA_TRUE. + * + * If the thread is already running, then this function returns @c EINA_FALSE + * after marking the @p thread as pending cancellation. For the thread to + * actually be terminated, it needs to return from the user function back + * into Ecore control. This can happen in several ways: + * @li The function ends and returns normally. If it hadn't been cancelled, + * @c func_end would be called here, but instead @c func_cancel will happen. + * @li The function returns after requesting to be rescheduled with + * ecore_thread_reschedule(). + * @li The function is prepared to leave early by checking if + * ecore_thread_check() returns @c EINA_TRUE. + * + * The user function can cancel itself by calling ecore_thread_cancel(), but + * it should always use the ::Ecore_Thread handle passed to it and never + * share it with the main loop thread by means of shared user data or any + * other way. + * + * @p thread will be freed and should not be used again if this function + * returns @c EINA_TRUE or after the @c func_cancel callback returns. + * + * @see ecore_thread_check() + */ +EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread); +/** + * Checks if a thread is pending cancellation + * + * @param thread The thread to test. + * @return @c EINA_TRUE if the thread is pending cancellation, + * @c EINA_FALSE if it is not. + * + * This function can be called both in the main loop or in the running thread. + * + * When ecore_thread_cancel() is called on an already running task, the + * thread is marked as pending cancellation. This function returns @c EINA_TRUE + * if this mark is set for the given @p thread and can be used from the + * main loop thread to check if a still active thread has been cancelled, + * or from the user function running in the thread to check if it should + * stop doing what it's doing and return early, effectively cancelling the + * task. + * + * @see ecore_thread_cancel() + */ +EAPI Eina_Bool ecore_thread_check(Ecore_Thread *thread); +/** + * Sends data from the worker thread to the main loop + * + * @param thread The current ::Ecore_Thread context to send data from + * @param msg_data Data to be transmitted to the main loop + * @return @c EINA_TRUE if @p msg_data was successfully sent to main loop, + * @c EINA_FALSE if anything goes wrong. + * + * You should use this function only in the @c func_heavy call. + * + * Only the address to @p msg_data will be sent and once this function + * returns @c EINA_TRUE, the job running in the thread should never touch the + * contents of it again. The data sent should be malloc()'ed or something + * similar, as long as it's not memory local to the thread that risks being + * overwritten or deleted once it goes out of scope or the thread finishes. + * + * Care must be taken that @p msg_data is properly freed in the @c func_notify + * callback set when creating the thread. + * + * @see ecore_thread_feedback_run() + */ +EAPI Eina_Bool ecore_thread_feedback(Ecore_Thread *thread, const void *msg_data); +/** + * Asks for the function in the thread to be called again at a later time + * + * @param thread The current ::Ecore_Thread context to rescheduled + * @return @c EINA_TRUE if the task was successfully rescheduled, + * @c EINA_FALSE if anything goes wrong. + * + * This function should be called only from the same function represented + * by @p thread. + * + * Calling this function will mark the thread for a reschedule, so as soon + * as it returns, it will be added to the end of the list of pending tasks. + * If no other tasks are waiting or there are sufficient threads available, + * the rescheduled task will be launched again immediately. + * + * This should never return @c EINA_FALSE, unless it was called from the wrong + * thread or with the wrong arguments. + * + * The @c func_end callback set when the thread is created will not be + * called until the function in the thread returns without being rescheduled. + * Similarly, if the @p thread is cancelled, the reschedule will not take + * effect. + */ +EAPI Eina_Bool ecore_thread_reschedule(Ecore_Thread *thread); +/** + * Gets the number of active threads running jobs + * + * @return Number of active threads running jobs + * + * This returns the number of threads currently running jobs of any type + * through the Ecore_Thread API. + * + * @note Jobs started through the ecore_thread_feedback_run() function with + * the @c try_no_queue parameter set to @c EINA_TRUE will not be accounted for + * in the return of this function unless the thread creation fails and it + * falls back to using one from the pool. + */ +EAPI int ecore_thread_active_get(void); +/** + * Gets the number of short jobs waiting for a thread to run + * + * @return Number of pending threads running "short" jobs + * + * This returns the number of tasks started with ecore_thread_run() that are + * pending, waiting for a thread to become available to run them. + */ +EAPI int ecore_thread_pending_get(void); +/** + * Gets the number of feedback jobs waiting for a thread to run + * + * @return Number of pending threads running "feedback" jobs + * + * This returns the number of tasks started with ecore_thread_feedback_run() + * that are pending, waiting for a thread to become available to run them. + */ +EAPI int ecore_thread_pending_feedback_get(void); +/** + * Gets the total number of pending jobs + * + * @return Number of pending threads running jobs + * + * Same as the sum of ecore_thread_pending_get() and + *ecore_thread_pending_feedback_get(). + */ +EAPI int ecore_thread_pending_total_get(void); +/** + * Gets the maximum number of threads that can run simultaneously + * + * @return Max possible number of Ecore_Thread's running concurrently + * + * This returns the maximum number of Ecore_Thread's that may be running at + * the same time. If this number is reached, new jobs started by either + *ecore_thread_run() or ecore_thread_feedback_run() will be added to the + * respective pending queue until one of the running threads finishes its + * task and becomes available to run a new one. + * + * By default, this will be the number of available CPUs for the + * running program (as returned by eina_cpu_count()), or 1 if this value + * could not be fetched. + * + * @see ecore_thread_max_set() + * @see ecore_thread_max_reset() + */ +EAPI int ecore_thread_max_get(void); +/** + * Sets the maximum number of threads allowed to run simultaneously + * + * @param num The new maximum + * + * This sets a new value for the maximum number of concurrently running + * Ecore_Thread's. It @b must an integer between 1 and (16 * @c x), where @c x + * is the number for CPUs available. + * + * @see ecore_thread_max_get() + * @see ecore_thread_max_reset() + */ +EAPI void ecore_thread_max_set(int num); +/** + * Resets the maximum number of concurrently running threads to the default + * + * This resets the value returned by ecore_thread_max_get() back to its + * default. + * + * @see ecore_thread_max_get() + * @see ecore_thread_max_set() + */ +EAPI void ecore_thread_max_reset(void); +/** + * Gets the number of threads available for running tasks + * + * @return The number of available threads + * + * Same as doing ecore_thread_max_get() - ecore_thread_active_get(). + * + * This function may return a negative number only in the case the user + * changed the maximum number of running threads while other tasks are + * running. + */ +EAPI int ecore_thread_available_get(void); +/** + * Adds some data to a hash local to the thread + * + * @param thread The thread context the data belongs to + * @param key The name under which the data will be stored + * @param value The data to add + * @param cb Function to free the data when removed from the hash + * @param direct If true, this will not copy the key string (like + * eina_hash_direct_add()) + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + * + * Ecore Thread has a mechanism to share data across several worker functions + * that run on the same system thread. That is, the data is stored per + * thread and for a worker function to have access to it, it must be run + * by the same thread that stored the data. + * + * When there are no more workers pending, the thread will be destroyed + * along with the internal hash and any data left in it will be freed with + * the @p cb function given. + * + * This set of functions is useful to share things around several instances + * of a function when that thing is costly to create and can be reused, but + * may only be used by one function at a time. + * + * For example, if you have a program doing requisitions to a database, + * these requisitions can be done in threads so that waiting for the + * database to respond doesn't block the UI. Each of these threads will + * run a function, and each function will be dependent on a connection to + * the database, which may not be able to handle more than one request at + * a time so for each running function you will need one connection handle. + * The options then are: + * @li Each function opens a connection when it's called, does the work and + * closes the connection when it finishes. This may be costly, wasting a lot + * of time on resolving hostnames, negotiating permissions and allocating + * memory. + * @li Open the connections in the main loop and pass it to the threads + * using the data pointer. Even worse, it's just as costly as before and now + * it may even be kept with connections open doing nothing until a thread + * becomes available to run the function. + * @li Have a way to share connection handles, so that each instance of the + * function can check if an available connection exists, and if it doesn't, + * create one and add it to the pool. When no more connections are needed, + * they are all closed. + * + * The last option is the most efficient, but it requires a lot of work to + * implement properly. Using thread local data helps to achieve the same + * result while avoiding doing all the tracking work on your code. The way + * to use it would be, at the worker function, to ask for the connection + * with ecore_thread_local_data_find() and if it doesn't exist, then open + * a new one and save it with ecore_thread_local_data_add(). Do the work and + * forget about the connection handle, when everything is done the function + * just ends. The next worker to run on that thread will check if a + * connection exists and find that it does, so the process of opening a + * new one has been spared. When no more workers exist, the thread is + * destroyed and the callback used when saving the connection will be called + * to close it. + * + * This function adds the data @p value to the thread data under the given + * @p key. + * No other value in the hash may have the same @p key. If you need to + * change the value under a @p key, or you don't know if one exists already, + * you can use ecore_thread_local_data_set(). + * + * Neither @p key nor @p value may be @c NULL and @p key will be copied in the + * hash, unless @p direct is set, in which case the string used should not + * be freed until the data is removed from the hash. + * + * The @p cb function will be called when the data in the hash needs to be + * freed, be it because it got deleted with ecore_thread_local_data_del() or + * because @p thread was terminated and the hash destroyed. This parameter + * may be NULL, in which case @p value needs to be manually freed after + * removing it from the hash with either ecore_thread_local_data_del() or + * ecore_thread_local_data_set(), but it's very unlikely that this is what + * you want. + * + * This function, and all of the others in the @c ecore_thread_local_data + * family of functions, can only be called within the worker function running + * in the thread. Do not call them from the main loop or from a thread + * other than the one represented by @p thread. + * + * @see ecore_thread_local_data_set() + * @see ecore_thread_local_data_find() + * @see ecore_thread_local_data_del() + */ +EAPI Eina_Bool ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, + Eina_Free_Cb cb, Eina_Bool direct); +/** + * Sets some data in the hash local to the given thread + * + * @param thread The thread context the data belongs to + * @param key The name under which the data will be stored + * @param value The data to add + * @param cb Function to free the data when removed from the hash + * + * If no data exists in the hash under the @p key, this function adds + * @p value in the hash under the given @p key and returns NULL. + * The key itself is copied. + * + * If the hash already contains something under @p key, the data will be + * replaced by @p value and the old value will be returned. + * + * @c NULL will also be returned if either @p key or @p value are @c NULL, or + * if an error occurred. + * + * This function, and all of the others in the @c ecore_thread_local_data + * family of functions, can only be called within the worker function running + * in the thread. Do not call them from the main loop or from a thread + * other than the one represented by @p thread. + * + * @see ecore_thread_local_data_add() + * @see ecore_thread_local_data_del() + * @see ecore_thread_local_data_find() + */ +EAPI void *ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb); +/** + * Gets data stored in the hash local to the given thread + * + * @param thread The thread context the data belongs to + * @param key The name under which the data is stored + * @return The value under the given key, or @c NULL on error. + * + * Finds and return the data stored in the shared hash under the key @p key. + * + * This function, and all of the others in the @c ecore_thread_local_data + * family of functions, can only be called within the worker function running + * in the thread. Do not call them from the main loop or from a thread + * other than the one represented by @p thread. + * + * @see ecore_thread_local_data_add() + * @see ecore_thread_local_data_wait() + */ +EAPI void *ecore_thread_local_data_find(Ecore_Thread *thread, const char *key); +/** + * Deletes from the thread's hash the data corresponding to the given key + * + * @param thread The thread context the data belongs to + * @param key The name under which the data is stored + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + * + * If there's any data stored associated with @p key in the global hash, + * this function will remove it from it and return @c EINA_TRUE. If no data + * exists or an error occurs, it returns @c EINA_FALSE. + * + * If the data was added to the hash with a free function, then it will + * also be freed after removing it from the hash, otherwise it requires + * to be manually freed by the user, which means that if no other reference + * to it exists before calling this function, it will result in a memory + * leak. + * + * This function, and all of the others in the @c ecore_thread_local_data + * family of functions, can only be called within the worker function running + * in the thread. Do not call them from the main loop or from a thread + * other than the one represented by @p thread. + * + * @see ecore_thread_local_data_add() + */ +EAPI Eina_Bool ecore_thread_local_data_del(Ecore_Thread *thread, const char *key); + +/** + * Adds some data to a hash shared by all threads + * + * @param key The name under which the data will be stored + * @param value The data to add + * @param cb Function to free the data when removed from the hash + * @param direct If true, this will not copy the key string (like + * eina_hash_direct_add()) + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + * + * Ecore Thread keeps a hash that can be used to share data across several + * threads, including the main loop one, without having to manually handle + * mutexes to do so safely. + * + * This function adds the data @p value to this hash under the given @p key. + * No other value in the hash may have the same @p key. If you need to + * change the value under a @p key, or you don't know if one exists already, + * you can use ecore_thread_global_data_set(). + * + * Neither @p key nor @p value may be @c NULL and @p key will be copied in the + * hash, unless @p direct is set, in which case the string used should not + * be freed until the data is removed from the hash. + * + * The @p cb function will be called when the data in the hash needs to be + * freed, be it because it got deleted with ecore_thread_global_data_del() or + * because Ecore Thread was shut down and the hash destroyed. This parameter + * may be NULL, in which case @p value needs to be manually freed after + * removing it from the hash with either ecore_thread_global_data_del() or + *ecore_thread_global_data_set(). + * + * Manually freeing any data that was added to the hash with a @p cb function + * is likely to produce a segmentation fault, or any other strange + * happenings, later on in the program. + * + * @see ecore_thread_global_data_del() + * @see ecore_thread_global_data_set() + * @see ecore_thread_global_data_find() + */ +EAPI Eina_Bool ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct); +/** + * Sets some data in the hash shared by all threads + * + * @param key The name under which the data will be stored + * @param value The data to add + * @param cb Function to free the data when removed from the hash + * + * If no data exists in the hash under the @p key, this function adds + * @p value in the hash under the given @p key and returns NULL. + * The key itself is copied. + * + * If the hash already contains something under @p key, the data will be + * replaced by @p value and the old value will be returned. + * + * @c NULL will also be returned if either @p key or @p value are @c NULL, or + * if an error occurred. + * + * @see ecore_thread_global_data_add() + * @see ecore_thread_global_data_del() + * @see ecore_thread_global_data_find() + */ +EAPI void *ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb); +/** + * Gets data stored in the hash shared by all threads + * + * @param key The name under which the data is stored + * @return The value under the given key, or @c NULL on error. + * + * Finds and return the data stored in the shared hash under the key @p key. + * + * Keep in mind that the data returned may be used by more than one thread + * at the same time and no reference counting is done on it by Ecore. + * Freeing the data or modifying its contents may require additional + * precautions to be considered, depending on the application's design. + * + * @see ecore_thread_global_data_add() + * @see ecore_thread_global_data_wait() + */ +EAPI void *ecore_thread_global_data_find(const char *key); +/** + * Deletes from the shared hash the data corresponding to the given key + * + * @param key The name under which the data is stored + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + * + * If there's any data stored associated with @p key in the global hash, + * this function will remove it from it and return @c EINA_TRUE. If no data + * exists or an error occurs, it returns @c EINA_FALSE. + * + * If the data was added to the hash with a free function, then it will + * also be freed after removing it from the hash, otherwise it requires + * to be manually freed by the user, which means that if no other reference + * to it exists before calling this function, it will result in a memory + * leak. + * + * Note, also, that freeing data that other threads may be using will result + * in a crash, so appropriate care must be taken by the application when + * that possibility exists. + * + * @see ecore_thread_global_data_add() + */ +EAPI Eina_Bool ecore_thread_global_data_del(const char *key); +/** + * Gets data stored in the shared hash, or wait for it if it doesn't exist + * + * @param key The name under which the data is stored + * @param seconds The amount of time in seconds to wait for the data. + * @return The value under the given key, or @c NULL on error. + * + * Finds and return the data stored in the shared hash under the key @p key. + * + * If there's nothing in the hash under the given @p key, the function + * will block and wait up to @p seconds seconds for some other thread to + * add it with either ecore_thread_global_data_add() or + * ecore_thread_global_data_set(). If after waiting there's still no data + * to get, @c NULL will be returned. + * + * If @p seconds is 0, then no waiting will happen and this function works + * like ecore_thread_global_data_find(). If @p seconds is less than 0, then + * the function will wait indefinitely. + * + * Keep in mind that the data returned may be used by more than one thread + * at the same time and no reference counting is done on it by Ecore. + * Freeing the data or modifying its contents may require additional + * precautions to be considered, depending on the application's design. + * + * @see ecore_thread_global_data_add() + * @see ecore_thread_global_data_find() + */ +EAPI void *ecore_thread_global_data_wait(const char *key, double seconds); + +/** + * @} + */ + +/** + * @defgroup Ecore_Pipe_Group Pipe wrapper + * + * These functions wrap the pipe / write / read functions to easily + * integrate its use into ecore's main loop. + * + * The ecore_pipe_add() function creates file descriptors (sockets + * on Windows) and attach a 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(). + * + * For examples see here: + * @li @ref tutorial_ecore_pipe_gstreamer_example + * @li @ref tutorial_ecore_pipe_simple_example + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +typedef struct _Ecore_Pipe Ecore_Pipe; /**< A handle for pipes */ + +/** + * @typedef Ecore_Pipe_Cb Ecore_Pipe_Cb + * The callback that data written to the pipe is sent to. + */ +typedef void (*Ecore_Pipe_Cb)(void *data, void *buffer, unsigned int nbyte); + +EAPI Ecore_Pipe *ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data); +EAPI void *ecore_pipe_del(Ecore_Pipe *p); +EAPI Eina_Bool 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 void ecore_pipe_thaw(Ecore_Pipe *p); +EAPI void ecore_pipe_freeze(Ecore_Pipe *p); +EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait); + +/** + * @} + */ + +/** + * @defgroup Ecore_Job_Group Ecore Job functions + * + * You can queue jobs that are to be done by the main loop when the + * current event is dealt with. + * + * Jobs are processed by the main loop similarly to events. They + * also will be executed in the order in which they were added. + * + * A good use for them is when you don't want to execute an action + * immediately, but want to give the control back to the main loop + * so that it will call your job callback when jobs start being + * processed (and if there are other jobs added before yours, they + * will be processed first). This also gives the chance to other + * actions in your program to cancel the job before it is started. + * + * Examples of using @ref Ecore_Job : + * @li @ref ecore_job_example_c + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +/* + * @since 1.8 + */ +typedef Eo Ecore_Job; /**< A job handle */ +#define ECORE_JOB_CLASS ecore_job_class_get() +const Eo_Class *ecore_job_class_get(void) EINA_CONST; + +extern EAPI Eo_Op ECORE_JOB_BASE_ID; + +enum +{ + ECORE_JOB_SUB_ID_CONSTRUCTOR, + ECORE_JOB_SUB_ID_LAST +}; + +#define ECORE_JOB_ID(sub_id) (ECORE_JOB_BASE_ID + sub_id) + +/** + * @def ecore_job_constructor + * @since 1.8 + * + * Contructor. + * + * @param[in] func + * @param[in] data + * + */ +#define ecore_job_constructor(func, data) ECORE_JOB_ID(ECORE_JOB_SUB_ID_CONSTRUCTOR), EO_TYPECHECK(Ecore_Cb, func), EO_TYPECHECK(const void *, data) + +EAPI Ecore_Job *ecore_job_add(Ecore_Cb func, const void *data); +EAPI void *ecore_job_del(Ecore_Job *job); + +/** + * @} + */ + +/** + * @defgroup Ecore_Application_Group Ecore Application functions + * + * @{ + */ + +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); + +/** + * @} + */ + +/** + * @defgroup Ecore_Throttle_Group Ecore Throttle functions + * + * @ingroup Ecore_Main_Loop_Group + * + * @{ + */ + +EAPI void ecore_throttle_adjust(double amount); +EAPI double ecore_throttle_get(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/lib/ecore/Ecore_Getopt.h b/src/lib/ecore/Ecore_Getopt.h new file mode 100644 index 0000000000..0a11787d4d --- /dev/null +++ b/src/lib/ecore/Ecore_Getopt.h @@ -0,0 +1,419 @@ +#ifndef _ECORE_GETOPT_H +#define _ECORE_GETOPT_H + +#include +#include + +#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; + Eina_Bool boolv; + short shortv; + int intv; + long longv; + unsigned short ushortv; + unsigned int uintv; + unsigned long ulongv; + double doublev; + } def; +}; + +struct _Ecore_Getopt_Desc_Callback +{ + Eina_Bool (*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 */ + Eina_Bool 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 Eina_Bool + 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 Eina_Bool +ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser, + const Ecore_Getopt_Desc *desc, + const char *str, + void *data, + Ecore_Getopt_Value *storage); +EAPI Eina_Bool +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 */ diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c new file mode 100644 index 0000000000..3aa15bf77c --- /dev/null +++ b/src/lib/ecore/ecore.c @@ -0,0 +1,878 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_LOCALE_H +# include +#endif + +#ifdef HAVE_LANGINFO_H +# include +#endif + +#ifdef HAVE_SYS_MMAN_H +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#if HAVE_MALLINFO +#include + + +static Ecore_Version _version = { VMAJ, VMIN, VMIC, VREV }; +EAPI Ecore_Version *ecore_version = &_version; + +#define KEEP_MAX(Global, Local) \ + if (Global < (Local)) \ + Global = Local; + +static Eina_Bool _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 + +Eo *_ecore_parent = NULL; + +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; + +typedef struct _Ecore_Safe_Call Ecore_Safe_Call; +struct _Ecore_Safe_Call +{ + union { + Ecore_Cb async; + Ecore_Data_Cb sync; + } cb; + void *data; + + Eina_Lock m; + Eina_Condition c; + + int current_id; + + Eina_Bool sync : 1; + Eina_Bool suspend : 1; +}; + +static void _ecore_main_loop_thread_safe_call(Ecore_Safe_Call *order); +static void _thread_safe_cleanup(void *data); +static void _thread_callback(void *data, + void *buffer, + unsigned int nbyte); +static Eina_List *_thread_cb = NULL; +static Ecore_Pipe *_thread_call = NULL; +static Eina_Lock _thread_safety; +static const int wakeup = 42; + +static int _thread_loop = 0; +static Eina_Lock _thread_mutex; +static Eina_Condition _thread_cond; +static Eina_Lock _thread_feedback_mutex; +static Eina_Condition _thread_feedback_cond; + +static Eina_Lock _thread_id_lock; +static int _thread_id = -1; +static int _thread_id_max = 0; +static int _thread_id_update = 0; + +Eina_Lock _ecore_main_loop_lock; +int _ecore_main_lock_count; + +/** OpenBSD does not define CODESET + * FIXME ?? + */ + +#ifndef CODESET +# define CODESET "INVALID" +#endif + +/** + * @addtogroup Ecore_Init_Group + * + * @{ + */ + +/** + * 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 + * + * 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; + + eo_init(); + +#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(); + if (!ecore_mempool_init()) goto shutdown_mempool; + _ecore_main_loop_init(); + _ecore_signal_init(); +#ifndef HAVE_EXOTIC + _ecore_exe_init(); +#endif + _ecore_thread_init(); + _ecore_glib_init(); + _ecore_job_init(); + _ecore_time_init(); + + eina_lock_new(&_thread_mutex); + eina_condition_new(&_thread_cond, &_thread_mutex); + eina_lock_new(&_thread_feedback_mutex); + eina_condition_new(&_thread_feedback_cond, &_thread_feedback_mutex); + _thread_call = _ecore_pipe_add(_thread_callback, NULL); + eina_lock_new(&_thread_safety); + + eina_lock_new(&_thread_id_lock); + + eina_lock_new(&_ecore_main_loop_lock); + +#if HAVE_MALLINFO + if (getenv("ECORE_MEM_STAT")) + { + _ecore_memory_pid = getpid(); + ecore_animator_add(_ecore_memory_statistic, NULL); + } +#endif + +#if defined(GLIB_INTEGRATION_ALWAYS) + if (_ecore_glib_always_integrate) ecore_main_loop_glib_integrate(); +#endif + _ecore_parent = eo_add(ECORE_PARENT_CLASS, NULL); + + return _ecore_init_count; + +shutdown_mempool: + ecore_mempool_shutdown(); +shutdown_log_dom: + eina_shutdown(); +shutdown_evil: +#ifdef HAVE_EVIL + evil_shutdown(); +#endif + + eo_shutdown(); + + return --_ecore_init_count; +} + +/** + * Shut down connections, signal handlers sockets etc. + * + * @return 0 if ecore shuts down, greater than 0 otherwise. + * 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) +{ + Ecore_Pipe *p; + /* + * take a lock here because _ecore_event_shutdown() does callbacks + */ + _ecore_lock(); + if (_ecore_init_count <= 0) + { + ERR("Init count not greater than 0 in shutdown."); + _ecore_unlock(); + return 0; + } + if (--_ecore_init_count != 0) + goto unlock; + + if (_ecore_fps_debug) _ecore_fps_debug_shutdown(); + _ecore_poller_shutdown(); + _ecore_animator_shutdown(); + _ecore_glib_shutdown(); + _ecore_job_shutdown(); + _ecore_thread_shutdown(); + + /* this looks horrible - a hack for now, but something to note. as + * we delete the _thread_call pipe a thread COULD be doing + * ecore_pipe_write() or what not to it at the same time - we + * must ensure all possible users of this _thread_call are finished + * and exited before we delete it here */ + /* + * ok - this causes other valgrind complaints regarding glib aquiring + * locks internally. so fix bug a or bug b. let's leave the original + * bug in then and leave this as a note for now + */ + /* + * It should be fine now as we do wait for thread to shutdown before + * we try to destroy the pipe. + */ + p = _thread_call; + _thread_call = NULL; + _ecore_pipe_wait(p, 1, 0.1); + _ecore_pipe_del(p); + eina_lock_free(&_thread_safety); + eina_condition_free(&_thread_cond); + eina_lock_free(&_thread_mutex); + eina_condition_free(&_thread_feedback_cond); + eina_lock_free(&_thread_feedback_mutex); + eina_lock_free(&_thread_id_lock); + + +#ifndef HAVE_EXOTIC + _ecore_exe_shutdown(); +#endif + _ecore_idle_enterer_shutdown(); + _ecore_idle_exiter_shutdown(); + _ecore_idler_shutdown(); + _ecore_timer_shutdown(); + _ecore_event_shutdown(); + _ecore_main_shutdown(); + _ecore_signal_shutdown(); + _ecore_main_loop_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 + ecore_mempool_shutdown(); + eina_log_domain_unregister(_ecore_log_dom); + _ecore_log_dom = -1; + eina_shutdown(); +#ifdef HAVE_EVIL + evil_shutdown(); +#endif + + eo_unref(_ecore_parent); + eo_shutdown(); +unlock: + _ecore_unlock(); + + return _ecore_init_count; +} + +struct _Ecore_Fork_Cb +{ + Ecore_Cb func; + void *data; + Eina_Bool delete_me : 1; +}; + +typedef struct _Ecore_Fork_Cb Ecore_Fork_Cb; + +static int fork_cbs_walking = 0; +static Eina_List *fork_cbs = NULL; + +EAPI Eina_Bool +ecore_fork_reset_callback_add(Ecore_Cb func, const void *data) +{ + Ecore_Fork_Cb *fcb; + + fcb = calloc(1, sizeof(Ecore_Fork_Cb)); + if (!fcb) return EINA_FALSE; + fcb->func = func; + fcb->data = (void *)data; + fork_cbs = eina_list_append(fork_cbs, fcb); + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_fork_reset_callback_del(Ecore_Cb func, const void *data) +{ + Eina_List *l; + Ecore_Fork_Cb *fcb; + + EINA_LIST_FOREACH(fork_cbs, l, fcb) + { + if ((fcb->func == func) && (fcb->data == data)) + { + if (!fork_cbs_walking) + { + fork_cbs = eina_list_remove_list(fork_cbs, l); + free(fcb); + } + else + fcb->delete_me = EINA_TRUE; + return EINA_TRUE; + } + } + return EINA_FALSE; +} + +EAPI void +ecore_fork_reset(void) +{ + Eina_List *l, *ln; + Ecore_Fork_Cb *fcb; + + eina_lock_take(&_thread_safety); + + ecore_pipe_del(_thread_call); + _thread_call = ecore_pipe_add(_thread_callback, NULL); + /* If there was something in the pipe, trigger a wakeup again */ + if (_thread_cb) ecore_pipe_write(_thread_call, &wakeup, sizeof (int)); + + eina_lock_release(&_thread_safety); + + // should this be done withing the eina lock stuff? + + fork_cbs_walking++; + EINA_LIST_FOREACH(fork_cbs, l, fcb) + { + fcb->func(fcb->data); + } + fork_cbs_walking--; + + EINA_LIST_FOREACH_SAFE(fork_cbs, l, ln, fcb) + { + if (fcb->delete_me) + { + fork_cbs = eina_list_remove_list(fork_cbs, l); + free(fcb); + } + } +} + +/** + * @} + */ + +EAPI void +ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, + void *data) +{ + Ecore_Safe_Call *order; + + if (!callback) return; + + if (eina_main_loop_is()) + { + callback(data); + return; + } + + order = malloc(sizeof (Ecore_Safe_Call)); + if (!order) return; + + order->cb.async = callback; + order->data = data; + order->sync = EINA_FALSE; + order->suspend = EINA_FALSE; + + _ecore_main_loop_thread_safe_call(order); +} + +EAPI void * +ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, + void *data) +{ + Ecore_Safe_Call *order; + void *ret; + + if (!callback) return NULL; + + if (eina_main_loop_is()) + { + return callback(data); + } + + order = malloc(sizeof (Ecore_Safe_Call)); + if (!order) return NULL; + + order->cb.sync = callback; + order->data = data; + eina_lock_new(&order->m); + eina_condition_new(&order->c, &order->m); + order->sync = EINA_TRUE; + order->suspend = EINA_FALSE; + + _ecore_main_loop_thread_safe_call(order); + + eina_lock_take(&order->m); + eina_condition_wait(&order->c); + eina_lock_release(&order->m); + + ret = order->data; + + order->sync = EINA_FALSE; + order->cb.async = _thread_safe_cleanup; + order->data = order; + + _ecore_main_loop_thread_safe_call(order); + + return ret; +} + +EAPI int +ecore_thread_main_loop_begin(void) +{ + Ecore_Safe_Call *order; + + if (eina_main_loop_is()) + { + return ++_thread_loop; + } + + order = malloc(sizeof (Ecore_Safe_Call)); + if (!order) return -1; + + eina_lock_take(&_thread_id_lock); + order->current_id = ++_thread_id_max; + if (order->current_id < 0) + { + _thread_id_max = 0; + order->current_id = ++_thread_id_max; + } + eina_lock_release(&_thread_id_lock); + + eina_lock_new(&order->m); + eina_condition_new(&order->c, &order->m); + order->suspend = EINA_TRUE; + + _ecore_main_loop_thread_safe_call(order); + + eina_lock_take(&order->m); + while (order->current_id != _thread_id) + eina_condition_wait(&order->c); + eina_lock_release(&order->m); + + eina_main_loop_define(); + + _thread_loop = 1; + + return EINA_TRUE; +} + +EAPI int +ecore_thread_main_loop_end(void) +{ + int current_id; + + if (_thread_loop == 0) + { + ERR("the main loop is not locked ! No matching call to ecore_thread_main_loop_begin()."); + return -1; + } + + /* until we unlock the main loop, this thread has the main loop id */ + if (!eina_main_loop_is()) + { + ERR("Not in a locked thread !"); + return -1; + } + + _thread_loop--; + if (_thread_loop > 0) + return _thread_loop; + + current_id = _thread_id; + + eina_lock_take(&_thread_mutex); + _thread_id_update = _thread_id; + eina_condition_broadcast(&_thread_cond); + eina_lock_release(&_thread_mutex); + + eina_lock_take(&_thread_feedback_mutex); + while (current_id == _thread_id && _thread_id != -1) + eina_condition_wait(&_thread_feedback_cond); + eina_lock_release(&_thread_feedback_mutex); + + return 0; +} + +EAPI void +ecore_print_warning(const char *function EINA_UNUSED, + const char *sparam EINA_UNUSED) +{ + 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 EINA_UNUSED) +{ + 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 ""; + } +} + +/* 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[PATH_MAX]; + 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 = 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 *buf2 = (char *)&zero; + ssize_t todo = sizeof(unsigned int); + + while (todo > 0) + { + ssize_t r = write(_ecore_fps_debug_fd, buf2, todo); + if (r > 0) + { + todo -= r; + buf2 += 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 Eina_Bool +_ecore_memory_statistic(EINA_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 ECORE_CALLBACK_RENEW; +} + +#endif + +static void +_ecore_main_loop_thread_safe_call(Ecore_Safe_Call *order) +{ + Eina_Bool count; + + eina_lock_take(&_thread_safety); + + count = _thread_cb ? 0 : 1; + _thread_cb = eina_list_append(_thread_cb, order); + if (count) ecore_pipe_write(_thread_call, &wakeup, sizeof (int)); + + eina_lock_release(&_thread_safety); +} + +static void +_thread_safe_cleanup(void *data) +{ + Ecore_Safe_Call *call = data; + + eina_condition_free(&call->c); + eina_lock_free(&call->m); +} + +void +_ecore_main_call_flush(void) +{ + Ecore_Safe_Call *call; + Eina_List *callback; + + eina_lock_take(&_thread_safety); + callback = _thread_cb; + _thread_cb = NULL; + eina_lock_release(&_thread_safety); + + EINA_LIST_FREE(callback, call) + { + if (call->suspend) + { + eina_lock_take(&_thread_mutex); + + eina_lock_take(&call->m); + _thread_id = call->current_id; + eina_condition_broadcast(&call->c); + eina_lock_release(&call->m); + + while (_thread_id_update != _thread_id) + eina_condition_wait(&_thread_cond); + eina_lock_release(&_thread_mutex); + + eina_main_loop_define(); + + eina_lock_take(&_thread_feedback_mutex); + + _thread_id = -1; + + eina_condition_broadcast(&_thread_feedback_cond); + eina_lock_release(&_thread_feedback_mutex); + + _thread_safe_cleanup(call); + free(call); + } + else if (call->sync) + { + call->data = call->cb.sync(call->data); + eina_condition_broadcast(&call->c); + } + else + { + call->cb.async(call->data); + free(call); + } + } +} + +static void +_thread_callback(void *data EINA_UNUSED, + void *buffer EINA_UNUSED, + unsigned int nbyte EINA_UNUSED) +{ + _ecore_main_call_flush(); +} + +static const Eo_Class_Description parent_class_desc = { + EO_VERSION, + "ecore_parent", + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), + NULL, + 0, + NULL, + NULL +}; + +EO_DEFINE_CLASS(ecore_parent_class_get, &parent_class_desc, EO_BASE_CLASS, NULL); diff --git a/src/lib/ecore/ecore_alloc.c b/src/lib/ecore/ecore_alloc.c new file mode 100644 index 0000000000..bec66ef0d5 --- /dev/null +++ b/src/lib/ecore/ecore_alloc.c @@ -0,0 +1,132 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +typedef struct _Ecore_Mempool Ecore_Mempool; +struct _Ecore_Mempool +{ + const char *name; + Eina_Mempool *mp; + size_t size; +}; + +#define GENERIC_ALLOC_FREE(TYPE, Type) \ + extern size_t _ecore_sizeof_##TYPE; \ + Ecore_Mempool Type##_mp = { #TYPE, NULL, 0 }; \ + TYPE * \ + Type##_calloc(unsigned int num) \ + { \ + return eina_mempool_calloc(Type##_mp.mp, \ + num * _ecore_sizeof_##TYPE); \ + } \ + void \ + Type##_mp_free(TYPE *e) \ + { \ + eina_mempool_free(Type##_mp.mp, e); \ + } + +//GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator); +GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler); +GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter); +GENERIC_ALLOC_FREE(Ecore_Event, ecore_event); +//GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter); +//GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer); +//GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler); +//GENERIC_ALLOC_FREE(Ecore_Job, ecore_job); +//GENERIC_ALLOC_FREE(Ecore_Timer, ecore_timer); +//GENERIC_ALLOC_FREE(Ecore_Poller, ecore_poller); +GENERIC_ALLOC_FREE(Ecore_Pipe, ecore_pipe); +GENERIC_ALLOC_FREE(Ecore_Fd_Handler, ecore_fd_handler); +#ifdef _WIN32 +GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler); +#endif + +static Ecore_Mempool *mempool_array[] = { +// &ecore_animator_mp, + &ecore_event_handler_mp, + &ecore_event_filter_mp, + &ecore_event_mp, +// &ecore_idle_exiter_mp, +// &ecore_idle_enterer_mp, +// &ecore_idler_mp, +// &ecore_job_mp, +// &ecore_timer_mp, +// &ecore_poller_mp, + &ecore_pipe_mp, + &ecore_fd_handler_mp, +#ifdef _WIN32 + &ecore_win32_handler_mp +#endif +}; + +Eina_Bool +ecore_mempool_init(void) +{ + const char *choice; + unsigned int i; + +#define MP_SIZE_INIT(TYPE, Type) \ + Type##_mp.size = _ecore_sizeof_##TYPE + +// MP_SIZE_INIT(Ecore_Animator, ecore_animator); + MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler); + MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter); + MP_SIZE_INIT(Ecore_Event, ecore_event); +// MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter); +// MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer); +// MP_SIZE_INIT(Ecore_Idler, ecore_idler); +// MP_SIZE_INIT(Ecore_Job, ecore_job); +// MP_SIZE_INIT(Ecore_Timer, ecore_timer); +// MP_SIZE_INIT(Ecore_Poller, ecore_poller); + MP_SIZE_INIT(Ecore_Pipe, ecore_pipe); + MP_SIZE_INIT(Ecore_Fd_Handler, ecore_fd_handler); +#ifdef _WIN32 + MP_SIZE_INIT(Ecore_Win32_Handler, ecore_win32_handler); +#endif +#undef MP_SIZE_INIT + + choice = getenv("EINA_MEMPOOL"); + if ((!choice) || (!choice[0])) + choice = "chained_mempool"; + + for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) + { + retry: + mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 16); + if (!mempool_array[i]->mp) + { + if (!(!strcmp(choice, "pass_through"))) + { + ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice); + choice = "pass_through"; + goto retry; + } + else + { + ERR("Impossible to allocate mempool '%s' !", choice); + return EINA_FALSE; + } + } + } + return EINA_TRUE; +} + +void +ecore_mempool_shutdown(void) +{ + unsigned int i; + + for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) + { + eina_mempool_del(mempool_array[i]->mp); + mempool_array[i]->mp = NULL; + } +} + diff --git a/src/lib/ecore/ecore_anim.c b/src/lib/ecore/ecore_anim.c new file mode 100644 index 0000000000..c06d139add --- /dev/null +++ b/src/lib/ecore/ecore_anim.c @@ -0,0 +1,633 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#define MY_CLASS ECORE_ANIMATOR_CLASS + +#define MY_CLASS_NAME "ecore_animator" + +#define ECORE_ANIMATOR_CHECK(obj) \ + if (!eo_isa((obj), ECORE_ANIMATOR_CLASS)) \ + return + +EAPI Eo_Op ECORE_ANIMATOR_BASE_ID = EO_NOOP; + +struct _Ecore_Animator_Private_Data +{ + EINA_INLIST; + Ecore_Animator *obj; + + Ecore_Task_Cb func; + void *data; + + double start, run; + Ecore_Timeline_Cb run_func; + void *run_data; + + Eina_Bool delete_me : 1; + Eina_Bool suspended : 1; + Eina_Bool just_added : 1; +}; + +typedef struct _Ecore_Animator_Private_Data Ecore_Animator_Private_Data; + +static Eina_Bool _ecore_animator_run(void *data); +static Eina_Bool _ecore_animator(void *data); + +static int animators_delete_me = 0; +static Ecore_Animator_Private_Data *animators = NULL; +static double animators_frametime = 1.0 / 30.0; + +static Ecore_Animator_Source src = ECORE_ANIMATOR_SOURCE_TIMER; +static Ecore_Timer *timer = NULL; +static int ticking = 0; +static Ecore_Cb begin_tick_cb = NULL; +static const void *begin_tick_data = NULL; +static Ecore_Cb end_tick_cb = NULL; +static const void *end_tick_data = NULL; + +static void +_begin_tick(void) +{ + if (ticking) return; + ticking = 1; + switch (src) + { + case ECORE_ANIMATOR_SOURCE_TIMER: + 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); + } + break; + + case ECORE_ANIMATOR_SOURCE_CUSTOM: + if (begin_tick_cb) begin_tick_cb((void *)begin_tick_data); + break; + + default: + break; + } +} + +static void +_end_tick(void) +{ + if (!ticking) return; + ticking = 0; + switch (src) + { + case ECORE_ANIMATOR_SOURCE_TIMER: + if (timer) + { + _ecore_timer_del(timer); + timer = NULL; + } + break; + + case ECORE_ANIMATOR_SOURCE_CUSTOM: + if (end_tick_cb) end_tick_cb((void *)end_tick_data); + break; + + default: + break; + } +} + +static Eina_Bool +_do_tick(void) +{ + Ecore_Animator_Private_Data *animator; + + EINA_INLIST_FOREACH(animators, animator) + { + animator->just_added = EINA_FALSE; + } + EINA_INLIST_FOREACH(animators, animator) + { + if ((!animator->delete_me) && + (!animator->suspended) && + (!animator->just_added)) + { + if (!_ecore_call_task_cb(animator->func, animator->data)) + { + animator->delete_me = EINA_TRUE; + animators_delete_me++; + } + } + else animator->just_added = EINA_FALSE; + } + if (animators_delete_me) + { + Ecore_Animator_Private_Data *l; + for (l = animators; l; ) + { + animator = l; + l = (Ecore_Animator_Private_Data *)EINA_INLIST_GET(l)->next; + if (animator->delete_me) + { + animators = (Ecore_Animator_Private_Data *) + eina_inlist_remove(EINA_INLIST_GET(animators), + EINA_INLIST_GET(animator)); + + eo_parent_set(animator->obj, NULL); + if (eo_destructed_is(animator->obj)) + eo_manual_free(animator->obj); + else + eo_manual_free_set(animator->obj, EINA_FALSE); + + animators_delete_me--; + if (animators_delete_me == 0) break; + } + } + } + if (!animators) + { + _end_tick(); + return ECORE_CALLBACK_CANCEL; + } + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_ecore_animator_add(Ecore_Animator *obj, + Ecore_Animator_Private_Data *animator, + Ecore_Task_Cb func, + const void *data) +{ + if (EINA_UNLIKELY(!eina_main_loop_is())) + { + eo_error_set(obj); + EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); + } + + animator->obj = obj; + eo_do_super(obj, eo_constructor()); + eo_manual_free_set(obj, EINA_TRUE); + + if (!func) + { + eo_error_set(obj); + ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); + return EINA_FALSE; + } + + animator->func = func; + animator->data = (void *)data; + animator->just_added = EINA_TRUE; + animators = (Ecore_Animator_Private_Data *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator)); + _begin_tick(); + return EINA_TRUE; +} + +static void +_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) +{ + eo_error_set(obj); + ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); +} + +EAPI Ecore_Animator * +ecore_animator_add(Ecore_Task_Cb func, + const void *data) +{ + Ecore_Animator *animator = NULL; + + animator = eo_add_custom(MY_CLASS, _ecore_parent, + ecore_animator_constructor(func, data)); + eo_unref(animator); + return animator; +} + +static void +_animator_constructor(Eo *obj, void *_pd, va_list *list) +{ + Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); + const void *data = va_arg(*list, const void *); + + _ecore_lock(); + Ecore_Animator_Private_Data *animator = _pd; + _ecore_animator_add(obj, animator, func, data); + _ecore_unlock(); +} + +EAPI Ecore_Animator * +ecore_animator_timeline_add(double runtime, + Ecore_Timeline_Cb func, + const void *data) +{ + Ecore_Animator *animator; + animator = eo_add_custom(MY_CLASS, _ecore_parent, + ecore_animator_timeline_constructor(runtime, func, data)); + eo_unref(animator); + return animator; +} + +static void +_animator_timeline_constructor(Eo *obj, void *_pd, va_list *list) +{ + _ecore_lock(); + double runtime = va_arg(*list, double); + if (runtime <= 0.0) runtime = 0.0; + Ecore_Timeline_Cb func = va_arg(*list, Ecore_Timeline_Cb); + const void *data = va_arg(*list, const void *); + + Ecore_Animator_Private_Data *animator = _pd; + if (!_ecore_animator_add(obj, animator, _ecore_animator_run, NULL)) goto unlock; + + animator->data = obj; + animator->run_func = func; + animator->run_data = (void *)data; + animator->start = ecore_loop_time_get(); + animator->run = runtime; + +unlock: + _ecore_unlock(); +} + +static double +_pos_map_sin(double in) +{ + return eina_f32p32_double_to(eina_f32p32_sin(eina_f32p32_double_from(in))); +} + +#if 0 +static double +_pos_map_cos(double in) +{ + return eina_f32p32_double_to(eina_f32p32_cos(eina_f32p32_double_from(in))); +} +#endif + +static double +_pos_map_accel_factor(double pos, + double v1) +{ + int i, fact = (int)v1; + double p, o1 = pos, o2, v; + p = 1.0 - _pos_map_sin((M_PI / 2.0) + ((pos * M_PI) / 2.0)); + o2 = p; + for (i = 0; i < fact; i++) + { + o1 = o2; + o2 = o2 * p; + } + v = v1 - (double)fact; + pos = (v * o2) + ((1.0 - v) * o1); + return pos; +} + +static double +_pos_map_pow(double pos, + double divis, + int p) +{ + double v = 1.0; + int i; + for (i = 0; i < p; i++) v *= pos; + return ((pos * divis) * (1.0 - v)) + (pos * v); +} + +static double +_pos_map_spring(double pos, + int bounces, + double decfac) +{ + int segnum, segpos, b1, b2; + double len, decay, decpos, p2; + if (bounces < 0) bounces = 0; + p2 = _pos_map_pow(pos, 0.5, 3); + len = (M_PI / 2.0) + ((double)bounces * M_PI); + segnum = (bounces * 2) + 1; + segpos = 2 * (((int)(p2 * segnum) + 1) / 2); + b1 = segpos; + b2 = segnum + 1; + if (b1 < 0) b1 = 0; + decpos = (double)b1 / (double)b2; + decay = _pos_map_accel_factor(1.0 - decpos, decfac); + return _pos_map_sin((M_PI / 2.0) + (p2 * len)) * decay; +} + +#define DBL_TO(Fp) eina_f32p32_double_to(Fp) +#define DBL_FROM(D) eina_f32p32_double_from(D) +#define INT_FROM(I) eina_f32p32_int_from(I) +#define SIN(Fp) eina_f32p32_sin(Fp) +#define COS(Fp) eina_f32p32_cos(Fp) +#define ADD(A, B) eina_f32p32_add(A, B) +#define SUB(A, B) eina_f32p32_sub(A, B) +#define MUL(A, B) eina_f32p32_mul(A, B) + +EAPI double +ecore_animator_pos_map(double pos, + Ecore_Pos_Map map, + double v1, + double v2) +{ + /* purely functional - locking not required */ + if (pos > 1.0) pos = 1.0; + else if (pos < 0.0) + pos = 0.0; + switch (map) + { + case ECORE_POS_MAP_LINEAR: + return pos; + + case ECORE_POS_MAP_ACCELERATE: + /* pos = 1 - sin(Pi / 2 + pos * Pi / 2); */ + pos = DBL_TO(SUB(INT_FROM(1), SIN(ADD((EINA_F32P32_PI >> 1), MUL(DBL_FROM(pos), (EINA_F32P32_PI >> 1)))))); + return pos; + + case ECORE_POS_MAP_DECELERATE: + /* pos = sin(pos * Pi / 2); */ + pos = DBL_TO(SIN(MUL(DBL_FROM(pos), (EINA_F32P32_PI >> 1)))); + return pos; + + case ECORE_POS_MAP_SINUSOIDAL: + /* pos = (1 - cos(pos * Pi)) / 2 */ + pos = DBL_TO((SUB(INT_FROM(1), COS(MUL(DBL_FROM(pos), EINA_F32P32_PI)))) >> 1); + return pos; + + case ECORE_POS_MAP_ACCELERATE_FACTOR: + pos = _pos_map_accel_factor(pos, v1); + return pos; + + case ECORE_POS_MAP_DECELERATE_FACTOR: + pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v1); + return pos; + + case ECORE_POS_MAP_SINUSOIDAL_FACTOR: + if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v1) / 2.0; + else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v1) / 2.0); + return pos; + + case ECORE_POS_MAP_DIVISOR_INTERP: + pos = _pos_map_pow(pos, v1, (int)v2); + return pos; + + case ECORE_POS_MAP_BOUNCE: + pos = _pos_map_spring(pos, (int)v2, v1); + if (pos < 0.0) pos = -pos; + pos = 1.0 - pos; + return pos; + + case ECORE_POS_MAP_SPRING: + pos = 1.0 - _pos_map_spring(pos, (int)v2, v1); + return pos; + + default: + return pos; + } + return pos; +} + +EAPI void * +ecore_animator_del(Ecore_Animator *obj) +{ + void *data = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + Ecore_Animator_Private_Data *animator = eo_data_get(obj, MY_CLASS); + _ecore_lock(); + + if (animator->delete_me) + { + data = animator->data; + goto unlock; + } + animator->delete_me = EINA_TRUE; + animators_delete_me++; + if (animator->run_func) + data = animator->run_data; + else + data = animator->data; +unlock: + _ecore_unlock(); + return data; +} + +static void +_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Animator_Private_Data *pd = _pd; + + pd->delete_me = EINA_TRUE; + animators_delete_me++; + + eo_do_super(obj, eo_destructor()); +} + +EAPI void +ecore_animator_frametime_set(double frametime) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + if (frametime < 0.0) frametime = 0.0; + if (animators_frametime == frametime) goto unlock; + animators_frametime = frametime; + _end_tick(); + if (animators) _begin_tick(); +unlock: + _ecore_unlock(); +} + +EAPI double +ecore_animator_frametime_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); + return animators_frametime; +} + +EAPI void +ecore_animator_freeze(Ecore_Animator *animator) +{ + ECORE_ANIMATOR_CHECK(animator); + eo_do(animator, eo_event_freeze()); +} + +static void +_ecore_animator_freeze(Eo *obj EINA_UNUSED, void *_pd, + va_list *list EINA_UNUSED) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + Ecore_Animator_Private_Data *animator = _pd; + + if (animator->delete_me) goto unlock; + animator->suspended = EINA_TRUE; +unlock: + _ecore_unlock(); +} + +EAPI void +ecore_animator_thaw(Ecore_Animator *animator) +{ + ECORE_ANIMATOR_CHECK(animator); + eo_do(animator, eo_event_thaw()); +} + +static void +_ecore_animator_thaw(Eo *obj EINA_UNUSED, void *_pd, + va_list *list EINA_UNUSED) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + Ecore_Animator_Private_Data *animator = _pd; + + _ecore_lock(); + if (animator->delete_me) goto unlock; + animator->suspended = EINA_FALSE; +unlock: + _ecore_unlock(); +} + +EAPI void +ecore_animator_source_set(Ecore_Animator_Source source) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + src = source; + _end_tick(); + if (animators) _begin_tick(); + _ecore_unlock(); +} + +EAPI Ecore_Animator_Source +ecore_animator_source_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + return src; +} + +EAPI void +ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, + const void *data) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + begin_tick_cb = func; + begin_tick_data = data; + _end_tick(); + if (animators) _begin_tick(); + _ecore_unlock(); +} + +EAPI void +ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, + const void *data) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + end_tick_cb = func; + end_tick_data = data; + _end_tick(); + if (animators) _begin_tick(); + _ecore_unlock(); +} + +EAPI void +ecore_animator_custom_tick(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + if (src == ECORE_ANIMATOR_SOURCE_CUSTOM) _do_tick(); + _ecore_unlock(); +} + +void +_ecore_animator_shutdown(void) +{ + _end_tick(); + while (animators) + { + Ecore_Animator_Private_Data *animator; + + animator = animators; + animators = (Ecore_Animator_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators)); + + eo_parent_set(animator->obj, NULL); + if (eo_destructed_is(animator->obj)) + eo_manual_free(animator->obj); + else + eo_manual_free_set(animator->obj, EINA_FALSE); + } +} + +static Eina_Bool +_ecore_animator_run(void *data) +{ + Ecore_Animator *obj = data; + Ecore_Animator_Private_Data *animator = eo_data_get(obj, MY_CLASS); + + double pos = 0.0, t; + Eina_Bool run_ret; + + t = ecore_loop_time_get(); + if (animator->run > 0.0) + { + pos = (t - animator->start) / animator->run; + if (pos > 1.0) pos = 1.0; + else if (pos < 0.0) + pos = 0.0; + } + run_ret = animator->run_func(animator->run_data, pos); + if (t >= (animator->start + animator->run)) run_ret = EINA_FALSE; + return run_ret; +} + +static Eina_Bool +_ecore_animator(void *data EINA_UNUSED) +{ + Eina_Bool r; + _ecore_lock(); + r = _do_tick(); + _ecore_unlock(); + return r; +} + +static void +_class_constructor(Eo_Class *klass) +{ + const Eo_Op_Func_Description func_desc[] = { + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE), _ecore_animator_freeze), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW), _ecore_animator_thaw), + + EO_OP_FUNC(ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR), _animator_constructor), + EO_OP_FUNC(ECORE_ANIMATOR_ID(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR), _animator_timeline_constructor), + EO_OP_FUNC_SENTINEL + }; + + eo_class_funcs_set(klass, func_desc); +} + +static const Eo_Op_Description op_desc[] = { + EO_OP_DESCRIPTION(ECORE_ANIMATOR_SUB_ID_CONSTRUCTOR, "Add an animator to call func at every animation tick during main loop execution."), + EO_OP_DESCRIPTION(ECORE_ANIMATOR_SUB_ID_TIMELINE_CONSTRUCTOR, "Add an animator that runs for a limited time"), + EO_OP_DESCRIPTION_SENTINEL +}; + +static const Eo_Class_Description class_desc = { + EO_VERSION, + MY_CLASS_NAME, + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(&ECORE_ANIMATOR_BASE_ID, op_desc, ECORE_ANIMATOR_SUB_ID_LAST), + NULL, + sizeof(Ecore_Animator_Private_Data), + _class_constructor, + NULL +}; + +EO_DEFINE_CLASS(ecore_animator_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/src/lib/ecore/ecore_app.c b/src/lib/ecore/ecore_app.c new file mode 100644 index 0000000000..04df487d3c --- /dev/null +++ b/src/lib/ecore/ecore_app.c @@ -0,0 +1,98 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef _MSC_VER +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" + +static int app_argc = 0; +static char **app_argv = NULL; + +/** + * @addtogroup Ecore_Application_Group + * + * @{ + */ + +/** + * 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) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + + 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) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + + 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) +{ + EINA_MAIN_LOOP_CHECK_RETURN; +#ifdef HAVE_EXECVP + 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); +#endif +} + +/** + * @} + */ diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c new file mode 100644 index 0000000000..2d8ac1f661 --- /dev/null +++ b/src/lib/ecore/ecore_events.c @@ -0,0 +1,648 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +static int inpurge = 0; + +struct _Ecore_Event_Handler +{ + EINA_INLIST; + ECORE_MAGIC; + int type; + Ecore_Event_Handler_Cb func; + void *data; + int references; + Eina_Bool delete_me : 1; +}; +GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Handler); + +struct _Ecore_Event_Filter +{ + EINA_INLIST; + ECORE_MAGIC; + Ecore_Data_Cb func_start; + Ecore_Filter_Cb func_filter; + Ecore_End_Cb func_end; + void *loop_data; + void *data; + int references; + Eina_Bool delete_me : 1; +}; +GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Filter); + +struct _Ecore_Event +{ + EINA_INLIST; + ECORE_MAGIC; + int type; + void *event; + Ecore_End_Cb func_free; + void *data; + int references; + Eina_Bool delete_me : 1; +}; +GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event); + +static int events_num = 0; +static Ecore_Event *events = NULL; +static Ecore_Event *event_current = NULL; +static Ecore_Event *purge_events = 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_Handler *event_handlers_add_list = NULL; + +static Ecore_Event_Filter *event_filters = NULL; +static Ecore_Event_Filter *event_filter_current = NULL; +static Ecore_Event *event_filter_event_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); + +EAPI Ecore_Event_Handler * +ecore_event_handler_add(int type, + Ecore_Event_Handler_Cb func, + const void *data) +{ + Ecore_Event_Handler *eh = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + + if (!func) goto unlock; + if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) goto unlock; + eh = ecore_event_handler_calloc(1); + if (!eh) goto unlock; + 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) + { + ecore_event_handler_mp_free(eh); + goto unlock; + } + event_handlers = new_handlers; + for (i = p_alloc_num; i < event_handlers_alloc_num; i++) + event_handlers[i] = NULL; + } + } + if (ecore_raw_event_type == type) + event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh)); + else if (type < event_handlers_alloc_num) + event_handlers[type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh)); + +unlock: + _ecore_unlock(); + return eh; +} + +EAPI void * +ecore_event_handler_del(Ecore_Event_Handler *event_handler) +{ + void *data = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER)) + { + ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER, + "ecore_event_handler_del"); + goto unlock; + } + data = _ecore_event_handler_del(event_handler); +unlock: + _ecore_unlock(); + + return data; +} + +EAPI void * +ecore_event_handler_data_get(Ecore_Event_Handler *eh) +{ + void *data = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER)) + { + ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_get"); + goto unlock; + } + data = eh->data; +unlock: + _ecore_unlock(); + return data; +} + +EAPI void * +ecore_event_handler_data_set(Ecore_Event_Handler *eh, + const void *data) +{ + void *old = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER)) + { + ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_set"); + goto unlock; + } + old = eh->data; + eh->data = (void *)data; +unlock: + _ecore_unlock(); + + return old; +} + +static void +_ecore_event_generic_free(void *data EINA_UNUSED, + void *event) +{ /* DO NOT MEMPOOL FREE THIS */ + free(event); +} + +EAPI Ecore_Event * +ecore_event_add(int type, + void *ev, + Ecore_End_Cb func_free, + void *data) +{ + Ecore_Event *event = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + +/* if (!ev) goto unlock; */ + if (type <= ECORE_EVENT_NONE) goto unlock; + if (type >= event_id_max) goto unlock; + if ((ev) && (!func_free)) func_free = _ecore_event_generic_free; + event = _ecore_event_add(type, ev, func_free, data); +unlock: + _ecore_unlock(); + return event; +} + +EAPI void * +ecore_event_del(Ecore_Event *event) +{ + void *data = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT)) + { + ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del"); + goto unlock; + } + EINA_SAFETY_ON_TRUE_GOTO(event->delete_me, unlock); + event->delete_me = 1; + data = event->data; +unlock: + _ecore_unlock(); + return data; +} + +EAPI int +ecore_event_type_new(void) +{ + int id; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + _ecore_lock(); + id = event_id_max++; + _ecore_unlock(); + + return id; +} + +EAPI Ecore_Event_Filter * +ecore_event_filter_add(Ecore_Data_Cb func_start, + Ecore_Filter_Cb func_filter, + Ecore_End_Cb func_end, + const void *data) +{ + Ecore_Event_Filter *ef = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + if (!func_filter) goto unlock; + ef = ecore_event_filter_calloc(1); + if (!ef) goto unlock; + 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)); +unlock: + _ecore_unlock(); + return ef; +} + +EAPI void * +ecore_event_filter_del(Ecore_Event_Filter *ef) +{ + void *data = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER)) + { + ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del"); + goto unlock; + } + EINA_SAFETY_ON_TRUE_GOTO(ef->delete_me, unlock); + ef->delete_me = 1; + event_filters_delete_me = 1; + data = ef->data; +unlock: + _ecore_unlock(); + + return data; +} + +EAPI int +ecore_event_current_type_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + return ecore_raw_event_type; +} + +EAPI void * +ecore_event_current_event_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + return ecore_raw_event_event; +} + +EAPI void * +_ecore_event_handler_del(Ecore_Event_Handler *event_handler) +{ + EINA_SAFETY_ON_TRUE_RETURN_VAL(event_handler->delete_me, NULL); + event_handler->delete_me = 1; + event_handlers_delete_list = eina_list_append(event_handlers_delete_list, event_handler); + return event_handler->data; +} + +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) ecore_event_handler_mp_free(eh); + } + } + EINA_LIST_FREE(event_handlers_delete_list, eh) + ecore_event_handler_mp_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); + ecore_event_filter_mp_free(ef); + } + event_filters_delete_me = 0; + event_filter_current = NULL; + event_filter_event_current = NULL; +} + +int +_ecore_event_exist(void) +{ + Ecore_Event *e; + EINA_INLIST_FOREACH(events, e) + if (!e->delete_me) return 1; + return 0; +} + +Ecore_Event * +_ecore_event_add(int type, + void *ev, + Ecore_End_Cb func_free, + void *data) +{ + Ecore_Event *e; + + e = ecore_event_calloc(1); + 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; + if (inpurge > 0) + { + purge_events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(e)); + events_num++; + } + else + { + 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) _ecore_call_end_cb(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); + ecore_event_mp_free(event); + events_num--; + return data; +} + +static void +_ecore_event_purge_deleted(void) +{ + Ecore_Event *itr = events; + + inpurge++; + while (itr) + { + Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next; + if ((!itr->references) && (itr->delete_me)) + _ecore_event_del(itr); + itr = next; + } + inpurge--; + while (purge_events) + { + Ecore_Event *e = purge_events; + purge_events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(purge_events)); + events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e)); + } +} + +static inline void +_ecore_event_filters_apply() +{ + 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 = _ecore_call_data_cb(ef->func_start, ef->data); + + if (!event_filter_event_current) + { + /* regular main loop, start from head */ + event_filter_event_current = events; + } + else + { + /* recursive main loop, continue from where we were */ + event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next; + } + + while (event_filter_event_current) + { + Ecore_Event *e = event_filter_event_current; + + if (!_ecore_call_filter_cb(ef->func_filter, ef->data, + ef->loop_data, e->type, e->event)) + { + ecore_event_del(e); + } + + if (event_filter_event_current) /* may have changed in recursive main loops */ + event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next; + } + if (ef->func_end) + _ecore_call_end_cb(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); + ecore_event_filter_mp_free(ef); + } + } + if (!deleted_in_use) + event_filters_delete_me = 0; + } +} + +void +_ecore_event_call(void) +{ + Eina_List *l, *l_next; + Ecore_Event_Handler *eh; + + _ecore_event_filters_apply(); + + if (!event_current) + { + /* regular main loop, start from head */ + event_current = events; + event_handler_current = NULL; + } + + while (event_current) + { + Ecore_Event *e = event_current; + int handle_count = 0; + + if (e->delete_me) + { + event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next; + continue; + } + + ecore_raw_event_type = e->type; + ecore_raw_event_event = e->event; + e->references++; + 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)) + { + eh = event_handler_current; + if (!eh->delete_me) + { + Eina_Bool ret; + + handle_count++; + + eh->references++; + ret = _ecore_call_handler_cb(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; + } + } + while (event_handlers_add_list) + { + eh = event_handlers_add_list; + event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh)); + event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh)); + } + /* 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--; + e->delete_me = 1; + + if (event_current) /* may have changed in recursive main loops */ + event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next; + } + + 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); + ecore_event_handler_mp_free(eh); + } +} + +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)); +} + diff --git a/src/lib/ecore/ecore_exe.c b/src/lib/ecore/ecore_exe.c new file mode 100644 index 0000000000..19bc39b008 --- /dev/null +++ b/src/lib/ecore/ecore_exe.c @@ -0,0 +1,1913 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_PRCTL_H +# include +#endif + +#ifdef HAVE_SYS_WAIT_H +# include +#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 existent 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 */ + + Ecore_Exe_Cb pre_free_cb; +}; + +/* 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 preceding 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 Eina_Bool _ecore_exe_data_generic_handler(void *data, + Ecore_Fd_Handler *fd_handler, + Ecore_Exe_Flags flags); +static Eina_Bool _ecore_exe_data_error_handler(void *data, + Ecore_Fd_Handler *fd_handler); +static Eina_Bool _ecore_exe_data_read_handler(void *data, + Ecore_Fd_Handler *fd_handler); +static Eina_Bool _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 EINA_UNUSED, + void *ev); +static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid); +static Eina_Bool _ecore_exe_make_sure_its_dead(void *data); +static Eina_Bool _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 EINA_UNUSED, + int line EINA_UNUSED) +{ + 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; +} + +/** + * @addtogroup Ecore_Exe_Group + * + * @{ + */ + +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 + * @ref ECORE_EXE_WIN32_PRIORITY_NORMAL priority, unless the calling + * process is in @ref ECORE_EXE_WIN32_PRIORITY_IDLE or + * @ref ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL priority. In that case, the + * child process inherits this priority. + * @li On other platforms, if set to @ref 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 @ref ECORE_EXE_PRIORITY_INHERIT on other OS. + */ +EAPI void +ecore_exe_run_priority_set(int pri) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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() + */ +EAPI int +ecore_exe_run_priority_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + return run_pri; +} + +/** + * Spawns a child process. + * + * This is now just a thin wrapper around ecore_exe_pipe_run() + * @note When you use this function you will have no permissions + * to write or read on the pipe that connects you with the spwaned process. + * If you need to do that use ecore_exe_pipe_run() with the + * appropriated flags. + * + * @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. + */ +EAPI Ecore_Exe * +ecore_exe_run(const char *exe_cmd, + const void *data) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + return ecore_exe_pipe_run(exe_cmd, 0, data); +} + +/** + * 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. + */ +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; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + if (!exe_cmd) return 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->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) + { +#ifdef PRIO_PROCESS + if ((run_pri >= -20) && (run_pri <= 19)) + setpriority(PRIO_PROCESS, 0, run_pri); +#else +#warning "Your OS/libc does not provide PRIO_PROCESS (and possibly setpriority())" +#warning "This is a POSIX-1.2001 standard and it is highly encouraged that you" +#warning "Have support for this" +#endif + } + /* 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 success */ + { + /* 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) + 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) + 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, + Ecore_Exe_Cb func) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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 receives 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 @c EINA_TRUE if successful, @c EINA_FALSE on failure. + */ +EAPI Eina_Bool +ecore_exe_send(Ecore_Exe *exe, + const void *data, + int size) +{ + void *buf; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_send"); + return EINA_FALSE; + } + + if (exe->close_stdin) + { + ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p", + exe, size, data); + return EINA_FALSE; + } + + 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 EINA_FALSE; + } + + buf = realloc(exe->write_data_buf, exe->write_data_size + size); + if (!buf) return EINA_FALSE; + + 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 EINA_TRUE; +} + +/** + * The stdin of the given child process will close when the write buffer is empty. + * + * @param exe The child process + */ +EAPI void +ecore_exe_close_stdin(Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI void +ecore_exe_auto_limits_set(Ecore_Exe *exe, + int start_bytes, + int end_bytes, + int start_lines, + int end_lines) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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 separate 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? + * @return The event data. + */ +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; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + 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 (i > last) /* Partial line left over, save it for next time. */ + { + if (count != 0) 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); + } + } + 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; + } + } + } + + 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. + */ +EAPI void +ecore_exe_tag_set(Ecore_Exe *exe, + const char *tag) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI const char * +ecore_exe_tag_get(const Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + 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. + */ +EAPI void * +ecore_exe_free(Ecore_Exe *exe) +{ + void *data; + int ok = 0; + int result; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + 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. + */ +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. + */ +EAPI pid_t +ecore_exe_pid_get(const Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + 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, @c NULL otherwise. This string is the + * pointer to the internal value and must not be modified in + * any way. + */ +EAPI const char * +ecore_exe_cmd_get(const Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + 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() + */ +EAPI void * +ecore_exe_data_get(const Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get"); + return NULL; + } + return exe->data; +} + +/** + * Sets the data attached to the given process handle. + * @param exe The given process handle. + * @param data The pointer to attach + * @return The data pointer previously attached to @p exe with + * ecore_exe_run(), ecore_exe_pipe_run(), or ecore_exe_data_set() + * @since 1.1 + */ +EAPI void * +ecore_exe_data_set(Ecore_Exe *exe, + void *data) +{ + void *ret; + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, __func__); + return NULL; + } + ret = exe->data; + exe->data = data; + return ret; +} + +/** + * Retrieves the flags attached to the given process handle. + * @param exe The given process handle. + * @return The flags attached to @p exe. + */ +EAPI Ecore_Exe_Flags +ecore_exe_flags_get(const Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get"); + return 0; + } + return exe->flags; +} + +/** + * Pauses the given process by sending it a @c SIGSTOP signal. + * @param exe Process handle to the given process. + */ +EAPI void +ecore_exe_pause(Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI void +ecore_exe_continue(Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI void +ecore_exe_interrupt(Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI void +ecore_exe_quit(Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI void +ecore_exe_terminate(Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI void +ecore_exe_kill(Ecore_Exe *exe) +{ + struct _ecore_exe_dead_exe *dead; + + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI void +ecore_exe_signal(Ecore_Exe *exe, + int num) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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. + */ +EAPI void +ecore_exe_hup(Ecore_Exe *exe) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + 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 independent 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 Eina_Bool +_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))) + { + if (dead->cmd) + INF("Sending KILL signal to allegedly dead %s (%d).", + dead->cmd, dead->pid); + else + INF("Sending KILL signal to allegedly 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 ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_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))) + { + 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 ECORE_CALLBACK_CANCEL; +} + +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; + } + } + +#ifdef HAVE_SYS_PRCTL_H + if ((flags & ECORE_EXE_TERM_WITH_PARENT)) + { + prctl(PR_SET_PDEATHSIG, SIGTERM); + } +#endif + + 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) /* Find users preferred shell. */ + { + shell = getenv("SHELL"); + if (!shell) + shell = "/bin/sh"; + } + errno = 0; + execl(shell, shell, "-c", exe_cmd, (char *)NULL); + } + else + { /* We can run this directly. */ + if (!args) + { + IF_FREE(buf); + IF_FREE(args); + ERR("arg[0] is NULL!"); + return; + } + errno = 0; + execvp(args[0], args); + } + + save_errno = errno; + IF_FREE(buf); + IF_FREE(args); + errno = save_errno; + return; +} + +static Eina_Bool +_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 ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_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 Eina_Bool +_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 Eina_Bool +_ecore_exe_data_write_handler(void *data, + Ecore_Fd_Handler *fd_handler EINA_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 ECORE_CALLBACK_RENEW; +} + +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 EINA_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 EINA_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 EINA_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; + } +} + diff --git a/src/lib/ecore/ecore_exe_ps3.c b/src/lib/ecore/ecore_exe_ps3.c new file mode 100644 index 0000000000..1ef1e81fcb --- /dev/null +++ b/src/lib/ecore/ecore_exe_ps3.c @@ -0,0 +1,20 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_ESCAPE +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" + +void +_ecore_exe_init(void) +{ +} + +void +_ecore_exe_shutdown(void) +{ +} diff --git a/src/lib/ecore/ecore_exe_win32.c b/src/lib/ecore/ecore_exe_win32.c new file mode 100644 index 0000000000..71557c3676 --- /dev/null +++ b/src/lib/ecore/ecore_exe_win32.c @@ -0,0 +1,1055 @@ +/* + * 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 +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include + +#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; + + Ecore_Exe_Cb pre_free_cb; +}; + +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 Eina_Bool _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, + Ecore_Exe_Cb func) +{ + 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) 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 EINA_UNUSED, + int start_bytes EINA_UNUSED, + int end_bytes EINA_UNUSED, + int start_lines EINA_UNUSED, + int end_lines EINA_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 EINA_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 2048 + 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, sizeof(buf), &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 EINA_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 EINA_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 EINA_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 EINA_UNUSED, + void *ev) +{ + Ecore_Exe_Event_Data *e; + + e = (Ecore_Exe_Event_Data *)ev; + ecore_exe_event_data_free(e); +} + +static Eina_Bool +_ecore_exe_close_cb(void *data, + Ecore_Win32_Handler *wh EINA_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 EINA_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); +} + diff --git a/src/lib/ecore/ecore_exe_wince.c b/src/lib/ecore/ecore_exe_wince.c new file mode 100644 index 0000000000..c07fcbe31b --- /dev/null +++ b/src/lib/ecore/ecore_exe_wince.c @@ -0,0 +1,21 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" + +void +_ecore_exe_init(void) +{ +} + +void +_ecore_exe_shutdown(void) +{ +} + diff --git a/src/lib/ecore/ecore_getopt.c b/src/lib/ecore/ecore_getopt.c new file mode 100644 index 0000000000..42e43e8915 --- /dev/null +++ b/src/lib/ecore/ecore_getopt.c @@ -0,0 +1,1936 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include +#include +#include +#include +#include + +#ifdef ENABLE_NLS +# include +#else +# define gettext(x) (x) +# define dgettext(domain, x) (x) +#endif + +#define _(x) dgettext("ecore", x) + +#ifdef _WIN32_WCE +# include +#endif + +#ifdef HAVE_EXOTIC +# include +#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 EINA_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((unsigned char)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((int) 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; itr++) + { + used = _ecore_getopt_help_line + (fp, base, total, used, *itr, strlen(*itr)); + if (itr[1]) + 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 Eina_Bool +_ecore_getopt_desc_is_sentinel(const Ecore_Getopt_Desc *desc) +{ + return (desc->shortname == '\0') && (!desc->longname); +} + +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. + * + * @param fp The file the message will be printed on. + * @param parser The parser to be used. + */ +EAPI void +ecore_getopt_help(FILE *fp, + const Ecore_Getopt *parser) +{ + const char *var; + + EINA_MAIN_LOOP_CHECK_RETURN; + if (!parser) return; + + if (_argc < 1) + { + ecore_app_args_get(&_argc, &_argv); + if ((_argc > 0) && (_argv[0])) + 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 Eina_Bool +_ecore_getopt_parse_bool(const char *str, + Eina_Bool *v) +{ + if ((strcmp(str, "0") == 0) || + (strcasecmp(str, "f") == 0) || + (strcasecmp(str, "false") == 0) || + (strcasecmp(str, "no") == 0) || + (strcasecmp(str, "off") == 0) + ) + { + *v = EINA_FALSE; + return EINA_TRUE; + } + else if ((strcmp(str, "1") == 0) || + (strcasecmp(str, "t") == 0) || + (strcasecmp(str, "true") == 0) || + (strcasecmp(str, "yes") == 0) || + (strcasecmp(str, "on") == 0) + ) + { + *v = EINA_TRUE; + return EINA_TRUE; + } + + return EINA_FALSE; +} + +static Eina_Bool +_ecore_getopt_parse_long(const char *str, + long int *v) +{ + char *endptr = NULL; + *v = strtol(str, &endptr, 0); + return endptr > str; +} + +static Eina_Bool +_ecore_getopt_parse_double(const char *str, + double *v) +{ + char *endptr = NULL; + *v = strtod(str, &endptr); + return endptr > str; +} + +static Eina_Bool +_ecore_getopt_parse_store(const Ecore_Getopt *parser EINA_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; + Eina_Bool b; + + if (!value->ptrp) + { + _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); + return EINA_FALSE; + } + + 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 EINA_TRUE; + + case ECORE_GETOPT_TYPE_BOOL: + if (_ecore_getopt_parse_bool(arg_val, &b)) + { + *value->boolp = b; + return EINA_TRUE; + } + else + { + _ecore_getopt_desc_print_error + (desc, _("unknown boolean value %s.\n"), arg_val); + return EINA_FALSE; + } + + case ECORE_GETOPT_TYPE_SHORT: + if (!_ecore_getopt_parse_long(arg_val, &v)) + goto error; + *value->shortp = v; + return EINA_TRUE; + + case ECORE_GETOPT_TYPE_INT: + if (!_ecore_getopt_parse_long(arg_val, &v)) + goto error; + *value->intp = v; + return EINA_TRUE; + + case ECORE_GETOPT_TYPE_LONG: + if (!_ecore_getopt_parse_long(arg_val, &v)) + goto error; + *value->longp = v; + return EINA_TRUE; + + case ECORE_GETOPT_TYPE_USHORT: + if (!_ecore_getopt_parse_long(arg_val, &v)) + goto error; + *value->ushortp = v; + return EINA_TRUE; + + case ECORE_GETOPT_TYPE_UINT: + if (!_ecore_getopt_parse_long(arg_val, &v)) + goto error; + *value->uintp = v; + return EINA_TRUE; + + case ECORE_GETOPT_TYPE_ULONG: + if (!_ecore_getopt_parse_long(arg_val, &v)) + goto error; + *value->ulongp = v; + return EINA_TRUE; + + case ECORE_GETOPT_TYPE_DOUBLE: + if (!_ecore_getopt_parse_double(arg_val, &d)) + goto error; + *value->doublep = d; + break; + } + + return EINA_TRUE; + +error: + _ecore_getopt_desc_print_error + (desc, _("invalid number format %s\n"), arg_val); + return EINA_FALSE; + +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 EINA_TRUE; +} + +static Eina_Bool +_ecore_getopt_parse_store_const(const Ecore_Getopt *parser EINA_UNUSED, + const Ecore_Getopt_Desc *desc, + Ecore_Getopt_Value *val, + const char *arg_val EINA_UNUSED) +{ + if (!val->ptrp) + { + _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); + return EINA_FALSE; + } + + *val->ptrp = (void *)desc->action_param.store_const; + return EINA_TRUE; +} + +static Eina_Bool +_ecore_getopt_parse_store_true(const Ecore_Getopt *parser EINA_UNUSED, + const Ecore_Getopt_Desc *desc, + Ecore_Getopt_Value *val, + const char *arg_val EINA_UNUSED) +{ + if (!val->boolp) + { + _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); + return EINA_FALSE; + } + *val->boolp = EINA_TRUE; + return EINA_TRUE; +} + +static Eina_Bool +_ecore_getopt_parse_store_false(const Ecore_Getopt *parser EINA_UNUSED, + const Ecore_Getopt_Desc *desc, + Ecore_Getopt_Value *val, + const char *arg_val EINA_UNUSED) +{ + if (!val->boolp) + { + _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); + return EINA_FALSE; + } + *val->boolp = EINA_FALSE; + return EINA_TRUE; +} + +static Eina_Bool +_ecore_getopt_parse_choice(const Ecore_Getopt *parser EINA_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 EINA_FALSE; + } + + pchoice = desc->action_param.choices; + for (; *pchoice; pchoice++) + if (strcmp(*pchoice, arg_val) == 0) + { + *val->strp = (char *)*pchoice; + return EINA_TRUE; + } + + _ecore_getopt_desc_print_error + (desc, _("invalid choice \"%s\". Valid values are: "), arg_val); + + pchoice = desc->action_param.choices; + for (; *pchoice; pchoice++) + { + fputs(*pchoice, stderr); + if (pchoice[1]) + fputs(", ", stderr); + } + + fputs(".\n", stderr); + return EINA_FALSE; +} + +static Eina_Bool +_ecore_getopt_parse_append(const Ecore_Getopt *parser EINA_UNUSED, + const Ecore_Getopt_Desc *desc, + Ecore_Getopt_Value *val, + const char *arg_val) +{ + void *data; + long int v; + double d; + Eina_Bool b; + + if (!arg_val) + { + _ecore_getopt_desc_print_error + (desc, _("missing parameter to append.\n")); + return EINA_FALSE; + } + + if (!val->listp) + { + _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); + return EINA_FALSE; + } + + 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(Eina_Bool)); + if (data) + *(Eina_Bool *)data = b; + } + else + { + _ecore_getopt_desc_print_error(desc, _("unknown boolean value %s.\n"), arg_val); + return EINA_FALSE; + } + } + 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 EINA_FALSE; + } + } + + *val->listp = eina_list_append(*val->listp, data); + return EINA_TRUE; + +error: + _ecore_getopt_desc_print_error + (desc, _("invalid number format %s\n"), arg_val); + return EINA_FALSE; +} + +static Eina_Bool +_ecore_getopt_parse_count(const Ecore_Getopt *parser EINA_UNUSED, + const Ecore_Getopt_Desc *desc, + Ecore_Getopt_Value *val, + const char *arg_val EINA_UNUSED) +{ + if (!val->intp) + { + _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); + return EINA_FALSE; + } + + (*val->intp)++; + return EINA_TRUE; +} + +static Eina_Bool +_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 EINA_FALSE; + } + + if (!val->ptrp) + { + _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n")); + return EINA_FALSE; + } + } + + if (!cb->func) + { + _ecore_getopt_desc_print_error(desc, _("missing callback function!\n")); + return EINA_FALSE; + } + + return cb->func(parser, desc, arg_val, (void *)cb->data, val); +} + +static Eina_Bool +_ecore_getopt_parse_help(const Ecore_Getopt *parser, + const Ecore_Getopt_Desc *desc EINA_UNUSED, + Ecore_Getopt_Value *val, + const char *arg_val EINA_UNUSED) +{ + if (val->boolp) + (*val->boolp) = EINA_TRUE; + ecore_getopt_help(stdout, parser); + return EINA_TRUE; +} + +static Eina_Bool +_ecore_getopt_parse_version(const Ecore_Getopt *parser, + const Ecore_Getopt_Desc *desc, + Ecore_Getopt_Value *val, + const char *arg_val EINA_UNUSED) +{ + if (val->boolp) + (*val->boolp) = EINA_TRUE; + if (!parser->version) + { + _ecore_getopt_desc_print_error(desc, _("no version was defined.\n")); + return EINA_FALSE; + } + _ecore_getopt_version(stdout, parser); + return EINA_TRUE; +} + +static Eina_Bool +_ecore_getopt_parse_copyright(const Ecore_Getopt *parser, + const Ecore_Getopt_Desc *desc, + Ecore_Getopt_Value *val, + const char *arg_val EINA_UNUSED) +{ + if (val->boolp) + (*val->boolp) = EINA_TRUE; + if (!parser->copyright) + { + _ecore_getopt_desc_print_error(desc, _("no copyright was defined.\n")); + return EINA_FALSE; + } + _ecore_getopt_copyright(stdout, parser); + return EINA_TRUE; +} + +static Eina_Bool +_ecore_getopt_parse_license(const Ecore_Getopt *parser, + const Ecore_Getopt_Desc *desc, + Ecore_Getopt_Value *val, + const char *arg_val EINA_UNUSED) +{ + if (val->boolp) + (*val->boolp) = EINA_TRUE; + if (!parser->license) + { + _ecore_getopt_desc_print_error(desc, _("no license was defined.\n")); + return EINA_FALSE; + } + _ecore_getopt_license(stdout, parser); + return EINA_TRUE; +} + +static Eina_Bool +_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 EINA_FALSE; + } +} + +static Eina_Bool +_ecore_getopt_parse_arg_long(const Ecore_Getopt *parser, + Ecore_Getopt_Value *values, + int argc EINA_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; + Eina_Bool ret; + + desc = _ecore_getopt_parse_find_long(parser, arg); + if (!desc) + { + fprintf(stderr, _("ERROR: unknown option --%s, ignored.\n"), arg); + if (parser->strict) + return EINA_FALSE; + + (*idx)++; + return EINA_TRUE; + } + + (*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 EINA_FALSE; + return EINA_TRUE; + } + } + 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 EINA_FALSE; + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_getopt_parse_arg_short(const Ecore_Getopt *parser, + Ecore_Getopt_Value *values, + int argc EINA_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; + Eina_Bool 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 EINA_FALSE; + + 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 EINA_FALSE; + return EINA_TRUE; + } + } + 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 EINA_FALSE; + } + + if (run) + (*idx)++; + + return EINA_TRUE; +} + +static Eina_Bool +_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 EINA_TRUE; + } + + 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 @c EINA_TRUE if there are duplicates, @c EINA_FALSE otherwise. + * @param parser The parser to be checked. + */ +EAPI Eina_Bool +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 EINA_TRUE; + } + } + + 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 EINA_TRUE; + } + } + } + return EINA_FALSE; +} + +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 @c 1 on value as a boolean + * (@c value->boolp) if it's not @c 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 @c -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 values 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. + */ +EAPI 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)) + ecore_app_args_get(&argc, &argv); + + if (argc < 1) + { + fputs(_("ERROR: no arguments provided.\n"), stderr); + return -1; + } + + if (argv[0]) + 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 @c NULL, so you can easily make your list head @c NULL. + */ +EAPI 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). + * + * @param parser This parameter isn't in use. + * @param desc This parameter isn't in use. + * @param str Geometry value + * @param data This parameter isn't in use. + * @param storage must be a pointer to @c Eina_Rectangle and will be used to + * store the four values passed in the given string. + * @return @c EINA_TRUE on success, @c EINA_FALSE on incorrect geometry value. + * + * @c callback_data value is ignored, you can safely use @c NULL. + */ +EAPI Eina_Bool +ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser EINA_UNUSED, + const Ecore_Getopt_Desc *desc EINA_UNUSED, + const char *str, + void *data EINA_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 EINA_FALSE; + } + + return EINA_TRUE; +} + +/** + * Helper ecore_getopt callback to parse geometry size (WxH). + * + * @param parser This parameter isn't in use. + * @param desc This parameter isn't in use. + * @param str size value + * @param data This parameter isn't in use. + * @param storage must be a pointer to @c Eina_Rectangle and will be used to + * store the two values passed in the given string and @c 0 in the x and y + * fields. + * @return @c EINA_TRUE on success, @c EINA_FALSE on incorrect size value. + * + * @c callback_data value is ignored, you can safely use @c NULL. + */ +EAPI Eina_Bool +ecore_getopt_callback_size_parse(const Ecore_Getopt *parser EINA_UNUSED, + const Ecore_Getopt_Desc *desc EINA_UNUSED, + const char *str, + void *data EINA_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 EINA_FALSE; + } + v->x = 0; + v->y = 0; + + return EINA_TRUE; +} + diff --git a/src/lib/ecore/ecore_glib.c b/src/lib/ecore/ecore_glib.c new file mode 100644 index 0000000000..5b73180951 --- /dev/null +++ b/src/lib/ecore/ecore_glib.c @@ -0,0 +1,346 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#ifdef HAVE_GLIB +# include + +static Eina_Bool _ecore_glib_active = EINA_FALSE; +static Ecore_Select_Function _ecore_glib_select_original; +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->events & G_IO_IN)) + { + itr->revents |= G_IO_IN; + ready--; + } + if (FD_ISSET(itr->fd, wfds) && (itr->events & G_IO_OUT)) + { + itr->revents |= G_IO_OUT; + ready--; + } + if (FD_ISSET(itr->fd, efds) && (itr->events & (G_IO_HUP | G_IO_ERR))) + { + 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; + GMutex *mutex; + GMainContext *ctx; + int ret; + + g_static_mutex_init(&lock); + mutex = g_static_mutex_get_mutex(&lock); + ctx = g_main_context_default(); + + if (g_main_context_acquire(ctx)) + { + if (mutex) 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); + + if (mutex) g_mutex_unlock(mutex); + g_main_context_release(ctx); + g_static_mutex_free(&lock); + + 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 +} + +/** + * @addtogroup Ecore_Main_Loop_Group + * + * @} + */ + +/** + * 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. + * + * Example of use: + * @code + * + * int main(void) + * { + * ecore_init(); + * ecore_main_loop_glib_integrate(); + * + * // some code here + * + * ecore_main_loop_begin(); + * + * ecore_shutdown(); + * + * return 0; + * } + * + * @endcode + * + * @note This is only available if Ecore was compiled with GLib support. + * @note You don't need to call this function if Ecore was compiled with + * --enable-glib-integration-always. + * + * @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 + ERR("No glib support"); + 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; +} + +/** + * @} + */ diff --git a/src/lib/ecore/ecore_idle_enterer.c b/src/lib/ecore/ecore_idle_enterer.c new file mode 100644 index 0000000000..e7d10e555a --- /dev/null +++ b/src/lib/ecore/ecore_idle_enterer.c @@ -0,0 +1,313 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#define MY_CLASS ECORE_IDLE_ENTERER_CLASS + +#define MY_CLASS_NAME "ecore_idle_enterer" + +EAPI Eo_Op ECORE_IDLE_ENTERER_BASE_ID = EO_NOOP; + +struct _Ecore_Idle_Enterer_Private_Data +{ + EINA_INLIST; + Ecore_Idle_Enterer *obj; + Ecore_Task_Cb func; + void *data; + int references; + Eina_Bool delete_me : 1; +}; +typedef struct _Ecore_Idle_Enterer_Private_Data Ecore_Idle_Enterer_Private_Data; + +static Ecore_Idle_Enterer_Private_Data *idle_enterers = NULL; +static Ecore_Idle_Enterer_Private_Data *idle_enterer_current = NULL; +static int idle_enterers_delete_me = 0; + +static void * +_ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer); + +/** + * @addtogroup Ecore_Idle_Group + * + * @{ + */ + +static Eina_Bool +_ecore_idle_enterer_add(Ecore_Idle_Enterer *obj, + Ecore_Idle_Enterer_Private_Data *ie, + Ecore_Task_Cb func, + const void *data) +{ + if (EINA_UNLIKELY(!eina_main_loop_is())) + { + eo_error_set(obj); + EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); + } + + ie->obj = obj; + eo_do_super(obj, eo_constructor()); + eo_manual_free_set(obj, EINA_TRUE); + + if (!func) + { + eo_error_set(obj); + ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); + return EINA_FALSE; + } + + ie->func = func; + ie->data = (void *)data; + return EINA_TRUE; +} + +/** + * 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. + * @note The function func will be called every time the main loop is entering + * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 + * (or ECORE_CALLBACK_CANCEL) deletes the idle enterer. + */ +EAPI Ecore_Idle_Enterer * +ecore_idle_enterer_add(Ecore_Task_Cb func, + const void *data) +{ + Ecore_Idle_Enterer *ie = NULL; + ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_enterer_after_constructor(func, data)); + eo_unref(ie); + return ie; +} + +static void +_idle_enterer_after_constructor(Eo *obj, void *_pd, va_list *list) +{ + Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); + const void *data = va_arg(*list, const void *); + + _ecore_lock(); + Ecore_Idle_Enterer_Private_Data *ie = _pd; + if (!_ecore_idle_enterer_add(obj, ie, func, data)) goto unlock; + + idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie)); + +unlock: + _ecore_unlock(); +} + +/** + * 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. + * @note The function func will be called every time the main loop is entering + * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 + * (or ECORE_CALLBACK_CANCEL) deletes the idle enterer. + */ +EAPI Ecore_Idle_Enterer * +ecore_idle_enterer_before_add(Ecore_Task_Cb func, + const void *data) +{ + Ecore_Idle_Enterer *ie = NULL; + ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_enterer_before_constructor(func, data)); + eo_unref(ie); + return ie; +} + +static void +_idle_enterer_before_constructor(Eo *obj, void *_pd, va_list *list) +{ + Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); + const void *data = va_arg(*list, const void *); + + _ecore_lock(); + Ecore_Idle_Enterer_Private_Data *ie = _pd; + if (!_ecore_idle_enterer_add(obj, ie, func, data)) goto unlock; + + idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie)); + +unlock: + _ecore_unlock(); +} + +static void +_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) +{ + eo_error_set(obj); + ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); +} + +/** + * 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. + */ +EAPI void * +ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer) +{ + void *data = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + + _ecore_lock(); + data = _ecore_idle_enterer_del(idle_enterer); + _ecore_unlock(); + return data; +} + +/** + * @} + */ + + +static void * +_ecore_idle_enterer_del(Ecore_Idle_Enterer *obj) +{ + Ecore_Idle_Enterer_Private_Data *idle_enterer = eo_data_get(obj, MY_CLASS); + + EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_enterer->delete_me, NULL); + idle_enterer->delete_me = 1; + idle_enterers_delete_me = 1; + return idle_enterer->data; +} + +static void +_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Idle_Enterer_Private_Data *idle_enterer = _pd; + + idle_enterer->delete_me = 1; + idle_enterers_delete_me = 1; + + eo_do_super(obj, eo_destructor()); +} + +void +_ecore_idle_enterer_shutdown(void) +{ + Ecore_Idle_Enterer_Private_Data *ie; + while ((ie = idle_enterers)) + { + idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers)); + + eo_parent_set(ie->obj, NULL); + if (eo_destructed_is(ie->obj)) + eo_manual_free(ie->obj); + else + eo_manual_free_set(ie->obj, EINA_FALSE); + } + 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_Private_Data *)EINA_INLIST_GET(idle_enterer_current)->next; + } + + while (idle_enterer_current) + { + Ecore_Idle_Enterer_Private_Data *ie = (Ecore_Idle_Enterer_Private_Data *)idle_enterer_current; + if (!ie->delete_me) + { + ie->references++; + if (!_ecore_call_task_cb(ie->func, ie->data)) + { + if (!ie->delete_me) _ecore_idle_enterer_del(ie->obj); + } + ie->references--; + } + if (idle_enterer_current) /* may have changed in recursive main loops */ + idle_enterer_current = + (Ecore_Idle_Enterer_Private_Data *)EINA_INLIST_GET(idle_enterer_current)->next; + } + if (idle_enterers_delete_me) + { + Ecore_Idle_Enterer_Private_Data *l; + int deleted_idler_enterers_in_use = 0; + + for (l = idle_enterers; l; ) + { + Ecore_Idle_Enterer_Private_Data *ie = l; + l = (Ecore_Idle_Enterer_Private_Data *)EINA_INLIST_GET(l)->next; + if (ie->delete_me) + { + if (ie->references) + { + deleted_idler_enterers_in_use++; + continue; + } + + idle_enterers = (Ecore_Idle_Enterer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie)); + + eo_parent_set(ie->obj, NULL); + if (eo_destructed_is(ie->obj)) + eo_manual_free(ie->obj); + else + eo_manual_free_set(ie->obj, EINA_FALSE); + } + } + if (!deleted_idler_enterers_in_use) + idle_enterers_delete_me = 0; + } +} + +int +_ecore_idle_enterer_exist(void) +{ + if (idle_enterers) return 1; + return 0; +} + +static void +_class_constructor(Eo_Class *klass) +{ + const Eo_Op_Func_Description func_desc[] = { + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), + + EO_OP_FUNC(ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR), _idle_enterer_after_constructor), + EO_OP_FUNC(ECORE_IDLE_ENTERER_ID(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR), _idle_enterer_before_constructor), + EO_OP_FUNC_SENTINEL + }; + + eo_class_funcs_set(klass, func_desc); +} + +static const Eo_Op_Description op_desc[] = { + EO_OP_DESCRIPTION(ECORE_IDLE_ENTERER_SUB_ID_AFTER_CONSTRUCTOR, "Add an idle enterer handler."), + EO_OP_DESCRIPTION(ECORE_IDLE_ENTERER_SUB_ID_BEFORE_CONSTRUCTOR, "Add an idle enterer handler at the start of the list so it gets called earlier than others."), + EO_OP_DESCRIPTION_SENTINEL +}; +static const Eo_Class_Description class_desc = { + EO_VERSION, + MY_CLASS_NAME, + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(&ECORE_IDLE_ENTERER_BASE_ID, op_desc, ECORE_IDLE_ENTERER_SUB_ID_LAST), + NULL, + sizeof(Ecore_Idle_Enterer_Private_Data), + _class_constructor, + NULL +}; + +EO_DEFINE_CLASS(ecore_idle_enterer_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/src/lib/ecore/ecore_idle_exiter.c b/src/lib/ecore/ecore_idle_exiter.c new file mode 100644 index 0000000000..8fd20e7a0a --- /dev/null +++ b/src/lib/ecore/ecore_idle_exiter.c @@ -0,0 +1,264 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#define MY_CLASS ECORE_IDLE_EXITER_CLASS + +#define MY_CLASS_NAME "ecore_idle_exiter" + +EAPI Eo_Op ECORE_IDLE_EXITER_BASE_ID = EO_NOOP; + +struct _Ecore_Idle_Exiter_Private_Data +{ + EINA_INLIST; + Ecore_Idle_Exiter *obj; + Ecore_Task_Cb func; + void *data; + int references; + Eina_Bool delete_me : 1; +}; + +typedef struct _Ecore_Idle_Exiter_Private_Data Ecore_Idle_Exiter_Private_Data; + +static Ecore_Idle_Exiter_Private_Data *idle_exiters = NULL; +static Ecore_Idle_Exiter_Private_Data *idle_exiter_current = NULL; +static int idle_exiters_delete_me = 0; + +static void * +_ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter); + +/** + * @addtogroup Ecore_Idle_Group + * + * @{ + */ + +/** + * 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. + * @note The function func will be called every time the main loop is exiting + * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0 + * (or ECORE_CALLBACK_CANCEL) deletes the idle exiter. + */ +EAPI Ecore_Idle_Exiter * +ecore_idle_exiter_add(Ecore_Task_Cb func, + const void *data) +{ + Ecore_Idle_Exiter *ie = NULL; + ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idle_exiter_constructor(func, data)); + eo_unref(ie); + return ie; +} + +static void +_idle_exiter_constructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); + const void *data = va_arg(*list, const void *); + + _ecore_lock(); + if (EINA_UNLIKELY(!eina_main_loop_is())) + { + eo_error_set(obj); + EINA_MAIN_LOOP_CHECK_RETURN; + } + + Ecore_Idle_Exiter_Private_Data *ie = _pd; + + ie->obj = obj; + eo_do_super(obj, eo_constructor()); + eo_manual_free_set(obj, EINA_TRUE); + + if (!func) + { + eo_error_set(obj); + ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); + return; + } + + ie->func = func; + ie->data = (void *)data; + + idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie)); + _ecore_unlock(); +} + +static void +_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) +{ + eo_error_set(obj); + ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); +} + +/** + * 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. + */ +EAPI void * +ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter) +{ + void *data; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + + _ecore_lock(); + data = _ecore_idle_exiter_del(idle_exiter); + _ecore_unlock(); + return data; +} + +/** + * @} + */ +static void * +_ecore_idle_exiter_del(Ecore_Idle_Exiter *obj) +{ + Ecore_Idle_Exiter_Private_Data *idle_exiter = eo_data_get(obj, MY_CLASS); + EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_exiter->delete_me, NULL); + idle_exiter->delete_me = 1; + idle_exiters_delete_me = 1; + return idle_exiter->data; +} + + +static void +_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Idle_Exiter_Private_Data *idle_exiter = _pd; + + idle_exiter->delete_me = 1; + idle_exiters_delete_me = 1; + + eo_do_super(obj, eo_destructor()); +} + +void +_ecore_idle_exiter_shutdown(void) +{ + Ecore_Idle_Exiter_Private_Data *ie; + while ((ie = idle_exiters)) + { + idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters)); + + eo_parent_set(ie->obj, NULL); + if (eo_destructed_is(ie->obj)) + eo_manual_free(ie->obj); + else + eo_manual_free_set(ie->obj, EINA_FALSE); + } + 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_Private_Data *)EINA_INLIST_GET(idle_exiter_current)->next; + } + + while (idle_exiter_current) + { + Ecore_Idle_Exiter_Private_Data *ie = (Ecore_Idle_Exiter_Private_Data *)idle_exiter_current; + if (!ie->delete_me) + { + ie->references++; + if (!_ecore_call_task_cb(ie->func, ie->data)) + { + if (!ie->delete_me) _ecore_idle_exiter_del(ie->obj); + } + ie->references--; + } + if (idle_exiter_current) /* may have changed in recursive main loops */ + idle_exiter_current = + (Ecore_Idle_Exiter_Private_Data *)EINA_INLIST_GET(idle_exiter_current)->next; + } + if (idle_exiters_delete_me) + { + Ecore_Idle_Exiter_Private_Data *l; + int deleted_idler_exiters_in_use = 0; + + for (l = idle_exiters; l; ) + { + Ecore_Idle_Exiter_Private_Data *ie = l; + + l = (Ecore_Idle_Exiter_Private_Data *)EINA_INLIST_GET(l)->next; + if (ie->delete_me) + { + if (ie->references) + { + deleted_idler_exiters_in_use++; + continue; + } + + idle_exiters = (Ecore_Idle_Exiter_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie)); + + eo_parent_set(ie->obj, NULL); + if (eo_destructed_is(ie->obj)) + eo_manual_free(ie->obj); + else + eo_manual_free_set(ie->obj, EINA_FALSE); + } + } + if (!deleted_idler_exiters_in_use) + idle_exiters_delete_me = 0; + } +} + +int +_ecore_idle_exiter_exist(void) +{ + if (idle_exiters) return 1; + return 0; +} + +static void +_class_constructor(Eo_Class *klass) +{ + const Eo_Op_Func_Description func_desc[] = { + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), + + EO_OP_FUNC(ECORE_IDLE_EXITER_ID(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR), _idle_exiter_constructor), + EO_OP_FUNC_SENTINEL + }; + + eo_class_funcs_set(klass, func_desc); +} + +static const Eo_Op_Description op_desc[] = { + EO_OP_DESCRIPTION(ECORE_IDLE_EXITER_SUB_ID_CONSTRUCTOR, "Add an idle exiter handler."), + EO_OP_DESCRIPTION_SENTINEL +}; + +static const Eo_Class_Description class_desc = { + EO_VERSION, + MY_CLASS_NAME, + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(&ECORE_IDLE_EXITER_BASE_ID, op_desc, ECORE_IDLE_EXITER_SUB_ID_LAST), + NULL, + sizeof(Ecore_Idle_Exiter_Private_Data), + _class_constructor, + NULL +}; + +EO_DEFINE_CLASS(ecore_idle_exiter_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/src/lib/ecore/ecore_idler.c b/src/lib/ecore/ecore_idler.c new file mode 100644 index 0000000000..147b3c1880 --- /dev/null +++ b/src/lib/ecore/ecore_idler.c @@ -0,0 +1,247 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#define MY_CLASS ECORE_IDLER_CLASS + +#define MY_CLASS_NAME "ecore_idler" + +EAPI Eo_Op ECORE_IDLER_BASE_ID = EO_NOOP; + +struct _Ecore_Idler_Private_Data +{ + EINA_INLIST; + Ecore_Idler *obj; + Ecore_Task_Cb func; + void *data; + int references; + Eina_Bool delete_me : 1; +}; + +typedef struct _Ecore_Idler_Private_Data Ecore_Idler_Private_Data; +static Ecore_Idler_Private_Data *idlers = NULL; +static Ecore_Idler_Private_Data *idler_current = NULL; +static int idlers_delete_me = 0; + +static void * +_ecore_idler_del(Ecore_Idler *idler); + +EAPI Ecore_Idler * +ecore_idler_add(Ecore_Task_Cb func, + const void *data) +{ + Ecore_Idler *ie = NULL; + + _ecore_lock(); + + ie = eo_add_custom(MY_CLASS, _ecore_parent, ecore_idler_constructor(func, data)); + eo_unref(ie); + + _ecore_unlock(); + return ie; +} + +static void +_idler_constructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); + const void *data = va_arg(*list, const void *); + + if (EINA_UNLIKELY(!eina_main_loop_is())) + { + eo_error_set(obj); + EINA_MAIN_LOOP_CHECK_RETURN; + } + + Ecore_Idler_Private_Data *ie = _pd; + + ie->obj = obj; + eo_do_super(obj, eo_constructor()); + eo_manual_free_set(obj, EINA_TRUE); + + if (!func) + { + eo_error_set(obj); + ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); + return; + } + + ie->func = func; + ie->data = (void *)data; + idlers = (Ecore_Idler_Private_Data *)eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie)); +} + + +static void +_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) +{ + eo_error_set(obj); + ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); +} + +EAPI void * +ecore_idler_del(Ecore_Idler *idler) +{ + void *data = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + + _ecore_lock(); + data = _ecore_idler_del(idler); + _ecore_unlock(); + return data; +} + +/** + * @} + */ + +/** + * @} + */ + +static void * +_ecore_idler_del(Ecore_Idler *obj) +{ + Ecore_Idler_Private_Data *idler = eo_data_get(obj, MY_CLASS); + EINA_SAFETY_ON_TRUE_RETURN_VAL(idler->delete_me, NULL); + idler->delete_me = 1; + idlers_delete_me = 1; + return idler->data; +} + +static void +_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Idler_Private_Data *idler = _pd; + + idler->delete_me = 1; + idlers_delete_me = 1; + + eo_do_super(obj, eo_destructor()); +} + +void +_ecore_idler_shutdown(void) +{ + Ecore_Idler_Private_Data *ie; + while ((ie = idlers)) + { + idlers = (Ecore_Idler_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers)); + + eo_parent_set(ie->obj, NULL); + if (eo_destructed_is(ie->obj)) + eo_manual_free(ie->obj); + else + eo_manual_free_set(ie->obj, EINA_FALSE); + } + idlers_delete_me = 0; + idler_current = NULL; +} + +int +_ecore_idler_all_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_Private_Data *)EINA_INLIST_GET(idler_current)->next; + } + + while (idler_current) + { + Ecore_Idler_Private_Data *ie = (Ecore_Idler_Private_Data *)idler_current; + if (!ie->delete_me) + { + ie->references++; + if (!_ecore_call_task_cb(ie->func, ie->data)) + { + if (!ie->delete_me) _ecore_idler_del(ie->obj); + } + ie->references--; + } + if (idler_current) /* may have changed in recursive main loops */ + idler_current = (Ecore_Idler_Private_Data *)EINA_INLIST_GET(idler_current)->next; + } + if (idlers_delete_me) + { + Ecore_Idler_Private_Data *l; + int deleted_idlers_in_use = 0; + for (l = idlers; l; ) + { + Ecore_Idler_Private_Data *ie = l; + l = (Ecore_Idler_Private_Data *)EINA_INLIST_GET(l)->next; + if (ie->delete_me) + { + if (ie->references) + { + deleted_idlers_in_use++; + continue; + } + + idlers = (Ecore_Idler_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie)); + + eo_parent_set(ie->obj, NULL); + if (eo_destructed_is(ie->obj)) + eo_manual_free(ie->obj); + else + eo_manual_free_set(ie->obj, EINA_FALSE); + } + } + 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; +} + +static void +_class_constructor(Eo_Class *klass) +{ + const Eo_Op_Func_Description func_desc[] = { + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), + + EO_OP_FUNC(ECORE_IDLER_ID(ECORE_IDLER_SUB_ID_CONSTRUCTOR), _idler_constructor), + EO_OP_FUNC_SENTINEL + }; + + eo_class_funcs_set(klass, func_desc); +} + +static const Eo_Op_Description op_desc[] = { + EO_OP_DESCRIPTION(ECORE_IDLER_SUB_ID_CONSTRUCTOR, "Add an idler handler."), + EO_OP_DESCRIPTION_SENTINEL +}; + +static const Eo_Class_Description class_desc = { + EO_VERSION, + MY_CLASS_NAME, + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(&ECORE_IDLER_BASE_ID, op_desc, ECORE_IDLER_SUB_ID_LAST), + NULL, + sizeof(Ecore_Idler_Private_Data), + _class_constructor, + NULL +}; + +EO_DEFINE_CLASS(ecore_idler_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/src/lib/ecore/ecore_job.c b/src/lib/ecore/ecore_job.c new file mode 100644 index 0000000000..bc438b7209 --- /dev/null +++ b/src/lib/ecore/ecore_job.c @@ -0,0 +1,198 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#define MY_CLASS ECORE_JOB_CLASS + +#define MY_CLASS_NAME "ecore_job" + +EAPI Eo_Op ECORE_JOB_BASE_ID = EO_NOOP; + +static Eina_Bool _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; + +typedef struct _Ecore_Job_Private_Data Ecore_Job_Private_Data; + +struct _Ecore_Job_Private_Data +{ + Ecore_Event *event; + Ecore_Cb func; + 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; +} + +/** + * @addtogroup Ecore_Job_Group + * + * @{ + */ + +/** + * 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. + * @note Once the job has been executed, the job handle is invalid. + */ +EAPI Ecore_Job * +ecore_job_add(Ecore_Cb func, + const void *data) +{ + Ecore_Job *job = eo_add_custom(MY_CLASS, _ecore_parent, ecore_job_constructor(func, data)); + eo_unref(job); + return job; +} + +static void +_job_constructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Cb func = va_arg(*list, Ecore_Cb); + const void *data = va_arg(*list, const void *); + + if (EINA_UNLIKELY(!eina_main_loop_is())) + { + eo_error_set(obj); + EINA_MAIN_LOOP_CHECK_RETURN; + } + eo_do_super(obj, eo_constructor()); + eo_manual_free_set(obj, EINA_TRUE); + + if (!func) + { + eo_error_set(obj); + ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); + return; + } + + Ecore_Job_Private_Data *job = _pd; + + job->event = ecore_event_add(ecore_event_job_type, job, _ecore_job_event_free, obj); + if (!job->event) + { + eo_error_set(obj); + ERR("no event was assigned to object '%p' of class '%s'", obj, MY_CLASS_NAME); + return; + } + job->func = func; + job->data = (void *)data; +} + +static void +_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) +{ + eo_error_set(obj); + ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); +} + +/** + * 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. + */ +EAPI void * +ecore_job_del(Ecore_Job *obj) +{ + void *data; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + Ecore_Job_Private_Data *job = eo_data_get(obj, MY_CLASS); + data = job->data; + ecore_event_del(job->event); + eo_parent_set(obj, NULL); + return data; +} + +static void +_destructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) +{ + /*FIXME: check if ecore_event_del should be called from here*/ + eo_do_super(obj, eo_destructor()); +} + +/** + * @} + */ + +static Eina_Bool +_ecore_job_event_handler(void *data EINA_UNUSED, + int type EINA_UNUSED, + void *ev) +{ + Ecore_Job_Private_Data *job; + + job = ev; + job->func(job->data); + return ECORE_CALLBACK_CANCEL; +} + +static void +_ecore_job_event_free(void *data, + void *job EINA_UNUSED) +{ + eo_parent_set(data, NULL); + + Ecore_Job *obj = data; + + if (eo_destructed_is(obj)) + eo_manual_free(obj); + else + eo_manual_free_set(obj, EINA_FALSE); +} + +static void +_class_constructor(Eo_Class *klass) +{ + const Eo_Op_Func_Description func_desc[] = { + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), + EO_OP_FUNC(ECORE_JOB_ID(ECORE_JOB_SUB_ID_CONSTRUCTOR), _job_constructor), + EO_OP_FUNC_SENTINEL + }; + + eo_class_funcs_set(klass, func_desc); +} + +static const Eo_Op_Description op_desc[] = { + EO_OP_DESCRIPTION(ECORE_JOB_SUB_ID_CONSTRUCTOR, "Add a job to the event queue."), + EO_OP_DESCRIPTION_SENTINEL +}; +static const Eo_Class_Description class_desc = { + EO_VERSION, + MY_CLASS_NAME, + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(&ECORE_JOB_BASE_ID, op_desc, ECORE_JOB_SUB_ID_LAST), + NULL, + sizeof(Ecore_Job_Private_Data), + _class_constructor, + NULL +}; + +EO_DEFINE_CLASS(ecore_job_class_get, &class_desc, EO_BASE_CLASS, NULL); diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c new file mode 100644 index 0000000000..cc7b0654a5 --- /dev/null +++ b/src/lib/ecore/ecore_main.c @@ -0,0 +1,2111 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include +# undef WIN32_LEAN_AND_MEAN +# ifndef USER_TIMER_MINIMUM +# define USER_TIMER_MINIMUM 0x0a +# endif +#endif + +#ifdef __SUNPRO_C +# include +# include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_TIME_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef _MSC_VER +# include +#endif + +#ifdef HAVE_ISFINITE +# define ECORE_FINITE(t) isfinite(t) +#else +# ifdef _MSC_VER +# define ECORE_FINITE(t) _finite(t) +# else +# define ECORE_FINITE(t) finite(t) +# endif +#endif + +//#define FIX_HZ 1 + +#ifdef FIX_HZ +# ifndef _MSC_VER +# include +# endif +# ifndef HZ +# define HZ 100 +# endif +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" + +#ifdef HAVE_SYS_EPOLL_H +# define HAVE_EPOLL 1 +# include +#else + +# define HAVE_EPOLL 0 +# define EPOLLIN 1 +# define EPOLLPRI 2 +# define EPOLLOUT 4 +# define EPOLLERR 8 + +#define EPOLL_CTL_ADD 1 +#define EPOLL_CTL_DEL 2 +#define EPOLL_CTL_MOD 3 + +typedef union epoll_data { + void *ptr; + int fd; + uint32_t u32; + uint64_t u64; +} epoll_data_t; + +struct epoll_event +{ + uint32_t events; + epoll_data_t data; +}; + +static inline int +epoll_create(int size EINA_UNUSED) +{ + return -1; +} + +static inline int +epoll_wait(int epfd EINA_UNUSED, + struct epoll_event *events EINA_UNUSED, + int maxevents EINA_UNUSED, + int timeout EINA_UNUSED) +{ + return -1; +} + +static inline int +epoll_ctl(int epfd EINA_UNUSED, + int op EINA_UNUSED, + int fd EINA_UNUSED, + struct epoll_event *event EINA_UNUSED) +{ + return -1; +} + +#endif + +#ifdef HAVE_SYS_TIMERFD_H +# include +#else +/* fallback code if we don't have real timerfd - reduces number of ifdefs */ +# ifndef CLOCK_MONOTONIC +# define CLOCK_MONOTONIC 0 /* bogus value */ +# endif +# ifndef TFD_NONBLOCK +# define TFD_NONBLOCK 0 /* bogus value */ +# endif +#endif /* HAVE_SYS_TIMERFD_H */ + +#ifndef HAVE_TIMERFD_CREATE +static inline int +timerfd_create(int clockid EINA_UNUSED, + int flags EINA_UNUSED) +{ + return -1; +} + +static inline int +timerfd_settime(int fd EINA_UNUSED, + int flags EINA_UNUSED, + const struct itimerspec *new_value EINA_UNUSED, + struct itimerspec *old_value EINA_UNUSED) +{ + return -1; +} + +#endif /* HAVE_TIMERFD_CREATE */ + +#ifdef USE_G_MAIN_LOOP +# include +#endif + +#define NS_PER_SEC (1000.0 * 1000.0 * 1000.0) + +struct _Ecore_Fd_Handler +{ + EINA_INLIST; + ECORE_MAGIC; + Ecore_Fd_Handler *next_ready; + int fd; + Ecore_Fd_Handler_Flags flags; + Ecore_Fd_Cb func; + void *data; + Ecore_Fd_Cb buf_func; + void *buf_data; + Ecore_Fd_Prep_Cb prep_func; + 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; + Eina_Bool file : 1; +#if defined(USE_G_MAIN_LOOP) + GPollFD gfd; +#endif +}; +GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler); + +#ifdef _WIN32 +struct _Ecore_Win32_Handler +{ + EINA_INLIST; + ECORE_MAGIC; + HANDLE h; + Ecore_Win32_Handle_Cb func; + void *data; + int references; + Eina_Bool delete_me : 1; +}; +GENERIC_ALLOC_SIZE_DECLARE(Ecore_Win32_Handler); +#endif + +#ifndef USE_G_MAIN_LOOP +static int _ecore_main_select(double timeout); +#endif +static void _ecore_main_prepare_handlers(void); +static void _ecore_main_fd_handlers_cleanup(void); +#ifndef _WIN32 +# ifndef USE_G_MAIN_LOOP +static void _ecore_main_fd_handlers_bads_rem(void); +# endif +#endif +static void _ecore_main_fd_handlers_call(void); +static int _ecore_main_fd_handlers_buf_call(void); +#ifndef USE_G_MAIN_LOOP +static void _ecore_main_loop_iterate_internal(int once_only); +#endif + +#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 Eina_List *fd_handlers_with_prep = NULL; +static Eina_List *file_fd_handlers = NULL; +static Eina_List *fd_handlers_with_buffer = NULL; +static Eina_List *fd_handlers_to_delete = NULL; + +/* single linked list of ready fdhs, terminated by loop to self */ +static Ecore_Fd_Handler *fd_handlers_to_call; +static Ecore_Fd_Handler *fd_handlers_to_call_current; + +#ifdef _WIN32 +static Ecore_Win32_Handler *win32_handlers = NULL; +static Ecore_Win32_Handler *win32_handler_current = NULL; +static Eina_Bool win32_handlers_delete_me = EINA_FALSE; +#endif + +#ifdef _WIN32 +Ecore_Select_Function main_loop_select = _ecore_main_win32_select; +#else +# if !defined EXOTIC_NO_SELECT +# ifdef HAVE_SYS_SELECT_H +# include +# endif +Ecore_Select_Function main_loop_select = select; +# else +Ecore_Select_Function main_loop_select = NULL; +# endif +#endif + +#ifndef USE_G_MAIN_LOOP +static double t1 = 0.0; +static double t2 = 0.0; +#endif + +static int timer_fd = -1; +static int epoll_fd = -1; +static pid_t epoll_pid; + +#ifdef USE_G_MAIN_LOOP +static GPollFD ecore_epoll_fd; +static GPollFD ecore_timer_fd; +static GSource *ecore_glib_source; +static guint ecore_glib_source_id; +static GMainLoop *ecore_main_loop; +static gboolean ecore_idling; +static gboolean _ecore_glib_idle_enterer_called; +static gboolean ecore_fds_ready; +#endif + +static inline void +_ecore_fd_valid(void) +{ + if (HAVE_EPOLL && epoll_fd >= 0) + { + if (fcntl(epoll_fd, F_GETFD) < 0) + { + ERR("arghhh you caught me! report a backtrace to edevel!"); + pause(); + } + } +} + +static inline void +_ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh) +{ + /* check if this fdh is already in the list */ + if (fdh->next_ready) + return; + if (fdh->read_active || fdh->write_active || fdh->error_active) + { + /* + * make sure next_ready is non-null by pointing to ourselves + * use that to indicate this fdh is in the ready list + * insert at the head of the list to avoid trouble + */ + fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh; + fd_handlers_to_call = fdh; + } +} + +static inline int +_ecore_get_epoll_fd(void) +{ + if (epoll_pid && epoll_pid != getpid()) + { + /* forked! */ + _ecore_main_loop_shutdown(); + } + if (epoll_pid == 0 && epoll_fd < 0) + { + _ecore_main_loop_init(); + } + return epoll_fd; +} + +static inline int +_ecore_epoll_add(int efd, + int fd, + int events, + void *ptr) +{ + struct epoll_event ev; + + memset(&ev, 0, sizeof (ev)); + ev.events = events; + ev.data.ptr = ptr; + INF("adding poll on %d %08x", fd, events); + return epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev); +} + +static inline int +_ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh) +{ + int events = 0; + if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN; + if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT; + if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR | EPOLLPRI; + return events; +} + +#ifdef USE_G_MAIN_LOOP +static inline int +_gfd_events_from_fdh(Ecore_Fd_Handler *fdh) +{ + int events = 0; + if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN; + if (fdh->flags & ECORE_FD_WRITE) events |= G_IO_OUT; + if (fdh->flags & ECORE_FD_ERROR) events |= G_IO_ERR; + return events; +} + +#endif + +static inline int +_ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh) +{ + int r = 0; + + if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) + { + r = _ecore_epoll_add(_ecore_get_epoll_fd(), fdh->fd, + _ecore_poll_events_from_fdh(fdh), fdh); + } + else + { +#ifdef USE_G_MAIN_LOOP + fdh->gfd.fd = fdh->fd; + fdh->gfd.events = _gfd_events_from_fdh(fdh); + fdh->gfd.revents = 0; + INF("adding gpoll on %d %08x", fdh->fd, fdh->gfd.events); + g_source_add_poll(ecore_glib_source, &fdh->gfd); +#endif + } + return r; +} + +static inline void +_ecore_main_fdh_poll_del(Ecore_Fd_Handler *fdh) +{ + if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) + { + struct epoll_event ev; + int efd = _ecore_get_epoll_fd(); + + memset(&ev, 0, sizeof (ev)); + INF("removing poll on %d", fdh->fd); + /* could get an EBADF if somebody closed the FD before removing it */ + if ((epoll_ctl(efd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0)) + { + if (errno == EBADF) + { + WRN("fd %d was closed, can't remove from epoll - reinit!", + fdh->fd); + _ecore_main_loop_shutdown(); + _ecore_main_loop_init(); + } + else + { + ERR("Failed to delete epoll fd %d! (errno=%d)", fdh->fd, errno); + } + } + } + else + { +#ifdef USE_G_MAIN_LOOP + fdh->gfd.fd = fdh->fd; + fdh->gfd.events = _gfd_events_from_fdh(fdh); + fdh->gfd.revents = 0; + INF("adding gpoll on %d %08x", fdh->fd, fdh->gfd.events); + g_source_add_poll(ecore_glib_source, &fdh->gfd); +#endif + } +} + +static inline int +_ecore_main_fdh_poll_modify(Ecore_Fd_Handler *fdh) +{ + int r = 0; + if ((!fdh->file) && HAVE_EPOLL && epoll_fd >= 0) + { + struct epoll_event ev; + int efd = _ecore_get_epoll_fd(); + + memset(&ev, 0, sizeof (ev)); + ev.events = _ecore_poll_events_from_fdh(fdh); + ev.data.ptr = fdh; + INF("modifing epoll on %d to %08x", fdh->fd, ev.events); + r = epoll_ctl(efd, EPOLL_CTL_MOD, fdh->fd, &ev); + } + else + { +#ifdef USE_G_MAIN_LOOP + fdh->gfd.fd = fdh->fd; + fdh->gfd.events = _gfd_events_from_fdh(fdh); + fdh->gfd.revents = 0; + INF("modifing gpoll on %d to %08x", fdh->fd, fdh->gfd.events); +#endif + } + return r; +} + +static inline int +_ecore_main_fdh_epoll_mark_active(void) +{ + struct epoll_event ev[32]; + int i, ret; + int efd = _ecore_get_epoll_fd(); + + memset(&ev, 0, sizeof (ev)); + ret = epoll_wait(efd, ev, sizeof(ev) / sizeof(struct epoll_event), 0); + if (ret < 0) + { + if (errno == EINTR) return -1; + ERR("epoll_wait failed %d", errno); + return -1; + } + + for (i = 0; i < ret; i++) + { + Ecore_Fd_Handler *fdh; + + fdh = ev[i].data.ptr; + if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER)) + { + ECORE_MAGIC_FAIL(fdh, ECORE_MAGIC_FD_HANDLER, + "_ecore_main_fdh_epoll_mark_active"); + continue; + } + if (fdh->delete_me) + { + ERR("deleted fd in epoll"); + continue; + } + + if (ev[i].events & EPOLLIN) + fdh->read_active = EINA_TRUE; + if (ev[i].events & EPOLLOUT) + fdh->write_active = EINA_TRUE; + if (ev[i].events & EPOLLERR) + fdh->error_active = EINA_TRUE; + + _ecore_try_add_to_call_list(fdh); + } + + return ret; +} + +#ifdef USE_G_MAIN_LOOP + +static inline int +_ecore_main_fdh_glib_mark_active(void) +{ + Ecore_Fd_Handler *fdh; + int ret = 0; + + /* call the prepare callback for all handlers */ + EINA_INLIST_FOREACH(fd_handlers, fdh) + { + if (fdh->delete_me) + continue; + + if (fdh->gfd.revents & G_IO_IN) + fdh->read_active = EINA_TRUE; + if (fdh->gfd.revents & G_IO_OUT) + fdh->write_active = EINA_TRUE; + if (fdh->gfd.revents & G_IO_ERR) + fdh->error_active = EINA_TRUE; + + _ecore_try_add_to_call_list(fdh); + + if (fdh->gfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR)) ret++; + } + + return ret; +} + +/* like we are about to enter main_loop_select in _ecore_main_select */ +static gboolean +_ecore_main_gsource_prepare(GSource *source EINA_UNUSED, + gint *next_time) +{ + gboolean ready = FALSE; + + _ecore_lock(); + in_main_loop++; + + if (!ecore_idling && !_ecore_glib_idle_enterer_called) + { + _ecore_time_loop_time = ecore_time_get(); + _ecore_timer_expired_timers_call(_ecore_time_loop_time); + _ecore_timer_cleanup(); + + _ecore_idle_enterer_call(); + _ecore_throttle(); + _ecore_glib_idle_enterer_called = FALSE; + + if (fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(); + } + + _ecore_signal_received_process(); + + /* don't check fds if somebody quit */ + if (g_main_loop_is_running(ecore_main_loop)) + { + /* only set idling state in dispatch */ + if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist()) + { + if (_ecore_timers_exists()) + { + int r = -1; + double t = _ecore_timer_next_get(); + if (timer_fd >= 0 && t > 0.0) + { + struct itimerspec ts; + + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + ts.it_value.tv_sec = t; + ts.it_value.tv_nsec = fmod(t * NS_PER_SEC, NS_PER_SEC); + + /* timerfd cannot sleep for 0 time */ + if (ts.it_value.tv_sec || ts.it_value.tv_nsec) + { + r = timerfd_settime(timer_fd, 0, &ts, NULL); + if (r < 0) + { + ERR("timer set returned %d (errno=%d)", r, errno); + close(timer_fd); + timer_fd = -1; + } + else + INF("sleeping for %ld s %06ldus", + ts.it_value.tv_sec, + ts.it_value.tv_nsec / 1000); + } + } + if (r == -1) + { + *next_time = ceil(t * 1000.0); + if (t == 0.0) + ready = TRUE; + } + } + else + *next_time = -1; + } + else + { + *next_time = 0; + if (_ecore_event_exist()) + ready = TRUE; + } + + if (fd_handlers_with_prep) + _ecore_main_prepare_handlers(); + } + else + ready = TRUE; + + in_main_loop--; + INF("leave, timeout = %d", *next_time); + _ecore_unlock(); + + /* ready if we're not running (about to quit) */ + return ready; +} + +static gboolean +_ecore_main_gsource_check(GSource *source EINA_UNUSED) +{ + gboolean ret = FALSE; + + _ecore_lock(); + in_main_loop++; + + /* check if old timers expired */ + if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist()) + { + if (timer_fd >= 0) + { + uint64_t count = 0; + int r = read(timer_fd, &count, sizeof count); + if (r == -1 && errno == EAGAIN) + ; + else if (r == sizeof count) + ret = TRUE; + else + { + /* unexpected things happened... fail back to old way */ + ERR("timer read returned %d (errno=%d)", r, errno); + close(timer_fd); + timer_fd = -1; + } + } + } + else + ret = TRUE; + + /* check if fds are ready */ + if (HAVE_EPOLL && epoll_fd >= 0) + ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active() > 0); + else + ecore_fds_ready = (_ecore_main_fdh_glib_mark_active() > 0); + _ecore_main_fd_handlers_cleanup(); + if (ecore_fds_ready) + ret = TRUE; + + /* check timers after updating loop time */ + if (!ret && _ecore_timers_exists()) + ret = (0.0 == _ecore_timer_next_get()); + + in_main_loop--; + _ecore_unlock(); + + return ret; +} + +/* like we just came out of main_loop_select in _ecore_main_select */ +static gboolean +_ecore_main_gsource_dispatch(GSource *source EINA_UNUSED, + GSourceFunc callback EINA_UNUSED, + gpointer user_data EINA_UNUSED) +{ + gboolean events_ready, timers_ready, idlers_ready; + double next_time; + + _ecore_lock(); + _ecore_time_loop_time = ecore_time_get(); + _ecore_timer_enable_new(); + next_time = _ecore_timer_next_get(); + + events_ready = _ecore_event_exist(); + timers_ready = _ecore_timers_exists() && (0.0 == next_time); + idlers_ready = _ecore_idler_exist(); + + in_main_loop++; + INF("enter idling=%d fds=%d events=%d timers=%d (next=%.2f) idlers=%d", + ecore_idling, ecore_fds_ready, events_ready, + timers_ready, next_time, idlers_ready); + + if (ecore_idling && events_ready) + { + _ecore_idle_exiter_call(); + ecore_idling = 0; + } + else if (!ecore_idling && !events_ready) + { + ecore_idling = 1; + } + + if (ecore_idling) + { + _ecore_idler_all_call(); + + events_ready = _ecore_event_exist(); + + if (ecore_fds_ready || events_ready || timers_ready) + { + _ecore_idle_exiter_call(); + ecore_idling = 0; + } + } + + /* process events */ + if (!ecore_idling) + { + _ecore_main_fd_handlers_call(); + if (fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(); + _ecore_signal_received_process(); + _ecore_event_call(); + _ecore_main_fd_handlers_cleanup(); + + _ecore_timer_expired_timers_call(_ecore_time_loop_time); + _ecore_timer_cleanup(); + + _ecore_idle_enterer_call(); + _ecore_throttle(); + _ecore_glib_idle_enterer_called = TRUE; + + if (fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(); + } + + in_main_loop--; + _ecore_unlock(); + + return TRUE; /* what should be returned here? */ +} + +static void +_ecore_main_gsource_finalize(GSource *source EINA_UNUSED) +{ +} + +static GSourceFuncs ecore_gsource_funcs = +{ + .prepare = _ecore_main_gsource_prepare, + .check = _ecore_main_gsource_check, + .dispatch = _ecore_main_gsource_dispatch, + .finalize = _ecore_main_gsource_finalize, +}; + +#endif + +void +_ecore_main_loop_init(void) +{ + epoll_fd = epoll_create(1); + if (epoll_fd < 0) + WRN("Failed to create epoll fd!"); + epoll_pid = getpid(); + + /* add polls on all our file descriptors */ + Ecore_Fd_Handler *fdh; + EINA_INLIST_FOREACH(fd_handlers, fdh) + { + if (fdh->delete_me) + continue; + _ecore_epoll_add(epoll_fd, fdh->fd, + _ecore_poll_events_from_fdh(fdh), fdh); + _ecore_main_fdh_poll_add(fdh); + } + + /* setup for the g_main_loop only integration */ +#ifdef USE_G_MAIN_LOOP + ecore_glib_source = g_source_new(&ecore_gsource_funcs, sizeof (GSource)); + if (!ecore_glib_source) + CRIT("Failed to create glib source for epoll!"); + else + { + g_source_set_priority(ecore_glib_source, G_PRIORITY_HIGH_IDLE + 20); + if (HAVE_EPOLL && epoll_fd >= 0) + { + /* epoll multiplexes fds into the g_main_loop */ + ecore_epoll_fd.fd = epoll_fd; + ecore_epoll_fd.events = G_IO_IN; + ecore_epoll_fd.revents = 0; + g_source_add_poll(ecore_glib_source, &ecore_epoll_fd); + } + + /* timerfd gives us better than millisecond accuracy in g_main_loop */ + timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); + if (timer_fd < 0) + WRN("failed to create timer fd!"); + else + { + ecore_timer_fd.fd = timer_fd; + ecore_timer_fd.events = G_IO_IN; + ecore_timer_fd.revents = 0; + g_source_add_poll(ecore_glib_source, &ecore_timer_fd); + } + + ecore_glib_source_id = g_source_attach(ecore_glib_source, NULL); + if (ecore_glib_source_id <= 0) + CRIT("Failed to attach glib source to default context"); + } +#endif +} + +void +_ecore_main_loop_shutdown(void) +{ +#ifdef USE_G_MAIN_LOOP + if (ecore_glib_source) + { + g_source_destroy(ecore_glib_source); + ecore_glib_source = NULL; + } +#endif + + if (epoll_fd >= 0) + { + close(epoll_fd); + epoll_fd = -1; + } + epoll_pid = 0; + + if (timer_fd >= 0) + { + close(timer_fd); + timer_fd = -1; + } +} + +void * +_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) +{ + if (fd_handler->delete_me) + { + ERR("fdh %p deleted twice", fd_handler); + return NULL; + } + + _ecore_main_fdh_poll_del(fd_handler); + fd_handler->delete_me = EINA_TRUE; + fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fd_handler); + if (fd_handler->prep_func && fd_handlers_with_prep) + fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler); + if (fd_handler->buf_func && fd_handlers_with_buffer) + fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler); + return fd_handler->data; +} + +/** + * @addtogroup Ecore_Main_Loop_Group + * + * @{ + */ + +/** + * Runs a single iteration of the main loop to process everything on the + * queue. + * + * It does everything that is already done inside an @c Ecore main loop, like + * checking for expired timers, idlers, etc. But it will do it only once and + * return, instead of keep watching for new events. + * + * DO NOT use this function unless you are the person God comes to ask for + * advice when He has trouble managing the Universe. + * + * @see ecore_main_loop_iterate_may_block() + */ +EAPI void +ecore_main_loop_iterate(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN; +#ifndef USE_G_MAIN_LOOP + _ecore_lock(); + _ecore_time_loop_time = ecore_time_get(); + _ecore_main_loop_iterate_internal(1); + _ecore_unlock(); +#else + g_main_context_iteration(NULL, 0); +#endif +} + +/** + * Runs a single iteration of the main loop to process everything on the + * queue with block/non-blocking status. + * + * @param may_block A flag if the main loop has a possibility of blocking. + * (@c EINA_TRUE = may block/@c EINA_FALSE = non block) + * + * This is an extension API for ecore_main_loop_iterate() with additional + * parameter. It does everything that is already done inside an + * @c Ecore main loop, like checking for expired timers, idlers, etc. But it + * will do it only once and return, instead of keep watching for new events. + * + * DO NOT use this function unless you are the person God comes to ask for + * advice when He has trouble managing the Universe. + * + * @see ecore_main_loop_iterate() + */ +EAPI int +ecore_main_loop_iterate_may_block(int may_block) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); +#ifndef USE_G_MAIN_LOOP + _ecore_lock(); + _ecore_time_loop_time = ecore_time_get(); +in_main_loop++; + _ecore_main_loop_iterate_internal(!may_block); +in_main_loop--; + _ecore_unlock(); + return _ecore_event_exist(); +#else + return g_main_context_iteration(NULL, may_block); +#endif +} + +/** + * Runs the application main loop. + * + * This function will not return until @ref ecore_main_loop_quit is called. It + * will check for expired timers, idlers, file descriptors being watched by fd + * handlers, etc. Once everything is done, before entering again on idle state, + * any callback set as @c Idle_Enterer will be called. + * + * Each main loop iteration is done by calling ecore_main_loop_iterate() + * internally. + * + * The polling (select) function used can be changed with + * ecore_main_loop_select_func_set(). + * + * The function used to check for file descriptors, events, and that has a + * timeout for the timers can be changed using + * ecore_main_loop_select_func_set(). + */ +EAPI void +ecore_main_loop_begin(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN; +#ifndef USE_G_MAIN_LOOP + _ecore_lock(); + in_main_loop++; + _ecore_time_loop_time = ecore_time_get(); + while (do_quit == 0) _ecore_main_loop_iterate_internal(0); + do_quit = 0; + in_main_loop--; + _ecore_unlock(); +#else + if (!do_quit) + { + if (!ecore_main_loop) + ecore_main_loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(ecore_main_loop); + } + do_quit = 0; +#endif +} + +/** + * Quits the main loop once all the events currently on the queue have + * been processed. + * + * This function returns immediately, but will mark the ecore_main_loop_begin() + * function to return at the end of the current main loop iteration. + */ +EAPI void +ecore_main_loop_quit(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + do_quit = 1; +#ifdef USE_G_MAIN_LOOP + if (ecore_main_loop) + g_main_loop_quit(ecore_main_loop); +#endif +} + +/** + * 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. + * + * @param func The function to be used. + */ +EAPI void +ecore_main_loop_select_func_set(Ecore_Select_Function func) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + main_loop_select = func; +} + +/** + * Gets the select function set by ecore_select_func_set(), + * or the native select function if none was set. + * + */ +EAPI Ecore_Select_Function +ecore_main_loop_select_func_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + return main_loop_select; +} + +Ecore_Fd_Handler * +_ecore_main_fd_handler_add(int fd, + Ecore_Fd_Handler_Flags flags, + Ecore_Fd_Cb func, + const void *data, + Ecore_Fd_Cb buf_func, + const void *buf_data) +{ + Ecore_Fd_Handler *fdh = NULL; + + if ((fd < 0) || (flags == 0) || (!func)) return NULL; + + fdh = ecore_fd_handler_calloc(1); + if (!fdh) return NULL; + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); + fdh->next_ready = NULL; + fdh->fd = fd; + fdh->flags = flags; + if (_ecore_main_fdh_poll_add(fdh) < 0) + { + int err = errno; + ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err)); + ecore_fd_handler_mp_free(fdh); + return NULL; + } + fdh->read_active = EINA_FALSE; + fdh->write_active = EINA_FALSE; + fdh->error_active = EINA_FALSE; + fdh->delete_me = EINA_FALSE; + fdh->func = func; + fdh->data = (void *)data; + fdh->buf_func = buf_func; + if (buf_func) + fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh); + 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; +} + +EAPI Ecore_Fd_Handler * +ecore_main_fd_handler_add(int fd, + Ecore_Fd_Handler_Flags flags, + Ecore_Fd_Cb func, + const void *data, + Ecore_Fd_Cb buf_func, + const void *buf_data) +{ + Ecore_Fd_Handler *fdh = NULL; + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + fdh = _ecore_main_fd_handler_add(fd, flags, func, data, buf_func, buf_data); + _ecore_unlock(); + return fdh; +} + +EAPI Ecore_Fd_Handler * +ecore_main_fd_handler_file_add(int fd, + Ecore_Fd_Handler_Flags flags, + Ecore_Fd_Cb func, + const void *data, + Ecore_Fd_Cb buf_func, + const void *buf_data) +{ + Ecore_Fd_Handler *fdh = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + + if ((fd < 0) || (flags == 0) || (!func)) goto unlock; + + fdh = ecore_fd_handler_calloc(1); + if (!fdh) goto unlock; + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); + fdh->next_ready = NULL; + fdh->fd = fd; + fdh->flags = flags; + fdh->file = EINA_TRUE; + if (_ecore_main_fdh_poll_add(fdh) < 0) + { + int err = errno; + ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err)); + ecore_fd_handler_mp_free(fdh); + fdh = NULL; + goto unlock; + } + fdh->read_active = EINA_FALSE; + fdh->write_active = EINA_FALSE; + fdh->error_active = EINA_FALSE; + fdh->delete_me = EINA_FALSE; + fdh->func = func; + fdh->data = (void *)data; + fdh->buf_func = buf_func; + if (buf_func) + fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh); + fdh->buf_data = (void *)buf_data; + fd_handlers = (Ecore_Fd_Handler *) + eina_inlist_append(EINA_INLIST_GET(fd_handlers), + EINA_INLIST_GET(fdh)); + file_fd_handlers = eina_list_append(file_fd_handlers, fdh); +unlock: + _ecore_unlock(); + + return fdh; +} + +#ifdef _WIN32 +EAPI Ecore_Win32_Handler * +ecore_main_win32_handler_add(void *h, + Ecore_Win32_Handle_Cb func, + const void *data) +{ + Ecore_Win32_Handler *wh; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + if (!h || !func) return NULL; + + wh = ecore_win32_handler_calloc(1); + if (!wh) return NULL; + ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER); + wh->h = (HANDLE)h; + wh->delete_me = EINA_FALSE; + 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 EINA_UNUSED, + Ecore_Win32_Handle_Cb func EINA_UNUSED, + const void *data EINA_UNUSED) +{ + return NULL; +} + +#endif + +EAPI void * +ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) +{ + void *ret = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + + if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) + { + ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, + "ecore_main_fd_handler_del"); + goto unlock; + } + ret = _ecore_main_fd_handler_del(fd_handler); +unlock: + _ecore_unlock(); + return ret; +} + +#ifdef _WIN32 +EAPI void * +ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + 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 = EINA_TRUE; + win32_handlers_delete_me = EINA_TRUE; + return win32_handler->data; +} + +#else +EAPI void * +ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler EINA_UNUSED) +{ + return NULL; +} + +#endif + +EAPI void +ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, + Ecore_Fd_Prep_Cb func, + const void *data) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + + 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"); + goto unlock; + } + fd_handler->prep_func = func; + fd_handler->prep_data = (void *)data; + if ((!fd_handlers_with_prep) || + (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler)))) + /* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */ + fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler); +unlock: + _ecore_unlock(); +} + +EAPI int +ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler) +{ + int fd = -1; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1); + _ecore_lock(); + + 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"); + goto unlock; + } + fd = fd_handler->fd; +unlock: + _ecore_unlock(); + return fd; +} + +EAPI Eina_Bool +ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, + Ecore_Fd_Handler_Flags flags) +{ + int ret = EINA_FALSE; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); + _ecore_lock(); + + 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"); + goto unlock; + } + if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE; + if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE; + if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE; +unlock: + _ecore_unlock(); + return ret; +} + +EAPI void +ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, + Ecore_Fd_Handler_Flags flags) +{ + int ret; + + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + + 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"); + goto unlock; + } + fd_handler->flags = flags; + ret = _ecore_main_fdh_poll_modify(fd_handler); + if (ret < 0) + { + ERR("Failed to mod epoll fd %d: %s!", fd_handler->fd, strerror(ret)); + } +unlock: + _ecore_unlock(); +} + +/** + * @} + */ + +void +_ecore_main_shutdown(void) +{ + if (in_main_loop) + { + ERR("\n" + "*** ECORE WARNING: 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); + ecore_fd_handler_mp_free(fdh); + } + if (fd_handlers_with_buffer) + fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer); + if (fd_handlers_with_prep) + fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep); + if (fd_handlers_to_delete) + fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete); + if (file_fd_handlers) + file_fd_handlers = eina_list_free(file_fd_handlers); + + fd_handlers_to_call = NULL; + fd_handlers_to_call_current = NULL; + fd_handlers_to_delete = NULL; + 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); + ecore_win32_handler_mp_free(wh); + } + win32_handlers_delete_me = EINA_FALSE; + win32_handler_current = NULL; +#endif +} + +static void +_ecore_main_prepare_handlers(void) +{ + Ecore_Fd_Handler *fdh; + Eina_List *l, *l2; + + /* call the prepare callback for all handlers with prep functions */ + EINA_LIST_FOREACH_SAFE(fd_handlers_with_prep, l, l2, fdh) + { + if (!fdh) + { + fd_handlers_with_prep = eina_list_remove_list(l, fd_handlers_with_prep); + continue; + } + if (!fdh->delete_me && fdh->prep_func) + { + fdh->references++; + _ecore_call_prep_cb(fdh->prep_func, fdh->prep_data, fdh); + fdh->references--; + } + else + fd_handlers_with_prep = eina_list_remove_list(fd_handlers_with_prep, l); + } +} + +#ifndef USE_G_MAIN_LOOP +static int +_ecore_main_select(double timeout) +{ + struct timeval tv, *t; + fd_set rfds, wfds, exfds; + Ecore_Fd_Handler *fdh; + Eina_List *l; + int max_fd; + int ret; + + t = NULL; + if ((!ECORE_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 */ + if (fd_handlers_with_prep) + _ecore_main_prepare_handlers(); + + if (!HAVE_EPOLL || epoll_fd < 0) + { + 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; + } + } + } + } + else + { + /* polling on the epoll fd will wake when an fd in the epoll set is active */ + max_fd = _ecore_get_epoll_fd(); + FD_SET(max_fd, &rfds); + } + EINA_LIST_FOREACH(file_fd_handlers, l, 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 (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (_ecore_signal_count_get()) return -1; + + _ecore_unlock(); + ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t); + _ecore_lock(); + + _ecore_time_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) + { + if (HAVE_EPOLL && epoll_fd >= 0) + _ecore_main_fdh_epoll_mark_active(); + else + { + EINA_INLIST_FOREACH(fd_handlers, fdh) + { + if (!fdh->delete_me) + { + if (FD_ISSET(fdh->fd, &rfds)) + fdh->read_active = EINA_TRUE; + if (FD_ISSET(fdh->fd, &wfds)) + fdh->write_active = EINA_TRUE; + if (FD_ISSET(fdh->fd, &exfds)) + fdh->error_active = EINA_TRUE; + _ecore_try_add_to_call_list(fdh); + } + } + } + EINA_LIST_FOREACH(file_fd_handlers, l, fdh) + { + if (!fdh->delete_me) + { + if (FD_ISSET(fdh->fd, &rfds)) + fdh->read_active = EINA_TRUE; + if (FD_ISSET(fdh->fd, &wfds)) + fdh->write_active = EINA_TRUE; + if (FD_ISSET(fdh->fd, &exfds)) + fdh->error_active = EINA_TRUE; + _ecore_try_add_to_call_list(fdh); + } + } + _ecore_main_fd_handlers_cleanup(); +#ifdef _WIN32 + _ecore_main_win32_handlers_cleanup(); +#endif + return 1; + } + return 0; +} + +#endif + +#ifndef _WIN32 +# ifndef USE_G_MAIN_LOOP +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 (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh)) + { + ERR("Fd function err returned 0, remove it"); + if (!fdh->delete_me) + { + fdh->delete_me = EINA_TRUE; + fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); + } + found++; + } + fdh->references--; + } + else + { + ERR("Problematic fd found at %d! setting it for delete", fdh->fd); + if (!fdh->delete_me) + { + fdh->delete_me = EINA_TRUE; + fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); + } + + 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 +#endif + +static void +_ecore_main_fd_handlers_cleanup(void) +{ + Ecore_Fd_Handler *fdh; + Eina_List *l, *l2; + + if (!fd_handlers_to_delete) return; + EINA_LIST_FOREACH_SAFE(fd_handlers_to_delete, l, l2, fdh) + { + if (!fdh) + { + fd_handlers_to_delete = eina_list_remove_list(l, fd_handlers_to_delete); + continue; + } + /* fdh->delete_me should be set for all fdhs at the start of the list */ + if (fdh->references) + continue; + if (fdh->buf_func && fd_handlers_with_buffer) + fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fdh); + if (fdh->prep_func && fd_handlers_with_prep) + fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh); + fd_handlers = (Ecore_Fd_Handler *) + eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh)); + if (fdh->file) + file_fd_handlers = eina_list_remove(file_fd_handlers, fdh); + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); + ecore_fd_handler_mp_free(fdh); + fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l); + } +} + +#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); + ecore_win32_handler_mp_free(wh); + } + } + if (!deleted_in_use) win32_handlers_delete_me = EINA_FALSE; +} + +#endif + +static void +_ecore_main_fd_handlers_call(void) +{ + /* grab a new list */ + if (!fd_handlers_to_call_current) + { + fd_handlers_to_call_current = fd_handlers_to_call; + fd_handlers_to_call = NULL; + } + + while (fd_handlers_to_call_current) + { + Ecore_Fd_Handler *fdh = fd_handlers_to_call_current; + + if (!fdh->delete_me) + { + if ((fdh->read_active) || + (fdh->write_active) || + (fdh->error_active)) + { + fdh->references++; + if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh)) + { + if (!fdh->delete_me) + { + fdh->delete_me = EINA_TRUE; + fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); + } + } + fdh->references--; + _ecore_fd_valid(); + + fdh->read_active = EINA_FALSE; + fdh->write_active = EINA_FALSE; + fdh->error_active = EINA_FALSE; + } + } + + /* stop when we point to ourselves */ + if (fdh->next_ready == fdh) + { + fdh->next_ready = NULL; + fd_handlers_to_call_current = NULL; + break; + } + + fd_handlers_to_call_current = fdh->next_ready; + fdh->next_ready = NULL; + } +} + +static int +_ecore_main_fd_handlers_buf_call(void) +{ + Ecore_Fd_Handler *fdh; + Eina_List *l, *l2; + int ret; + + ret = 0; + EINA_LIST_FOREACH_SAFE(fd_handlers_with_buffer, l, l2, fdh) + { + if (!fdh) + { + fd_handlers_with_buffer = eina_list_remove_list(l, fd_handlers_with_buffer); + continue; + } + if ((!fdh->delete_me) && fdh->buf_func) + { + fdh->references++; + if (_ecore_call_fd_cb(fdh->buf_func, fdh->buf_data, fdh)) + { + ret |= _ecore_call_fd_cb(fdh->func, fdh->data, fdh); + fdh->read_active = EINA_TRUE; + _ecore_try_add_to_call_list(fdh); + } + fdh->references--; + } + else + fd_handlers_with_buffer = eina_list_remove_list(fd_handlers_with_buffer, l); + } + return ret; +} + +#ifndef USE_G_MAIN_LOOP + +enum { + SPIN_MORE, + SPIN_RESTART, + LOOP_CONTINUE +}; + +static int +_ecore_main_loop_spin_core(void) +{ + /* as we are spinning we need to update loop time per spin */ + _ecore_time_loop_time = ecore_time_get(); + /* call all idlers, which returns false if no more idelrs exist */ + if (!_ecore_idler_all_call()) return SPIN_RESTART; + /* sneaky - drop through or if checks - the first one to succeed + * drops through and returns "continue" so further ones dont run */ + if ((_ecore_main_select(0.0) > 0) || (_ecore_event_exist()) || + (_ecore_signal_count_get() > 0) || (do_quit)) + return LOOP_CONTINUE; + /* default - spin more */ + return SPIN_MORE; +} + +static int +_ecore_main_loop_spin_no_timers(void) +{ + /* if we have idlers we HAVE to spin and handle everything + * in a polling way - spin in a tight polling loop */ + for (;; ) + { + int action = _ecore_main_loop_spin_core(); + if (action != SPIN_MORE) return action; + /* if an idler has added a timer then we need to go through + * the start of the spin cycle again to handle cases properly */ + if (_ecore_timers_exists()) return SPIN_RESTART; + } + /* just contiune handling events etc. */ + return LOOP_CONTINUE; +} + +static int +_ecore_main_loop_spin_timers(void) +{ + /* if we have idlers we HAVE to spin and handle everything + * in a polling way - spin in a tight polling loop */ + for (;; ) + { + int action = _ecore_main_loop_spin_core(); + if (action != SPIN_MORE) return action; + /* if next timer expires now or in the past - stop spinning and + * continue the mainloop walk as our "select" timeout has + * expired now */ + if (_ecore_timer_next_get() <= 0.0) return LOOP_CONTINUE; + } + /* just contiune handling events etc. */ + return LOOP_CONTINUE; +} + +static void +_ecore_fps_marker_1(void) +{ + if (!_ecore_fps_debug) return; + t2 = ecore_time_get(); + if ((t1 > 0.0) && (t2 > 0.0)) _ecore_fps_debug_runtime_add(t2 - t1); +} + +static void +_ecore_fps_marker_2(void) +{ + if (!_ecore_fps_debug) return; + t1 = ecore_time_get(); +} + +static void +_ecore_main_loop_iterate_internal(int once_only) +{ + double next_time = -1.0; + + in_main_loop++; + /* expire any timers */ + _ecore_timer_expired_timers_call(_ecore_time_loop_time); + _ecore_timer_cleanup(); + + /* process signals into events .... */ + _ecore_signal_received_process(); + /* if as a result of timers/animators or signals we have accumulated + * events, then instantly handle them */ + if (_ecore_event_exist()) + { + /* but first conceptually enter an idle state */ + _ecore_idle_enterer_call(); + _ecore_throttle(); + /* now quickly poll to see which input fd's are active */ + _ecore_main_select(0.0); + /* allow newly queued timers to expire from now on */ + _ecore_timer_enable_new(); + /* go straight to processing the events we had queued */ + goto process_all; + } + + if (once_only) + { + /* in once_only mode we should quickly poll for inputs, signals + * if we got any events or signals, allow new timers to process. + * use bitwise or to force both conditions to be tested and + * merged together */ + if (_ecore_main_select(0.0) | _ecore_signal_count_get()) + { + _ecore_timer_enable_new(); + goto process_all; + } + } + else + { + /* call idle enterers ... */ + _ecore_idle_enterer_call(); + _ecore_throttle(); + } + + /* if these calls caused any buffered events to appear - deal with them */ + if (fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(); + + /* if there are any (buffered fd handling may generate them) + * then jump to processing them */ + if (_ecore_event_exist()) + { + _ecore_main_select(0.0); + _ecore_timer_enable_new(); + goto process_all; + } + + if (once_only) + { + /* in once_only mode enter idle here instead and then return */ + _ecore_idle_enterer_call(); + _ecore_throttle(); + _ecore_timer_enable_new(); + goto done; + } + + _ecore_fps_marker_1(); + + /* start of the sleeping or looping section */ +start_loop: /***************************************************************/ + /* any timers re-added as a result of these are allowed to go */ + _ecore_timer_enable_new(); + /* if we have been asked to quit the mainloop then exit at this point */ + if (do_quit) + { + _ecore_timer_enable_new(); + goto done; + } + if (!_ecore_event_exist()) + { + /* init flags */ + next_time = _ecore_timer_next_get(); + /* no idlers */ + if (!_ecore_idler_exist()) + { + /* sleep until timeout or forever (-1.0) waiting for on fds */ + _ecore_main_select(next_time); + } + else + { + int action = LOOP_CONTINUE; + + /* no timers - spin */ + if (next_time < 0) action = _ecore_main_loop_spin_no_timers(); + /* timers - spin */ + else action = _ecore_main_loop_spin_timers(); + if (action == SPIN_RESTART) goto start_loop; + } + } + _ecore_fps_marker_2(); + + /* actually wake up and deal with input, events etc. */ +process_all: /***********************************************************/ + + /* 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 */ + _ecore_main_fd_handlers_call(); + if (fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call(); + /* process signals into events .... */ + _ecore_signal_received_process(); + /* handle events ... */ + _ecore_event_call(); + _ecore_main_fd_handlers_cleanup(); + + if (once_only) + { + /* if in once_only mode handle idle exiting */ + _ecore_idle_enterer_call(); + _ecore_throttle(); + } + +done: /*******************************************************************/ + in_main_loop--; +} + +#endif + +#ifdef _WIN32 +static int +_ecore_main_win32_select(int nfds EINA_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 (readfds) + { + if (FD_ISSET(fdh->fd, readfds)) + network_event |= FD_READ; + } + if (writefds) + { + if (FD_ISSET(fdh->fd, writefds)) + network_event |= FD_WRITE; + } + if (exceptfds) + { + 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) + 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); + + if (readfds) + FD_ZERO(readfds); + if (writefds) + FD_ZERO(writefds); + if (exceptfds) + FD_ZERO(exceptfds); + + /* The result tells us the type of event we have. */ + if (result == WAIT_FAILED) + { + char *m; + + m = evil_last_error_get(); + ERR("%s", m); + free(m); + 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) && readfds) + FD_SET(sockets[result], readfds); + if ((network_event.lNetworkEvents & FD_WRITE) && writefds) + FD_SET(sockets[result], writefds); + if ((network_event.lNetworkEvents & FD_OOB) && exceptfds) + 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 = EINA_TRUE; + win32_handlers_delete_me = EINA_TRUE; + } + 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 diff --git a/src/lib/ecore/ecore_pipe.c b/src/lib/ecore/ecore_pipe.c new file mode 100644 index 0000000000..c6962a5d58 --- /dev/null +++ b/src/lib/ecore/ecore_pipe.c @@ -0,0 +1,748 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#ifdef HAVE_ISFINITE +# define ECORE_FINITE(t) isfinite(t) +#else +# ifdef _MSC_VER +# define ECORE_FINITE(t) _finite(t) +# else +# define ECORE_FINITE(t) finite(t) +# endif +#endif + +#define FIX_HZ 1 + +#ifdef FIX_HZ +# ifndef _MSC_VER +# include +# endif +# ifndef HZ +# define HZ 100 +# endif +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#ifdef HAVE_ESCAPE +# include +#endif + +#ifdef HAVE_EXOTIC +# include +#endif + +/* + * 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 + +# 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 +# include + +# 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 */ + +#include "Ecore.h" +#include "ecore_private.h" + +/* How of then we should retry to write to the pipe */ +#define ECORE_PIPE_WRITE_RETRY 6 + +struct _Ecore_Pipe +{ + ECORE_MAGIC; + int fd_read; + int fd_write; + Ecore_Fd_Handler *fd_handler; + const void *data; + Ecore_Pipe_Cb handler; + unsigned int len; + int handling; + size_t already_read; + void *passed_data; + int message; + Eina_Bool delete_me : 1; +}; +GENERIC_ALLOC_SIZE_DECLARE(Ecore_Pipe); + +static Eina_Bool _ecore_pipe_read(void *data, + Ecore_Fd_Handler *fd_handler); + +/** + * @addtogroup Ecore_Pipe_Group + * + * @{ + */ + +/** + * 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. + */ +EAPI Ecore_Pipe * +ecore_pipe_add(Ecore_Pipe_Cb handler, + const void *data) +{ + Ecore_Pipe *p; + + _ecore_lock(); + p = _ecore_pipe_add(handler, data); + _ecore_unlock(); + + 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 + */ +EAPI void * +ecore_pipe_del(Ecore_Pipe *p) +{ + void *r; + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + r = _ecore_pipe_del(p); + _ecore_unlock(); + return r; +} + +/** + * Close the read end of an Ecore_Pipe object created with ecore_pipe_add(). + * + * @param p The Ecore_Pipe object. + */ +EAPI void +ecore_pipe_read_close(Ecore_Pipe *p) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_close"); + goto out; + } + if (p->fd_handler) + { + _ecore_main_fd_handler_del(p->fd_handler); + p->fd_handler = NULL; + } + if (p->fd_read != PIPE_FD_INVALID) + { + pipe_close(p->fd_read); + p->fd_read = PIPE_FD_INVALID; + } +out: + _ecore_unlock(); +} + +/** + * Stop monitoring if necessary the pipe for reading. See ecore_pipe_thaw() + * for monitoring it again. + * + * @param p The Ecore_Pipe object. + * @since 1.1 + */ +EAPI void +ecore_pipe_freeze(Ecore_Pipe *p) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_freeze"); + goto out; + } + if (p->fd_handler) + { + _ecore_main_fd_handler_del(p->fd_handler); + p->fd_handler = NULL; + } +out: + _ecore_unlock(); +} + +/** + * Start monitoring again the pipe for reading. See ecore_pipe_freeze() for + * stopping the monitoring activity. This will not work if + * ecore_pipe_read_close() was previously called on the same pipe. + * + * @param p The Ecore_Pipe object. + * @since 1.1 + */ +EAPI void +ecore_pipe_thaw(Ecore_Pipe *p) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_thaw"); + goto out; + } + if (!p->fd_handler && p->fd_read != PIPE_FD_INVALID) + { + p->fd_handler = ecore_main_fd_handler_add(p->fd_read, + ECORE_FD_READ, + _ecore_pipe_read, + p, + NULL, NULL); + } +out: + _ecore_unlock(); +} + +/** + * @brief Wait from another thread on the read side of a pipe. + * + * @param p The pipe to watch on. + * @param message_count The minimal number of message to wait before exiting. + * @param wait The amount of time in second to wait before exiting. + * @return the number of message catched during that wait call. + * @since 1.1 + * + * Negative value for @p wait means infite wait. + */ +EAPI int +ecore_pipe_wait(Ecore_Pipe *p, + int message_count, + double wait) +{ + int r; + _ecore_lock(); + r = _ecore_pipe_wait(p, message_count, wait); + _ecore_unlock(); + return r; +} + +/** + * Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). + * + * @param p The Ecore_Pipe object. + */ +EAPI void +ecore_pipe_write_close(Ecore_Pipe *p) +{ + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close"); + goto out; + } + if (p->fd_write != PIPE_FD_INVALID) + { + pipe_close(p->fd_write); + p->fd_write = PIPE_FD_INVALID; + } +out: + _ecore_unlock(); +} + +/** + * 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 @c EINA_TRUE on a successful write, @c EINA_FALSE on error. + */ +EAPI Eina_Bool +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; + Eina_Bool ok = EINA_FALSE; + + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write"); + goto out; + } + + if (p->delete_me) goto out; + + if (p->fd_write == PIPE_FD_INVALID) goto out; + + /* 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"); + goto out; + } + else if (ret == PIPE_FD_ERROR && errno == EPIPE) + { + pipe_close(p->fd_write); + p->fd_write = PIPE_FD_INVALID; + goto out; + } + else if (ret == PIPE_FD_ERROR && errno == EINTR) + /* try it again */ + ; + else + { + ERR("An unhandled error (ret: %zd errno: %d)" + "occurred while writing to the pipe the length", + ret, errno); + } + } + while (retry--); + + if (retry != ECORE_PIPE_WRITE_RETRY) goto out; + + /* 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)) + { + ok = EINA_TRUE; + goto out; + } + 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; + goto out; + } + else if (ret == PIPE_FD_ERROR && errno == EINTR) + /* try it again */ + ; + else + { + ERR("An unhandled error (ret: %zd errno: %d)" + "occurred while writing to the pipe the length", + ret, errno); + } + } + while (retry--); + +out: + _ecore_unlock(); + return ok; +} + +/** + * @} + */ + +/* Private functions */ +Ecore_Pipe * +_ecore_pipe_add(Ecore_Pipe_Cb handler, + const void *data) +{ + Ecore_Pipe *p = NULL; + int fds[2]; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + if (!handler) return NULL; + + p = ecore_pipe_calloc(1); + if (!p) return NULL; + + if (pipe(fds)) + { + ecore_pipe_mp_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; +} + +void * +_ecore_pipe_del(Ecore_Pipe *p) +{ + void *data = NULL; + + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_del"); + return NULL; + } + p->delete_me = EINA_TRUE; + if (p->handling > 0) return (void *)p->data; + if (p->fd_handler) _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; + ecore_pipe_mp_free(p); + return data; +} + +int +_ecore_pipe_wait(Ecore_Pipe *p, + int message_count, + double wait) +{ + struct timeval tv, *t; + fd_set rset; + double end = 0.0; + double timeout; + int ret; + int total = 0; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1); + if (p->fd_read == PIPE_FD_INVALID) + return -1; + + FD_ZERO(&rset); + FD_SET(p->fd_read, &rset); + + if (wait >= 0.0) + end = ecore_loop_time_get() + wait; + timeout = wait; + + while (message_count > 0 && (timeout > 0.0 || wait <= 0.0)) + { + if (wait >= 0.0) + { + /* finite() tests for NaN, too big, too small, and infinity. */ + if ((!ECORE_FINITE(timeout)) || (timeout == 0.0)) + { + tv.tv_sec = 0; + tv.tv_usec = 0; + } + 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; + } + else + { + t = NULL; + } + + ret = main_loop_select(p->fd_read + 1, &rset, NULL, NULL, t); + + if (ret > 0) + { + _ecore_pipe_read(p, NULL); + message_count -= p->message; + total += p->message; + p->message = 0; + } + else if (ret == 0) + { + break; + } + else if (errno != EINTR) + { + close(p->fd_read); + p->fd_read = PIPE_FD_INVALID; + break; + } + + if (wait >= 0.0) + timeout = end - ecore_loop_time_get(); + } + + return total; +} + +static void +_ecore_pipe_unhandle(Ecore_Pipe *p) +{ + p->handling--; + if (p->delete_me) + { + _ecore_pipe_del(p); + } +} + +static void +_ecore_pipe_handler_call(Ecore_Pipe *p, + unsigned char *buf, + size_t len) +{ + void *data = (void*) p->data; + if (!p->delete_me) + { + _ecore_unlock(); + p->handler(data, buf, len); + _ecore_lock(); + } +} + +static Eina_Bool +_ecore_pipe_read(void *data, + Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + Ecore_Pipe *p = (Ecore_Pipe *)data; + int i; + + p->handling++; + for (i = 0; i < 16; i++) + { + 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 */ + /* read amount ok - nothing more to do */ + if (ret == sizeof(p->len)) + ; + else if (ret > 0) + { + /* we got more data than we asked for - definite error */ + ERR("Only read %i bytes from the pipe, although" + " we need to read %i bytes.", + (int)ret, (int)sizeof(p->len)); + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_CANCEL; + } + else if (ret == 0) + { + /* we got no data */ + if (i == 0) + { + /* no data on first try through means an error */ + _ecore_pipe_handler_call(p, NULL, 0); + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; + pipe_close(p->fd_read); + p->fd_read = PIPE_FD_INVALID; + p->fd_handler = NULL; + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_CANCEL; + } + else + { + /* no data after first loop try is ok */ + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; + } + } +#ifndef _WIN32 + else if ((ret == PIPE_FD_ERROR) && + ((errno == EINTR) || (errno == EAGAIN))) + { + return ECORE_CALLBACK_RENEW; + } + else + { + ERR("An unhandled error (ret: %i errno: %i [%s])" + "occurred while reading from the pipe the length", + (int)ret, errno, strerror(errno)); + return ECORE_CALLBACK_RENEW; + } +#else + else /* ret == PIPE_FD_ERROR is the only other case on Windows */ + { + if (WSAGetLastError() != WSAEWOULDBLOCK) + { + _ecore_pipe_handler_call(p, NULL, 0); + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; + pipe_close(p->fd_read); + p->fd_read = PIPE_FD_INVALID; + p->fd_handler = NULL; + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_CANCEL; + } + } +#endif + } + + /* if somehow we got less than or equal to 0 we got an errnoneous + * messages so call callback with null and len we got. this case should + * never happen */ + if (p->len == 0) + { + _ecore_pipe_handler_call(p, NULL, 0); + /* reset all values to 0 */ + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; + } + + /* we dont have a buffer to hold the data, so alloc it */ + if (!p->passed_data) + { + p->passed_data = malloc(p->len); + /* alloc failed - error case */ + if (!p->passed_data) + { + _ecore_pipe_handler_call(p, NULL, 0); + /* close the pipe */ + p->already_read = 0; + p->len = 0; + p->message++; + pipe_close(p->fd_read); + p->fd_read = PIPE_FD_INVALID; + p->fd_handler = NULL; + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_CANCEL; + } + } + + /* 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 we read enough data to finish the message/buffer */ + if (ret == (ssize_t)(p->len - p->already_read)) + { + _ecore_pipe_handler_call(p, 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; + p->message++; + } + else if (ret > 0) + { + /* more data left to read */ + p->already_read += ret; + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; + } + else if (ret == 0) + { + /* 0 bytes to read - could be more to read next select wake up */ + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; + } +#ifndef _WIN32 + else if ((ret == PIPE_FD_ERROR) && + ((errno == EINTR) || (errno == EAGAIN))) + { + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; + } + else + { + ERR("An unhandled error (ret: %zd errno: %d)" + "occurred while reading from the pipe the data", + ret, errno); + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; + } +#else + else /* ret == PIPE_FD_ERROR is the only other case on Windows */ + { + if (WSAGetLastError() != WSAEWOULDBLOCK) + { + _ecore_pipe_handler_call(p, NULL, 0); + if (p->passed_data) free(p->passed_data); + p->passed_data = NULL; + p->already_read = 0; + p->len = 0; + p->message++; + pipe_close(p->fd_read); + p->fd_read = PIPE_FD_INVALID; + p->fd_handler = NULL; + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_CANCEL; + } + else + break; + } +#endif + } + + _ecore_pipe_unhandle(p); + return ECORE_CALLBACK_RENEW; +} + diff --git a/src/lib/ecore/ecore_poll.c b/src/lib/ecore/ecore_poll.c new file mode 100644 index 0000000000..28be53857c --- /dev/null +++ b/src/lib/ecore/ecore_poll.c @@ -0,0 +1,490 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#define MY_CLASS ECORE_POLLER_CLASS + +#define MY_CLASS_NAME "ecore_poller" + +EAPI Eo_Op ECORE_POLLER_BASE_ID = EO_NOOP; + +#define ECORE_POLLER_CHECK(obj) \ + if (!eo_isa((obj), ECORE_POLLER_CLASS)) \ + return + +struct _Ecore_Poller_Private_Data +{ + EINA_INLIST; + ECORE_MAGIC; + Ecore_Poller *obj; + int ibit; + unsigned char delete_me : 1; + Ecore_Task_Cb func; + void *data; +}; + +typedef struct _Ecore_Poller_Private_Data Ecore_Poller_Private_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_Private_Data *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 Eina_Bool _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 Eina_Bool +_ecore_poller_cb_timer(void *data EINA_UNUSED) +{ + int i; + Ecore_Poller_Private_Data *poller, *l; + int changes = 0; + + at_tick++; + last_tick = ecore_time_get(); + /* we have 16 counters - each increments every time the poller counter + * "ticks". it increments 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_Private_Data *)EINA_INLIST_GET(l)->next; + if (poller->delete_me) + { + pollers[i] = (Ecore_Poller_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller)); + + eo_parent_set(poller->obj, NULL); + if (eo_destructed_is(poller->obj)) + eo_manual_free(poller->obj); + else + eo_manual_free_set(poller->obj, EINA_FALSE); + + 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 implies keep running me" but we have been deleted + * anyway */ + if (!timer) return ECORE_CALLBACK_CANCEL; + + /* adjust interval */ + ecore_timer_interval_set(timer, poll_cur_interval); + return ECORE_CALLBACK_RENEW; +} + +EAPI void +ecore_poller_poll_interval_set(Ecore_Poller_Type type EINA_UNUSED, + double poll_time) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + + if (poll_time < 0.0) + { + ERR("Poll time %f less than zero, ignored", poll_time); + return; + } + + poll_interval = poll_time; + _ecore_poller_next_tick_eval(); +} + +EAPI double +ecore_poller_poll_interval_get(Ecore_Poller_Type type EINA_UNUSED) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); + return poll_interval; +} + +static void +_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) +{ + eo_error_set(obj); + ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); +} + +EAPI Ecore_Poller * +ecore_poller_add(Ecore_Poller_Type type EINA_UNUSED, + int interval, + Ecore_Task_Cb func, + const void *data) +{ + Ecore_Poller *poller; + poller = eo_add_custom(MY_CLASS, _ecore_parent, + ecore_poller_constructor(type, interval, func, data)); + eo_unref(poller); + return poller; +} + +static void +_poller_constructor(Eo *obj, void *_pd, va_list *list) +{ + Ecore_Poller_Type type = va_arg(*list, Ecore_Poller_Type); + (void)type; + int interval = va_arg(*list, int); + Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); + const void *data = va_arg(*list, const void *); + + + Ecore_Poller_Private_Data *poller = _pd; + poller->obj = obj; + + int ibit; + + if (EINA_UNLIKELY(!eina_main_loop_is())) + { + eo_error_set(obj); + EINA_MAIN_LOOP_CHECK_RETURN; + } + + eo_do_super(obj, eo_constructor()); + eo_manual_free_set(obj, EINA_TRUE); + + if (!func) + { + eo_error_set(obj); + ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); + return; + } + + /* 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_Private_Data *)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(); +} + +EAPI Eina_Bool +ecore_poller_poller_interval_set(Ecore_Poller *obj, + int interval) +{ + Eina_Bool ret; + ECORE_POLLER_CHECK(obj) EINA_FALSE; + eo_do(obj, ecore_poller_interval_set(interval, &ret)); + return ret; +} + +static void +_poller_interval_set(Eo *obj EINA_UNUSED, void *_pd, va_list *list) +{ + int interval = va_arg(*list, int); + Eina_Bool *ret = va_arg(*list, Eina_Bool *); + Eina_Bool int_ret; + + EINA_MAIN_LOOP_CHECK_RETURN; + + int ibit; + + Ecore_Poller_Private_Data *poller = _pd; + + /* 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; + /* if interval specified is the same as interval set, return true without wasting time */ + if (poller->ibit == ibit) + { + int_ret = EINA_TRUE; + goto end; + } + + pollers[poller->ibit] = (Ecore_Poller_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller)); + poller->ibit = ibit; + pollers[poller->ibit] = (Ecore_Poller_Private_Data *)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(); + + int_ret = EINA_TRUE; + +end: + if (ret) *ret = int_ret; +} + +EAPI int +ecore_poller_poller_interval_get(Ecore_Poller *obj) +{ + int ret; + ECORE_POLLER_CHECK(obj) EINA_FALSE; + eo_do(obj, ecore_poller_interval_get(&ret)); + return ret; +} + +static void +_poller_interval_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) +{ + int *ret = va_arg(*list, int *); + *ret =0; + + int ibit, interval = 1; + + EINA_MAIN_LOOP_CHECK_RETURN; + Ecore_Poller_Private_Data *poller = _pd; + + ibit = poller->ibit; + while (ibit != 0) + { + ibit--; + interval <<= 1; + } + *ret = interval; +} + +EAPI void * +ecore_poller_del(Ecore_Poller *obj) +{ + void *data; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + Ecore_Poller_Private_Data *poller = eo_data_get(obj, MY_CLASS); + /* 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_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller)); + + eo_parent_set(poller->obj, NULL); + if (eo_destructed_is(poller->obj)) + eo_manual_free(obj); + else + eo_manual_free_set(obj, EINA_FALSE); + + _ecore_poller_next_tick_eval(); + return data; +} + +static void +_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Poller_Private_Data *pd = _pd; + + if (!pd->delete_me) + { + pd->delete_me = 1; + poller_delete_count++; + } + + eo_do_super(obj, eo_destructor()); +} + +/** + * @} + */ + +void +_ecore_poller_shutdown(void) +{ + int i; + Ecore_Poller_Private_Data *poller; + + for (i = 0; i < 15; i++) + { + while ((poller = pollers[i])) + { + pollers[i] = (Ecore_Poller_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i])); + eo_parent_set(poller->obj, NULL); + if (eo_destructed_is(poller->obj)) + eo_manual_free(poller->obj); + else + eo_manual_free_set(poller->obj, EINA_FALSE); + } + } +} + +static void +_class_constructor(Eo_Class *klass) +{ + const Eo_Op_Func_Description func_desc[] = { + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), + EO_OP_FUNC(ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_CONSTRUCTOR), _poller_constructor), + EO_OP_FUNC(ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_SET), _poller_interval_set), + EO_OP_FUNC(ECORE_POLLER_ID(ECORE_POLLER_SUB_ID_INTERVAL_GET), _poller_interval_get), + EO_OP_FUNC_SENTINEL + }; + + eo_class_funcs_set(klass, func_desc); +} + +static const Eo_Op_Description op_desc[] = { + EO_OP_DESCRIPTION(ECORE_POLLER_SUB_ID_CONSTRUCTOR, "Add an idle enterer handler."), + EO_OP_DESCRIPTION(ECORE_POLLER_SUB_ID_INTERVAL_SET, "Changes the polling interval rate of poller."), + EO_OP_DESCRIPTION(ECORE_POLLER_SUB_ID_INTERVAL_GET, "Gets the polling interval rate of poller"), + EO_OP_DESCRIPTION_SENTINEL +}; +static const Eo_Class_Description class_desc = { + EO_VERSION, + MY_CLASS_NAME, + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(&ECORE_POLLER_BASE_ID, op_desc, ECORE_POLLER_SUB_ID_LAST), + NULL, + sizeof(Ecore_Poller_Private_Data), + _class_constructor, + NULL +}; + +EO_DEFINE_CLASS(ecore_poller_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h new file mode 100644 index 0000000000..f0add822fe --- /dev/null +++ b/src/lib/ecore/ecore_private.h @@ -0,0 +1,398 @@ +#ifndef _ECORE_PRIVATE_H +#define _ECORE_PRIVATE_H + +#include + +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 EVAS_FRAME_QUEUING 1 /* for test */ + +#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 + +typedef unsigned int Ecore_Magic; +#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; \ + } + +EAPI void _ecore_magic_fail(const void *d, + Ecore_Magic m, + Ecore_Magic req_m, + const char *fname); + +void _ecore_time_init(void); + +Ecore_Timer *_ecore_timer_loop_add(double in, + Ecore_Task_Cb func, + const void *data); +void *_ecore_timer_del(Ecore_Timer *timer); +void _ecore_timer_delay(Ecore_Timer *timer, + double add); +void _ecore_timer_shutdown(void); +void _ecore_timer_cleanup(void); +void _ecore_timer_enable_new(void); +double _ecore_timer_next_get(void); +void _ecore_timer_expired_timers_call(double when); +int _ecore_timers_exists(void); + +int _ecore_timer_expired_call(double when); + +void _ecore_idler_shutdown(void); +int _ecore_idler_all_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, + Ecore_End_Cb func_free, + void *data); +void _ecore_event_call(void); +void *_ecore_event_handler_del(Ecore_Event_Handler *event_handler); + +Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe *exe); +void _ecore_exe_doomsday_clock_set(Ecore_Exe *exe, + Ecore_Timer *dc); + +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); + +Ecore_Pipe *_ecore_pipe_add(Ecore_Pipe_Cb handler, + const void *data); +int _ecore_pipe_wait(Ecore_Pipe *p, + int message_count, + double wait); +void *_ecore_pipe_del(Ecore_Pipe *p); + +Ecore_Fd_Handler * + _ecore_main_fd_handler_add(int fd, + Ecore_Fd_Handler_Flags flags, + Ecore_Fd_Cb func, + const void *data, + Ecore_Fd_Cb buf_func, + const void *buf_data); +void *_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); + +void _ecore_main_shutdown(void); + +#if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC) +static inline void _ecore_signal_shutdown(void) { } + +static inline void _ecore_signal_init(void) { } + +static inline void _ecore_signal_received_process(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); +void _ecore_signal_received_process(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); + +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); + +void _ecore_main_loop_init(void); +void _ecore_main_loop_shutdown(void); + +void _ecore_throttle(void); + +void _ecore_main_call_flush(void); + +extern int _ecore_main_lock_count; +extern Eina_Lock _ecore_main_loop_lock; + +static inline void +_ecore_lock(void) +{ +#ifdef HAVE_THREAD_SAFETY + eina_lock_take(&_ecore_main_loop_lock); +#else + /* at least check we're not being called from a thread */ + EINA_MAIN_LOOP_CHECK_RETURN; +#endif + _ecore_main_lock_count++; + /* assert(_ecore_main_lock_count == 1); */ +} + +static inline void +_ecore_unlock(void) +{ + _ecore_main_lock_count--; + /* assert(_ecore_main_lock_count == 0); */ +#ifdef HAVE_THREAD_SAFETY + eina_lock_release(&_ecore_main_loop_lock); +#endif +} + +/* + * Callback wrappers all assume that ecore _ecore_lock has been called + */ +static inline Eina_Bool +_ecore_call_task_cb(Ecore_Task_Cb func, + void *data) +{ + Eina_Bool r; + + _ecore_unlock(); + r = func(data); + _ecore_lock(); + + return r; +} + +static inline void * +_ecore_call_data_cb(Ecore_Data_Cb func, + void *data) +{ + void *r; + + _ecore_unlock(); + r = func(data); + _ecore_lock(); + + return r; +} + +static inline void +_ecore_call_end_cb(Ecore_End_Cb func, + void *user_data, + void *func_data) +{ + _ecore_unlock(); + func(user_data, func_data); + _ecore_lock(); +} + +static inline Eina_Bool +_ecore_call_filter_cb(Ecore_Filter_Cb func, + void *data, + void *loop_data, + int type, + void *event) +{ + Eina_Bool r; + + _ecore_unlock(); + r = func(data, loop_data, type, event); + _ecore_lock(); + + return r; +} + +static inline Eina_Bool +_ecore_call_handler_cb(Ecore_Event_Handler_Cb func, + void *data, + int type, + void *event) +{ + Eina_Bool r; + + _ecore_unlock(); + r = func(data, type, event); + _ecore_lock(); + + return r; +} + +static inline void +_ecore_call_prep_cb(Ecore_Fd_Prep_Cb func, + void *data, + Ecore_Fd_Handler *fd_handler) +{ + _ecore_unlock(); + func(data, fd_handler); + _ecore_lock(); +} + +static inline Eina_Bool +_ecore_call_fd_cb(Ecore_Fd_Cb func, + void *data, + Ecore_Fd_Handler *fd_handler) +{ + Eina_Bool r; + + _ecore_unlock(); + r = func(data, fd_handler); + _ecore_lock(); + + return r; +} + +extern int _ecore_fps_debug; +extern double _ecore_time_loop_time; +extern Eina_Bool _ecore_glib_always_integrate; +extern Ecore_Select_Function main_loop_select; + +Eina_Bool ecore_mempool_init(void); +void ecore_mempool_shutdown(void); +#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \ + TYPE *Type##_calloc(unsigned int); \ + void Type##_mp_free(TYPE *e); +#define GENERIC_ALLOC_SIZE_DECLARE(TYPE) \ + size_t _ecore_sizeof_##TYPE = sizeof (TYPE); + +//GENERIC_ALLOC_FREE_HEADER(Ecore_Animator, ecore_animator); +GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Handler, ecore_event_handler); +GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Filter, ecore_event_filter); +GENERIC_ALLOC_FREE_HEADER(Ecore_Event, ecore_event); +//GENERIC_ALLOC_FREE_HEADER(Ecore_Idle_Exiter, ecore_idle_exiter); +//GENERIC_ALLOC_FREE_HEADER(Ecore_Idle_Enterer, ecore_idle_enterer); +//GENERIC_ALLOC_FREE_HEADER(Ecore_Idler, ecore_idler); +//GENERIC_ALLOC_FREE_HEADER(Ecore_Job, ecore_job); +//GENERIC_ALLOC_FREE_HEADER(Ecore_Timer, ecore_timer); +//GENERIC_ALLOC_FREE_HEADER(Ecore_Poller, ecore_poller); +GENERIC_ALLOC_FREE_HEADER(Ecore_Pipe, ecore_pipe); +GENERIC_ALLOC_FREE_HEADER(Ecore_Fd_Handler, ecore_fd_handler); +#ifdef _WIN32 +GENERIC_ALLOC_FREE_HEADER(Ecore_Win32_Handler, ecore_win32_handler); +#endif + +#undef GENERIC_ALLOC_FREE_HEADER + +extern Eo *_ecore_parent; +#define ECORE_PARENT_CLASS ecore_parent_class_get() +const Eo_Class *ecore_parent_class_get(void) EINA_CONST; + +#endif diff --git a/src/lib/ecore/ecore_signal.c b/src/lib/ecore/ecore_signal.c new file mode 100644 index 0000000000..8114f72b09 --- /dev/null +++ b/src/lib/ecore/ecore_signal.c @@ -0,0 +1,594 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#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 */ + +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 + +static Eina_Bool _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 + +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 + +void +_ecore_signal_shutdown(void) +{ + _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; +} + +void +_ecore_signal_init(void) +{ + _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 +} + +void +_ecore_signal_received_process(void) +{ + while (_ecore_signal_count_get()) _ecore_signal_call(); +} + +int +_ecore_signal_count_get(void) +{ + return sig_count; +} + +static void +_ecore_signal_generic_free(void *data EINA_UNUSED, + void *event) +{ + free(event); +} + +void +_ecore_signal_call(void) +{ + volatile sig_atomic_t n; + sigset_t oldset, newset; + int tot; + + 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 + 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); + tot = sigchld_count + sigusr1_count + sigusr2_count + + sighup_count + sigquit_count + sigint_count + sigterm_count +#ifdef SIGPWR + + sigpwr_count +#endif + ; + + if (sig_count != tot) + { + ERR("sig_count (%i) != actual totals (%i) ", sig_count, tot); + sig_count = tot; + } + + 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_unlock(); + doomsday_clock = ecore_timer_add + (0.1, _ecore_signal_exe_exit_delay, e); + _ecore_lock(); + _ecore_exe_doomsday_clock_set(e->exe, doomsday_clock); + } + 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, + _ecore_signal_generic_free, 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, + _ecore_signal_generic_free, 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, + _ecore_signal_generic_free, 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, + _ecore_signal_generic_free, 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, + _ecore_signal_generic_free, 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, + _ecore_signal_generic_free, 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, + _ecore_signal_generic_free, NULL); + } + sig_count--; + } + sigpwr_count = 0; +#endif + sig_count = 0; + + 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 EINA_UNUSED, + siginfo_t *si EINA_UNUSED, + void *foo EINA_UNUSED) +{ +} + +static void +_ecore_signal_callback_sigchld(int sig EINA_UNUSED, + siginfo_t *si, + void *foo EINA_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 EINA_UNUSED, + siginfo_t *si, + void *foo EINA_UNUSED) +{ + volatile sig_atomic_t n; + n = sigusr1_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 EINA_UNUSED, + siginfo_t *si, + void *foo EINA_UNUSED) +{ + volatile sig_atomic_t n; + n = sigusr2_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 EINA_UNUSED, + siginfo_t *si, + void *foo EINA_UNUSED) +{ + volatile sig_atomic_t n; + n = sighup_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 EINA_UNUSED, + siginfo_t *si, + void *foo EINA_UNUSED) +{ + volatile sig_atomic_t n; + n = sigquit_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 EINA_UNUSED, + siginfo_t *si, + void *foo EINA_UNUSED) +{ + volatile sig_atomic_t n; + n = sigint_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 EINA_UNUSED, + siginfo_t *si, + void *foo EINA_UNUSED) +{ + volatile sig_atomic_t n; + n = sigterm_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 EINA_UNUSED, + siginfo_t *si, + void *foo EINA_UNUSED) +{ + volatile sig_atomic_t n; + n = sigpwr_count; + if (n < MAXSIGQ) + { + if (si) + sigpwr_info[n] = *si; + else + sigpwr_info[n].si_signo = 0; + } + sigpwr_count++; + sig_count++; +} + +#endif + +static Eina_Bool +_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 ECORE_CALLBACK_CANCEL; +} + diff --git a/src/lib/ecore/ecore_thread.c b/src/lib/ecore/ecore_thread.c new file mode 100644 index 0000000000..4937ef5290 --- /dev/null +++ b/src/lib/ecore/ecore_thread.c @@ -0,0 +1,1509 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" + +#ifdef EFL_HAVE_THREADS + +# define LK(x) Eina_Lock x +# define LKI(x) eina_lock_new(&(x)) +# define LKD(x) eina_lock_free(&(x)) +# define LKL(x) eina_lock_take(&(x)) +# define LKU(x) eina_lock_release(&(x)) + +# define CD(x) Eina_Condition x +# define CDI(x, m) eina_condition_new(&(x), &(m)) +# define CDD(x) eina_condition_free(&(x)) +# define CDB(x) eina_condition_broadcast(&(x)) +# define CDW(x, t) eina_condition_timedwait(&(x), t) + +# define LRWK(x) Eina_RWLock x +# define LRWKI(x) eina_rwlock_new(&(x)); +# define LRWKD(x) eina_rwlock_free(&(x)); +# define LRWKWL(x) eina_rwlock_take_write(&(x)); +# define LRWKRL(x) eina_rwlock_take_read(&(x)); +# define LRWKU(x) eina_rwlock_release(&(x)); + +# define PH(x) Eina_Thread x +# define PHE(x, y) eina_thread_equal(x, y) +# define PHS() eina_thread_self() +# define PHC(x, f, d) eina_thread_create(&(x), EINA_THREAD_BACKGROUND, -1, (void *)f, d) +# define PHJ(x) eina_thread_join(x) + +# ifdef EFL_HAVE_POSIX_THREADS +# include +# ifdef __linux__ +# include +# include +# include +# include +# include +# endif + +# else /* EFL_HAVE_WIN32_THREADS */ + +# define WIN32_LEAN_AND_MEAN +# include +# undef WIN32_LEAN_AND_MEAN + +# endif + +#endif + +typedef struct _Ecore_Pthread_Worker Ecore_Pthread_Worker; +typedef struct _Ecore_Pthread Ecore_Pthread; +typedef struct _Ecore_Thread_Data Ecore_Thread_Data; + +struct _Ecore_Thread_Data +{ + void *data; + Eina_Free_Cb cb; +}; + +struct _Ecore_Pthread_Worker +{ + union { + struct + { + Ecore_Thread_Cb func_blocking; + } short_run; + struct + { + Ecore_Thread_Cb func_heavy; + Ecore_Thread_Notify_Cb func_notify; + + Ecore_Pthread_Worker *direct_worker; + + int send; + int received; + } feedback_run; + struct { + Ecore_Thread_Cb func_main; + Ecore_Thread_Notify_Cb func_notify; + + Ecore_Pipe *send; + Ecore_Pthread_Worker *direct_worker; + + struct { + int send; + int received; + } from, to; + } message_run; + } u; + + Ecore_Thread_Cb func_cancel; + Ecore_Thread_Cb func_end; +#ifdef EFL_HAVE_THREADS + PH(self); + Eina_Hash *hash; + CD(cond); + LK(mutex); +#endif + + const void *data; + + int cancel; + +#ifdef EFL_HAVE_THREADS + LK(cancel_mutex); +#endif + + Eina_Bool message_run : 1; + Eina_Bool feedback_run : 1; + Eina_Bool kill : 1; + Eina_Bool reschedule : 1; + Eina_Bool no_queue : 1; +}; + +#ifdef EFL_HAVE_THREADS +typedef struct _Ecore_Pthread_Notify Ecore_Pthread_Notify; +struct _Ecore_Pthread_Notify +{ + Ecore_Pthread_Worker *work; + const void *user_data; +}; + +typedef void *(*Ecore_Thread_Sync_Cb)(void* data, Ecore_Thread *thread); + +typedef struct _Ecore_Pthread_Message Ecore_Pthread_Message; +struct _Ecore_Pthread_Message +{ + union { + Ecore_Thread_Cb async; + Ecore_Thread_Sync_Cb sync; + } u; + + const void *data; + + int code; + + Eina_Bool callback : 1; + Eina_Bool sync : 1; +}; + +#endif + +static int _ecore_thread_count_max = 0; + +#ifdef EFL_HAVE_THREADS + +static void _ecore_thread_handler(void *data); + +static int _ecore_thread_count = 0; + +static Eina_List *_ecore_running_job = NULL; +static Eina_List *_ecore_pending_job_threads = NULL; +static Eina_List *_ecore_pending_job_threads_feedback = NULL; +static LK(_ecore_pending_job_threads_mutex); +static LK(_ecore_running_job_mutex); + +static Eina_Hash *_ecore_thread_global_hash = NULL; +static LRWK(_ecore_thread_global_hash_lock); +static LK(_ecore_thread_global_hash_mutex); +static CD(_ecore_thread_global_hash_cond); + +static Eina_Bool have_main_loop_thread = 0; + +static Eina_Trash *_ecore_thread_worker_trash = NULL; +static int _ecore_thread_worker_count = 0; + +static void *_ecore_thread_worker(void *); +static Ecore_Pthread_Worker *_ecore_thread_worker_new(void); + +static PH(get_main_loop_thread) (void) +{ + static PH(main_loop_thread); + static pid_t main_loop_pid; + pid_t pid = getpid(); + + if (pid != main_loop_pid) + { + main_loop_pid = pid; + main_loop_thread = PHS(); + have_main_loop_thread = 1; + } + + return main_loop_thread; +} + +static void +_ecore_thread_worker_free(Ecore_Pthread_Worker *worker) +{ + LKD(worker->cancel_mutex); + CDD(worker->cond); + LKD(worker->mutex); + + if (_ecore_thread_worker_count > ((_ecore_thread_count_max + 1) * 16)) + { + _ecore_thread_worker_count--; + free(worker); + return; + } + + eina_trash_push(&_ecore_thread_worker_trash, worker); +} + +static void +_ecore_thread_data_free(void *data) +{ + Ecore_Thread_Data *d = data; + + if (d->cb) d->cb(d->data); + free(d); +} + +static void +_ecore_thread_join(PH(thread)) +{ + PHJ(thread); +} + +static void +_ecore_thread_kill(Ecore_Pthread_Worker *work) +{ + if (work->cancel) + { + if (work->func_cancel) + work->func_cancel((void *)work->data, (Ecore_Thread *)work); + } + else + { + if (work->func_end) + work->func_end((void *)work->data, (Ecore_Thread *)work); + } + + if (work->feedback_run) + { + if (work->u.feedback_run.direct_worker) + _ecore_thread_worker_free(work->u.feedback_run.direct_worker); + } + if (work->hash) + eina_hash_free(work->hash); + _ecore_thread_worker_free(work); +} + +static void +_ecore_thread_handler(void *data) +{ + Ecore_Pthread_Worker *work = data; + + if (work->feedback_run) + { + if (work->u.feedback_run.send != work->u.feedback_run.received) + { + work->kill = EINA_TRUE; + return; + } + } + + _ecore_thread_kill(work); +} + +#if 0 +static void +_ecore_nothing_handler(void *data EINA_UNUSED, void *buffer EINA_UNUSED, unsigned int nbyte EINA_UNUSED) +{ +} +#endif + +static void +_ecore_notify_handler(void *data) +{ + Ecore_Pthread_Notify *notify = data; + Ecore_Pthread_Worker *work = notify->work; + void *user_data = (void*) notify->user_data; + + work->u.feedback_run.received++; + + if (work->u.feedback_run.func_notify) + work->u.feedback_run.func_notify((void *)work->data, (Ecore_Thread *)work, user_data); + + /* Force reading all notify event before killing the thread */ + if (work->kill && work->u.feedback_run.send == work->u.feedback_run.received) + { + _ecore_thread_kill(work); + } + + free(notify); +} + +static void +_ecore_message_notify_handler(void *data) +{ + Ecore_Pthread_Notify *notify = data; + Ecore_Pthread_Worker *work = notify->work; + Ecore_Pthread_Message *user_data = (void *) notify->user_data; + Eina_Bool delete = EINA_TRUE; + + work->u.message_run.from.received++; + + if (!user_data->callback) + { + if (work->u.message_run.func_notify) + work->u.message_run.func_notify((void *) work->data, (Ecore_Thread *) work, (void *) user_data->data); + } + else + { + if (user_data->sync) + { + user_data->data = user_data->u.sync((void*) user_data->data, (Ecore_Thread *) work); + user_data->callback = EINA_FALSE; + user_data->code = INT_MAX; + ecore_pipe_write(work->u.message_run.send, &user_data, sizeof (Ecore_Pthread_Message *)); + + delete = EINA_FALSE; + } + else + { + user_data->u.async((void*) user_data->data, (Ecore_Thread *) work); + } + } + + if (delete) + { + free(user_data); + } + + /* Force reading all notify event before killing the thread */ + if (work->kill && work->u.message_run.from.send == work->u.message_run.from.received) + { + _ecore_thread_kill(work); + } + free(notify); +} + +static void +_ecore_short_job(PH(thread)) +{ + Ecore_Pthread_Worker *work; + int cancel; + + LKL(_ecore_pending_job_threads_mutex); + + if (!_ecore_pending_job_threads) + { + LKU(_ecore_pending_job_threads_mutex); + return; + } + + work = eina_list_data_get(_ecore_pending_job_threads); + _ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, + _ecore_pending_job_threads); + LKU(_ecore_pending_job_threads_mutex); + + LKL(_ecore_running_job_mutex); + _ecore_running_job = eina_list_append(_ecore_running_job, work); + LKU(_ecore_running_job_mutex); + + LKL(work->cancel_mutex); + cancel = work->cancel; + LKU(work->cancel_mutex); + work->self = thread; + if (!cancel) + work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work); + + LKL(_ecore_running_job_mutex); + _ecore_running_job = eina_list_remove(_ecore_running_job, work); + LKU(_ecore_running_job_mutex); + + if (work->reschedule) + { + work->reschedule = EINA_FALSE; + + LKL(_ecore_pending_job_threads_mutex); + _ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work); + LKU(_ecore_pending_job_threads_mutex); + } + else + { + ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work); + } +} + +static void +_ecore_feedback_job(PH(thread)) +{ + Ecore_Pthread_Worker *work; + int cancel; + + LKL(_ecore_pending_job_threads_mutex); + + if (!_ecore_pending_job_threads_feedback) + { + LKU(_ecore_pending_job_threads_mutex); + return; + } + + work = eina_list_data_get(_ecore_pending_job_threads_feedback); + _ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback, + _ecore_pending_job_threads_feedback); + LKU(_ecore_pending_job_threads_mutex); + LKL(_ecore_running_job_mutex); + _ecore_running_job = eina_list_append(_ecore_running_job, work); + LKU(_ecore_running_job_mutex); + + LKL(work->cancel_mutex); + cancel = work->cancel; + LKU(work->cancel_mutex); + work->self = thread; + if (!cancel) + work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work); + + LKL(_ecore_running_job_mutex); + _ecore_running_job = eina_list_remove(_ecore_running_job, work); + LKU(_ecore_running_job_mutex); + + if (work->reschedule) + { + work->reschedule = EINA_FALSE; + + LKL(_ecore_pending_job_threads_mutex); + _ecore_pending_job_threads_feedback = eina_list_append(_ecore_pending_job_threads_feedback, work); + LKU(_ecore_pending_job_threads_mutex); + } + else + { + ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work); + } +} + +static void * +_ecore_direct_worker(Ecore_Pthread_Worker *work) +{ + work->self = PHS(); + if (work->message_run) + work->u.message_run.func_main((void *) work->data, (Ecore_Thread *) work); + else + work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work); + + ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work); + + ecore_main_loop_thread_safe_call_async((Ecore_Cb) _ecore_thread_join, + (void*) PHS()); + + return NULL; +} + +static void * +_ecore_thread_worker(void *data EINA_UNUSED) +{ +restart: + _ecore_short_job(PHS()); + _ecore_feedback_job(PHS()); + + /* FIXME: Check if there is feedback running task todo, and switch to feedback run handler. */ + + LKL(_ecore_pending_job_threads_mutex); + if (_ecore_pending_job_threads || _ecore_pending_job_threads_feedback) + { + LKU(_ecore_pending_job_threads_mutex); + goto restart; + } + LKU(_ecore_pending_job_threads_mutex); + + /* Sleep a little to prevent premature death */ +#ifdef _WIN32 + Sleep(1); /* around 50ms */ +#else + usleep(50); +#endif + + LKL(_ecore_pending_job_threads_mutex); + if (_ecore_pending_job_threads || _ecore_pending_job_threads_feedback) + { + LKU(_ecore_pending_job_threads_mutex); + goto restart; + } + _ecore_thread_count--; + + ecore_main_loop_thread_safe_call_async((Ecore_Cb) _ecore_thread_join, + (void*) PHS()); + LKU(_ecore_pending_job_threads_mutex); + + return NULL; +} + +#endif + +static Ecore_Pthread_Worker * +_ecore_thread_worker_new(void) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *result; + + result = eina_trash_pop(&_ecore_thread_worker_trash); + + if (!result) + { + result = calloc(1, sizeof(Ecore_Pthread_Worker)); + _ecore_thread_worker_count++; + } + + LKI(result->cancel_mutex); + LKI(result->mutex); + CDI(result->cond, result->mutex); + + return result; +#else + return malloc(sizeof (Ecore_Pthread_Worker)); +#endif +} + +void +_ecore_thread_init(void) +{ + _ecore_thread_count_max = eina_cpu_count(); + if (_ecore_thread_count_max <= 0) + _ecore_thread_count_max = 1; + +#ifdef EFL_HAVE_THREADS + LKI(_ecore_pending_job_threads_mutex); + LRWKI(_ecore_thread_global_hash_lock); + LKI(_ecore_thread_global_hash_mutex); + LKI(_ecore_running_job_mutex); + CDI(_ecore_thread_global_hash_cond, _ecore_thread_global_hash_mutex); +#endif +} + +void +_ecore_thread_shutdown(void) +{ + /* FIXME: If function are still running in the background, should we kill them ? */ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *work; + Eina_List *l; + Eina_Bool test; + int iteration = 0; + + LKL(_ecore_pending_job_threads_mutex); + + EINA_LIST_FREE(_ecore_pending_job_threads, work) + { + if (work->func_cancel) + work->func_cancel((void *)work->data, (Ecore_Thread *) work); + free(work); + } + + EINA_LIST_FREE(_ecore_pending_job_threads_feedback, work) + { + if (work->func_cancel) + work->func_cancel((void *)work->data, (Ecore_Thread *) work); + free(work); + } + + LKU(_ecore_pending_job_threads_mutex); + LKL(_ecore_running_job_mutex); + + EINA_LIST_FOREACH(_ecore_running_job, l, work) + ecore_thread_cancel((Ecore_Thread*) work); + + LKU(_ecore_running_job_mutex); + + do + { + LKL(_ecore_pending_job_threads_mutex); + if (_ecore_thread_count > 0) + { + test = EINA_TRUE; + } + else + { + test = EINA_FALSE; + } + LKU(_ecore_pending_job_threads_mutex); + iteration++; + if (test) usleep(50000); + } + while (test == EINA_TRUE && iteration < 20); + + if (iteration == 20 && _ecore_thread_count > 0) + { + ERR("%i of the child thread are still running after 1s. This can lead to a segv. Sorry.", _ecore_thread_count); + } + + if (_ecore_thread_global_hash) + eina_hash_free(_ecore_thread_global_hash); + have_main_loop_thread = 0; + + while ((work = eina_trash_pop(&_ecore_thread_worker_trash))) + { + free(work); + } + + LKD(_ecore_pending_job_threads_mutex); + LRWKD(_ecore_thread_global_hash_lock); + LKD(_ecore_thread_global_hash_mutex); + LKD(_ecore_running_job_mutex); + CDD(_ecore_thread_global_hash_cond); +#endif +} + +EAPI Ecore_Thread * +ecore_thread_run(Ecore_Thread_Cb func_blocking, + Ecore_Thread_Cb func_end, + Ecore_Thread_Cb func_cancel, + const void *data) +{ + Ecore_Pthread_Worker *work; + Eina_Bool tried = EINA_FALSE; +#ifdef EFL_HAVE_THREADS + PH(thread); +#endif + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + + if (!func_blocking) return NULL; + + work = _ecore_thread_worker_new(); + if (!work) + { + if (func_cancel) + func_cancel((void *)data, NULL); + return NULL; + } + + work->u.short_run.func_blocking = func_blocking; + work->func_end = func_end; + work->func_cancel = func_cancel; + work->cancel = EINA_FALSE; + work->feedback_run = EINA_FALSE; + work->message_run = EINA_FALSE; + work->kill = EINA_FALSE; + work->reschedule = EINA_FALSE; + work->no_queue = EINA_FALSE; + work->data = data; + +#ifdef EFL_HAVE_THREADS + work->self = 0; + work->hash = NULL; + + LKL(_ecore_pending_job_threads_mutex); + _ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work); + + if (_ecore_thread_count == _ecore_thread_count_max) + { + LKU(_ecore_pending_job_threads_mutex); + return (Ecore_Thread *)work; + } + + LKU(_ecore_pending_job_threads_mutex); + + /* One more thread could be created. */ + eina_threads_init(); + + LKL(_ecore_pending_job_threads_mutex); + + retry: + if (PHC(thread, _ecore_thread_worker, NULL)) + { + _ecore_thread_count++; + LKU(_ecore_pending_job_threads_mutex); + return (Ecore_Thread *)work; + } + if (!tried) + { + _ecore_main_call_flush(); + tried = EINA_TRUE; + goto retry; + } + + if (_ecore_thread_count == 0) + { + _ecore_pending_job_threads = eina_list_remove(_ecore_pending_job_threads, work); + + if (work->func_cancel) + work->func_cancel((void *) work->data, (Ecore_Thread *) work); + + _ecore_thread_worker_free(work); + work = NULL; + } + LKU(_ecore_pending_job_threads_mutex); + + eina_threads_shutdown(); + + return (Ecore_Thread *)work; +#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. + */ + do { + /* Handle reschedule by forcing it here. That would mean locking the app, + * would be better with an idler, but really to complex for a case where + * thread should really exist. + */ + work->reschedule = EINA_FALSE; + + func_blocking((void *)data, (Ecore_Thread *)work); + if (work->cancel == EINA_FALSE) func_end((void *)data, (Ecore_Thread *)work); + else func_cancel((void *)data, (Ecore_Thread *)work); + } while (work->reschedule == EINA_TRUE); + + free(work); + + return NULL; +#endif +} + +EAPI Eina_Bool +ecore_thread_cancel(Ecore_Thread *thread) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *volatile work = (Ecore_Pthread_Worker *)thread; + Eina_List *l; + int cancel; + + if (!work) + return EINA_TRUE; + LKL(work->cancel_mutex); + cancel = work->cancel; + LKU(work->cancel_mutex); + if (cancel) + return EINA_FALSE; + + if (work->feedback_run) + { + if (work->kill) + return EINA_TRUE; + if (work->u.feedback_run.send != work->u.feedback_run.received) + goto on_exit; + } + + LKL(_ecore_pending_job_threads_mutex); + + if ((have_main_loop_thread) && + (PHE(get_main_loop_thread(), PHS()))) + { + if (!work->feedback_run) + EINA_LIST_FOREACH(_ecore_pending_job_threads, l, work) + { + if ((void *)work == (void *)thread) + { + _ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, l); + + LKU(_ecore_pending_job_threads_mutex); + + if (work->func_cancel) + work->func_cancel((void *)work->data, (Ecore_Thread *)work); + free(work); + + return EINA_TRUE; + } + } + else + EINA_LIST_FOREACH(_ecore_pending_job_threads_feedback, l, work) + { + if ((void *)work == (void *)thread) + { + _ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback, l); + + LKU(_ecore_pending_job_threads_mutex); + + if (work->func_cancel) + work->func_cancel((void *)work->data, (Ecore_Thread *)work); + free(work); + + return EINA_TRUE; + } + } + } + + LKU(_ecore_pending_job_threads_mutex); + + work = (Ecore_Pthread_Worker *)thread; + + /* Delay the destruction */ + on_exit: + LKL(work->cancel_mutex); + work->cancel = EINA_TRUE; + LKU(work->cancel_mutex); + + return EINA_FALSE; +#else + (void) thread; + return EINA_TRUE; +#endif +} + +EAPI Eina_Bool +ecore_thread_check(Ecore_Thread *thread) +{ + Ecore_Pthread_Worker *volatile worker = (Ecore_Pthread_Worker *) thread; + int cancel; + + if (!worker) return EINA_TRUE; +#ifdef EFL_HAVE_THREADS + LKL(worker->cancel_mutex); +#endif + cancel = worker->cancel; + /* FIXME: there is an insane bug driving me nuts here. I don't know if + it's a race condition, some cache issue or some alien attack on our software. + But ecore_thread_check will only work correctly with a printf, all the volatile, + lock and even usleep don't help here... */ + /* fprintf(stderr, "wc: %i\n", cancel); */ +#ifdef EFL_HAVE_THREADS + LKU(worker->cancel_mutex); +#endif + return cancel; +} + +EAPI Ecore_Thread * +ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy, + Ecore_Thread_Notify_Cb func_notify, + Ecore_Thread_Cb func_end, + Ecore_Thread_Cb func_cancel, + const void *data, + Eina_Bool try_no_queue) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *worker; + Eina_Bool tried = EINA_FALSE; + PH(thread); + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + + if (!func_heavy) return NULL; + + worker = _ecore_thread_worker_new(); + if (!worker) goto on_error; + + worker->u.feedback_run.func_heavy = func_heavy; + worker->u.feedback_run.func_notify = func_notify; + worker->hash = NULL; + worker->func_cancel = func_cancel; + worker->func_end = func_end; + worker->data = data; + worker->cancel = EINA_FALSE; + worker->message_run = EINA_FALSE; + worker->feedback_run = EINA_TRUE; + worker->kill = EINA_FALSE; + worker->reschedule = EINA_FALSE; + worker->self = 0; + + worker->u.feedback_run.send = 0; + worker->u.feedback_run.received = 0; + + worker->u.feedback_run.direct_worker = NULL; + + if (try_no_queue) + { + PH(t); + + worker->u.feedback_run.direct_worker = _ecore_thread_worker_new(); + worker->no_queue = EINA_TRUE; + + eina_threads_init(); + + retry_direct: + if (PHC(t, _ecore_direct_worker, worker)) + return (Ecore_Thread *)worker; + if (!tried) + { + _ecore_main_call_flush(); + tried = EINA_TRUE; + goto retry_direct; + } + + if (worker->u.feedback_run.direct_worker) + { + _ecore_thread_worker_free(worker->u.feedback_run.direct_worker); + worker->u.feedback_run.direct_worker = NULL; + } + + eina_threads_shutdown(); + } + + worker->no_queue = EINA_FALSE; + + LKL(_ecore_pending_job_threads_mutex); + _ecore_pending_job_threads_feedback = eina_list_append(_ecore_pending_job_threads_feedback, worker); + + if (_ecore_thread_count == _ecore_thread_count_max) + { + LKU(_ecore_pending_job_threads_mutex); + return (Ecore_Thread *)worker; + } + + LKU(_ecore_pending_job_threads_mutex); + + /* One more thread could be created. */ + eina_threads_init(); + + LKL(_ecore_pending_job_threads_mutex); + retry: + if (PHC(thread, _ecore_thread_worker, NULL)) + { + _ecore_thread_count++; + LKU(_ecore_pending_job_threads_mutex); + return (Ecore_Thread *)worker; + } + if (!tried) + { + _ecore_main_call_flush(); + tried = EINA_TRUE; + goto retry; + } + LKU(_ecore_pending_job_threads_mutex); + + eina_threads_shutdown(); + +on_error: + LKL(_ecore_pending_job_threads_mutex); + if (_ecore_thread_count == 0) + { + _ecore_pending_job_threads_feedback = eina_list_remove(_ecore_pending_job_threads_feedback, + worker); + + if (func_cancel) func_cancel((void *)data, NULL); + + if (worker) + { + CDD(worker->cond); + LKD(worker->mutex); + free(worker); + worker = NULL; + } + } + LKU(_ecore_pending_job_threads_mutex); + + return (Ecore_Thread *)worker; +#else + Ecore_Pthread_Worker worker; + + (void)try_no_queue; + + /* + 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. + */ + worker.u.feedback_run.func_heavy = func_heavy; + worker.u.feedback_run.func_notify = func_notify; + worker.u.feedback_run.send = 0; + worker.u.feedback_run.received = 0; + worker.func_cancel = func_cancel; + worker.func_end = func_end; + worker.data = data; + worker.cancel = EINA_FALSE; + worker.feedback_run = EINA_TRUE; + worker.message_run = EINA_FALSE; + worker.kill = EINA_FALSE; + + do { + worker.reschedule = EINA_FALSE; + + func_heavy((void *)data, (Ecore_Thread *)&worker); + + if (worker.cancel) func_cancel((void *)data, (Ecore_Thread *)&worker); + else func_end((void *)data, (Ecore_Thread *)&worker); + } while (worker.reschedule == EINA_TRUE); + + return NULL; +#endif +} + +EAPI Eina_Bool +ecore_thread_feedback(Ecore_Thread *thread, + const void *data) +{ + Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; + + if (!worker) return EINA_FALSE; + +#ifdef EFL_HAVE_THREADS + if (!PHE(worker->self, PHS())) return EINA_FALSE; + + if (worker->feedback_run) + { + Ecore_Pthread_Notify *notify; + + notify = malloc(sizeof (Ecore_Pthread_Notify)); + if (!notify) return EINA_FALSE; + + notify->user_data = data; + notify->work = worker; + worker->u.feedback_run.send++; + + ecore_main_loop_thread_safe_call_async(_ecore_notify_handler, notify); + } + else if (worker->message_run) + { + Ecore_Pthread_Message *msg; + Ecore_Pthread_Notify *notify; + + msg = malloc(sizeof (Ecore_Pthread_Message)); + if (!msg) return EINA_FALSE; + msg->data = data; + msg->callback = EINA_FALSE; + msg->sync = EINA_FALSE; + + notify = malloc(sizeof (Ecore_Pthread_Notify)); + if (!notify) + { + free(msg); + return EINA_FALSE; + } + notify->work = worker; + notify->user_data = msg; + + worker->u.message_run.from.send++; + ecore_main_loop_thread_safe_call_async(_ecore_message_notify_handler, notify); + } + else + return EINA_FALSE; + + return EINA_TRUE; +#else + worker->u.feedback_run.func_notify((void *)worker->data, thread, (void *)data); + + return EINA_TRUE; +#endif +} + +#if 0 +EAPI Ecore_Thread * +ecore_thread_message_run(Ecore_Thread_Cb func_main, + Ecore_Thread_Notify_Cb func_notify, + Ecore_Thread_Cb func_end, + Ecore_Thread_Cb func_cancel, + const void *data) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *worker; + PH(t); + + if (!func_main) return NULL; + + worker = _ecore_thread_worker_new(); + if (!worker) return NULL; + + worker->u.message_run.func_main = func_main; + worker->u.message_run.func_notify = func_notify; + worker->u.message_run.direct_worker = _ecore_thread_worker_new(); + worker->u.message_run.send = ecore_pipe_add(_ecore_nothing_handler, worker); + worker->u.message_run.from.send = 0; + worker->u.message_run.from.received = 0; + worker->u.message_run.to.send = 0; + worker->u.message_run.to.received = 0; + + ecore_pipe_freeze(worker->u.message_run.send); + + worker->func_cancel = func_cancel; + worker->func_end = func_end; + worker->hash = NULL; + worker->data = data; + + worker->cancel = EINA_FALSE; + worker->message_run = EINA_TRUE; + worker->feedback_run = EINA_FALSE; + worker->kill = EINA_FALSE; + worker->reschedule = EINA_FALSE; + worker->no_queue = EINA_FALSE; + worker->self = 0; + + eina_threads_init(); + + if (PHC(t, _ecore_direct_worker, worker)) + return (Ecore_Thread*) worker; + + eina_threads_shutdown(); + + if (worker->u.message_run.direct_worker) _ecore_thread_worker_free(worker->u.message_run.direct_worker); + if (worker->u.message_run.send) ecore_pipe_del(worker->u.message_run.send); + + CDD(worker->cond); + LKD(worker->mutex); +#else + /* Note: This type of thread can't and never will work without thread support */ + WRN("ecore_thread_message_run called, but threads disable in Ecore, things will go wrong. Starting now !"); +# warning "You disabled threads support in ecore, I hope you know what you are doing !" +#endif + + func_cancel((void *) data, NULL); + + return NULL; +} +#endif + +EAPI Eina_Bool +ecore_thread_reschedule(Ecore_Thread *thread) +{ + Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; + + if (!worker) return EINA_FALSE; + +#ifdef EFL_HAVE_THREADS + if (!PHE(worker->self, PHS())) return EINA_FALSE; +#endif + + worker->reschedule = EINA_TRUE; + return EINA_TRUE; +} + +EAPI int +ecore_thread_active_get(void) +{ +#ifdef EFL_HAVE_THREADS + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + return _ecore_thread_count; +#else + return 0; +#endif +} + +EAPI int +ecore_thread_pending_get(void) +{ +#ifdef EFL_HAVE_THREADS + int ret; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + LKL(_ecore_pending_job_threads_mutex); + ret = eina_list_count(_ecore_pending_job_threads); + LKU(_ecore_pending_job_threads_mutex); + return ret; +#else + return 0; +#endif +} + +EAPI int +ecore_thread_pending_feedback_get(void) +{ +#ifdef EFL_HAVE_THREADS + int ret; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + LKL(_ecore_pending_job_threads_mutex); + ret = eina_list_count(_ecore_pending_job_threads_feedback); + LKU(_ecore_pending_job_threads_mutex); + return ret; +#else + return 0; +#endif +} + +EAPI int +ecore_thread_pending_total_get(void) +{ +#ifdef EFL_HAVE_THREADS + int ret; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + LKL(_ecore_pending_job_threads_mutex); + ret = eina_list_count(_ecore_pending_job_threads) + eina_list_count(_ecore_pending_job_threads_feedback); + LKU(_ecore_pending_job_threads_mutex); + return ret; +#else + return 0; +#endif +} + +EAPI int +ecore_thread_max_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + return _ecore_thread_count_max; +} + +EAPI void +ecore_thread_max_set(int num) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + if (num < 1) return; + /* avoid doing something hilarious by blocking dumb users */ + if (num > (16 * eina_cpu_count())) num = 16 * eina_cpu_count(); + + _ecore_thread_count_max = num; +} + +EAPI void +ecore_thread_max_reset(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_thread_count_max = eina_cpu_count(); +} + +EAPI int +ecore_thread_available_get(void) +{ +#ifdef EFL_HAVE_THREADS + int ret; + + LKL(_ecore_pending_job_threads_mutex); + ret = _ecore_thread_count_max - _ecore_thread_count; + LKU(_ecore_pending_job_threads_mutex); + return ret; +#else + return 0; +#endif +} + +EAPI Eina_Bool +ecore_thread_local_data_add(Ecore_Thread *thread, + const char *key, + void *value, + Eina_Free_Cb cb, + Eina_Bool direct) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; + Ecore_Thread_Data *d; + Eina_Bool ret; +#endif + + if ((!thread) || (!key) || (!value)) + return EINA_FALSE; +#ifdef EFL_HAVE_THREADS + if (!PHE(worker->self, PHS())) return EINA_FALSE; + + if (!worker->hash) + worker->hash = eina_hash_string_small_new(_ecore_thread_data_free); + + if (!worker->hash) + return EINA_FALSE; + + if (!(d = malloc(sizeof(Ecore_Thread_Data)))) + return EINA_FALSE; + + d->data = value; + d->cb = cb; + + if (direct) + ret = eina_hash_direct_add(worker->hash, key, d); + else + ret = eina_hash_add(worker->hash, key, d); + CDB(worker->cond); + return ret; +#else + (void) cb; + (void) direct; + return EINA_FALSE; +#endif +} + +EAPI void * +ecore_thread_local_data_set(Ecore_Thread *thread, + const char *key, + void *value, + Eina_Free_Cb cb) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; + Ecore_Thread_Data *d, *r; + void *ret; +#endif + + if ((!thread) || (!key) || (!value)) + return NULL; +#ifdef EFL_HAVE_THREADS + if (!PHE(worker->self, PHS())) return NULL; + + if (!worker->hash) + worker->hash = eina_hash_string_small_new(_ecore_thread_data_free); + + if (!worker->hash) + return NULL; + + if (!(d = malloc(sizeof(Ecore_Thread_Data)))) + return NULL; + + d->data = value; + d->cb = cb; + + r = eina_hash_set(worker->hash, key, d); + CDB(worker->cond); + ret = r->data; + free(r); + return ret; +#else + (void) cb; + return NULL; +#endif +} + +EAPI void * +ecore_thread_local_data_find(Ecore_Thread *thread, + const char *key) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; + Ecore_Thread_Data *d; +#endif + + if ((!thread) || (!key)) + return NULL; +#ifdef EFL_HAVE_THREADS + if (!PHE(worker->self, PHS())) return NULL; + + if (!worker->hash) + return NULL; + + d = eina_hash_find(worker->hash, key); + if (d) + return d->data; + return NULL; +#else + return NULL; +#endif +} + +EAPI Eina_Bool +ecore_thread_local_data_del(Ecore_Thread *thread, + const char *key) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; +#endif + + if ((!thread) || (!key)) + return EINA_FALSE; +#ifdef EFL_HAVE_THREADS + if (!PHE(worker->self, PHS())) return EINA_FALSE; + + if (!worker->hash) + return EINA_FALSE; + return eina_hash_del_by_key(worker->hash, key); +#else + return EINA_TRUE; +#endif +} + +EAPI Eina_Bool +ecore_thread_global_data_add(const char *key, + void *value, + Eina_Free_Cb cb, + Eina_Bool direct) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Thread_Data *d; + Eina_Bool ret; +#endif + + if ((!key) || (!value)) + return EINA_FALSE; +#ifdef EFL_HAVE_THREADS + LRWKWL(_ecore_thread_global_hash_lock); + if (!_ecore_thread_global_hash) + _ecore_thread_global_hash = eina_hash_string_small_new(_ecore_thread_data_free); + LRWKU(_ecore_thread_global_hash_lock); + + if (!(d = malloc(sizeof(Ecore_Thread_Data)))) + return EINA_FALSE; + + d->data = value; + d->cb = cb; + + if (!_ecore_thread_global_hash) + return EINA_FALSE; + LRWKWL(_ecore_thread_global_hash_lock); + if (direct) + ret = eina_hash_direct_add(_ecore_thread_global_hash, key, d); + else + ret = eina_hash_add(_ecore_thread_global_hash, key, d); + LRWKU(_ecore_thread_global_hash_lock); + CDB(_ecore_thread_global_hash_cond); + return ret; +#else + (void) cb; + (void) direct; + return EINA_TRUE; +#endif +} + +EAPI void * +ecore_thread_global_data_set(const char *key, + void *value, + Eina_Free_Cb cb) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Thread_Data *d, *r; + void *ret; +#endif + + if ((!key) || (!value)) + return NULL; +#ifdef EFL_HAVE_THREADS + LRWKWL(_ecore_thread_global_hash_lock); + if (!_ecore_thread_global_hash) + _ecore_thread_global_hash = eina_hash_string_small_new(_ecore_thread_data_free); + LRWKU(_ecore_thread_global_hash_lock); + + if (!_ecore_thread_global_hash) + return NULL; + + if (!(d = malloc(sizeof(Ecore_Thread_Data)))) + return NULL; + + d->data = value; + d->cb = cb; + + LRWKWL(_ecore_thread_global_hash_lock); + r = eina_hash_set(_ecore_thread_global_hash, key, d); + LRWKU(_ecore_thread_global_hash_lock); + CDB(_ecore_thread_global_hash_cond); + + ret = r->data; + free(r); + return ret; +#else + (void) cb; + return NULL; +#endif +} + +EAPI void * +ecore_thread_global_data_find(const char *key) +{ +#ifdef EFL_HAVE_THREADS + Ecore_Thread_Data *ret; +#endif + + if (!key) + return NULL; +#ifdef EFL_HAVE_THREADS + if (!_ecore_thread_global_hash) return NULL; + + LRWKRL(_ecore_thread_global_hash_lock); + ret = eina_hash_find(_ecore_thread_global_hash, key); + LRWKU(_ecore_thread_global_hash_lock); + if (ret) + return ret->data; + return NULL; +#else + return NULL; +#endif +} + +EAPI Eina_Bool +ecore_thread_global_data_del(const char *key) +{ +#ifdef EFL_HAVE_THREADS + Eina_Bool ret; +#endif + + if (!key) + return EINA_FALSE; +#ifdef EFL_HAVE_THREADS + if (!_ecore_thread_global_hash) + return EINA_FALSE; + + LRWKWL(_ecore_thread_global_hash_lock); + ret = eina_hash_del_by_key(_ecore_thread_global_hash, key); + LRWKU(_ecore_thread_global_hash_lock); + return ret; +#else + return EINA_TRUE; +#endif +} + +EAPI void * +ecore_thread_global_data_wait(const char *key, + double seconds) +{ +#ifdef EFL_HAVE_THREADS + double tm = 0; + Ecore_Thread_Data *ret = NULL; +#endif + + if (!key) + return NULL; +#ifdef EFL_HAVE_THREADS + if (!_ecore_thread_global_hash) + return NULL; + if (seconds > 0) + tm = ecore_time_get() + seconds; + + while (1) + { + LRWKRL(_ecore_thread_global_hash_lock); + ret = eina_hash_find(_ecore_thread_global_hash, key); + LRWKU(_ecore_thread_global_hash_lock); + if ((ret) || (!seconds) || ((seconds > 0) && (tm <= ecore_time_get()))) + break; + LKL(_ecore_thread_global_hash_mutex); + CDW(_ecore_thread_global_hash_cond, tm); + LKU(_ecore_thread_global_hash_mutex); + } + if (ret) return ret->data; + return NULL; +#else + (void) seconds; + return NULL; +#endif +} + diff --git a/src/lib/ecore/ecore_throttle.c b/src/lib/ecore/ecore_throttle.c new file mode 100644 index 0000000000..febaeacb77 --- /dev/null +++ b/src/lib/ecore/ecore_throttle.c @@ -0,0 +1,104 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" + +static int throttle_val = 0; + +/** + * @addtogroup Ecore_Throttle_Group Ecore Throttle functions + * + * @{ + */ + +/** + * Increase throttle amount + * + * This will increase or decrease (if @p amount is positive or negative) the + * amount of "voluntary throttling" ecore will do to its main loop while + * running. This is intended to be used to limit animations and wakeups when + * in a strict power management state. The higher the current throttle value + * (which can be retrieved by ecore_throttle_get() ), the more throttling + * takes place. If the current throttle value is 0, then no throttling takes + * place at all. + * + * The value represents how long the ecore main loop will sleep (in seconds) + * before it goes into a fully idle state waiting for events, input or + * timing events to wake it up. For example, if the current throttle level + * is 0.5, then after every time the main loop cycles and goes into idle + * affter processing all events, the main loop will explicitly sleep for 0.5 + * seconds before sitting and waiting for incoming events or timeouts, thus + * preventing animation, async IO and network handling etc. for that period + * of time. Of course these events, data and timeouts will be buffered, + * thus not losing anything, simply delaying when they get handled by the + * throttle value. + * + * Example: + * @code + * void enter_powersave(void) { + * ecore_throttle_adjust(0.2); + * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); + * } + * + * void enter_deep_powersave(void) { + * ecore_throttle_adjust(0.5); + * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); + * } + * + * void exit_powersave(void) { + * ecore_throttle_adjust(-0.2); + * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); + * } + * + * void exit_deep_powersave(void) { + * ecore_throttle_adjust(-0.5); + * printf("Now at throttle level: %1.3f\n", ecore_throttle_get()); + * } + * @endcode + * + * @param amount Amount (in seconds) to adjust by + */ +EAPI void +ecore_throttle_adjust(double amount) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + int adj = amount * 1000000.0; + throttle_val += adj; + if (throttle_val < 0) throttle_val = 0; +} + +/** + * Get current throttle level + * + * This gets the current throttling level, which can be adjusted by + * ecore_throttle_adjust(). The value is in seconds. Please see + * ecore_throttle_adjust() for more information. + * + * @return The current throttle level + */ +EAPI double +ecore_throttle_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); + return (double)throttle_val / 1000000.0; +} + +/** + * @} + */ + +void +_ecore_throttle(void) +{ + if (throttle_val <= 0) return; + usleep(throttle_val); +} + diff --git a/src/lib/ecore/ecore_time.c b/src/lib/ecore/ecore_time.c new file mode 100644 index 0000000000..44b1dab81f --- /dev/null +++ b/src/lib/ecore/ecore_time.c @@ -0,0 +1,184 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef HAVE_SYS_TIME_H +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#if defined(__APPLE__) && defined(__MACH__) +# include +#endif + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME) +static clockid_t _ecore_time_clock_id = -1; +#elif defined(__APPLE__) && defined(__MACH__) +static double _ecore_time_clock_conversion = 1e-9; +#endif +double _ecore_time_loop_time = -1.0; + +/** + * @addtogroup Ecore_Time_Group + * + * @{ + */ + +/** + * Retrieves the current system time as a floating point value in seconds. + * + * This uses a monotonic clock and thus never goes back in time while + * machine is live (even if user changes time or timezone changes, + * however it may be reset whenever the machine is restarted). + * + * @see ecore_loop_time_get(). + * @see ecore_time_unix_get(). + * + * @return The number of seconds. Start time is not defined (it may be + * when the machine was booted, unix time, etc), all it is + * defined is that it never goes backwards (unless you got big critical + * messages when the application started). + */ +EAPI double +ecore_time_get(void) +{ +#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME) + struct timespec t; + + if (EINA_UNLIKELY(_ecore_time_clock_id < 0)) + return ecore_time_unix_get(); + + if (EINA_UNLIKELY(clock_gettime(_ecore_time_clock_id, &t))) + { + CRIT("Cannot get current time."); + /* Try to at least return the latest value retrieved*/ + return _ecore_time_loop_time; + } + + return (double)t.tv_sec + (((double)t.tv_nsec) / 1000000000.0); +#elif defined(HAVE_EVIL) + return evil_time_get(); +#elif defined(__APPLE__) && defined(__MACH__) + return _ecore_time_clock_conversion * (double)mach_absolute_time(); +#else + return ecore_time_unix_get(); +#endif +} + +/** + * Retrieves the current UNIX time as a floating point value in seconds. + * + * @see ecore_time_get(). + * @see ecore_loop_time_get(). + * + * @return The number of seconds since 12.00AM 1st January 1970. + */ +EAPI double +ecore_time_unix_get(void) +{ +#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 +} + +/** + * Retrieves the time at which the last loop stopped waiting for timeouts or + * events. + * + * This gets the time 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(). Note that this time is meant to be used as relative to + * other times obtained on this run. If you need absolute time references, use + * ecore_time_unix_get() instead. + * + * This function can be called before any loop has ever been run, but either + * ecore_init() or ecore_time_get() must have been called once. + * + * @return The number of seconds. Start time is not defined (it may be + * when the machine was booted, unix time, etc), all it is + * defined is that it never goes backwards (unless you got big critical + * messages when the application started). + */ +EAPI double +ecore_loop_time_get(void) +{ + return _ecore_time_loop_time; +} + +/** + * @} + */ + +/********************** Internal methods ********************************/ + +/* TODO: Documentation says "All implementations support the system-wide + * real-time clock, which is identified by CLOCK_REALTIME. Check if the fallback + * to unix time (without specifying the resolution) might be removed + */ +void +_ecore_time_init(void) +{ +#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME) + struct timespec t; + + if (_ecore_time_clock_id != -1) return; + + if (!clock_gettime(CLOCK_MONOTONIC, &t)) + { + _ecore_time_clock_id = CLOCK_MONOTONIC; + DBG("using CLOCK_MONOTONIC."); + } + else if (!clock_gettime(CLOCK_REALTIME, &t)) + { + /* may go backwards */ + _ecore_time_clock_id = CLOCK_REALTIME; + WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME."); + } + else + { + _ecore_time_clock_id = -2; + CRIT("Cannot get a valid clock_gettime() clock id! " + "Fallback to unix time."); + } +#else +# ifndef HAVE_EVIL +# if defined(__APPLE__) && defined(__MACH__) + mach_timebase_info_data_t info; + kern_return_t err = mach_timebase_info(&info); + if (err == 0) + { + _ecore_time_clock_conversion = 1e-9 * (double)info.numer / (double)info.denom; + } + else + { + WRN("Unable to get timebase info. Fallback to nanoseconds."); + } +# else +# warning "Your platform isn't supported yet" + CRIT("Platform does not support clock_gettime. " + "Fallback to unix time."); +# endif +# endif +#endif + + _ecore_time_loop_time = ecore_time_get(); +} + diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c new file mode 100644 index 0000000000..768198876b --- /dev/null +++ b/src/lib/ecore/ecore_timer.c @@ -0,0 +1,1015 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#define MY_CLASS ECORE_TIMER_CLASS +#define MY_CLASS_NAME "ecore_timer" + +EAPI Eo_Op ECORE_TIMER_BASE_ID = EO_NOOP; + +#define ECORE_TIMER_CHECK(obj) \ + if (!eo_isa((obj), ECORE_TIMER_CLASS)) \ + return + +#ifdef WANT_ECORE_TIMER_DUMP +# include +# include +# define ECORE_TIMER_DEBUG_BT_NUM 64 +typedef void (*Ecore_Timer_Bt_Func)(); +#endif + +struct _Ecore_Timer_Private_Data +{ + EINA_INLIST; + Ecore_Timer *obj; + double in; + double at; + double pending; + Ecore_Task_Cb func; + void *data; + +#ifdef WANT_ECORE_TIMER_DUMP + Ecore_Timer_Bt_Func timer_bt[ECORE_TIMER_DEBUG_BT_NUM]; + int timer_bt_num; +#endif + + int references; + unsigned char delete_me : 1; + unsigned char just_added : 1; + unsigned char frozen : 1; +}; + +typedef struct _Ecore_Timer_Private_Data Ecore_Timer_Private_Data; + +static void _ecore_timer_set(Ecore_Timer *timer, + double at, + double in, + Ecore_Task_Cb func, + void *data); +#ifdef WANT_ECORE_TIMER_DUMP +static int _ecore_timer_cmp(const void *d1, + const void *d2); +#endif + +static int timers_added = 0; +static int timers_delete_me = 0; +static Ecore_Timer_Private_Data *timers = NULL; +static Ecore_Timer_Private_Data *timer_current = NULL; +static Ecore_Timer_Private_Data *suspended = NULL; +static double last_check = 0.0; +static double precision = 10.0 / 1000000.0; + +/** + * @addtogroup Ecore_Timer_Group + * + * @{ + */ + +/** + * Retrieves the current precision used by timer infrastructure. + * @return Current precision. + * @see ecore_timer_precision_set() + */ +EAPI double +ecore_timer_precision_get(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0); + return precision; +} + +/** + * @brief Sets the precision to be used by timer infrastructure. + * + * @param value allowed introduced timeout delay, in seconds. + * + * This sets the precision for @b all timers. The precision determines how much + * of an difference from the requested interval is acceptable. One common reason + * to use this function is to @b increase the allowed timeout and thus @b + * decrease precision of the timers, this is because less precise the timers + * result in the system waking up less often and thus consuming less resources. + * + * 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. + */ +EAPI void +ecore_timer_precision_set(double value) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + + if (value < 0.0) + { + ERR("Precision %f less than zero, ignored", value); + goto unlock; + } + precision = value; + +unlock: + _ecore_unlock(); +} + +/** + * 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. + * + * 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, + Ecore_Task_Cb func, + const void *data) +{ + Ecore_Timer *timer = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + timer = eo_add_custom(MY_CLASS, _ecore_parent, ecore_timer_constructor(in, func, data)); + eo_unref(timer); + return timer; +} + +static Eina_Bool +_ecore_timer_add(Ecore_Timer *obj, + Ecore_Timer_Private_Data *timer, + double now, + double in, + Ecore_Task_Cb func, + const void *data) +{ + + if (EINA_UNLIKELY(!eina_main_loop_is())) + { + eo_error_set(obj); + EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); + } + + timer->obj = obj; + eo_do_super(obj, eo_constructor()); + eo_manual_free_set(obj, EINA_TRUE); + + if (!func) + { + eo_error_set(obj); + ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); + return EINA_FALSE; + } + + if (in < 0.0) in = 0.0; + +#ifdef WANT_ECORE_TIMER_DUMP + timer->timer_bt_num = backtrace((void **)(timer->timer_bt), + ECORE_TIMER_DEBUG_BT_NUM); +#endif + _ecore_timer_set(obj, now + in, in, func, (void *)data); + return EINA_TRUE; +} + +static void +_timer_constructor(Eo *obj, void *_pd, va_list *list) +{ + double in = va_arg(*list, double); + Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); + const void *data = va_arg(*list, const void *); + double now; + + _ecore_lock(); + now = ecore_time_get(); + + Ecore_Timer_Private_Data *timer = _pd; + _ecore_timer_add(obj, timer, now, in, func, data); + _ecore_unlock(); +} + +static void +_timer_loop_constructor(Eo *obj, void *_pd, va_list *list) +{ + double in = va_arg(*list, double); + Ecore_Task_Cb func = va_arg(*list, Ecore_Task_Cb); + const void *data = va_arg(*list, const void *); + double now; + + now = ecore_loop_time_get(); + + Ecore_Timer_Private_Data *timer = _pd; + _ecore_timer_add(obj, timer, now, in, func, data); +} + +static void +_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) +{ + eo_error_set(obj); + ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME); +} + + +/** + * 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. + * + * 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, + Ecore_Task_Cb func, + const void *data) +{ + Ecore_Timer *timer; + + _ecore_lock(); + timer = _ecore_timer_loop_add(in, func, data); + _ecore_unlock(); + + 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. + * + * 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) +{ + void *data = NULL; + + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + + data = _ecore_timer_del(timer); + + _ecore_unlock(); + return 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. + */ +EAPI void +ecore_timer_interval_set(Ecore_Timer *timer, + double in) +{ + ECORE_TIMER_CHECK(timer); + eo_do(timer, ecore_obj_timer_interval_set(in)); +} + +static void +_timer_interval_set(Eo *obj EINA_UNUSED, void *_pd, va_list *list) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + double in = va_arg(*list, double); + if (in < 0.0) in = 0.0; + Ecore_Timer_Private_Data *timer = _pd; + + _ecore_lock(); + timer->in = in; + _ecore_unlock(); +} + +/** + * Get the interval the timer ticks on. + * + * @param timer The timer to retrieve the interval from + * @return The interval on success. -1 on failure. + */ +EAPI double +ecore_timer_interval_get(Ecore_Timer *timer) +{ + double interval = -1.0; + + ECORE_TIMER_CHECK(timer) interval; + eo_do(timer, ecore_obj_timer_interval_get(&interval)); + return interval; +} + +static void +_timer_interval_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) +{ + double *ret = va_arg(*list, double *); + *ret = -1.0; + + EINA_MAIN_LOOP_CHECK_RETURN; + Ecore_Timer_Private_Data *timer = _pd; + _ecore_lock(); + *ret = timer->in; + _ecore_unlock(); +} + +/** + * Add some delay for the next occurrence of a timer. + * This doesn't affect the interval of a timer. + * + * @param timer The timer to change. + * @param add The delay to add to the next iteration. + */ +EAPI void +ecore_timer_delay(Ecore_Timer *timer, + double add) +{ + ECORE_TIMER_CHECK(timer); + eo_do(timer, ecore_obj_timer_delay(add)); +} + +static void +_timer_delay(Eo *obj, void *_pd EINA_UNUSED, va_list *list) +{ + double add = va_arg(*list, double); + EINA_MAIN_LOOP_CHECK_RETURN; + + _ecore_lock(); + _ecore_timer_delay(obj, add); + _ecore_unlock(); +} + +/** + * Reset a timer to its full interval + * This doesn't affect the interval of a timer + * @param timer The timer + * @since 1.2 + * @note This is equivalent to (but faster than) + * @code + * ecore_timer_delay(timer, ecore_timer_interval_get(timer) - ecore_timer_pending_get(timer)); + * @endcode + */ +EAPI void +ecore_timer_reset(Ecore_Timer *timer) +{ + ECORE_TIMER_CHECK(timer); + eo_do(timer, ecore_obj_timer_reset()); +} + +static void +_timer_reset(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + double now, add; + EINA_MAIN_LOOP_CHECK_RETURN; + + Ecore_Timer_Private_Data *timer = _pd; + + _ecore_lock(); + now = ecore_time_get(); + + if (timer->frozen) + add = timer->pending; + else + add = timer->at - now; + _ecore_timer_delay(obj, timer->in - add); + _ecore_unlock(); +} + +/** + * Get the pending time regarding a timer. + * + * @param timer The timer to learn from. + * @return The pending time. + * @ingroup Ecore_Timer_Group + */ +EAPI double +ecore_timer_pending_get(Ecore_Timer *timer) +{ + double ret = 0.0; + + ECORE_TIMER_CHECK(timer) ret; + eo_do(timer, ecore_obj_timer_pending_get(&ret)); + return ret; +} + +static void +_timer_pending_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) +{ + double now; + double *ret = va_arg(*list, double *); + *ret = 0.0; + + EINA_MAIN_LOOP_CHECK_RETURN; + + _ecore_lock(); + Ecore_Timer_Private_Data *timer = _pd; + + now = ecore_time_get(); + + if (timer->frozen) + *ret = timer->pending; + else + *ret = timer->at - now; + _ecore_unlock(); +} +/** + * Pauses a running timer. + * + * @param timer The timer to be paused. + * + * The timer callback won't be called while the timer is paused. The remaining + * time until the timer expires will be saved, so the timer can be resumed with + * that same remaining time to expire, instead of expiring instantly. Use + * ecore_timer_thaw() to resume it. + * + * @note Nothing happens if the timer was already paused. + * + * @see ecore_timer_thaw() + */ +EAPI void +ecore_timer_freeze(Ecore_Timer *timer) +{ + ECORE_TIMER_CHECK(timer); + eo_do(timer, eo_event_freeze()); +} + +static void +_timer_freeze(Eo *obj EINA_UNUSED, void *_pd, va_list *list EINA_UNUSED) +{ + double now; + + EINA_MAIN_LOOP_CHECK_RETURN; + + Ecore_Timer_Private_Data *timer = _pd; + _ecore_lock(); + + /* Timer already frozen */ + if (timer->frozen) + goto unlock; + + timers = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); + suspended = (Ecore_Timer_Private_Data *)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; +unlock: + _ecore_unlock(); +} + +/** + * Resumes a frozen (paused) timer. + * + * @param timer The timer to be resumed. + * + * The timer will be resumed from its previous relative position in time. That + * means, if it had X seconds remaining until expire when it was paused, it will + * be started now with those same X seconds remaining to expire again. But + * notice that the interval time won't be touched by this call or by + * ecore_timer_freeze(). + * + * @see ecore_timer_freeze() + */ +EAPI void +ecore_timer_thaw(Ecore_Timer *timer) +{ + ECORE_TIMER_CHECK(timer); + eo_do(timer, eo_event_thaw()); +} + +static void +_timer_thaw(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + double now; + + EINA_MAIN_LOOP_CHECK_RETURN; + Ecore_Timer_Private_Data *timer = _pd; + + _ecore_lock(); + + /* Timer not frozen */ + if (!timer->frozen) + goto unlock; + + suspended = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer)); + now = ecore_time_get(); + + _ecore_timer_set(obj, timer->pending + now, timer->in, timer->func, timer->data); +unlock: + _ecore_unlock(); +} + +EAPI char * +ecore_timer_dump(void) +{ +#ifdef WANT_ECORE_TIMER_DUMP + Eina_Strbuf *result; + char *out; + Ecore_Timer *tm; + Eina_List *tmp = NULL; + int living_timer = 0; + int unknow_timer = 0; + + EINA_MAIN_LOOP_CHECK_RETURN(NULL); + _ecore_lock(); + result = eina_strbuf_new(); + + EINA_INLIST_FOREACH(timers, tm) + tmp = eina_list_sorted_insert(tmp, _ecore_timer_cmp, tm); + + EINA_LIST_FREE(tmp, tm) + { + char **strings; + int j; + + if (!tm->frozen && !tm->delete_me) + living_timer++; + + strings = backtrace_symbols((void **)tm->timer_bt, tm->timer_bt_num); + if (tm->timer_bt_num <= 0 || strings == NULL) + { + unknow_timer++; + continue; + } + + eina_strbuf_append_printf(result, "*** timer: %f ***\n", tm->in); + if (tm->frozen) + eina_strbuf_append(result, "FROZEN\n"); + if (tm->delete_me) + eina_strbuf_append(result, "DELETED\n"); + for (j = 0; j < tm->timer_bt_num; j++) + eina_strbuf_append_printf(result, "%s\n", strings[j]); + + free(strings); + } + + eina_strbuf_append_printf(result, "\n***\nThere is %i living timer.\nWe did lost track of %i timers.\n", living_timer, unknow_timer); + + out = eina_strbuf_string_steal(result); + eina_strbuf_free(result); + _ecore_unlock(); + + return out; +#else + return NULL; +#endif +} + +/** + * @} + */ + +Ecore_Timer * +_ecore_timer_loop_add(double in, + Ecore_Task_Cb func, + const void *data) +{ + Ecore_Timer *timer = NULL; + timer = eo_add_custom(MY_CLASS, _ecore_parent, ecore_timer_loop_constructor(in, func, data)); + eo_unref(timer); + + return timer; +} + +EAPI void +_ecore_timer_delay(Ecore_Timer *obj, + double add) +{ + Ecore_Timer_Private_Data *timer = eo_data_get(obj, MY_CLASS); + + if (timer->frozen) + { + timer->pending += add; + } + else + { + timers = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); + _ecore_timer_set(obj, timer->at + add, timer->in, timer->func, timer->data); + } +} + +void * +_ecore_timer_del(Ecore_Timer *obj) +{ + Ecore_Timer_Private_Data *timer = eo_data_get(obj, MY_CLASS); + + if (timer->frozen && !timer->references) + { + void *data = timer->data; + + suspended = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer)); + + if (timer->delete_me) + timers_delete_me--; + + eo_parent_set(obj, NULL); + + if (eo_destructed_is(obj)) + eo_manual_free(obj); + else + eo_manual_free_set(obj, EINA_FALSE); + return data; + } + + EINA_SAFETY_ON_TRUE_RETURN_VAL(timer->delete_me, NULL); + timer->delete_me = 1; + timers_delete_me++; + return timer->data; +} + +static void +_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) +{ + Ecore_Timer_Private_Data *pd = _pd; + + if (!pd->delete_me) + { + pd->delete_me = 1; + timers_delete_me++; + } + + eo_do_super(obj, eo_destructor()); +} + +void +_ecore_timer_shutdown(void) +{ + Ecore_Timer_Private_Data *timer; + + while ((timer = timers)) + { + timers = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timers)); + + eo_parent_set(timer->obj, NULL); + if (eo_destructed_is(timer->obj)) + eo_manual_free(timer->obj); + else + eo_manual_free_set(timer->obj, EINA_FALSE); + } + + while ((timer = suspended)) + { + suspended = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(suspended)); + + eo_parent_set(timer->obj, NULL); + if (eo_destructed_is(timer->obj)) + eo_manual_free(timer->obj); + else + eo_manual_free_set(timer->obj, EINA_FALSE); + } + + timer_current = NULL; +} + +void +_ecore_timer_cleanup(void) +{ + Ecore_Timer_Private_Data *l; + int in_use = 0, todo = timers_delete_me, done = 0; + + if (!timers_delete_me) return; + for (l = timers; l; ) + { + Ecore_Timer_Private_Data *timer = l; + + l = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(l)->next; + if (timer->delete_me) + { + if (timer->references) + { + in_use++; + continue; + } + timers = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); + + eo_parent_set(timer->obj, NULL); + if (eo_destructed_is(timer->obj)) + eo_manual_free(timer->obj); + else + eo_manual_free_set(timer->obj, EINA_FALSE); + timers_delete_me--; + done++; + if (timers_delete_me == 0) return; + } + } + for (l = suspended; l; ) + { + Ecore_Timer_Private_Data *timer = l; + + l = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(l)->next; + if (timer->delete_me) + { + if (timer->references) + { + in_use++; + continue; + } + suspended = (Ecore_Timer_Private_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer)); + + eo_parent_set(timer->obj, NULL); + if (eo_destructed_is(timer->obj)) + eo_manual_free(timer->obj); + else + eo_manual_free_set(timer->obj, EINA_FALSE); + timers_delete_me--; + done++; + if (timers_delete_me == 0) return; + } + } + + if ((!in_use) && (timers_delete_me)) + { + ERR("%d timers to delete, but they were not found!" + "Stats: todo=%d, done=%d, pending=%d, in_use=%d. " + "reset counter.", + timers_delete_me, todo, done, todo - done, in_use); + timers_delete_me = 0; + } +} + +void +_ecore_timer_enable_new(void) +{ + Ecore_Timer_Private_Data *timer; + + if (!timers_added) return; + timers_added = 0; + EINA_INLIST_FOREACH(timers, timer) timer->just_added = 0; +} + +int +_ecore_timers_exists(void) +{ + Ecore_Timer_Private_Data *timer = timers; + + while ((timer) && (timer->delete_me)) + timer = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer)->next; + + return !!timer; +} + +static inline Ecore_Timer * +_ecore_timer_first_get(void) +{ + Ecore_Timer *ret = NULL; + Ecore_Timer_Private_Data *timer = timers; + + while ((timer) && ((timer->delete_me) || (timer->just_added))) + timer = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer)->next; + + if (timer) + ret = timer->obj; + return ret; +} + +static inline Ecore_Timer * +_ecore_timer_after_get(Ecore_Timer *obj) +{ + Ecore_Timer *ret = NULL; + Ecore_Timer_Private_Data *base = eo_data_get(obj, MY_CLASS); + + Ecore_Timer_Private_Data *timer = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(base)->next; + Ecore_Timer_Private_Data *valid_timer = NULL; + double maxtime = base->at + precision; + + while ((timer) && (timer->at < maxtime)) + { + if (!((timer->delete_me) || (timer->just_added))) + valid_timer = timer; + timer = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer)->next; + } + + if (valid_timer) + ret = valid_timer->obj; + return ret; +} + +double +_ecore_timer_next_get(void) +{ + double now; + double in; + Ecore_Timer *first_obj, *second_obj; + Ecore_Timer_Private_Data *first; + + first_obj = _ecore_timer_first_get(); + if (!first_obj) return -1; + + second_obj = _ecore_timer_after_get(first_obj); + if (second_obj) first_obj = second_obj; + + first = eo_data_get(first_obj, MY_CLASS); + + now = ecore_loop_time_get(); + in = first->at - now; + if (in < 0) in = 0; + return in; +} + +static inline void +_ecore_timer_reschedule(Ecore_Timer *obj, + double when) +{ + Ecore_Timer_Private_Data *timer = eo_data_get(obj, MY_CLASS); + if ((timer->delete_me) || (timer->frozen)) return; + + timers = (Ecore_Timer_Private_Data *)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(obj, when + timer->in, timer->in, timer->func, timer->data); + else + _ecore_timer_set(obj, timer->at + timer->in, timer->in, timer->func, timer->data); +} + +/* assume that we hold the ecore lock when entering this function */ +void +_ecore_timer_expired_timers_call(double when) +{ + /* call the first expired timer until no expired timers exist */ + while (_ecore_timer_expired_call(when)) ; +} + +/* assume that we hold the ecore lock when entering this function */ +int +_ecore_timer_expired_call(double when) +{ + if (!timers) return 0; + if (last_check > when) + { + Ecore_Timer_Private_Data *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 */ + Ecore_Timer_Private_Data *timer_old = timer_current; + timer_current = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer_current)->next; + _ecore_timer_reschedule(timer_old->obj, when); + } + + while (timer_current) + { + Ecore_Timer_Private_Data *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_Private_Data *)EINA_INLIST_GET(timer_current)->next; + continue; + } + + timer->references++; + if (!_ecore_call_task_cb(timer->func, timer->data)) + { + if (!timer->delete_me) _ecore_timer_del(timer->obj); + } + timer->references--; + + if (timer_current) /* may have changed in recursive main loops */ + timer_current = (Ecore_Timer_Private_Data *)EINA_INLIST_GET(timer_current)->next; + + _ecore_timer_reschedule(timer->obj, when); + } + return 0; +} + +static void +_ecore_timer_set(Ecore_Timer *obj, + double at, + double in, + Ecore_Task_Cb func, + void *data) +{ + Ecore_Timer_Private_Data *t2; + + Ecore_Timer_Private_Data *timer = eo_data_get(obj, MY_CLASS); + + 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_Private_Data *)eina_inlist_append_relative(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer), EINA_INLIST_GET(t2)); + return; + } + } + } + timers = (Ecore_Timer_Private_Data *)eina_inlist_prepend(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer)); +} + +#ifdef WANT_ECORE_TIMER_DUMP +static int +_ecore_timer_cmp(const void *d1, + const void *d2) +{ + const Ecore_Timer *t1 = d1; + const Ecore_Timer *t2 = d2; + + return (int)((t1->in - t2->in) * 100); +} +#endif + +static void +_class_constructor(Eo_Class *klass) +{ + const Eo_Op_Func_Description func_desc[] = { + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), + + EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_CONSTRUCTOR), _timer_constructor), + EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR), _timer_loop_constructor), + EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_SET), _timer_interval_set), + EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_INTERVAL_GET), _timer_interval_get), + + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE), _timer_freeze), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW), _timer_thaw), + + EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_DELAY), _timer_delay), + EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_RESET), _timer_reset), + EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_PENDING_GET), _timer_pending_get), + EO_OP_FUNC_SENTINEL + }; + + eo_class_funcs_set(klass, func_desc); +} + +static const Eo_Op_Description op_desc[] = { + EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_CONSTRUCTOR, "Creates a timer to call the given function in the given period of time."), + EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_LOOP_CONSTRUCTOR, "Creates a timer to call the given function in the given period of time."), + EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_INTERVAL_SET, "Change the interval the timer ticks of."), + EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_INTERVAL_GET, "Get the interval the timer ticks on."), + EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_DELAY, "Add some delay for the next occurrence of a timer."), + EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_RESET, "Reset a timer to its full interval"), + EO_OP_DESCRIPTION(ECORE_TIMER_SUB_ID_PENDING_GET, "Get the pending time regarding a timer."), + EO_OP_DESCRIPTION_SENTINEL +}; +static const Eo_Class_Description class_desc = { + EO_VERSION, + MY_CLASS_NAME, + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(&ECORE_TIMER_BASE_ID, op_desc, ECORE_TIMER_SUB_ID_LAST), + NULL, + sizeof(Ecore_Timer_Private_Data), + _class_constructor, + NULL +}; + +EO_DEFINE_CLASS(ecore_timer_class_get, &class_desc, EO_BASE_CLASS, NULL) diff --git a/src/lib/ecore_cocoa/Ecore_Cocoa.h b/src/lib/ecore_cocoa/Ecore_Cocoa.h new file mode 100644 index 0000000000..51c8ead21b --- /dev/null +++ b/src/lib/ecore_cocoa/Ecore_Cocoa.h @@ -0,0 +1,147 @@ +#ifndef __ECORE_COCOA_H__ +#define __ECORE_COCOA_H__ + +/* + * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND + * THE API MAY CHANGE. + */ + +#ifndef ECORE_COCOA_WIP_GNSIDNQI +# warning "You are using a work in progress API. This API is not stable" +# warning "and is subject to change. You use this at your own risk." +#endif + +#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(void); +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); + +EAPI void ecore_cocoa_window_view_set(Ecore_Cocoa_Window *window, + void *view); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h b/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h new file mode 100644 index 0000000000..7068bc22a8 --- /dev/null +++ b/src/lib/ecore_cocoa/Ecore_Cocoa_Keys.h @@ -0,0 +1,285 @@ +#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, "asterisk", "*" }, +{ 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__ */ diff --git a/src/lib/ecore_cocoa/ecore_cocoa.m b/src/lib/ecore_cocoa/ecore_cocoa.m new file mode 100644 index 0000000000..3f6023af1f --- /dev/null +++ b/src/lib/ecore_cocoa/ecore_cocoa.m @@ -0,0 +1,283 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include + +#include +#include +#include + +#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(void) +{ + if (++_ecore_cocoa_init_count != 1) + return _ecore_cocoa_init_count; + + if (!ecore_event_init()) + return --_ecore_cocoa_init_count; + + NSApplicationLoad(); + + 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]; +} diff --git a/src/lib/ecore_cocoa/ecore_cocoa_private.h b/src/lib/ecore_cocoa/ecore_cocoa_private.h new file mode 100644 index 0000000000..0b4cf3178e --- /dev/null +++ b/src/lib/ecore_cocoa/ecore_cocoa_private.h @@ -0,0 +1,11 @@ +#ifndef _ECORE_COCOA_PRIVATE_H +#define _ECORE_COCOA_PRIVATE_H + +struct _Ecore_Cocoa_Window +{ + NSWindow *window; + unsigned int borderless : 1; +}; + + +#endif diff --git a/src/lib/ecore_cocoa/ecore_cocoa_window.m b/src/lib/ecore_cocoa/ecore_cocoa_window.m new file mode 100644 index 0000000000..2091a69b32 --- /dev/null +++ b/src/lib/ecore_cocoa/ecore_cocoa_window.m @@ -0,0 +1,163 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "Ecore_Cocoa.h" +#include "ecore_cocoa_private.h" + +Ecore_Cocoa_Window * +ecore_cocoa_window_new(int x, + int y, + int width, + int height) +{ + Ecore_Cocoa_Window *w; + + NSWindow *window = [[NSWindow alloc] + initWithContentRect:NSMakeRect(x, y, width, height) + styleMask:(NSTitledWindowMask | + NSClosableWindowMask | + NSResizableWindowMask | + NSMiniaturizableWindowMask) + backing:NSBackingStoreBuffered + defer:NO + screen:nil + ]; + + if (!window) + return NULL; + + [window setBackgroundColor:[NSColor whiteColor]]; + + w = calloc(1, sizeof(Ecore_Cocoa_Window)); + w->window = window; + w->borderless = 0; + + return w; +} + +void +ecore_cocoa_window_free(Ecore_Cocoa_Window *window) +{ + if (!window) + return; + + [window->window release]; + free(window); +} + +void +ecore_cocoa_window_move(Ecore_Cocoa_Window *window, + int x, + int y) +{ + NSRect win_frame; + + if (!window) + return; + + win_frame = [window->window frame]; + win_frame.origin.x = x; + win_frame.origin.y = y; + + [window->window setFrame:win_frame display:YES]; +} + +void +ecore_cocoa_window_resize(Ecore_Cocoa_Window *window, + int width, + int height) +{ + if (!window) + return; + + NSRect win_frame; + + if (!window) + return; + + win_frame = [window->window frame]; + win_frame.size.height = height; + win_frame.size.width = width; + + [window->window setFrame:win_frame display:YES]; +} + +void +ecore_cocoa_window_move_resize(Ecore_Cocoa_Window *window, + int x, + int y, + int width, + int height) +{ + if (!window) + return; + + NSRect win_frame; + + if (!window) + return; + + win_frame = [window->window frame]; + win_frame.size.height = height; + win_frame.size.width = width; + win_frame.origin.x = x; + win_frame.origin.y = y; + + [window->window setFrame:win_frame display:YES]; +} + +void +ecore_cocoa_window_title_set(Ecore_Cocoa_Window *window, const char *title) +{ + if (!window || !title) + return; + + [window->window setTitle:[NSString stringWithUTF8String:title]]; +} + +void +ecore_cocoa_window_show(Ecore_Cocoa_Window *window) +{ + if (!window || [window->window isVisible]) + { + printf("Window(%p) is not visible\n", window->window); + return; + } + + [window->window makeKeyAndOrderFront:NSApp]; +} + +void +ecore_cocoa_window_hide(Ecore_Cocoa_Window *window) +{ + if (!window || ![window->window isVisible]) + return; + + [window->window orderOut:NSApp]; +} + +void +ecore_cocoa_window_borderless_set(Ecore_Cocoa_Window *window, + int on) +{ + if (!window) + return; + + if (on) + [window->window setContentBorderThickness:0.0 + forEdje:NSMinXEdge | NSMinYEdge | NSMaxXEdge | NSMaxYEdge]; +} + +void +ecore_cocoa_window_view_set(Ecore_Cocoa_Window *window, + void *view) +{ + if (!window || !view) + return; + + [[window->window contentView] addSubview:view]; + +} diff --git a/src/lib/ecore_con/Ecore_Con.h b/src/lib/ecore_con/Ecore_Con.h new file mode 100644 index 0000000000..0a832fc37a --- /dev/null +++ b/src/lib/ecore_con/Ecore_Con.h @@ -0,0 +1,1948 @@ +#ifndef _ECORE_CON_H +#define _ECORE_CON_H + +#include +#include +#ifdef _WIN32 +# include +#else +# include +#endif +#include + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# ifdef EFL_ECORE_CON_BUILD +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif +# 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 + +/** + * @defgroup Ecore_Con_Group Ecore_Con - Connection 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 descriptors 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(), optionally using + * an ECORE_CON_USE_* encryption type OR'ed with the type for encryption. + * + * 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(). + * + * 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 + * + * Events are described in @ref Ecore_Con_Events_Group. + */ + + +/** + * @defgroup Ecore_Con_Events_Group Ecore Connection Events Functions + * + * @li ECORE_CON_CLIENT_ADD: Whenever a client connection is made to an + * @c Ecore_Con_Server, an event of this type is emitted, allowing the + * retrieval of the client's ip with @ref ecore_con_client_ip_get and + * associating data with the client using ecore_con_client_data_set. + * @li ECORE_CON_EVENT_CLIENT_DEL: Whenever a client connection to an + * @c Ecore_Con_Server, an event of this type is emitted. The contents of + * the data with this event are variable, but if the client object in the data + * is non-null, it must be freed with @ref ecore_con_client_del. + * @li ECORE_CON_EVENT_SERVER_ADD: Whenever a server object is created + * with @ref ecore_con_server_connect, an event of this type is emitted, + * allowing for data to be serialized and sent to the server using + * @ref ecore_con_server_send. At this point, the http handshake has + * occurred. + * @li ECORE_CON_EVENT_SERVER_DEL: Whenever a server object is destroyed, + * usually by the server connection being refused or dropped, an event of this + * type is emitted. The contents of the data with this event are variable, + * but if the server object in the data is non-null, it must be freed + * with @ref ecore_con_server_del. + * @li ECORE_CON_EVENT_CLIENT_DATA: Whenever a client connects to your server + * object and sends data, an event of this type is emitted. The data will contain both + * the size and contents of the message sent by the client. It should be noted that + * data within this object is transient, so it must be duplicated in order to be + * retained. This event will continue to occur until the client has stopped sending its + * message, so a good option for storing this data is an Eina_Strbuf. Once the message has + * been received in full, the client object must be freed with ecore_con_client_free. + * @li ECORE_CON_EVENT_SERVER_DATA: Whenever your server object connects to its destination + * and receives data, an event of this type is emitted. The data will contain both + * the size and contents of the message sent by the server. It should be noted that + * data within this object is transient, so it must be duplicated in order to be + * retained. This event will continue to occur until the server has stopped sending its + * message, so a good option for storing this data is an Eina_Strbuf. Once the message has + * been received in full, the server object must be freed with ecore_con_server_free. + * + */ + +/** + * @defgroup Ecore_Con_Buffer Ecore Connection Buffering + * + * As Ecore_Con works on an event driven design, as data arrives, events will + * be produced containing the data that arrived. It is up to the user of + * Ecore_Con to either parse as they go, append to a file to later parse the + * whole file in one go, or append to memory to parse or handle leter. + * + * To help with this Eina has some handy API's. The Eina_Binbuf and + * Eina_Strbuf APIs, abstract dynamic buffer management and make it trivial + * to handle buffers at runtime, without having to manage them. Eina_Binbuf + * makes it possible to create, expand, reset and slice a blob of memory - + * all via API. No system calls, no pointer manipulations and no size + * calculation. + * + * Additional functions include adding content at specified byte positions in + * the buffer, escaping the inputs, find and replace strings. This provides + * extreme flexibility to play around, with a dynamic blob of memory. + * + * It is good to free it (using eina_binbuf_free()) after using it. + * + * Eina_Binbuf compliments Ecore_Con use cases, where dynamic sizes of data + * arrive from the network (think http download in chunks). Using + * Eina_Binbuf provides enough flexibility to handle data as it arrives and + * to defer its processing until desired, without having to think about + * where to store the temporary data and how to manage its size. + * + * An example of how to use these with Ecore_Con follows. + * + * @code + * #include + * #include + * #include + * + * static Eina_Bool + * data_callback(void *data, int type, void *event) + * { + * Ecore_Con_Event_Url_Data *url_data = event; + * if ( url_data->size > 0) + * { + * // append data as it arrives - don't worry where or how it gets stored. + * // Also don't worry about size, expanding, reallocing etc. + * // just keep appending - size is automatically handled. + * + * eina_binbuf_append_length(data, url_data->data, url_data->size); + * + * fprintf(stderr, "Appended %d \n", url_data->size); + * } + * return EINA_TRUE; + * } + * + * + * + * static Eina_Bool + * completion_callback(void *data, int type, void *event) + * { + * Ecore_Con_Event_Url_Complete *url_complete = event; + * printf("download completed with status code: %d\n", url_complete->status); + * + * // get the data back from Eina_Binbuf + * char *ptr = eina_binbuf_string_get(data); + * size_t size = eina_binbuf_length_get(data); + * + * // process data as required (write to file) + * fprintf(stderr, "Size of data = %d bytes\n", size); + * int fd = open("./elm.png", O_CREAT); + * write(fd, ptr, size); + * close(fd); + * + * // free it when done. + * eina_binbuf_free(data); + * + * ecore_main_loop_quit(); + * + * return EINA_TRUE; + * } + * + * + * int + * main(int argc, char **argv) + * { + * + * const char *url = "http://www.enlightenment.org/p/index/d/logo.png"; + * + * ecore_init(); + * ecore_con_init(); + * ecore_con_url_init(); + * + * + * // This is single additional line to manage dynamic network data. + * Eina_Binbuf *data = eina_binbuf_new(); + * Ecore_Con_Url *url_con = ecore_con_url_new(url); + * + * ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, + * completion_callback, + * data); + * ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, + * data_callback, + * data); + * ecore_con_url_get(url_con); + * + * ecore_main_loop_begin(); + * return 0; + * } + * @endcode + */ + +#ifdef __cplusplus +extern "C" { +#endif +#define ECORE_CON_USE_SSL ECORE_CON_USE_SSL2 +#define ECORE_CON_REMOTE_SYSTEM ECORE_CON_REMOTE_TCP + + +/** + * @typedef Ecore_Con_Server + * A connection handle to a server + * @ingroup Ecore_Con_Server_Group + */ +typedef struct _Ecore_Con_Server Ecore_Con_Server; + +/** + * @typedef Ecore_Con_Client + * A connection handle to a client + * @ingroup Ecore_Con_Client_Group + */ +typedef struct _Ecore_Con_Client Ecore_Con_Client; + +/** + * @typedef Ecore_Con_Socks + * An object representing a SOCKS proxy + * @ingroup Ecore_Con_Socks_Group + * @since 1.2 + */ +typedef struct Ecore_Con_Socks Ecore_Con_Socks; + +/** + * @typedef Ecore_Con_Url + * A handle to an http upload/download object + * @ingroup Ecore_Con_Url_Group + */ +typedef struct _Ecore_Con_Url Ecore_Con_Url; + + +/** + * @addtogroup Ecore_Con_Events_Group + * @{ + */ + +/** + * @typedef Ecore_Con_Event_Client_Add + * Used as the @p data param for the corresponding event + */ +typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add; + +/** + * @typedef Ecore_Con_Event_Client_Upgrade + * Used as the @p data param for the corresponding event + * @since 1.1 + */ +typedef struct _Ecore_Con_Event_Client_Upgrade Ecore_Con_Event_Client_Upgrade; + +/** + * @typedef Ecore_Con_Event_Client_Del + * Used as the @p data param for the corresponding event + */ +typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del; + +/** + * @typedef Ecore_Con_Event_Client_Error + * Used as the @p data param for the corresponding event + * @since 1.1 + */ +typedef struct _Ecore_Con_Event_Client_Error Ecore_Con_Event_Client_Error; + +/** + * @typedef Ecore_Con_Event_Server_Add + * Used as the @p data param for the corresponding event + */ +typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add; + +/** + * @typedef Ecore_Con_Event_Server_Upgrade + * Used as the @p data param for the corresponding event + * @since 1.1 + */ +typedef struct _Ecore_Con_Event_Server_Upgrade Ecore_Con_Event_Server_Upgrade; + +/** + * @typedef Ecore_Con_Event_Server_Del + * Used as the @p data param for the corresponding event + */ +typedef struct _Ecore_Con_Event_Server_Del Ecore_Con_Event_Server_Del; + +/** + * @typedef Ecore_Con_Event_Server_Error + * Used as the @p data param for the corresponding event + * @since 1.1 + */ +typedef struct _Ecore_Con_Event_Server_Error Ecore_Con_Event_Server_Error; + +/** + * @typedef Ecore_Con_Event_Client_Data + * Used as the @p data param for the corresponding event + */ +typedef struct _Ecore_Con_Event_Client_Data Ecore_Con_Event_Client_Data; + +/** + * @typedef Ecore_Con_Event_Server_Data + * Used as the @p data param for the corresponding event + */ +typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data; + +/** + * @typedef Ecore_Con_Event_Client_Write + * Used as the @p data param for the corresponding event + * @since 1.1 + */ +typedef struct _Ecore_Con_Event_Client_Write Ecore_Con_Event_Client_Write; + +/** + * @typedef Ecore_Con_Event_Server_Write + * Used as the @p data param for the corresponding event + * @since 1.1 + */ +typedef struct _Ecore_Con_Event_Server_Write Ecore_Con_Event_Server_Write; + +/** + * @typedef Ecore_Con_Event_Proxy_Bind + * Used as the @p data param for the corresponding event + * @since 1.2 + */ +typedef struct _Ecore_Con_Event_Proxy_Bind Ecore_Con_Event_Proxy_Bind; + +/** + * @typedef Ecore_Con_Event_Url_Data + * Used as the @p data param for the corresponding event + * @ingroup Ecore_Con_Url_Group + */ +typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data; + +/** + * @typedef Ecore_Con_Event_Url_Complete + * Used as the @p data param for the corresponding event + * @ingroup Ecore_Con_Url_Group + */ +typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete; + +/** + * @typedef Ecore_Con_Event_Url_Progress + * Used as the @p data param for the corresponding event + * @ingroup Ecore_Con_Url_Group + */ +typedef struct _Ecore_Con_Event_Url_Progress Ecore_Con_Event_Url_Progress; + +/** + * @struct _Ecore_Con_Event_Client_Add + * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ADD event + */ +struct _Ecore_Con_Event_Client_Add +{ + Ecore_Con_Client *client; /** the client that connected */ +}; + +/** + * @struct _Ecore_Con_Event_Client_Upgrade + * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_UPGRADE event + * @since 1.1 + */ +struct _Ecore_Con_Event_Client_Upgrade +{ + Ecore_Con_Client *client; /** the client that completed handshake */ +}; + +/** + * @struct _Ecore_Con_Event_Client_Del + * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DEL event + */ +struct _Ecore_Con_Event_Client_Del +{ + Ecore_Con_Client *client; /** the client that was lost */ +}; + +/** + * @struct _Ecore_Con_Event_Client_Error + * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_ERROR event + */ +struct _Ecore_Con_Event_Client_Error +{ + Ecore_Con_Client *client; /** the client for which an error occurred */ + char *error; /**< the error string describing what happened */ +}; + +/** + * @struct _Ecore_Con_Event_Server_Add + * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ADD event + */ +struct _Ecore_Con_Event_Server_Add +{ + Ecore_Con_Server *server; /** the server that was connected to */ +}; + +/** + * @struct _Ecore_Con_Event_Server_Upgrade + * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_UPGRADE event + * @since 1.1 + */ +struct _Ecore_Con_Event_Server_Upgrade +{ + Ecore_Con_Server *server; /** the server that was connected to */ +}; + +/** + * @struct _Ecore_Con_Event_Server_Del + * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DEL event + */ +struct _Ecore_Con_Event_Server_Del +{ + Ecore_Con_Server *server; /** the client that was lost */ +}; + +/** + * @struct _Ecore_Con_Event_Server_Error + * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_ERROR event + */ +struct _Ecore_Con_Event_Server_Error +{ + Ecore_Con_Server *server; /** the server for which an error occurred */ + char *error; /**< the error string describing what happened */ +}; + +/** + * @struct _Ecore_Con_Event_Client_Data + * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_DATA event + */ +struct _Ecore_Con_Event_Client_Data +{ + Ecore_Con_Client *client; /**< the client that connected */ + void *data; /**< the data that the client sent */ + int size; /**< the length of the data sent */ +}; + +/** + * @struct _Ecore_Con_Event_Server_Data + * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_DATA event + */ +struct _Ecore_Con_Event_Server_Data +{ + Ecore_Con_Server *server; /**< the server that was connected to */ + void *data; /**< the data that the server sent */ + int size; /**< the length of the data sent */ +}; + +/** + * @struct _Ecore_Con_Event_Client_Write + * Used as the @p data param for the @ref ECORE_CON_EVENT_CLIENT_WRITE event + */ +struct _Ecore_Con_Event_Client_Write +{ + Ecore_Con_Client *client; /**< the client that connected */ + int size; /**< the length of the data sent */ +}; + +/** + * @struct _Ecore_Con_Event_Server_Write + * Used as the @p data param for the @ref ECORE_CON_EVENT_SERVER_WRITE event + */ +struct _Ecore_Con_Event_Server_Write +{ + Ecore_Con_Server *server; /**< the server that was connected to */ + int size; /**< the length of the data sent */ +}; + +/** + * @struct _Ecore_Con_Event_Proxy_Bind + * Used as the @p data param for the @ref ECORE_CON_EVENT_PROXY_BIND event + * @ingroup Ecore_Con_Socks_Group + * @since 1.2 + */ +struct _Ecore_Con_Event_Proxy_Bind +{ + Ecore_Con_Server *server; /**< the server object connected to the proxy */ + const char *ip; /**< the proxy-bound ip address */ + int port; /**< the proxy-bound port */ +}; + +/** + * @struct _Ecore_Con_Event_Url_Data + * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_DATA event + * @ingroup Ecore_Con_Url_Group + */ +struct _Ecore_Con_Event_Url_Data +{ + Ecore_Con_Url *url_con; /**< a pointer to the connection object */ + int size; /**< the size of the current received data (in bytes) */ + unsigned char data[1]; /**< the data received on this event */ +}; + +/** + * @struct _Ecore_Con_Event_Url_Complete + * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_COMPLETE event + * @ingroup Ecore_Con_Url_Group + */ +struct _Ecore_Con_Event_Url_Complete +{ + Ecore_Con_Url *url_con; /**< a pointer to the connection object */ + int status; /**< HTTP status code of the operation (200, 404, 401, etc.) */ +}; + +/** + * @struct _Ecore_Con_Event_Url_Progress + * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_PROGRESS event + * @ingroup Ecore_Con_Url_Group + */ +struct _Ecore_Con_Event_Url_Progress +{ + Ecore_Con_Url *url_con; /**< a pointer to the connection object */ + struct + { + double total; /**< total size of the downloading data (in bytes) */ + double now; /**< current size of the downloading data (in bytes) */ + } down; /**< download info */ + struct + { + double total; /**< total size of the uploading data (in bytes) */ + double now; /**< current size of the uploading data (in bytes) */ + } up; /**< upload info */ +}; + +/** A client has connected to the server */ +EAPI extern int ECORE_CON_EVENT_CLIENT_ADD; +/** A client has disconnected from the server */ +EAPI extern int ECORE_CON_EVENT_CLIENT_DEL; +/** A client experienced an error + * @since 1.1 + */ +EAPI extern int ECORE_CON_EVENT_CLIENT_ERROR; +/** A client connection has been upgraded to SSL + * @since 1.1 + */ +EAPI extern int ECORE_CON_EVENT_CLIENT_UPGRADE; +/** A server was created */ +EAPI extern int ECORE_CON_EVENT_SERVER_ADD; +/** A server connection was lost */ +EAPI extern int ECORE_CON_EVENT_SERVER_DEL; +/** A server experienced an error + * @since 1.1 + */ +EAPI extern int ECORE_CON_EVENT_SERVER_ERROR; +/** A server connection has been upgraded to SSL + * @since 1.1 + */ +EAPI extern int ECORE_CON_EVENT_SERVER_UPGRADE; +/** A server connection has sent data to its client + * @since 1.1 + */ +EAPI extern int ECORE_CON_EVENT_CLIENT_WRITE; +/** A server connection object has sent data + * @since 1.1 + */ +EAPI extern int ECORE_CON_EVENT_SERVER_WRITE; +/** A client connected to the server has sent data */ +EAPI extern int ECORE_CON_EVENT_CLIENT_DATA; +/** A server connection object has data */ +EAPI extern int ECORE_CON_EVENT_SERVER_DATA; +/** A server connection has successfully negotiated an ip:port binding + * @since 1.2 + */ +EAPI extern int ECORE_CON_EVENT_PROXY_BIND; +/** A URL object has data */ +EAPI extern int ECORE_CON_EVENT_URL_DATA; +/** A URL object has completed its transfer to and from the server and can be reused */ +EAPI extern int ECORE_CON_EVENT_URL_COMPLETE; +/** A URL object has made progress in its transfer */ +EAPI extern int ECORE_CON_EVENT_URL_PROGRESS; + +/** + * @} + */ + +/** + * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions + * + * Utility functions that set up and shut down the Ecore Connection + * library. + * + * There's also ecore_con_lookup() that can be used to make simple asynchronous + * DNS lookups. + * + * A simple example of how to use these functions: + * @li @ref ecore_con_lookup_example_c + * + * @{ + */ + +/** + * @typedef Ecore_Con_Dns_Cb + * A callback type for use with @ref ecore_con_lookup. + */ +typedef void (*Ecore_Con_Dns_Cb)(const char *canonname, + const char *ip, + struct sockaddr *addr, + int addrlen, + void *data); + +/** + * @typedef Ecore_Con_Type + * @enum _Ecore_Con_Type + * Types for an ecore_con client/server object. A correct way to set this type is + * with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if encryption is desired, + * and LOAD_CERT if the previously loaded certificate should be used. + * @code + * ECORE_CON_REMOTE_TCP | ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT + * @endcode + * @ingroup Ecore_Con_Server_Group + */ +typedef enum _Ecore_Con_Type +{ + /** Socket in ~/.ecore */ + ECORE_CON_LOCAL_USER = 0, + /** Socket in /tmp */ + ECORE_CON_LOCAL_SYSTEM = 1, + /** Abstract socket */ + ECORE_CON_LOCAL_ABSTRACT = 2, + /** Remote server using TCP */ + ECORE_CON_REMOTE_TCP = 3, + /** Remote multicast server */ + ECORE_CON_REMOTE_MCAST = 4, + /** Remote server using UDP */ + ECORE_CON_REMOTE_UDP = 5, + /** Remote broadcast using UDP */ + ECORE_CON_REMOTE_BROADCAST = 6, + /** Remote connection sending packets immediately */ + ECORE_CON_REMOTE_NODELAY = 7, + /** Remote connection sending data in large chunks + * @note Only available on Linux + * @since 1.2 + */ + ECORE_CON_REMOTE_CORK = 8, + /** Use SSL2: UNSUPPORTED. **/ + ECORE_CON_USE_SSL2 = (1 << 4), + /** Use SSL3 */ + ECORE_CON_USE_SSL3 = (1 << 5), + /** Use TLS */ + ECORE_CON_USE_TLS = (1 << 6), + /** Use both TLS and SSL3 */ + ECORE_CON_USE_MIXED = ECORE_CON_USE_SSL3 | ECORE_CON_USE_TLS, + /** Attempt to use the loaded certificate */ + ECORE_CON_LOAD_CERT = (1 << 7), + /** Disable all types of proxy on the server + * @note Only functional for clients + * @since 1.2 + */ + ECORE_CON_NO_PROXY = (1 << 8) +} Ecore_Con_Type; + +/** + * Initialises the Ecore_Con library. + * @return Number of times the library has been initialised without being + * shut down. + * + * @note This function already calls ecore_init() internally, so you don't need + * to call it explicitly. + */ +EAPI int ecore_con_init(void); + +/** + * Shuts down the Ecore_Con library. + * @return Number of times the library has been initialised without being + * shut down. + * @note This function already calls ecore_shutdown() internally, so you don't + * need to call it explicitly unless you called ecore_init() explicitly too. + */ +EAPI int ecore_con_shutdown(void); + +/** + * Do an asynchronous DNS lookup. + * + * @param name IP address or server name to translate. + * @param done_cb Callback to notify when done. + * @param data User data to be given to done_cb. + * @return @c EINA_TRUE if the request did not fail to be set up, @c EINA_FALSE + * if it failed. + * + * This function performs a DNS lookup on the hostname specified by @p name, + * then calls @p done_cb with the result and the @p data given as parameter. + * The result will be given to the @p done_cb as follows: + * @li @c canonname - the canonical name of the address + * @li @c ip - the resolved ip address + * @li @c addr - a pointer to the socket address + * @li @c addrlen - the length of the socket address, in bytes + * @li @c data - the data pointer given as parameter to ecore_con_lookup() + */ +EAPI Eina_Bool ecore_con_lookup(const char *name, + Ecore_Con_Dns_Cb done_cb, + const void *data); + +/** + * @} + */ + +/** + * @defgroup Ecore_Con_SSL_Group Ecore Connection SSL Functions + * + * @{ + */ +EAPI int ecore_con_ssl_available_get(void); +EAPI Eina_Bool ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr, const char *cert); +EAPI Eina_Bool ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr, const char *key_file); +EAPI Eina_Bool ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, const char *crl_file); +EAPI Eina_Bool ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, const char *ca_file); +EAPI void ecore_con_ssl_server_verify(Ecore_Con_Server *svr); +EAPI void ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr); +EAPI void ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name); +EAPI const char *ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr); +EAPI Eina_Bool ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type compl_type); +EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type compl_type); + +/** + * @} + */ + +EAPI Ecore_Con_Socks *ecore_con_socks4_remote_add(const char *ip, int port, const char *username); +EAPI Eina_Bool ecore_con_socks4_remote_exists(const char *ip, int port, const char *username); +EAPI void ecore_con_socks4_remote_del(const char *ip, int port, const char *username); +EAPI Ecore_Con_Socks *ecore_con_socks5_remote_add(const char *ip, int port, const char *username, const char *password); +EAPI Eina_Bool ecore_con_socks5_remote_exists(const char *ip, int port, const char *username, const char *password); +EAPI void ecore_con_socks5_remote_del(const char *ip, int port, const char *username, const char *password); +EAPI void ecore_con_socks_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable); +EAPI Eina_Bool ecore_con_socks_lookup_get(Ecore_Con_Socks *ecs); +EAPI void ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind); +EAPI Eina_Bool ecore_con_socks_bind_get(Ecore_Con_Socks *ecs); +EAPI unsigned int ecore_con_socks_version_get(Ecore_Con_Socks *ecs); +EAPI void ecore_con_socks_remote_del(Ecore_Con_Socks *ecs); +EAPI void ecore_con_socks_apply_once(Ecore_Con_Socks *ecs); +EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs); + +/** + * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions + * + * This group of functions is applied to an @ref Ecore_Con_Server object. It + * doesn't mean that they should be used in the server application, but on the + * server object. In fact, most of them should be used in the client + * application, when retrieving information or sending data. + * + * Setting up a server is very simple: you just need to start it with + * ecore_con_server_add() and setup some callbacks to the events + * @ref ECORE_CON_EVENT_CLIENT_ADD, @ref ECORE_CON_EVENT_CLIENT_DEL and + * @ref ECORE_CON_EVENT_CLIENT_DATA, that will be called when a client is + * communicating with the server: + * + * @code + * if (!(svr = ecore_con_server_add(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL))) + * exit(1); + * + * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, _add_cb, NULL); + * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, _del_cb, NULL); + * ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, _data_cb, NULL); + * + * ecore_main_loop_begin(); + * @endcode + * + * The function ecore_con_server_connect() can be used to write a client that + * connects to a server. The resulting code will be very similar to the server + * code: + * + * @code + * if (!(svr = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL))) + * exit(1); + * + * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _add_cb, NULL); + * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _del_cb, NULL); + * ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _data_cb, NULL); + * + * ecore_main_loop_begin(); + * @endcode + * + * After these two pieces of code are executed, respectively, in the server and + * client code, the server will be up and running and the client will try to + * connect to it. The connection, with its subsequent messages being sent from + * server to client and client to server, can be represented in the following + * sequence diagram: + * + * @htmlonly + * + * Full size + * @endhtmlonly + * + * @image rtf ecore_con-client-server.png + * @image latex ecore_con-client-server.eps width=\textwidth + * + * Please notice the important difference between these two codes: the first is + * used for writing a @b server, while the second should be used for writing a + * @b client. + * + * A reference for the @c client functions can be found at @ref + * Ecore_Con_Client_Group. + * + * Examples of usage for this API can be found here: + * @li @ref ecore_con_server_simple_example_c + * @li @ref ecore_con_client_simple_example_c + * + * @{ + */ + +/** + * Creates a server to listen for connections. + * + * @param type The connection type. + * @param name Name to associate with the socket. It is used when + * generating the socket name of a Unix socket, or for + * determining what host to listen on for TCP sockets. + * @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. + * + * The socket on which the server listens depends on the connection + * type: + * @li If @a type is @c ECORE_CON_LOCAL_USER, the server will listen on + * the Unix socket "~/.ecore/[name]/[port]". + * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen + * on Unix socket "/tmp/.ecore_service|[name]|[port]". + * @li If @a type is @c ECORE_CON_REMOTE_TCP, the server will listen + * on TCP port @c port. + * + * More information about the @p type can be found at @ref _Ecore_Con_Type. + * + * The @p data parameter can be fetched later using ecore_con_server_data_get() + * or changed with ecore_con_server_data_set(). + */ +EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, + const char *name, int port, + const void *data); + +/** + * Creates a connection to the specified server and returns an associated object. + * + * @param 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. + * + * The socket to which the connection is made depends on the connection type: + * @li If @a type is @c ECORE_CON_LOCAL_USER, the function will + * connect to the server at the Unix socket + * "~/.ecore/[name]/[port]". + * @li If @a type is @c ECORE_CON_LOCAL_SYSTEM, the function will + * connect to the server at the Unix socket + * "/tmp/.ecore_service|[name]|[port]". + * @li If @a type is @c ECORE_CON_REMOTE_TCP, the function will + * connect to the server at the TCP port "[name]:[port]". + * + * More information about the @p type can be found at @ref _Ecore_Con_Type. + * + * This function won't block. It will either succeed, or fail due to invalid + * parameters, failed memory allocation, etc., returning @c NULL on that case. + * + * However, even if this call returns a valid @ref Ecore_Con_Server, the + * connection will only be successfully completed if an event of type + * @ref ECORE_CON_EVENT_SERVER_ADD is received. If it fails to complete, an + * @ref ECORE_CON_EVENT_SERVER_DEL will be received. + * + * The @p data parameter can be fetched later using ecore_con_server_data_get() + * or changed with ecore_con_server_data_set(). + */ +EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, + const char *name, int port, + const void *data); +/** + * Closes the connection and frees the given server. + * + * @param svr The given server. + * @return Data associated with the server when it was created. + * + * All the clients connected to this server will be disconnected. + * + * @see ecore_con_server_add, ecore_con_server_connect + */ +EAPI void * ecore_con_server_del(Ecore_Con_Server *svr); + +/** + * Retrieves the data associated with the given server. + * + * @param svr The given server. + * @return The associated data. + * + * @see ecore_con_server_data_set() + */ +EAPI void * ecore_con_server_data_get(Ecore_Con_Server *svr); +/** + * Sets the data associated with the given server. + * + * @param svr The given server. + * @param data The data to associate with @p svr + * @return The previously associated data, if any. + * + * @see ecore_con_server_data_get() + */ +EAPI void * ecore_con_server_data_set(Ecore_Con_Server *svr, + void *data); +/** + * Retrieves whether the given server is currently connected. + * + * @param svr The given server. + * @return @c EINA_TRUE if the server is connected, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ecore_con_server_connected_get(Ecore_Con_Server *svr); +/** + * Retrieves the current list of clients. + * + * @param svr The given server. + * @return The list of clients on this server. + * + * Each node in the returned list points to an @ref Ecore_Con_Client. This list + * cannot be modified or freed. It can also change if new clients are connected + * or disconnected, and will become invalid when the server is deleted/freed. + */ +EAPI const Eina_List * ecore_con_server_clients_get(Ecore_Con_Server *svr); + +/** + * Retrieves the name of server. + * + * @param svr The given server. + * @return The name of the server. + * + * The name returned is the name used to connect on this server. + */ +EAPI const char * ecore_con_server_name_get(Ecore_Con_Server *svr); + +/** + * Retrieves the server port in use. + * + * @param svr The given server. + * @return The server port in use. + * + * The port where the server is listening for connections. + */ +EAPI int ecore_con_server_port_get(Ecore_Con_Server *svr); +/** + * @brief Check how long a server has been connected + * + * @param svr The server to check + * @return The total time, in seconds, that the server has been + * connected/running + * + * This function is used to find out the time that has been elapsed since + * ecore_con_server_add() succeeded. + */ +EAPI double ecore_con_server_uptime_get(Ecore_Con_Server *svr); +/** + * 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. + * + * This function will send the given data to the server as soon as the program + * is back to the main loop. Thus, this function returns immediately + * (non-blocking). If the data needs to be sent @b now, call + * ecore_con_server_flush() after this one. + * + * @see ecore_con_client_send() + * @see ecore_con_server_flush() + */ +EAPI int ecore_con_server_send(Ecore_Con_Server *svr, + const void *data, + int 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. + * + * @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). + * + * 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. + */ +EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, + int client_limit, + char 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 @c NULL is + * returned. + */ +EAPI const char * ecore_con_server_ip_get(Ecore_Con_Server *svr); +/** + * Flushes all pending data to the given server. + * + * @param svr The given server. + * + * This function will block until all data is sent to the server. + * + * @see ecore_con_server_send() + * @see ecore_con_client_flush() + */ +EAPI void ecore_con_server_flush(Ecore_Con_Server *svr); +/** + * Set the default time after which an inactive client will be disconnected + * + * @param svr The server object + * @param timeout The timeout, in seconds, to disconnect after + * + * This function is used by the server to set the default idle timeout on + * clients. If the any of the clients becomes idle for a time higher than this + * value, it will be disconnected. A value of < 1 disables the idle timeout. + * + * This timeout is not affected by the one set by + * ecore_con_client_timeout_set(). A client will be disconnected whenever the + * client or the server timeout is reached. That means, the lower timeout value + * will be used for that client if ecore_con_client_timeout_set() is used on it. + * + * @see ecore_con_server_timeout_get() + * @see ecore_con_client_timeout_set() + */ +EAPI void ecore_con_server_timeout_set(Ecore_Con_Server *svr, double timeout); +/** + * Get the default time after which an inactive client will be disconnected + * + * @param svr The server object + * @return The timeout, in seconds, to disconnect after + * + * This function is used to get the idle timeout for clients. A value of < 1 + * means the idle timeout is disabled. + * + * @see ecore_con_server_timeout_set() + * @see ecore_con_client_timeout_get() + */ +EAPI double ecore_con_server_timeout_get(Ecore_Con_Server *svr); + +/** + * Get the fd that the server is connected to + * + * @param svr The server object + * @return The fd, or -1 on failure + * + * This function returns the fd which is used by the underlying server connection. + * It should not be tampered with unless you REALLY know what you are doing. + * @note This function is only valid for servers created with ecore_con_server_connect() + * @warning Seriously. Don't use this unless you know what you are doing. + * @since 1.1 + */ +EAPI int ecore_con_server_fd_get(Ecore_Con_Server *svr); + +/** + * Get the fd that the client is connected to + * + * @param cl The client object + * @return The fd, or -1 on failure + * + * This function returns the fd which is used by the underlying client connection. + * It should not be tampered with unless you REALLY know what you are doing. + * @since 1.1 + */ +EAPI int ecore_con_client_fd_get(Ecore_Con_Client *cl); +/** + * @} + */ + +/** + * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions + * + * Functions to communicate with and/or set options on a client. + * + * This set of functions, as explained in @ref Ecore_Con_Server_Group, is used + * to send data to a client, or to set options and get information about this + * client. Most of them should be used on the server, applied on the client + * object. + * + * If you need to implement a client, the way to connect to a server is + * described in @ref Ecore_Con_Server_Group. + * + * An example of usage of these functions can be found at: + * @li @ref ecore_con_client_simple_example_c + * + * @{ + */ + +/** + * 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. + * + * This function will send the given data to the client as soon as the program + * is back to the main loop. Thus, this function returns immediately + * (non-blocking). If the data needs to be sent @b now, call + * ecore_con_client_flush() after this one. + * + * @see ecore_con_server_send() + * @see ecore_con_client_flush() + */ +EAPI int ecore_con_client_send(Ecore_Con_Client *cl, + const void *data, + int 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. + */ +EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl); +/** + * Closes the connection and frees memory allocated to the given client. + * + * @param cl The given client. + * @return Data associated with the client. + */ +EAPI void * ecore_con_client_del(Ecore_Con_Client *cl); +/** + * Sets the data associated with the given client to @p data. + * + * @param cl The given client. + * @param data What to set the data to. + */ +EAPI void ecore_con_client_data_set(Ecore_Con_Client *cl, + const void *data); +/** + * Retrieves the data associated with the given client. + * + * @param cl The given client. + * @return The data associated with @p cl. + */ +EAPI void * ecore_con_client_data_get(Ecore_Con_Client *cl); + +/** + * Gets the IP address of a client 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. + * + * The returned string should not be modified, freed or trusted to stay valid + * after deletion for the @p cl object. If no IP is known @c NULL is returned. + */ +EAPI const char * ecore_con_client_ip_get(Ecore_Con_Client *cl); +/** + * Flushes all pending data to the given client. + * + * @param cl The given client. + * + * This function will block until all data is sent to the server. + * + * @see ecore_con_client_send() + * @see ecore_con_server_flush() + */ +EAPI void ecore_con_client_flush(Ecore_Con_Client *cl); +/** + * @brief Check how long a client has been connected + * + * @param cl The client to check + * @return The total time, in seconds, that the client has been connected to + * the server + * + * This function is used to find out how long a client has been connected for. + */ +EAPI double ecore_con_client_uptime_get(Ecore_Con_Client *cl); +/** + * Get the default time after which the client will be disconnected when + * inactive + * + * @param cl The client object + * @return The timeout, in seconds, to disconnect after + * + * This function is used to get the idle timeout for a client. A value of < 1 + * means the idle timeout is disabled. + * + * @see ecore_con_client_timeout_set() + */ +EAPI double ecore_con_client_timeout_get(Ecore_Con_Client *cl); +/** + * Set the time after which the client will be disconnected when inactive + * + * @param cl The client object + * @param timeout The timeout, in seconds, to disconnect after + * + * This function is used by the server to set the idle timeout on a specific + * client. If the client becomes idle for a time higher than this value, it will + * be disconnected. A value of < 1 disables the idle timeout. + * + * This timeout is not affected by the one set by + * ecore_con_server_timeout_set(). A client will be disconnected whenever the + * client or the server timeout is reached. That means, the lower timeout value + * will be used for that client if ecore_con_server_timeout_set() is used on the + * server. + * + * @see ecore_con_client_timeout_get() + * @see ecore_con_server_timeout_set() + */ +EAPI void ecore_con_client_timeout_set(Ecore_Con_Client *cl, double timeout); +/** + * Returns whether the client is still connected + * + * @param cl The given client. + * @return @c EINA_TRUE if connected, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ecore_con_client_connected_get(Ecore_Con_Client *cl); +/** + * @brief Return the port that the client has connected to + * + * @param cl The client + * @return The port that @p cl has connected to, or -1 on error + * Use this function to return the port on which a given client has connected. + */ +EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl); + + + +/** + * @} + */ + +/** + * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions + * + * Utility functions that set up, use and shut down the Ecore URL + * Connection library. + * + * These functions are a shortcut to make it easy to perform http requests + * (POST, GET, etc). + * + * Brief usage: + * 1. Create an Ecore_Con_Url object with ecore_con_url_new(url); + * 2. Register to receive the #ECORE_CON_EVENT_URL_COMPLETE event + * (and optionally the #ECORE_CON_EVENT_URL_DATA and + * #ECORE_CON_EVENT_URL_PROGRESS event to receive + * the response, e.g. for HTTP/FTP downloads) + * 3. Perform the operation with ecore_con_url_get(...); + * + * Note that it is good to reuse @ref 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. + * + * If it's necessary to change the @ref Ecore_Con_Url object url, use + * ecore_con_url_url_set(). + * + * Simple Usage 1 (HTTP GET): + * @code + * ecore_con_url_url_set(url_con, "http://www.google.com"); + * ecore_con_url_get(url_con); + * @endcode + * + * Simple usage 2 (HTTP POST): + * @code + * ecore_con_url_url_set(url_con, "http://www.example.com/post_handler.cgi"); + * ecore_con_url_post(url_con, data, data_length, "multipart/form-data"); + * @endcode + * + * Simple Usage 3 (FTP download): + * @code + * fd = creat(filename, 0644) + * ecore_con_url_url_set(url_con, "ftp://ftp.example.com/pub/myfile"); + * ecore_con_url_fd_set(url_con, fd); + * ecore_con_url_get(url_con); + * @endcode + * + * Simple Usage 4 (FTP upload as ftp://ftp.example.com/file): + * @code + * ecore_con_url_url_set(url_con, "ftp://ftp.example.com"); + * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass", NULL); + * @endcode + * + * Simple Usage 5 (FTP upload as ftp://ftp.example.com/dir/file): + * @code + * ecore_con_url_url_set(url_con, "ftp://ftp.example.com"); + * ecore_con_url_ftp_upload(url_con, "/tmp/file", "user", "pass","dir"); + * @endcode + * + * These are complete examples for the API: + * @li @ref ecore_con_url_download_example.c "Downloading a file" + * @li @ref ecore_con_url_headers_example.c "Setting many options for the connection" + * + * @{ + */ + +/** + * @typedef Ecore_Con_Url_Time + * @enum _Ecore_Con_Url_Time + * The type of condition to use when making an HTTP request dependent on time, + * so that headers such as "If-Modified-Since" are used. + */ +typedef enum _Ecore_Con_Url_Time +{ + /** + * Do not place time restrictions on the HTTP requests. + */ + ECORE_CON_URL_TIME_NONE = 0, + /** + * Add the "If-Modified-Since" HTTP header, so that the request is performed + * by the server only if the target has been modified since the time value + * passed to it in the request. + */ + ECORE_CON_URL_TIME_IFMODSINCE, + /** + * Add the "If-Unmodified-Since" HTTP header, so that the request is + * performed by the server only if the target has NOT been modified since + * the time value passed to it in the request. + */ + ECORE_CON_URL_TIME_IFUNMODSINCE +} Ecore_Con_Url_Time; + +/** + * @typedef Ecore_Con_Url_Http_Version + * @enum _Ecore_Con_Url_Http_Version + * The http version to use + * @since 1.2 + */ +typedef enum _Ecore_Con_Url_Http_Version +{ + /** + * HTTP version 1.0 + * @since 1.2 + */ + ECORE_CON_URL_HTTP_VERSION_1_0, + /** + * HTTP version 1.1 (default) + * @since 1.2 + */ + ECORE_CON_URL_HTTP_VERSION_1_1 +} Ecore_Con_Url_Http_Version; + +/** + * Change the HTTP version used for the request + * @param url_con Connection object through which the request will be sent. + * @param version The version to be used + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure to change version. + * @since 1.2 + * @see ecore_con_url_pipeline_get() + */ +EAPI Eina_Bool ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Version version); + +/** + * Initialises the Ecore_Con_Url library. + * @return Number of times the library has been initialised without being + * shut down. + * + * @note This function doesn't call ecore_con_init(). You still need to call it + * explicitly before calling this one. + */ +EAPI int ecore_con_url_init(void); + +/** + * Shuts down the Ecore_Con_Url library. + * @return Number of calls that still uses Ecore_Con_Url + * + * @note This function doesn't call ecore_con_shutdown(). You still need to call + * it explicitly after calling this one. + */ +EAPI int ecore_con_url_shutdown(void); + +/** + * Enable or disable HTTP 1.1 pipelining. + * @param enable @c EINA_TRUE will turn it on, @c EINA_FALSE will disable it. + * + * Pipelining allows to send one request after another one, without having to + * wait for the reply of the first request. The respective replies are received + * in the order that the requests were sent. + * + * Enabling this feature will be valid for all requests done using @c + * ecore_con_url. + * + * See http://en.wikipedia.org/wiki/HTTP_pipelining for more info. + * + * @see ecore_con_url_pipeline_get() + */ +EAPI void ecore_con_url_pipeline_set(Eina_Bool enable); +/** + * Is HTTP 1.1 pipelining enable ? + * @return @c EINA_TRUE if it is enable. + * + * @see ecore_con_url_pipeline_set() + */ +EAPI Eina_Bool ecore_con_url_pipeline_get(void); + +/** + * Creates and initializes a new Ecore_Con_Url connection object. + * + * @param url URL that will receive requests. Can be changed using + * ecore_con_url_url_set. + * + * @return @c NULL on error, a new Ecore_Con_Url on success. + * + * Creates and initializes a new Ecore_Con_Url connection object that can be + * used for sending requests. + * + * @see ecore_con_url_custom_new() + * @see ecore_con_url_url_set() + */ +EAPI Ecore_Con_Url * ecore_con_url_new(const char *url); +/** + * Creates a custom connection object. + * + * @param url URL that will receive requests + * @param custom_request Custom request (e.g. GET, POST, HEAD, PUT, etc) + * + * @return @c NULL on error, a new Ecore_Con_Url on success. + * + * 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(). + * + * @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); +/** + * Destroys a Ecore_Con_Url connection object. + * + * @param url_con Connection object to free. + * + * @see ecore_con_url_new() + */ +EAPI void ecore_con_url_free(Ecore_Con_Url *url_con); +/** + * 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 @c EINA_TRUE on success, @c EINA_FALSE on error. + */ +EAPI Eina_Bool ecore_con_url_url_set(Ecore_Con_Url *url_con, + const char *url); +/** + * Gets the URL to send the request to. + * + * @param url_con Connection object through which the request will be sent. + * @return URL that will receive the request, @c NULL on failure. URL is + * stringshared. + * @since 1.1 + */ +EAPI const char *ecore_con_url_url_get(Ecore_Con_Url *url_con); +/** + * Associates data with a connection object. + * + * @param url_con Connection object to associate data. + * @param data Data to be set. + * + * Associates data with a connection object, which can be retrieved later with + * ecore_con_url_data_get()). + * + * @see ecore_con_url_data_get() + */ +EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con, + void *data); +/** + * Retrieves data associated with a Ecore_Con_Url connection object. + * + * @param url_con Connection object to retrieve data from. + * + * @return Data associated with the given object. + * + * Retrieves data associated with a Ecore_Con_Url connection object (previously + * set with ecore_con_url_data_set()). + * + * @see ecore_con_url_data_set() + */ +EAPI void * ecore_con_url_data_get(Ecore_Con_Url *url_con); +/** + * Adds an additional header to the request connection object. + * + * @param url_con Connection object + * @param key Header key + * @param value Header value + * + * Adds an additional header (User-Agent, Content-Type, etc.) to the request + * connection object. This addition will be valid for only one + * ecore_con_url_get() or ecore_con_url_post() call. + * + * Some functions like ecore_con_url_time() also add headers to the request. + * + * @see ecore_con_url_get() + * @see ecore_con_url_post() + * @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); +/** + * Cleans additional headers. + * + * @param url_con Connection object to clean additional headers. + * + * Cleans additional headers associated with a connection object (previously + * added with ecore_con_url_additional_header_add()). + * + * @see ecore_con_url_additional_header_add() + * @see ecore_con_url_get() + * @see ecore_con_url_post() + */ +EAPI void ecore_con_url_additional_headers_clear(Ecore_Con_Url *url_con); +/** + * Retrieves headers from last request sent. + * + * @param url_con Connection object to retrieve response headers from. + * + * 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). + * + * @return List of response headers. This list must not be modified by the user. + */ +EAPI const Eina_List * ecore_con_url_response_headers_get(Ecore_Con_Url *url_con); +/** + * Setup a file for receiving response data. + * + * @param url_con Connection object to set file + * @param fd File descriptor associated with the file. A negative value will + * unset any previously set fd. + * + * Sets up 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. + * + * This call can be used to easily setup a file where the downloaded data will + * be saved. + */ +EAPI void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd); +/** + * 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. + * + * @see ecore_con_url_get() + * @see ecore_con_url_post() + */ +EAPI int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con); +/** + * 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 @c EINA_TRUE on success, @c EINA_FALSE on error. + * + * @attention Requires libcurl >= 7.19.1 to work, otherwise will always return + * @c 0. + */ +EAPI Eina_Bool ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, + const char *username, + const char *password, + Eina_Bool safe); +/** + * Sends a get request. + * + * @param url_con Connection object to perform a request on, previously created + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * + * The request is performed immediately, but you need to setup event handlers + * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or + * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. + * + * @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() + * @see ecore_con_url_time() + * @see ecore_con_url_post() + */ +EAPI Eina_Bool ecore_con_url_get(Ecore_Con_Url *url_con); +/** + * Sends a post 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). Can be @c NULL. + * @param length Payload length. If @c -1, rely on automatic length + * calculation via @c strlen() on @p data. + * @param content_type Content type of the payload (e.g. text/xml). Can be @c + * NULL. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * + * The request starts immediately, but you need to setup event handlers + * for #ECORE_CON_EVENT_URL_DATA, #ECORE_CON_EVENT_URL_COMPLETE or + * #ECORE_CON_EVENT_URL_PROGRESS to get more information about its result. + * + * This call won't block your main loop. + * + * @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() + * @see ecore_con_url_time() + * @see ecore_con_url_get() + */ +EAPI Eina_Bool ecore_con_url_post(Ecore_Con_Url *url_con, + const void *data, long length, + const char *content_type); +/** + * Sets whether HTTP requests should be conditional, dependent on + * modification time. + * + * @param url_con Ecore_Con_Url to act upon. + * @param time_condition Condition to use for HTTP requests. + * @param timestamp Time since 1 Jan 1970 to use in the condition. + * + * This function may set the header "If-Modified-Since" or + * "If-Unmodified-Since", depending on the value of @p time_condition, with the + * value @p timestamp. + * + * @sa ecore_con_url_get() + * @sa ecore_con_url_post() + */ +EAPI void ecore_con_url_time(Ecore_Con_Url *url_con, + Ecore_Con_Url_Time time_condition, + double timestamp); + +/** + * @brief Uploads a file to an ftp site. + * + * @param url_con The Ecore_Con_Url object to send with + * @param filename The path to the file to send + * @param user The username to log in with + * @param pass The password to log in with + * @param upload_dir The directory to which the file should be uploaded + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * Upload @p filename to an ftp server set in @p url_con using @p user + * and @p pass to directory @p upload_dir + */ +EAPI Eina_Bool ecore_con_url_ftp_upload(Ecore_Con_Url *url_con, + const char *filename, + const char *user, + const char *pass, + const char *upload_dir); +/** + * Toggle libcurl's verbose output. + * + * @param url_con Ecore_Con_Url instance which will be acted upon. + * @param verbose Whether or not to enable libcurl's verbose output. + * + * If @p verbose is @c EINA_TRUE, libcurl will output a lot of verbose + * information about its operations, which is useful for + * debugging. The verbose information will be sent to stderr. + */ +EAPI void ecore_con_url_verbose_set(Ecore_Con_Url *url_con, + Eina_Bool verbose); +/** + * Enable or disable EPSV extension + * @param url_con The Ecore_Con_Url instance which will be acted upon. + * @param use_epsv Boolean to enable/disable the EPSV extension. + */ +EAPI void ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, + Eina_Bool use_epsv); + +/** + * Enables the cookie engine for subsequent HTTP requests. + * + * @param url_con Ecore_Con_Url instance which will be acted upon. + * + * After this function is called, cookies set by the server in HTTP responses + * will be parsed and stored, as well as sent back to the server in new HTTP + * requests. + * + * @note Even though this function is called @c ecore_con_url_cookies_init(), + * there is no symmetrical shutdown operation. + */ +EAPI void ecore_con_url_cookies_init(Ecore_Con_Url *url_con); +/** + * Controls whether session cookies from previous sessions shall be loaded. + * + * @param url_con Ecore_Con_Url instance which will be acted upon. + * @param ignore If @c EINA_TRUE, ignore session cookies when loading cookies + * from files. If @c EINA_FALSE, all cookies will be loaded. + * + * Session cookies are cookies with no expire date set, which usually means + * they are removed after the current session is closed. + * + * By default, when Ecore_Con_Url loads cookies from a file, all cookies are + * loaded, including session cookies, which, most of the time, were supposed + * to be loaded and valid only for that session. + * + * If @p ignore is set to @c EINA_TRUE, when Ecore_Con_Url loads cookies from + * the files passed to @c ecore_con_url_cookies_file_add(), session cookies + * will not be loaded. + * + * @see ecore_con_url_cookies_file_add() + */ +EAPI void ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, + Eina_Bool ignore); +/** + * Clears currently loaded cookies. + * @param url_con Ecore_Con_Url instance which will be acted upon. + * + * The cleared cookies are removed and will not be sent in subsequent HTTP + * requests, nor will they be written to the cookiejar file set via + * @c ecore_con_url_cookies_jar_file_set(). + * + * @note This function will initialize the cookie engine if it has not been + * initialized yet. + * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded + * immediately, just when the request is started. Thus, if you ask to + * clear the cookies, but has a file already set by that function, the + * cookies will then be loaded and you will have old cookies set. In order + * to don't have any old cookie set, you need to don't call + * ecore_con_url_cookies_file_add() ever on the @p url_con handler, and + * call this function to clear any cookie set by a previous request on + * this handler. + * + * @see ecore_con_url_cookies_session_clear() + * @see ecore_con_url_cookies_ignore_old_session_set() + */ +EAPI void ecore_con_url_cookies_clear(Ecore_Con_Url *url_con); +/** + * Clears currently loaded session cookies. + * + * @param url_con Ecore_Con_Url instance which will be acted upon. + * + * Session cookies are cookies with no expire date set, which usually means + * they are removed after the current session is closed. + * + * The cleared cookies are removed and will not be sent in subsequent HTTP + * requests, nor will they be written to the cookiejar file set via + * @c ecore_con_url_cookies_jar_file_set(). + * + * @note This function will initialize the cookie engine if it has not been + * initialized yet. + * @note The cookie files set by ecore_con_url_cookies_file_add() aren't loaded + * immediately, just when the request is started. Thus, if you ask to + * clear the session cookies, but has a file already set by that function, + * the session cookies will then be loaded and you will have old cookies + * set. In order to don't have any old session cookie set, you need to + * don't call ecore_con_url_cookies_file_add() ever on the @p url_con + * handler, and call this function to clear any session cookie set by a + * previous request on this handler. An easier way to don't use old + * session cookies is by using the function + * ecore_con_url_cookies_ignore_old_session_set(). + * + * @see ecore_con_url_cookies_clear() + * @see ecore_con_url_cookies_ignore_old_session_set() + */ +EAPI void ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con); +/** + * Adds a file to the list of files from which to load cookies. + * + * @param url_con Ecore_Con_Url instance which will be acted upon. + * @param file_name Name of the file that will be added to the list. + * + * Files must contain cookies defined according to two possible formats: + * + * @li HTTP-style header ("Set-Cookie: ..."). + * @li Netscape/Mozilla cookie data format. + * + * Cookies will only be @b read from this file. If you want to save cookies to a + * file, use ecore_con_url_cookies_jar_file_set(). Also notice that this + * function supports the both types of cookie file cited above, while + * ecore_con_url_cookies_jar_file_set() will save only in the Netscape/Mozilla's + * format. + * + * Please notice that the file will not be read immediately, but rather added + * to a list of files that will be loaded and parsed at a later time. + * + * @note This function will initialize the cookie engine if it has not been + * initialized yet. + * + * @see ecore_con_url_cookies_ignore_old_session_set() + * @see ecore_con_url_cookies_jar_file_set() + */ +EAPI void ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, + const char * const file_name); +/** + * Sets the name of the file to which all current cookies will be written when + * either cookies are flushed or Ecore_Con is shut down. + * + * @param url_con Ecore_Con_Url instance which will be acted upon. + * @param cookiejar_file File to which the cookies will be written. + * + * @return @c EINA_TRUE is the file name has been set successfully, + * @c EINA_FALSE otherwise. + * + * Cookies are written following Netscape/Mozilla's data format, also known as + * cookie-jar. + * + * Cookies will only be @b saved to this file. If you need to read cookies from + * a file, use ecore_con_url_cookies_file_add() instead. + * + * @note This function will initialize the cookie engine if it has not been + * initialized yet. + * + * @see ecore_con_url_cookies_jar_write() + */ +EAPI Eina_Bool ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, + const char * const cookiejar_file); +/** + * Writes all current cookies to the cookie jar immediately. + * + * @param url_con Ecore_Con_Url instance which will be acted upon. + * + * A cookie-jar file must have been previously set by + * @c ecore_con_url_jar_file_set, otherwise nothing will be done. + * + * @note This function will initialize the cookie engine if it has not been + * initialized yet. + * + * @see ecore_con_url_cookies_jar_file_set() + */ +EAPI void ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con); + +EAPI void ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con, + Eina_Bool verify); +EAPI int ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, + const char *ca_path); + +/** + * Set HTTP proxy to use. + * + * The parameter should be a char * to a zero terminated string holding + * the host name or dotted IP address. To specify port number in this string, + * append :[port] to the end of the host name. + * The proxy string may be prefixed with [protocol]:// since any such prefix + * will be ignored. + * The proxy's port number may optionally be specified with the separate option. + * If not specified, libcurl will default to using port 1080 for proxies. + * + * @param url_con Connection object that will use the proxy. + * @param proxy Porxy string or @c NULL to disable + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * @since 1.2 + */ +EAPI Eina_Bool ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy); + +/** + * Set zero terminated username to use for proxy. + * + * if socks protocol is used for proxy, protocol should be socks5 and above. + * + * @param url_con Connection object that will use the proxy. + * @param username Username string. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * + * @see ecore_con_url_proxy_set() + * + * @since 1.2 + */ +EAPI Eina_Bool ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username); + +/** + * Set zero terminated password to use for proxy. + * + * if socks protocol is used for proxy, protocol should be socks5 and above. + * + * @param url_con Connection object that will use the proxy. + * @param password Password string. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on error. + * + * @see ecore_con_url_proxy_set() + * + * @since 1.2 + */ +EAPI Eina_Bool ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password); + +/** + * Set timeout in seconds. + * + * the maximum time in seconds that you allow the ecore con url transfer + * operation to take. Normally, name lookups can take a considerable time + * and limiting operations to less than a few minutes risk aborting perfectly + * normal operations. + * + * @param url_con Connection object that will use the timeout. + * @param timeout time in seconds. + * + * @see ecore_con_url_cookies_jar_file_set() + * + * @since 1.2 + */ +EAPI void ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout); + +/** + * Get the returned HTTP STATUS code + * + * This is used to, at any time, try to return the status code for a transmission. + * @param url_con Connection object + * @return A valid HTTP STATUS code, or 0 on failure + * + * @since 1.2 + */ +EAPI int ecore_con_url_status_code_get(Ecore_Con_Url *url_con); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/ecore_con/Ecore_Con_Eet.h b/src/lib/ecore_con/Ecore_Con_Eet.h new file mode 100644 index 0000000000..bdf0d2d605 --- /dev/null +++ b/src/lib/ecore_con/Ecore_Con_Eet.h @@ -0,0 +1,73 @@ +#ifndef _ECORE_CON_EET +# define _ECORE_CON_EET + +#include +#include +#include + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# ifdef EFL_ECORE_CON_BUILD +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif +# 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 + +typedef struct _Ecore_Con_Eet Ecore_Con_Eet; +typedef struct _Ecore_Con_Reply Ecore_Con_Reply; + +typedef void (*Ecore_Con_Eet_Data_Cb)(void *data, Ecore_Con_Reply *reply, const char *protocol_name, void *value); +typedef void (*Ecore_Con_Eet_Raw_Data_Cb)(void *data, Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, size_t length); +typedef Eina_Bool (*Ecore_Con_Eet_Client_Cb)(void *data, Ecore_Con_Reply *reply, Ecore_Con_Client *conn); +typedef Eina_Bool (*Ecore_Con_Eet_Server_Cb)(void *data, Ecore_Con_Reply *reply, Ecore_Con_Server *conn); + +EAPI Ecore_Con_Eet *ecore_con_eet_server_new(Ecore_Con_Server *server); +EAPI Ecore_Con_Eet *ecore_con_eet_client_new(Ecore_Con_Server *server); +EAPI void ecore_con_eet_server_free(Ecore_Con_Eet *ece); + +EAPI void ecore_con_eet_register(Ecore_Con_Eet *ece, const char *name, Eet_Data_Descriptor *edd); + +EAPI void ecore_con_eet_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Data_Cb func, const void *data); +EAPI void ecore_con_eet_data_callback_del(Ecore_Con_Eet *ece, const char *name); + +EAPI void ecore_con_eet_raw_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Raw_Data_Cb func, const void *data); +EAPI void ecore_con_eet_raw_data_callback_del(Ecore_Con_Eet *ece, const char *name); + +EAPI void ecore_con_eet_client_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); +EAPI void ecore_con_eet_client_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); + +EAPI void ecore_con_eet_client_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); +EAPI void ecore_con_eet_client_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data); + +EAPI void ecore_con_eet_server_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); +EAPI void ecore_con_eet_server_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); + +EAPI void ecore_con_eet_server_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); +EAPI void ecore_con_eet_server_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data); + +EAPI void ecore_con_eet_data_set(Ecore_Con_Eet *ece, const void *data); +EAPI void *ecore_con_eet_data_get(Ecore_Con_Eet *ece); + +EAPI Ecore_Con_Eet *ecore_con_eet_reply(Ecore_Con_Reply *reply); +EAPI void ecore_con_eet_send(Ecore_Con_Reply *reply, const char *protocol_name, void *value); +EAPI void ecore_con_eet_raw_send(Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, unsigned int length); + +#endif diff --git a/src/lib/ecore_con/dns.c b/src/lib/ecore_con/dns.c new file mode 100644 index 0000000000..b50d306dc6 --- /dev/null +++ b/src/lib/ecore_con/dns.c @@ -0,0 +1,7878 @@ +/* ========================================================================== + * dns.c - Recursive, Reentrant DNS Resolver. + * -------------------------------------------------------------------------- + * Copyright (c) 2008, 2009, 2010 William Ahern + * + * 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 or substantial portions of the Software. + * + * 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 OR COPYRIGHT HOLDERS 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. + * ========================================================================== + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if !defined(__FreeBSD__) +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 +#endif + +#undef _BSD_SOURCE +#define _BSD_SOURCE + +#undef _DARWIN_C_SOURCE +#define _DARWIN_C_SOURCE + +#undef _NETBSD_SOURCE +#define _NETBSD_SOURCE +#endif + +#include /* offsetof() */ +#include /* uint32_t */ +#include /* malloc(3) realloc(3) free(3) rand(3) random(3) arc4random(3) */ +#include /* FILE fopen(3) fclose(3) getc(3) rewind(3) */ + +#include /* memcpy(3) strlen(3) memmove(3) memchr(3) memcmp(3) strchr(3) strsep(3) strcspn(3) */ +#include /* strcasecmp(3) strncasecmp(3) */ + +#include /* isspace(3) isdigit(3) */ + +#include /* time_t time(2) */ + +#include /* sig_atomic_t */ + +#include /* errno EINVAL ENOENT */ + +#undef NDEBUG +#include /* assert(3) */ + +#if _WIN32 +#include +#include +#else +#include /* FD_SETSIZE socklen_t */ +#include /* FD_ZERO FD_SET fd_set select(2) */ +#include /* AF_INET AF_INET6 AF_UNIX struct sockaddr struct sockaddr_in struct sockaddr_in6 socket(2) */ + +#if defined(AF_UNIX) +#include /* struct sockaddr_un */ +#endif + +#include /* F_SETFD F_GETFL F_SETFL O_NONBLOCK fcntl(2) */ + +#include /* gethostname(3) close(2) */ + +#include /* POLLIN POLLOUT */ + +#include /* struct sockaddr_in struct sockaddr_in6 */ + +#include /* inet_pton(3) inet_ntop(3) htons(3) ntohs(3) */ + +#include /* struct addrinfo */ +#endif + +#include "dns.h" + + +/* + * S T A N D A R D M A C R O S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef MIN +#define MIN(a, b) (((a) < (b))? (a) : (b)) +#endif + + +#ifndef MAX +#define MAX(a, b) (((a) > (b))? (a) : (b)) +#endif + + +#ifndef lengthof +#define lengthof(a) (sizeof (a) / sizeof (a)[0]) +#endif + +#ifndef endof +#define endof(a) (&(a)[lengthof((a))]) +#endif + + +/* + * D E B U G M A C R O S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +int dns_debug = 0; + +#if DNS_DEBUG + +#undef DNS_DEBUG +#define DNS_DEBUG dns_debug + +#define DNS_SAY_(fmt, ...) \ + do { if (DNS_DEBUG > 0) fprintf(stderr, fmt "%.1s", __func__, __LINE__, __VA_ARGS__); } while (0) +#define DNS_SAY(...) DNS_SAY_("@@ (%s:%d) " __VA_ARGS__, "\n") +#define DNS_HAI DNS_SAY("HAI") + +#define DNS_SHOW_(P, fmt, ...) do { \ + if (DNS_DEBUG > 1) { \ + fprintf(stderr, "@@ BEGIN * * * * * * * * * * * *\n"); \ + fprintf(stderr, "@@ " fmt "%.0s\n", __VA_ARGS__); \ + dns_p_dump((P), stderr); \ + fprintf(stderr, "@@ END * * * * * * * * * * * * *\n\n"); \ + } \ +} while (0) + +#define DNS_SHOW(...) DNS_SHOW_(__VA_ARGS__, "") + +#else /* !DNS_DEBUG */ + +#undef DNS_DEBUG +#define DNS_DEBUG 0 + +#define DNS_SAY(...) +#define DNS_HAI +#define DNS_SHOW(...) + +#endif /* DNS_DEBUG */ + + +/* + * V E R S I O N R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +const char *dns_vendor(void) { + return DNS_VENDOR; +} /* dns_vendor() */ + + +int dns_v_rel(void) { + return DNS_V_REL; +} /* dns_v_rel() */ + + +int dns_v_abi(void) { + return DNS_V_ABI; +} /* dns_v_abi() */ + + +int dns_v_api(void) { + return DNS_V_API; +} /* dns_v_api() */ + + +/* + * E R R O R R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#if _WIN32 + +#define DNS_EINTR WSAEINTR +#define DNS_EINPROGRESS WSAEINPROGRESS +#define DNS_EISCONN WSAEISCONN +#define DNS_EWOULDBLOCK WSAEWOULDBLOCK +#define DNS_EALREADY WSAEALREADY +#define DNS_EAGAIN EAGAIN +#define DNS_ETIMEDOUT WSAETIMEDOUT + +#define dns_syerr() ((int)GetLastError()) +#define dns_soerr() ((int)WSAGetLastError()) + +#else + +#define DNS_EINTR EINTR +#define DNS_EINPROGRESS EINPROGRESS +#define DNS_EISCONN EISCONN +#define DNS_EWOULDBLOCK EWOULDBLOCK +#define DNS_EALREADY EALREADY +#define DNS_EAGAIN EAGAIN +#define DNS_ETIMEDOUT ETIMEDOUT + +#define dns_syerr() errno +#define dns_soerr() errno + +#endif + + +const char *dns_strerror(int error) { + switch (error) { + case DNS_ENOBUFS: + return "DNS packet buffer too small"; + case DNS_EILLEGAL: + return "Illegal DNS RR name or data"; + case DNS_EORDER: + return "Attempt to push RR out of section order"; + case DNS_ESECTION: + return "Invalid section specified"; + case DNS_EUNKNOWN: + return "Unknown DNS error"; + default: + return strerror(error); + } /* switch() */ +} /* dns_strerror() */ + + +/* + * A T O M I C R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static unsigned dns_atomic_inc(dns_atomic_t *i) { + return (*i)++; +} /* dns_atomic_inc() */ + + +static unsigned dns_atomic_dec(dns_atomic_t *i) { + return (*i)--; +} /* dns_atomic_dec() */ + + +/* + * C R Y P T O R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * P R N G + */ + +#ifndef DNS_RANDOM +#if defined(HAVE_ARC4RANDOM) \ + || defined(__OpenBSD__) \ + || defined(__FreeBSD__) \ + || defined(__NetBSD__) \ + || defined(__APPLE__) +#define DNS_RANDOM arc4random +#elif __linux +#define DNS_RANDOM random +#else +#define DNS_RANDOM rand +#endif +#endif + +#define DNS_RANDOM_arc4random 1 +#define DNS_RANDOM_random 2 +#define DNS_RANDOM_rand 3 +#define DNS_RANDOM_RAND_bytes 4 + +#define DNS_RANDOM_OPENSSL (DNS_RANDOM_RAND_bytes == DNS_PP_XPASTE(DNS_RANDOM_, DNS_RANDOM)) + +#if DNS_RANDOM_OPENSSL +#include +#endif + +static unsigned dns_random_(void) { +#if DNS_RANDOM_OPENSSL + unsigned r; + + assert(1 == RAND_bytes((unsigned char *)&r, sizeof r)); + + return r; +#else + return DNS_RANDOM(); +#endif +} /* dns_random_() */ + +unsigned (*dns_random)(void) __attribute__((weak)) = &dns_random_; + + +/* + * P E R M U T A T I O N G E N E R A T O R + */ + +#define DNS_K_TEA_KEY_SIZE 16 +#define DNS_K_TEA_BLOCK_SIZE 8 +#define DNS_K_TEA_CYCLES 32 +#define DNS_K_TEA_MAGIC 0x9E3779B9U + +struct dns_k_tea { + uint32_t key[DNS_K_TEA_KEY_SIZE / sizeof (uint32_t)]; + unsigned cycles; +}; /* struct dns_k_tea */ + + +static void dns_k_tea_init(struct dns_k_tea *tea, uint32_t key[], unsigned cycles) { + memcpy(tea->key, key, sizeof tea->key); + + tea->cycles = (cycles)? cycles : DNS_K_TEA_CYCLES; +} /* dns_k_tea_init() */ + + +static void dns_k_tea_encrypt(struct dns_k_tea *tea, uint32_t v[], uint32_t *w) { + uint32_t y, z, sum, n; + + y = v[0]; + z = v[1]; + sum = 0; + + for (n = 0; n < tea->cycles; n++) { + sum += DNS_K_TEA_MAGIC; + y += ((z << 4) + tea->key[0]) ^ (z + sum) ^ ((z >> 5) + tea->key[1]); + z += ((y << 4) + tea->key[2]) ^ (y + sum) ^ ((y >> 5) + tea->key[3]); + } + + w[0] = y; + w[1] = z; + + return /* void */; +} /* dns_k_tea_encrypt() */ + + +/* + * Permutation generator, based on a Luby-Rackoff Feistel construction. + * + * Specifically, this is a generic balanced Feistel block cipher using TEA + * (another block cipher) as the pseudo-random function, F. At best it's as + * strong as F (TEA), notwithstanding the seeding. F could be AES, SHA-1, or + * perhaps Bernstein's Salsa20 core; I am naively trying to keep things + * simple. + * + * The generator can create a permutation of any set of numbers, as long as + * the size of the set is an even power of 2. This limitation arises either + * out of an inherent property of balanced Feistel constructions, or by my + * own ignorance. I'll tackle an unbalanced construction after I wrap my + * head around Schneier and Kelsey's paper. + * + * CAVEAT EMPTOR. IANAC. + */ +#define DNS_K_PERMUTOR_ROUNDS 8 + +struct dns_k_permutor { + unsigned stepi, length, limit; + unsigned shift, mask, rounds; + + struct dns_k_tea tea; +}; /* struct dns_k_permutor */ + + +static inline unsigned dns_k_permutor_powof(unsigned n) { + unsigned m, i = 0; + + for (m = 1; m < n; m <<= 1, i++) + ;; + + return i; +} /* dns_k_permutor_powof() */ + +static void dns_k_permutor_init(struct dns_k_permutor *p, unsigned low, unsigned high) { + uint32_t key[DNS_K_TEA_KEY_SIZE / sizeof (uint32_t)]; + unsigned width, i; + + p->stepi = 0; + + p->length = (high - low) + 1; + p->limit = high; + + width = dns_k_permutor_powof(p->length); + width += width % 2; + + p->shift = width / 2; + p->mask = (1U << p->shift) - 1; + p->rounds = DNS_K_PERMUTOR_ROUNDS; + + for (i = 0; i < lengthof(key); i++) + key[i] = dns_random(); + + dns_k_tea_init(&p->tea, key, 0); + + return /* void */; +} /* dns_k_permutor_init() */ + + +static unsigned dns_k_permutor_F(struct dns_k_permutor *p, unsigned k, unsigned x) { + uint32_t in[DNS_K_TEA_BLOCK_SIZE / sizeof (uint32_t)], out[DNS_K_TEA_BLOCK_SIZE / sizeof (uint32_t)]; + + memset(in, '\0', sizeof in); + + in[0] = k; + in[1] = x; + + dns_k_tea_encrypt(&p->tea, in, out); + + return p->mask & out[0]; +} /* dns_k_permutor_F() */ + + +static unsigned dns_k_permutor_E(struct dns_k_permutor *p, unsigned n) { + unsigned l[2], r[2]; + unsigned i; + + i = 0; + l[i] = p->mask & (n >> p->shift); + r[i] = p->mask & (n >> 0); + + do { + l[(i + 1) % 2] = r[i % 2]; + r[(i + 1) % 2] = l[i % 2] ^ dns_k_permutor_F(p, i, r[i % 2]); + + i++; + } while (i < p->rounds - 1); + + return ((l[i % 2] & p->mask) << p->shift) | ((r[i % 2] & p->mask) << 0); +} /* dns_k_permutor_E() */ + +static unsigned dns_k_permutor_step(struct dns_k_permutor *p) { + unsigned n; + + do { + n = dns_k_permutor_E(p, p->stepi++); + } while (n >= p->length); + + return n + (p->limit + 1 - p->length); +} /* dns_k_permutor_step() */ + + +/* + * Simple permutation box. Useful for shuffling rrsets from an iterator. + * Uses AES s-box to provide good diffusion. + * + * Seems to pass muster under runs test. + * + * $ for i in 0 1 2 3 4 5 6 7 8 9; do ./dns shuffle-16 > /tmp/out; done + * $ R -q -f /dev/stdin 2>/dev/null <<-EOF | awk '/p-value/{ print $8 }' + * library(lawstat) + * runs.test(scan(file="/tmp/out")) + * EOF + */ +static unsigned short dns_k_shuffle16(unsigned short n, unsigned s) { + static const unsigned char sbox[256] = + { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; + unsigned char a, b; + unsigned i; + + a = 0xff & (n >> 0); + b = 0xff & (n >> 8); + + for (i = 0; i < 4; i++) { + a ^= 0xff & s; + a = sbox[a] ^ b; + b = sbox[b] ^ a; + s >>= 8; + } + + return ((0xff00 & (a << 8)) | (0x00ff & (b << 0))); +} /* dns_k_shuffle16() */ + + +/* + * U T I L I T Y R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Monotonic Time + * + */ +static time_t dns_now(void) { + /* XXX: Assumes sizeof (time_t) <= sizeof (sig_atomic_t) */ + static volatile sig_atomic_t last, tick; + volatile sig_atomic_t tmp_last, tmp_tick; + time_t now; + + time(&now); + + tmp_last = last; + + if (now > tmp_last) { + tmp_tick = tick; + tmp_tick += now - tmp_last; + tick = tmp_tick; + } + + last = now; + + return tick; +} /* dns_now() */ + +static time_t dns_elapsed(time_t from) { + time_t now = dns_now(); + + return (now > from)? now - from : 0; +} /* dns_elpased() */ + + +static size_t dns_af_len(int af) { + static const size_t table[AF_MAX] = { + [AF_INET6] = sizeof (struct sockaddr_in6), + [AF_INET] = sizeof (struct sockaddr_in), +#if defined(AF_UNIX) && !defined(_WIN32) + [AF_UNIX] = sizeof (struct sockaddr_un), +#endif + }; + + return table[af]; +} /* dns_af_len() */ + +#define dns_sa_len(sa) dns_af_len(dns_sa_family(sa)) + + +#define DNS_SA_NOPORT &dns_sa_noport +static unsigned short dns_sa_noport; + +unsigned short *dns_sa_port(int af, void *sa) { + switch (af) { + case AF_INET6: + return &((struct sockaddr_in6 *)sa)->sin6_port; + case AF_INET: + return &((struct sockaddr_in *)sa)->sin_port; + default: + return DNS_SA_NOPORT; + } +} /* dns_sa_port() */ + + +void *dns_sa_addr(int af, void *sa) { + switch (af) { + case AF_INET6: + return &((struct sockaddr_in6 *)sa)->sin6_addr; + case AF_INET: + return &((struct sockaddr_in *)sa)->sin_addr; + default: + return 0; + } +} /* dns_sa_addr() */ + + +#if _WIN32 +static int dns_inet_pton(int af, const void *src, void *dst) { + union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } u; + + u.sin.sin_family = af; + + if (0 != WSAStringToAddressA((void *)src, af, (void *)0, (struct sockaddr *)&u, &(int){ sizeof u })) + return -1; + + switch (af) { + case AF_INET6: + *(struct in6_addr *)dst = u.sin6.sin6_addr; + + return 1; + case AF_INET: + *(struct in_addr *)dst = u.sin.sin_addr; + + return 1; + default: + return 0; + } +} /* dns_inet_pton() */ + +const char *dns_inet_ntop(int af, const void *src, void *dst, unsigned long lim) { + union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } u; + + /* NOTE: WSAAddressToString will print .sin_port unless zeroed. */ + memset(&u, 0, sizeof u); + + u.sin.sin_family = af; + + switch (af) { + case AF_INET6: + u.sin6.sin6_addr = *(struct in6_addr *)src; + break; + case AF_INET: + u.sin.sin_addr = *(struct in_addr *)src; + + break; + default: + return 0; + } + + if (0 != WSAAddressToStringA((struct sockaddr *)&u, dns_sa_len(&u), (void *)0, dst, &lim)) + return 0; + + return dst; +} /* dns_inet_ntop() */ +#endif + + +size_t dns_strlcpy(char *dst, const char *src, size_t lim) { + char *d = dst; + char *e = &dst[lim]; + const char *s = src; + + if (d < e) { + do { + if ('\0' == (*d++ = *s++)) + return s - src - 1; + } while (d < e); + + d[-1] = '\0'; + } + + while (*s++ != '\0') + ;; + + return s - src - 1; +} /* dns_strlcpy() */ + + +size_t dns_strlcat(char *dst, const char *src, size_t lim) { + char *d = memchr(dst, '\0', lim); + char *e = &dst[lim]; + const char *s = src; + const char *p; + + if (d && d < e) { + do { + if ('\0' == (*d++ = *s++)) + return d - dst - 1; + } while (d < e); + + d[-1] = '\0'; + } + + p = s; + + while (*s++ != '\0') + ;; + + return lim + (s - p - 1); +} /* dns_strlcat() */ + + +#if defined(_WIN32) || defined(__SUNPRO_C) + +static char *dns_strsep(char **sp, const char *delim) { + char *p; + + if (!(p = *sp)) + return 0; + + *sp += strcspn(p, delim); + + if (**sp != '\0') { + **sp = '\0'; + ++*sp; + } else + *sp = NULL; + + return p; +} /* dns_strsep() */ + +#else +#define dns_strsep(...) strsep(__VA_ARGS__) +#endif + + +#if _WIN32 +#define strcasecmp(...) _stricmp(__VA_ARGS__) +#define strncasecmp(...) _strnicmp(__VA_ARGS__) +#endif + + +static int dns_poll(int fd, short events, int timeout) { + fd_set rset, wset; + + if (!events) + return 0; + + assert(fd >= 0 && fd < FD_SETSIZE); + + FD_ZERO(&rset); + FD_ZERO(&wset); + + if (events & DNS_POLLIN) + FD_SET(fd, &rset); + + if (events & DNS_POLLOUT) + FD_SET(fd, &wset); + + select(fd + 1, &rset, &wset, 0, (timeout >= 0)? &(struct timeval){ timeout, 0 } : NULL); + + return 0; +} /* dns_poll() */ + + +/* + * P A C K E T R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +unsigned dns_p_count(struct dns_packet *P, enum dns_section section) { + unsigned count; + + switch (section) { + case DNS_S_QD: + return ntohs(dns_header(P)->qdcount); + case DNS_S_AN: + return ntohs(dns_header(P)->ancount); + case DNS_S_NS: + return ntohs(dns_header(P)->nscount); + case DNS_S_AR: + return ntohs(dns_header(P)->arcount); + default: + count = 0; + + if (section & DNS_S_QD) + count += ntohs(dns_header(P)->qdcount); + if (section & DNS_S_AN) + count += ntohs(dns_header(P)->ancount); + if (section & DNS_S_NS) + count += ntohs(dns_header(P)->nscount); + if (section & DNS_S_AR) + count += ntohs(dns_header(P)->arcount); + + return count; + } +} /* dns_p_count() */ + + +struct dns_packet *dns_p_init(struct dns_packet *P, size_t size) { + if (!P) + return 0; + + assert(size >= offsetof(struct dns_packet, data) + 12); + + memset(P, 0, sizeof *P); + P->size = size - offsetof(struct dns_packet, data); + P->end = 12; + + memset(P->data, '\0', 12); + + return P; +} /* dns_p_init() */ + + +static unsigned short dns_p_qend(struct dns_packet *P) { + unsigned short qend = 12; + unsigned i, count = dns_p_count(P, DNS_S_QD); + + for (i = 0; i < count && qend < P->end; i++) { + if (P->end == (qend = dns_d_skip(qend, P))) + goto invalid; + + if (P->end - qend < 4) + goto invalid; + + qend += 4; + } + + return MIN(qend, P->end); +invalid: + return P->end; +} /* dns_p_qend() */ + + +struct dns_packet *dns_p_make(size_t len, int *error) { + struct dns_packet *P; + size_t size = dns_p_calcsize(len); + + if (!(P = dns_p_init(malloc(size), size))) + *error = dns_syerr(); + + return P; +} /* dns_p_make() */ + + +int dns_p_grow(struct dns_packet **P) { + struct dns_packet *tmp; + size_t size; + int error; + + if (!*P) { + if (!(*P = dns_p_make(DNS_P_QBUFSIZ, &error))) + return error; + + return 0; + } + + size = dns_p_sizeof(*P); + size |= size >> 1; + size |= size >> 2; + size |= size >> 4; + size |= size >> 8; + size++; + + if (size > 65536) + return DNS_ENOBUFS; + + if (!(tmp = realloc(*P, dns_p_calcsize(size)))) + return dns_syerr(); + + tmp->size = size; + *P = tmp; + + return 0; +} /* dns_p_grow() */ + + +struct dns_packet *dns_p_copy(struct dns_packet *P, const struct dns_packet *P0) { + if (!P) + return 0; + + P->end = MIN(P->size, P0->end); + + memcpy(P->data, P0->data, P->end); + + return P; +} /* dns_p_copy() */ + + +struct dns_packet *dns_p_merge(struct dns_packet *A, enum dns_section Amask, struct dns_packet *B, enum dns_section Bmask, int *error_) { + size_t bufsiz = MIN(65535, ((A)? A->end : 0) + ((B)? B->end : 0)); + struct dns_packet *M; + enum dns_section section; + struct dns_rr rr, mr; + int error, copy; + + if (!A && B) { + A = B; + Amask = Bmask; + B = 0; + } + +merge: + if (!(M = dns_p_make(bufsiz, &error))) + goto error; + + for (section = DNS_S_QD; (DNS_S_ALL & section); section <<= 1) { + if (A && (section & Amask)) { + dns_rr_foreach(&rr, A, .section = section) { + if ((error = dns_rr_copy(M, &rr, A))) + goto error; + } + } + + if (B && (section & Bmask)) { + dns_rr_foreach(&rr, B, .section = section) { + copy = 1; + + dns_rr_foreach(&mr, M, .type = rr.type, .section = DNS_S_ALL) { + if (!(copy = dns_rr_cmp(&rr, B, &mr, M))) + break; + } + + if (copy && (error = dns_rr_copy(M, &rr, B))) + goto error; + } + } + } + + return M; +error: + free(M); M = 0; + + if (error == DNS_ENOBUFS && bufsiz < 65535) { + bufsiz = MIN(65535, bufsiz * 2); + + goto merge; + } + + *error_ = error; + + return 0; +} /* dns_p_merge() */ + + +static unsigned short dns_l_skip(unsigned short, const unsigned char *, size_t); + +void dns_p_dictadd(struct dns_packet *P, unsigned short dn) { + unsigned short lp, lptr, i; + + lp = dn; + + while (lp < P->end) { + if (0xc0 == (0xc0 & P->data[lp]) && P->end - lp >= 2 && lp != dn) { + lptr = ((0x3f & P->data[lp + 0]) << 8) + | ((0xff & P->data[lp + 1]) << 0); + + for (i = 0; i < lengthof(P->dict) && P->dict[i]; i++) { + if (P->dict[i] == lptr) { + P->dict[i] = dn; + + return; + } + } + } + + lp = dns_l_skip(lp, P->data, P->end); + } + + for (i = 0; i < lengthof(P->dict); i++) { + if (!P->dict[i]) { + P->dict[i] = dn; + + break; + } + } +} /* dns_p_dictadd() */ + + +int dns_p_push(struct dns_packet *P, enum dns_section section, const void *dn, size_t dnlen, enum dns_type type, enum dns_class class, unsigned ttl, const void *any) { + size_t end = P->end; + int error; + + if ((error = dns_d_push(P, dn, dnlen))) + goto error; + + if (P->size - P->end < 4) + goto nobufs; + + P->data[P->end++] = 0xff & (type >> 8); + P->data[P->end++] = 0xff & (type >> 0); + + P->data[P->end++] = 0xff & (class >> 8); + P->data[P->end++] = 0xff & (class >> 0); + + if (section == DNS_S_QD) + goto update; + + if (P->size - P->end < 6) + goto nobufs; + + P->data[P->end++] = 0x7f & (ttl >> 24); + P->data[P->end++] = 0xff & (ttl >> 16); + P->data[P->end++] = 0xff & (ttl >> 8); + P->data[P->end++] = 0xff & (ttl >> 0); + + if ((error = dns_any_push(P, (union dns_any *)any, type))) + goto error; + +update: + switch (section) { + case DNS_S_QD: + if (dns_p_count(P, DNS_S_AN|DNS_S_NS|DNS_S_AR)) + goto order; + + if (!P->qd.base && (error = dns_p_study(P))) + goto error; + + dns_header(P)->qdcount = htons(ntohs(dns_header(P)->qdcount) + 1); + + P->qd.end = P->end; + P->an.base = P->end; + P->an.end = P->end; + P->ns.base = P->end; + P->ns.end = P->end; + P->ar.base = P->end; + P->ar.end = P->end; + + break; + case DNS_S_AN: + if (dns_p_count(P, DNS_S_NS|DNS_S_AR)) + goto order; + + if (!P->an.base && (error = dns_p_study(P))) + goto error; + + dns_header(P)->ancount = htons(ntohs(dns_header(P)->ancount) + 1); + + P->an.end = P->end; + P->ns.base = P->end; + P->ns.end = P->end; + P->ar.base = P->end; + P->ar.end = P->end; + + break; + case DNS_S_NS: + if (dns_p_count(P, DNS_S_AR)) + goto order; + + if (!P->ns.base && (error = dns_p_study(P))) + goto error; + + dns_header(P)->nscount = htons(ntohs(dns_header(P)->nscount) + 1); + + P->ns.end = P->end; + P->ar.base = P->end; + P->ar.end = P->end; + + break; + case DNS_S_AR: + if (!P->ar.base && (error = dns_p_study(P))) + goto error; + + dns_header(P)->arcount = htons(ntohs(dns_header(P)->arcount) + 1); + + P->ar.end = P->end; + + break; + default: + error = DNS_ESECTION; + + goto error; + } /* switch() */ + + return 0; +nobufs: + error = DNS_ENOBUFS; + + goto error; +order: + error = DNS_EORDER; + + goto error; +error: + P->end = end; + + return error; +} /* dns_p_push() */ + + +static void dns_p_dump3(struct dns_packet *P, struct dns_rr_i *I, FILE *fp) { + enum dns_section section; + struct dns_rr rr; + int error; + union dns_any any; + char pretty[sizeof any * 2]; + size_t len; + + fputs(";; [HEADER]\n", fp); + fprintf(fp, ";; qr : %s(%d)\n", (dns_header(P)->qr)? "RESPONSE" : "QUERY", dns_header(P)->qr); + fprintf(fp, ";; opcode : %s(%d)\n", dns_stropcode(dns_header(P)->opcode), dns_header(P)->opcode); + fprintf(fp, ";; aa : %s(%d)\n", (dns_header(P)->aa)? "AUTHORITATIVE" : "NON-AUTHORITATIVE", dns_header(P)->aa); + fprintf(fp, ";; tc : %s(%d)\n", (dns_header(P)->tc)? "TRUNCATED" : "NOT-TRUNCATED", dns_header(P)->tc); + fprintf(fp, ";; rd : %s(%d)\n", (dns_header(P)->rd)? "RECURSION-DESIRED" : "RECURSION-NOT-DESIRED", dns_header(P)->rd); + fprintf(fp, ";; ra : %s(%d)\n", (dns_header(P)->ra)? "RECURSION-ALLOWED" : "RECURSION-NOT-ALLOWED", dns_header(P)->ra); + fprintf(fp, ";; rcode : %s(%d)\n", dns_strrcode(dns_header(P)->rcode), dns_header(P)->rcode); + + section = 0; + + while (dns_rr_grep(&rr, 1, I, P, &error)) { + if (section != rr.section) + fprintf(fp, "\n;; [%s:%d]\n", dns_strsection(rr.section), dns_p_count(P, rr.section)); + + if ((len = dns_rr_print(pretty, sizeof pretty, &rr, P, &error))) + fprintf(fp, "%s\n", pretty); + + section = rr.section; + } +} /* dns_p_dump3() */ + + +void dns_p_dump(struct dns_packet *P, FILE *fp) { + dns_p_dump3(P, dns_rr_i_new(P, .section = 0), fp); +} /* dns_p_dump() */ + + +static void dns_s_unstudy(struct dns_s_memo *m) + { m->base = 0; m->end = 0; } + +static void dns_p_unstudy(struct dns_packet *P) { + dns_s_unstudy(&P->qd); + dns_s_unstudy(&P->an); + dns_s_unstudy(&P->ns); + dns_s_unstudy(&P->ar); +} /* dns_p_unstudy() */ + +static int dns_s_study(struct dns_s_memo *m, enum dns_section section, unsigned base, struct dns_packet *P) { + unsigned short count, rp; + + count = dns_p_count(P, section); + + for (rp = base; count && rp < P->end; count--) + rp = dns_rr_skip(rp, P); + + m->base = base; + m->end = rp; + + return 0; +} /* dns_s_study() */ + +int dns_p_study(struct dns_packet *P) { + int error; + + if ((error = dns_s_study(&P->qd, DNS_S_QD, 12, P))) + goto error; + + if ((error = dns_s_study(&P->an, DNS_S_AN, P->qd.end, P))) + goto error; + + if ((error = dns_s_study(&P->ns, DNS_S_NS, P->an.end, P))) + goto error; + + if ((error = dns_s_study(&P->ar, DNS_S_AR, P->ns.end, P))) + goto error; + + return 0; +error: + dns_p_unstudy(P); + + return error; +} /* dns_p_study() */ + + +/* + * D O M A I N N A M E R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef DNS_D_MAXPTRS +#define DNS_D_MAXPTRS 127 /* Arbitrary; possible, valid depth is something like packet size / 2 + fudge. */ +#endif + +static size_t dns_l_expand(unsigned char *dst, size_t lim, unsigned short src, unsigned short *nxt, const unsigned char *data, size_t end) { + unsigned short len; + unsigned nptrs = 0; + +retry: + if (src >= end) + goto invalid; + + switch (0x03 & (data[src] >> 6)) { + case 0x00: + len = (0x3f & (data[src++])); + + if (end - src < len) + goto invalid; + + if (lim > 0) { + memcpy(dst, &data[src], MIN(lim, len)); + + dst[MIN(lim - 1, len)] = '\0'; + } + + *nxt = src + len; + + return len; + case 0x01: + goto invalid; + case 0x02: + goto invalid; + case 0x03: + if (++nptrs > DNS_D_MAXPTRS) + goto invalid; + + if (end - src < 2) + goto invalid; + + src = ((0x3f & data[src + 0]) << 8) + | ((0xff & data[src + 1]) << 0); + + goto retry; + } /* switch() */ + + /* NOT REACHED */ +invalid: + *nxt = end; + + return 0; +} /* dns_l_expand() */ + + +static unsigned short dns_l_skip(unsigned short src, const unsigned char *data, size_t end) { + unsigned short len; + + if (src >= end) + goto invalid; + + switch (0x03 & (data[src] >> 6)) { + case 0x00: + len = (0x3f & (data[src++])); + + if (end - src < len) + goto invalid; + + return (len)? src + len : end; + case 0x01: + goto invalid; + case 0x02: + goto invalid; + case 0x03: + return end; + } /* switch() */ + + /* NOT REACHED */ +invalid: + return end; +} /* dns_l_skip() */ + + +size_t dns_d_trim(void *dst_, size_t lim, const void *src_, size_t len, int flags) { + unsigned char *dst = dst_; + const unsigned char *src = src_; + size_t dp = 0, sp = 0; + int lc; + + /* trim any leading dot(s) */ + while (sp < len && src[sp] == '.') + sp++; + + for (lc = 0; sp < len; lc = src[sp]) { + if (dp < lim) + dst[dp] = src[sp]; + + sp++; + dp++; + + /* trim extra dot(s) */ + while (sp < len && src[sp] == '.') + sp++; + } + + if ((flags & DNS_D_ANCHOR) && lc != '.') { + if (dp < lim) + dst[dp] = '.'; + + dp++; + } + + if (lim > 0) + dst[MIN(dp, lim - 1)] = '\0'; + + return dp; +} /* dns_d_trim() */ + + +char *dns_d_init(void *dst, size_t lim, const void *src, size_t len, int flags) { + if (flags & DNS_D_TRIM) { + dns_d_trim(dst, lim, src, len, flags); + } if (flags & DNS_D_ANCHOR) { + dns_d_anchor(dst, lim, src, len); + } else { + memmove(dst, src, MIN(lim, len)); + + if (lim > 0) + ((char *)dst)[MIN(len, lim - 1)] = '\0'; + } + + return dst; +} /* dns_d_init() */ + + +size_t dns_d_anchor(void *dst, size_t lim, const void *src, size_t len) { + if (len == 0) + return 0; + + memmove(dst, src, MIN(lim, len)); + + if (((const char *)src)[len - 1] != '.') { + if (len < lim) + ((char *)dst)[len] = '.'; + len++; + } + + if (lim > 0) + ((char *)dst)[MIN(lim - 1, len)] = '\0'; + + return len; +} /* dns_d_anchor() */ + + +size_t dns_d_cleave(void *dst, size_t lim, const void *src, size_t len) { + const char *dot; + + /* XXX: Skip any leading dot. Handles cleaving root ".". */ + if (len == 0 || !(dot = memchr((const char *)src + 1, '.', len - 1))) + return 0; + + len -= dot - (const char *)src; + + /* XXX: Unless root, skip the label's trailing dot. */ + if (len > 1) { + src = ++dot; + len--; + } else + src = dot; + + memmove(dst, src, MIN(lim, len)); + + if (lim > 0) + ((char *)dst)[MIN(lim - 1, len)] = '\0'; + + return len; +} /* dns_d_cleave() */ + + +size_t dns_d_comp(void *dst_, size_t lim, const void *src_, size_t len, struct dns_packet *P, int *error EINA_UNUSED) { + struct { unsigned char *b; size_t p, x; } dst, src; + unsigned char ch = '.'; + + dst.b = dst_; + dst.p = 0; + dst.x = 1; + + src.b = (unsigned char *)src_; + src.p = 0; + src.x = 0; + + while (src.x < len) { + ch = src.b[src.x]; + + if (ch == '.') { + if (dst.p < lim) + dst.b[dst.p] = (0x3f & (src.x - src.p)); + + dst.p = dst.x++; + src.p = ++src.x; + } else { + if (dst.x < lim) + dst.b[dst.x] = ch; + + dst.x++; + src.x++; + } + } /* while() */ + + if (src.x > src.p) { + if (dst.p < lim) + dst.b[dst.p] = (0x3f & (src.x - src.p)); + + dst.p = dst.x; + } + + if (dst.p > 1) { + if (dst.p < lim) + dst.b[dst.p] = 0x00; + + dst.p++; + } + +#if 1 + if (dst.p < lim) { + struct { unsigned char label[DNS_D_MAXLABEL + 1]; size_t len; unsigned short p, x, y; } a, b; + unsigned i; + + a.p = 0; + + while ((a.len = dns_l_expand(a.label, sizeof a.label, a.p, &a.x, dst.b, lim))) { + for (i = 0; i < lengthof(P->dict) && P->dict[i]; i++) { + b.p = P->dict[i]; + + while ((b.len = dns_l_expand(b.label, sizeof b.label, b.p, &b.x, P->data, P->end))) { + a.y = a.x; + b.y = b.x; + + while (a.len && b.len && 0 == strcasecmp((char *)a.label, (char *)b.label)) { + a.len = dns_l_expand(a.label, sizeof a.label, a.y, &a.y, dst.b, lim); + b.len = dns_l_expand(b.label, sizeof b.label, b.y, &b.y, P->data, P->end); + } + + if (a.len == 0 && b.len == 0 && b.p <= 0x3fff) { + dst.b[a.p++] = 0xc0 + | (0x3f & (b.p >> 8)); + dst.b[a.p++] = (0xff & (b.p >> 0)); + + return a.p; + } + + b.p = b.x; + } /* while() */ + } /* for() */ + + a.p = a.x; + } /* while() */ + } /* if () */ +#endif + + return dst.p; +} /* dns_d_comp() */ + + +unsigned short dns_d_skip(unsigned short src, struct dns_packet *P) { + unsigned short len; + + while (src < P->end) { + switch (0x03 & (P->data[src] >> 6)) { + case 0x00: /* FOLLOWS */ + len = (0x3f & P->data[src++]); + + if (0 == len) { +/* success ==> */ return src; + } else if (P->end - src > len) { + src += len; + + break; + } else + goto invalid; + + /* NOT REACHED */ + case 0x01: /* RESERVED */ + goto invalid; + case 0x02: /* RESERVED */ + goto invalid; + case 0x03: /* POINTER */ + if (P->end - src < 2) + goto invalid; + + src += 2; + +/* success ==> */ return src; + } /* switch() */ + } /* while() */ + +invalid: +//assert(0); + return P->end; +} /* dns_d_skip() */ + + +#include + +size_t dns_d_expand(void *dst, size_t lim, unsigned short src, struct dns_packet *P, int *error) { + size_t dstp = 0; + unsigned nptrs = 0; + unsigned char len; + + while (src < P->end) { + switch ((0x03 & (P->data[src] >> 6))) { + case 0x00: /* FOLLOWS */ + len = (0x3f & P->data[src]); + + if (0 == len) { + if (dstp == 0) { + if (dstp < lim) + ((unsigned char *)dst)[dstp] = '.'; + + dstp++; + } + + /* NUL terminate */ + if (lim > 0) + ((unsigned char *)dst)[MIN(dstp, lim - 1)] = '\0'; + +/* success ==> */ return dstp; + } + + src++; + + if (P->end - src < len) + goto toolong; + + if (dstp < lim) + memcpy(&((unsigned char *)dst)[dstp], &P->data[src], MIN(len, lim - dstp)); + + src += len; + dstp += len; + + if (dstp < lim) + ((unsigned char *)dst)[dstp] = '.'; + + dstp++; + + nptrs = 0; + + continue; + case 0x01: /* RESERVED */ + goto reserved; + case 0x02: /* RESERVED */ + goto reserved; + case 0x03: /* POINTER */ + if (++nptrs > DNS_D_MAXPTRS) + goto toolong; + + if (P->end - src < 2) + goto toolong; + + src = ((0x3f & P->data[src + 0]) << 8) + | ((0xff & P->data[src + 1]) << 0); + + continue; + } /* switch() */ + } /* while() */ + +toolong: + *error = DNS_EILLEGAL; + + if (lim > 0) + ((unsigned char *)dst)[MIN(dstp, lim - 1)] = '\0'; + + return 0; +reserved: + *error = DNS_EILLEGAL; + + if (lim > 0) + ((unsigned char *)dst)[MIN(dstp, lim - 1)] = '\0'; + + return 0; +} /* dns_d_expand() */ + + +int dns_d_push(struct dns_packet *P, const void *dn, size_t len) { + size_t lim = P->size - P->end; + unsigned dp = P->end; + int error; + + len = dns_d_comp(&P->data[dp], lim, dn, len, P, &error); + + if (len == 0) + return error; + if (len > lim) + return DNS_ENOBUFS; + + P->end += len; + + dns_p_dictadd(P, dp); + + return 0; +} /* dns_d_push() */ + + +size_t dns_d_cname(void *dst, size_t lim, const void *dn, size_t len, struct dns_packet *P, int *error_) { + char host[DNS_D_MAXNAME + 1]; + struct dns_rr_i i; + struct dns_rr rr; + unsigned depth; + int error; + + if (sizeof host <= dns_d_anchor(host, sizeof host, dn, len)) + { error = ENAMETOOLONG; goto error; } + + for (depth = 0; depth < 7; depth++) { + dns_rr_i_init(memset(&i, 0, sizeof i), P); + + i.section = DNS_S_ALL & ~DNS_S_QD; + i.name = host; + i.type = DNS_T_CNAME; + + if (!dns_rr_grep(&rr, 1, &i, P, &error)) + break; + + if ((error = dns_cname_parse((struct dns_cname *)host, &rr, P))) + goto error; + } + + return dns_strlcpy(dst, host, lim); +error: + *error_ = error; + + return 0; +} /* dns_d_cname() */ + + +/* + * R E S O U R C E R E C O R D R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +int dns_rr_copy(struct dns_packet *P, struct dns_rr *rr, struct dns_packet *Q) { + unsigned char dn[DNS_D_MAXNAME + 1]; + union dns_any any; + size_t len; + int error; + + if (!(len = dns_d_expand(dn, sizeof dn, rr->dn.p, Q, &error))) + return error; + else if (len >= sizeof dn) + return DNS_EILLEGAL; + + if (rr->section != DNS_S_QD && (error = dns_any_parse(dns_any_init(&any, sizeof any), rr, Q))) + return error; + + return dns_p_push(P, rr->section, dn, len, rr->type, rr->class, rr->ttl, &any); +} /* dns_rr_copy() */ + + +int dns_rr_parse(struct dns_rr *rr, unsigned short src, struct dns_packet *P) { + unsigned short p = src; + + if (src >= P->end) + goto invalid; + + rr->dn.p = p; + rr->dn.len = (p = dns_d_skip(p, P)) - rr->dn.p; + + if (P->end - p < 4) + goto invalid; + + rr->type = ((0xff & P->data[p + 0]) << 8) + | ((0xff & P->data[p + 1]) << 0); + + rr->class = ((0xff & P->data[p + 2]) << 8) + | ((0xff & P->data[p + 3]) << 0); + + p += 4; + + if (src < dns_p_qend(P)) { + rr->section = DNS_S_QUESTION; + + rr->ttl = 0; + rr->rd.p = 0; + rr->rd.len = 0; + + return 0; + } + + if (P->end - p < 4) + goto invalid; + + rr->ttl = ((0x7f & P->data[p + 0]) << 24) + | ((0xff & P->data[p + 1]) << 16) + | ((0xff & P->data[p + 2]) << 8) + | ((0xff & P->data[p + 3]) << 0); + + p += 4; + + if (P->end - p < 2) + goto invalid; + + rr->rd.len = ((0xff & P->data[p + 0]) << 8) + | ((0xff & P->data[p + 1]) << 0); + rr->rd.p = p + 2; + + p += 2; + + if (P->end - p < rr->rd.len) + goto invalid; + + return 0; +invalid: +//assert(0); + return DNS_EILLEGAL; +} /* dns_rr_parse() */ + + +static unsigned short dns_rr_len(const unsigned short src, struct dns_packet *P) { + unsigned short rp, rdlen; + + rp = dns_d_skip(src, P); + + if (P->end - rp < 4) + return P->end - src; + + rp += 4; /* TYPE, CLASS */ + + if (rp <= dns_p_qend(P)) + return rp - src; + + if (P->end - rp < 6) + return P->end - src; + + rp += 6; /* TTL, RDLEN */ + + rdlen = ((0xff & P->data[rp - 2]) << 8) + | ((0xff & P->data[rp - 1]) << 0); + + if (P->end - rp < rdlen) + return P->end - src; + + rp += rdlen; + + return rp - src; +} /* dns_rr_len() */ + + +unsigned short dns_rr_skip(unsigned short src, struct dns_packet *P) { + return src + dns_rr_len(src, P); +} /* dns_rr_skip() */ + + +static enum dns_section dns_rr_section(unsigned short src, struct dns_packet *P) { + enum dns_section section; + unsigned count, ind; + unsigned short rp; + + if (src >= P->qd.base && src < P->qd.end) + return DNS_S_QD; + if (src >= P->an.base && src < P->an.end) + return DNS_S_AN; + if (src >= P->ns.base && src < P->ns.end) + return DNS_S_NS; + if (src >= P->ar.base && src < P->ar.end) + return DNS_S_AR; + + /* NOTE: Possibly bad memoization. Try it the hard-way. */ + + for (rp = 12, ind = 0; rp < src && rp < P->end; ind++) + rp = dns_rr_skip(rp, P); + + section = DNS_S_QD; + count = dns_p_count(P, section); + + while (ind >= count && section <= DNS_S_AR) { + section <<= 1; + count += dns_p_count(P, section); + } + + return DNS_S_ALL & section; +} /* dns_rr_section() */ + + +static enum dns_type dns_rr_type(unsigned short src, struct dns_packet *P) { + struct dns_rr rr; + int error; + + if ((error = dns_rr_parse(&rr, src, P))) + return 0; + + return rr.type; +} /* dns_rr_type() */ + + +int dns_rr_cmp(struct dns_rr *r0, struct dns_packet *P0, struct dns_rr *r1, struct dns_packet *P1) { + char host0[DNS_D_MAXNAME + 1], host1[DNS_D_MAXNAME + 1]; + union dns_any any0, any1; + int cmp, error; + size_t len; + + if ((cmp = r0->type - r1->type)) + return cmp; + + if ((cmp = r0->class - r1->class)) + return cmp; + + /* + * FIXME: Do label-by-label comparison to handle illegally long names? + */ + + if (!(len = dns_d_expand(host0, sizeof host0, r0->dn.p, P0, &error)) + || len >= sizeof host0) + return -1; + + if (!(len = dns_d_expand(host1, sizeof host1, r1->dn.p, P1, &error)) + || len >= sizeof host1) + return 1; + + if ((cmp = strcasecmp(host0, host1))) + return cmp; + + if (DNS_S_QD & (r0->section | r1->section)) { + if (r0->section == r1->section) + return 0; + + return (r0->section == DNS_S_QD)? -1 : 1; + } + + if ((error = dns_any_parse(&any0, r0, P0))) + return -1; + + if ((error = dns_any_parse(&any1, r1, P1))) + return 1; + + return dns_any_cmp(&any0, r0->type, &any1, r1->type); +} /* dns_rr_cmp() */ + + +static _Bool dns_rr_exists(struct dns_rr *rr0, struct dns_packet *P0, struct dns_packet *P1) { + struct dns_rr rr1; + + dns_rr_foreach(&rr1, P1, .section = rr0->section, .type = rr0->type) { + if (0 == dns_rr_cmp(rr0, P0, &rr1, P1)) + return 1; + } + + return 0; +} /* dns_rr_exists() */ + + +static unsigned short dns_rr_offset(struct dns_rr *rr) { + return rr->dn.p; +} /* dns_rr_offset() */ + + +static _Bool dns_rr_i_match(struct dns_rr *rr, struct dns_rr_i *i, struct dns_packet *P) { + if (i->section && !(rr->section & i->section)) + return 0; + + if (i->type && rr->type != i->type && i->type != DNS_T_ALL) + return 0; + + if (i->class && rr->class != i->class && i->class != DNS_C_ANY) + return 0; + + if (i->name) { + char dn[DNS_D_MAXNAME + 1]; + size_t len; + int error; + + if (!(len = dns_d_expand(dn, sizeof dn, rr->dn.p, P, &error)) + || len >= sizeof dn) + return 0; + + if (0 != strcasecmp(dn, i->name)) + return 0; + } + + if (i->data && i->type && rr->section > DNS_S_QD) { + union dns_any rd; + int error; + + if ((error = dns_any_parse(&rd, rr, P))) + return 0; + + if (0 != dns_any_cmp(&rd, rr->type, i->data, i->type)) + return 0; + } + + return 1; +} /* dns_rr_i_match() */ + + +static unsigned short dns_rr_i_start(struct dns_rr_i *i, struct dns_packet *P) { + unsigned short rp; + struct dns_rr r0, rr; + int error; + + if ((i->section & DNS_S_QD) && P->qd.base) + rp = P->qd.base; + else if ((i->section & DNS_S_AN) && P->an.base) + rp = P->an.base; + else if ((i->section & DNS_S_NS) && P->ns.base) + rp = P->ns.base; + else if ((i->section & DNS_S_AR) && P->ar.base) + rp = P->ar.base; + else + rp = 12; + + for (rp = 12; rp < P->end; rp = dns_rr_skip(rp, P)) { + if ((error = dns_rr_parse(&rr, rp, P))) + continue; + + rr.section = dns_rr_section(rp, P); + + if (!dns_rr_i_match(&rr, i, P)) + continue; + + r0 = rr; + + goto lower; + } + + return P->end; +lower: + if (i->sort == &dns_rr_i_packet) + return dns_rr_offset(&r0); + + while ((rp = dns_rr_skip(rp, P)) < P->end) { + if ((error = dns_rr_parse(&rr, rp, P))) + continue; + + rr.section = dns_rr_section(rp, P); + + if (!dns_rr_i_match(&rr, i, P)) + continue; + + if (i->sort(&rr, &r0, i, P) < 0) + r0 = rr; + } + + return dns_rr_offset(&r0); +} /* dns_rr_i_start() */ + + +static unsigned short dns_rr_i_skip(unsigned short rp, struct dns_rr_i *i, struct dns_packet *P) { + struct dns_rr r0, r1, rr; + int error; + + if ((error = dns_rr_parse(&r0, rp, P))) + return P->end; + + r0.section = dns_rr_section(rp, P); + + rp = (i->sort == &dns_rr_i_packet)? dns_rr_skip(rp, P) : 12; + + for (; rp < P->end; rp = dns_rr_skip(rp, P)) { + if ((error = dns_rr_parse(&rr, rp, P))) + continue; + + rr.section = dns_rr_section(rp, P); + + if (!dns_rr_i_match(&rr, i, P)) + continue; + + if (i->sort(&rr, &r0, i, P) <= 0) + continue; + + r1 = rr; + + goto lower; + } + + return P->end; +lower: + if (i->sort == &dns_rr_i_packet) + return dns_rr_offset(&r1); + + while ((rp = dns_rr_skip(rp, P)) < P->end) { + if ((error = dns_rr_parse(&rr, rp, P))) + continue; + + rr.section = dns_rr_section(rp, P); + + if (!dns_rr_i_match(&rr, i, P)) + continue; + + if (i->sort(&rr, &r0, i, P) <= 0) + continue; + + if (i->sort(&rr, &r1, i, P) >= 0) + continue; + + r1 = rr; + } + + return dns_rr_offset(&r1); +} /* dns_rr_i_skip() */ + + +int dns_rr_i_packet(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i EINA_UNUSED, struct dns_packet *P EINA_UNUSED) { + return (int)a->dn.p - (int)b->dn.p; +} /* dns_rr_i_packet() */ + + +int dns_rr_i_order(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i EINA_UNUSED, struct dns_packet *P) { + int cmp; + + if ((cmp = a->section - b->section)) + return cmp; + + if (a->type != b->type) + return (int)a->dn.p - (int)b->dn.p; + + return dns_rr_cmp(a, P, b, P); +} /* dns_rr_i_order() */ + + +int dns_rr_i_shuffle(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i, struct dns_packet *P EINA_UNUSED) { + int cmp; + + while (!i->state.regs[0]) + i->state.regs[0] = dns_random(); + + if ((cmp = a->section - b->section)) + return cmp; + + return dns_k_shuffle16(a->dn.p, i->state.regs[0]) - dns_k_shuffle16(b->dn.p, i->state.regs[0]); +} /* dns_rr_i_shuffle() */ + + +struct dns_rr_i *dns_rr_i_init(struct dns_rr_i *i, struct dns_packet *P EINA_UNUSED) { + static const struct dns_rr_i i_initializer; + + i->state = i_initializer.state; + i->saved = i->state; + + return i; +} /* dns_rr_i_init() */ + + +unsigned dns_rr_grep(struct dns_rr *rr, unsigned lim, struct dns_rr_i *i, struct dns_packet *P, int *error_) { + unsigned count = 0; + int error; + + switch (i->state.exec) { + case 0: + if (!i->sort) + i->sort = &dns_rr_i_packet; + + i->state.next = dns_rr_i_start(i, P); + i->state.exec++; + + /* FALL THROUGH */ + case 1: + while (count < lim && i->state.next < P->end) { + if ((error = dns_rr_parse(rr, i->state.next, P))) + goto error; + + rr->section = dns_rr_section(i->state.next, P); + + rr++; + count++; + i->state.count++; + + i->state.next = dns_rr_i_skip(i->state.next, i, P); + } /* while() */ + + break; + } /* switch() */ + + return count; +error: + *error_ = error; + + return count; +} /* dns_rr_grep() */ + + +static size_t dns__printchar(void *dst, size_t lim, size_t cp, unsigned char ch) { + if (cp < lim) + ((unsigned char *)dst)[cp] = ch; + + return 1; +} /* dns__printchar() */ + + +static size_t dns__printstring(void *dst, size_t lim, size_t cp, const void *src, size_t len) { + if (cp < lim) + memcpy(&((unsigned char *)dst)[cp], src, MIN(len, lim - cp)); + + return len; +} /* dns__printstring() */ + +#define dns__printstring5(a, b, c, d, e) dns__printstring((a), (b), (c), (d), (e)) +#define dns__printstring4(a, b, c, d) dns__printstring((a), (b), (c), (d), strlen((d))) +#define dns__printstring(...) DNS_PP_CALL(DNS_PP_XPASTE(dns__printstring, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) + + +static void dns__printnul(void *dst, size_t lim, size_t off) { + if (lim > 0) + ((unsigned char *)dst)[MIN(off, lim - 1)] = '\0'; +} /* dns__printnul() */ + + +static size_t dns__print10(void *dst, size_t lim, size_t off, unsigned n, unsigned pad) { + unsigned char tmp[32]; + unsigned dp = off; + unsigned cp = 0; + unsigned d = 1000000000; + unsigned ch; + + pad = MAX(1, pad); + + while (d) { + if ((ch = n / d) || cp > 0) { + n -= ch * d; + + tmp[cp] = '0' + ch; + + cp++; + } + + d /= 10; + } + + while (cp < pad) { + dp += dns__printchar(dst, lim, dp, '0'); + pad--; + } + + dp += dns__printstring(dst, lim, dp, tmp, cp); + + return dp - off; +} /* dns__print10() */ + + +size_t dns_rr_print(void *dst, size_t lim, struct dns_rr *rr, struct dns_packet *P, int *error_) { + union dns_any any; + size_t cp, n, rdlen; + void *rd; + int error; + + cp = 0; + + if (rr->section == DNS_S_QD) + cp += dns__printchar(dst, lim, cp, ';'); + + if (!(n = dns_d_expand(&((unsigned char *)dst)[cp], (cp < lim)? lim - cp : 0, rr->dn.p, P, &error))) + goto error; + + cp += n; + + if (rr->section != DNS_S_QD) { + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__print10(dst, lim, cp, rr->ttl, 0); + } + + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__printstring(dst, lim, cp, dns_strclass(rr->class), strlen(dns_strclass(rr->class))); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__printstring(dst, lim, cp, dns_strtype(rr->type), strlen(dns_strtype(rr->type))); + + if (rr->section == DNS_S_QD) + goto epilog; + + cp += dns__printchar(dst, lim, cp, ' '); + + if ((error = dns_any_parse(dns_any_init(&any, sizeof any), rr, P))) + goto error; + + if (cp < lim) { + rd = &((unsigned char *)dst)[cp]; + rdlen = lim - cp; + } else { + rd = 0; + rdlen = 0; + } + + cp += dns_any_print(rd, rdlen, &any, rr->type); + +epilog: + dns__printnul(dst, lim, cp); + + return cp; +error: + *error_ = error; + + return 0; +} /* dns_rr_print() */ + + +int dns_a_parse(struct dns_a *a, struct dns_rr *rr, struct dns_packet *P) { + unsigned long addr; + + if (rr->rd.len != 4) + return DNS_EILLEGAL; + + addr = ((0xff & P->data[rr->rd.p + 0]) << 24) + | ((0xff & P->data[rr->rd.p + 1]) << 16) + | ((0xff & P->data[rr->rd.p + 2]) << 8) + | ((0xff & P->data[rr->rd.p + 3]) << 0); + + a->addr.s_addr = htonl(addr); + + return 0; +} /* dns_a_parse() */ + + +int dns_a_push(struct dns_packet *P, struct dns_a *a) { + unsigned long addr; + + if (P->size - P->end < 6) + return DNS_ENOBUFS; + + P->data[P->end++] = 0x00; + P->data[P->end++] = 0x04; + + addr = ntohl(a->addr.s_addr); + + P->data[P->end++] = 0xff & (addr >> 24); + P->data[P->end++] = 0xff & (addr >> 16); + P->data[P->end++] = 0xff & (addr >> 8); + P->data[P->end++] = 0xff & (addr >> 0); + + return 0; +} /* dns_a_push() */ + + +size_t dns_a_arpa(void *dst, size_t lim, const struct dns_a *a) { + unsigned long a4 = ntohl(a->addr.s_addr); + size_t cp = 0; + unsigned i; + + for (i = 4; i > 0; i--) { + cp += dns__print10(dst, lim, cp, (0xff & a4), 0); + cp += dns__printchar(dst, lim, cp, '.'); + a4 >>= 8; + } + + cp += dns__printstring(dst, lim, cp, "in-addr.arpa."); + + dns__printnul(dst, lim, cp); + + return cp; +} /* dns_a_arpa() */ + + +int dns_a_cmp(const struct dns_a *a, const struct dns_a *b) { + if (ntohl(a->addr.s_addr) < ntohl(b->addr.s_addr)) + return -1; + if (ntohl(a->addr.s_addr) > ntohl(b->addr.s_addr)) + return 1; + + return 0; +} /* dns_a_cmp() */ + + +size_t dns_a_print(void *dst, size_t lim, struct dns_a *a) { + char addr[INET_ADDRSTRLEN + 1] = "0.0.0.0"; + size_t len; + + dns_inet_ntop(AF_INET, &a->addr, addr, sizeof addr); + + dns__printnul(dst, lim, (len = dns__printstring(dst, lim, 0, addr))); + + return len; +} /* dns_a_print() */ + + +int dns_aaaa_parse(struct dns_aaaa *aaaa, struct dns_rr *rr, struct dns_packet *P) { + if (rr->rd.len != sizeof aaaa->addr.s6_addr) + return DNS_EILLEGAL; + + memcpy(aaaa->addr.s6_addr, &P->data[rr->rd.p], sizeof aaaa->addr.s6_addr); + + return 0; +} /* dns_aaaa_parse() */ + + +int dns_aaaa_push(struct dns_packet *P, struct dns_aaaa *aaaa) { + if (P->size - P->end < 2 + sizeof aaaa->addr.s6_addr) + return DNS_ENOBUFS; + + P->data[P->end++] = 0x00; + P->data[P->end++] = 0x10; + + memcpy(&P->data[P->end], aaaa->addr.s6_addr, sizeof aaaa->addr.s6_addr); + + P->end += sizeof aaaa->addr.s6_addr; + + return 0; +} /* dns_aaaa_push() */ + + +int dns_aaaa_cmp(const struct dns_aaaa *a, const struct dns_aaaa *b) { + unsigned i; + int cmp; + + for (i = 0; i < lengthof(a->addr.s6_addr); i++) { + if ((cmp = (a->addr.s6_addr[i] - b->addr.s6_addr[i]))) + return cmp; + } + + return 0; +} /* dns_aaaa_cmp() */ + + +size_t dns_aaaa_arpa(void *dst, size_t lim, const struct dns_aaaa *aaaa) { + static const unsigned char hex[16] = "0123456789abcdef"; + size_t cp = 0; + unsigned nyble; + int i, j; + + for (i = sizeof aaaa->addr.s6_addr - 1; i >= 0; i--) { + nyble = aaaa->addr.s6_addr[i]; + + for (j = 0; j < 2; j++) { + cp += dns__printchar(dst, lim, cp, hex[0x0f & nyble]); + cp += dns__printchar(dst, lim, cp, '.'); + nyble >>= 4; + } + } + + cp += dns__printstring(dst, lim, cp, "ip6.arpa."); + + dns__printnul(dst, lim, cp); + + return cp; +} /* dns_aaaa_arpa() */ + + +size_t dns_aaaa_print(void *dst, size_t lim, struct dns_aaaa *aaaa) { + char addr[INET6_ADDRSTRLEN + 1] = "::"; + size_t len; + + dns_inet_ntop(AF_INET6, &aaaa->addr, addr, sizeof addr); + + dns__printnul(dst, lim, (len = dns__printstring(dst, lim, 0, addr))); + + return len; +} /* dns_aaaa_print() */ + + +int dns_mx_parse(struct dns_mx *mx, struct dns_rr *rr, struct dns_packet *P) { + size_t len; + int error; + + if (rr->rd.len < 3) + return DNS_EILLEGAL; + + mx->preference = (0xff00 & (P->data[rr->rd.p + 0] << 8)) + | (0x00ff & (P->data[rr->rd.p + 1] << 0)); + + if (!(len = dns_d_expand(mx->host, sizeof mx->host, rr->rd.p + 2, P, &error))) + return error; + else if (len >= sizeof mx->host) + return DNS_EILLEGAL; + + return 0; +} /* dns_mx_parse() */ + + +int dns_mx_push(struct dns_packet *P, struct dns_mx *mx) { + size_t end, len; + int error; + + if (P->size - P->end < 5) + return DNS_ENOBUFS; + + end = P->end; + P->end += 2; + + P->data[P->end++] = 0xff & (mx->preference >> 8); + P->data[P->end++] = 0xff & (mx->preference >> 0); + + if ((error = dns_d_push(P, mx->host, strlen(mx->host)))) + goto error; + + len = P->end - end - 2; + + P->data[end + 0] = 0xff & (len >> 8); + P->data[end + 1] = 0xff & (len >> 0); + + return 0; +error: + P->end = end; + + return error; +} /* dns_mx_push() */ + + +int dns_mx_cmp(const struct dns_mx *a, const struct dns_mx *b) { + int cmp; + + if ((cmp = a->preference - b->preference)) + return cmp; + + return strcasecmp(a->host, b->host); +} /* dns_mx_cmp() */ + + +size_t dns_mx_print(void *dst, size_t lim, struct dns_mx *mx) { + size_t cp = 0; + + cp += dns__print10(dst, lim, cp, mx->preference, 0); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__printstring(dst, lim, cp, mx->host, strlen(mx->host)); + + dns__printnul(dst, lim, cp); + + return cp; +} /* dns_mx_print() */ + + +size_t dns_mx_cname(void *dst, size_t lim, struct dns_mx *mx) { + return dns_strlcpy(dst, mx->host, lim); +} /* dns_mx_cname() */ + + +int dns_ns_parse(struct dns_ns *ns, struct dns_rr *rr, struct dns_packet *P) { + size_t len; + int error; + + if (!(len = dns_d_expand(ns->host, sizeof ns->host, rr->rd.p, P, &error))) + return error; + else if (len >= sizeof ns->host) + return DNS_EILLEGAL; + + return 0; +} /* dns_ns_parse() */ + + +int dns_ns_push(struct dns_packet *P, struct dns_ns *ns) { + size_t end, len; + int error; + + if (P->size - P->end < 3) + return DNS_ENOBUFS; + + end = P->end; + P->end += 2; + + if ((error = dns_d_push(P, ns->host, strlen(ns->host)))) + goto error; + + len = P->end - end - 2; + + P->data[end + 0] = 0xff & (len >> 8); + P->data[end + 1] = 0xff & (len >> 0); + + return 0; +error: + P->end = end; + + return error; +} /* dns_ns_push() */ + + +int dns_ns_cmp(const struct dns_ns *a, const struct dns_ns *b) { + return strcasecmp(a->host, b->host); +} /* dns_ns_cmp() */ + + +size_t dns_ns_print(void *dst, size_t lim, struct dns_ns *ns) { + size_t cp; + + cp = dns__printstring(dst, lim, 0, ns->host, strlen(ns->host)); + + dns__printnul(dst, lim, cp); + + return cp; +} /* dns_ns_print() */ + + +size_t dns_ns_cname(void *dst, size_t lim, struct dns_ns *ns) { + return dns_strlcpy(dst, ns->host, lim); +} /* dns_ns_cname() */ + + +int dns_cname_parse(struct dns_cname *cname, struct dns_rr *rr, struct dns_packet *P) { + return dns_ns_parse((struct dns_ns *)cname, rr, P); +} /* dns_cname_parse() */ + + +int dns_cname_push(struct dns_packet *P, struct dns_cname *cname) { + return dns_ns_push(P, (struct dns_ns *)cname); +} /* dns_cname_push() */ + + +int dns_cname_cmp(const struct dns_cname *a, const struct dns_cname *b) { + return strcasecmp(a->host, b->host); +} /* dns_cname_cmp() */ + + +size_t dns_cname_print(void *dst, size_t lim, struct dns_cname *cname) { + return dns_ns_print(dst, lim, (struct dns_ns *)cname); +} /* dns_cname_print() */ + + +size_t dns_cname_cname(void *dst, size_t lim, struct dns_cname *cname) { + return dns_strlcpy(dst, cname->host, lim); +} /* dns_cname_cname() */ + + +int dns_soa_parse(struct dns_soa *soa, struct dns_rr *rr, struct dns_packet *P) { + struct { void *dst; size_t lim; } dn[] = + { { soa->mname, sizeof soa->mname }, + { soa->rname, sizeof soa->rname } }; + unsigned *ts[] = + { &soa->serial, &soa->refresh, &soa->retry, &soa->expire, &soa->minimum }; + unsigned short rp; + unsigned i, j, n; + int error; + + /* MNAME / RNAME */ + if ((rp = rr->rd.p) >= P->end) + return DNS_EILLEGAL; + + for (i = 0; i < lengthof(dn); i++) { + if (!(n = dns_d_expand(dn[i].dst, dn[i].lim, rp, P, &error))) + return error; + else if (n >= dn[i].lim) + return DNS_EILLEGAL; + + if ((rp = dns_d_skip(rp, P)) >= P->end) + return DNS_EILLEGAL; + } + + /* SERIAL / REFRESH / RETRY / EXPIRE / MINIMUM */ + for (i = 0; i < lengthof(ts); i++) { + for (j = 0; j < 4; j++, rp++) { + if (rp >= P->end) + return DNS_EILLEGAL; + + *ts[i] <<= 8; + *ts[i] |= (0xff & P->data[rp]); + } + } + + return 0; +} /* dns_soa_parse() */ + + +int dns_soa_push(struct dns_packet *P, struct dns_soa *soa) { + void *dn[] = { soa->mname, soa->rname }; + unsigned ts[] = { (0xffffffff & soa->serial), + (0x7fffffff & soa->refresh), + (0x7fffffff & soa->retry), + (0x7fffffff & soa->expire), + (0xffffffff & soa->minimum) }; + unsigned i, j; + size_t end, len; + int error; + + end = P->end; + + if ((P->end += 2) >= P->size) + goto toolong; + + /* MNAME / RNAME */ + for (i = 0; i < lengthof(dn); i++) { + if ((error = dns_d_push(P, dn[i], strlen(dn[i])))) + goto error; + } + + /* SERIAL / REFRESH / RETRY / EXPIRE / MINIMUM */ + for (i = 0; i < lengthof(ts); i++) { + if ((P->end += 4) >= P->size) + goto toolong; + + for (j = 1; j <= 4; j++) { + P->data[P->end - j] = (0xff & ts[i]); + ts[i] >>= 8; + } + } + + len = P->end - end - 2; + P->data[end + 0] = (0xff & (len >> 8)); + P->data[end + 1] = (0xff & (len >> 0)); + + return 0; +toolong: + error = DNS_ENOBUFS; + + /* FALL THROUGH */ +error: + P->end = end; + + return error; +} /* dns_soa_push() */ + + +int dns_soa_cmp(const struct dns_soa *a, const struct dns_soa *b) { + int cmp; + + if ((cmp = strcasecmp(a->mname, b->mname))) + return cmp; + + if ((cmp = strcasecmp(a->rname, b->rname))) + return cmp; + + if (a->serial > b->serial) + return -1; + else if (a->serial < b->serial) + return 1; + + if (a->refresh > b->refresh) + return -1; + else if (a->refresh < b->refresh) + return 1; + + if (a->retry > b->retry) + return -1; + else if (a->retry < b->retry) + return 1; + + if (a->expire > b->expire) + return -1; + else if (a->expire < b->expire) + return 1; + + if (a->minimum > b->minimum) + return -1; + else if (a->minimum < b->minimum) + return 1; + + return 0; +} /* dns_soa_cmp() */ + + +size_t dns_soa_print(void *dst, size_t lim, struct dns_soa *soa) { + size_t cp = 0; + + cp += dns__printstring(dst, lim, cp, soa->mname, strlen(soa->mname)); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__printstring(dst, lim, cp, soa->rname, strlen(soa->rname)); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__print10(dst, lim, cp, soa->serial, 0); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__print10(dst, lim, cp, soa->refresh, 0); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__print10(dst, lim, cp, soa->retry, 0); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__print10(dst, lim, cp, soa->expire, 0); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__print10(dst, lim, cp, soa->minimum, 0); + + dns__printnul(dst, lim, cp); + + return cp; +} /* dns_soa_print() */ + + +int dns_srv_parse(struct dns_srv *srv, struct dns_rr *rr, struct dns_packet *P) { + unsigned short rp; + unsigned i; + size_t n; + int error; + + memset(srv, '\0', sizeof *srv); + + rp = rr->rd.p; + + if (P->size - P->end < 6) + return DNS_EILLEGAL; + + for (i = 0; i < 2; i++, rp++) { + srv->priority <<= 8; + srv->priority |= (0xff & P->data[rp]); + } + + for (i = 0; i < 2; i++, rp++) { + srv->weight <<= 8; + srv->weight |= (0xff & P->data[rp]); + } + + for (i = 0; i < 2; i++, rp++) { + srv->port <<= 8; + srv->port |= (0xff & P->data[rp]); + } + + if (!(n = dns_d_expand(srv->target, sizeof srv->target, rp, P, &error))) + return error; + else if (n >= sizeof srv->target) + return DNS_EILLEGAL; + + return 0; +} /* dns_srv_parse() */ + + +int dns_srv_push(struct dns_packet *P, struct dns_srv *srv) { + size_t end, len; + int error; + + end = P->end; + + if (P->size - P->end < 2) + goto toolong; + + P->end += 2; + + if (P->size - P->end < 6) + goto toolong; + + P->data[P->end++] = 0xff & (srv->priority >> 8); + P->data[P->end++] = 0xff & (srv->priority >> 0); + + P->data[P->end++] = 0xff & (srv->weight >> 8); + P->data[P->end++] = 0xff & (srv->weight >> 0); + + P->data[P->end++] = 0xff & (srv->port >> 8); + P->data[P->end++] = 0xff & (srv->port >> 0); + + if (0 == (len = dns_d_comp(&P->data[P->end], P->size - P->end, srv->target, strlen(srv->target), P, &error))) + goto error; + else if (P->size - P->end < len) + goto toolong; + + P->end += len; + + if (P->end > 65535) + goto toolong; + + len = P->end - end - 2; + + P->data[end + 0] = 0xff & (len >> 8); + P->data[end + 1] = 0xff & (len >> 0); + + return 0; +toolong: + error = DNS_ENOBUFS; + + /* FALL THROUGH */ +error: + P->end = end; + + return error; +} /* dns_srv_push() */ + + +int dns_srv_cmp(const struct dns_srv *a, const struct dns_srv *b) { + int cmp; + + if ((cmp = a->priority - b->priority)) + return cmp; + + /* + * FIXME: We need some sort of random seed to implement the dynamic + * weighting required by RFC 2782. + */ + if ((cmp = a->weight - b->weight)) + return cmp; + + if ((cmp = a->port - b->port)) + return cmp; + + return strcasecmp(a->target, b->target); +} /* dns_srv_cmp() */ + + +size_t dns_srv_print(void *dst, size_t lim, struct dns_srv *srv) { + size_t cp = 0; + + cp += dns__print10(dst, lim, cp, srv->priority, 0); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__print10(dst, lim, cp, srv->weight, 0); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__print10(dst, lim, cp, srv->port, 0); + cp += dns__printchar(dst, lim, cp, ' '); + cp += dns__printstring(dst, lim, cp, srv->target, strlen(srv->target)); + + dns__printnul(dst, lim, cp); + + return cp; +} /* dns_srv_print() */ + + +size_t dns_srv_cname(void *dst, size_t lim, struct dns_srv *srv) { + return dns_strlcpy(dst, srv->target, lim); +} /* dns_srv_cname() */ + + +int dns_ptr_parse(struct dns_ptr *ptr, struct dns_rr *rr, struct dns_packet *P) { + return dns_ns_parse((struct dns_ns *)ptr, rr, P); +} /* dns_ptr_parse() */ + + +int dns_ptr_push(struct dns_packet *P, struct dns_ptr *ptr) { + return dns_ns_push(P, (struct dns_ns *)ptr); +} /* dns_ptr_push() */ + + +size_t dns_ptr_qname(void *dst, size_t lim, int af, void *addr) { + unsigned len = (af == AF_INET6) + ? dns_aaaa_arpa(dst, lim, addr) + : dns_a_arpa(dst, lim, addr); + + dns__printnul(dst, lim, len); + + return len; +} /* dns_ptr_qname() */ + + +int dns_ptr_cmp(const struct dns_ptr *a, const struct dns_ptr *b) { + return strcasecmp(a->host, b->host); +} /* dns_ptr_cmp() */ + + +size_t dns_ptr_print(void *dst, size_t lim, struct dns_ptr *ptr) { + return dns_ns_print(dst, lim, (struct dns_ns *)ptr); +} /* dns_ptr_print() */ + + +size_t dns_ptr_cname(void *dst, size_t lim, struct dns_ptr *ptr) { + return dns_strlcpy(dst, ptr->host, lim); +} /* dns_ptr_cname() */ + + +int dns_sshfp_parse(struct dns_sshfp *fp, struct dns_rr *rr, struct dns_packet *P) { + unsigned p = rr->rd.p, pe = rr->rd.p + rr->rd.len; + + if (pe - p < 2) + return DNS_EILLEGAL; + + fp->algo = P->data[p++]; + fp->type = P->data[p++]; + + switch (fp->type) { + case DNS_SSHFP_SHA1: + if (pe - p < sizeof fp->digest.sha1) + return DNS_EILLEGAL; + + memcpy(fp->digest.sha1, &P->data[p], sizeof fp->digest.sha1); + + break; + default: + break; + } /* switch() */ + + return 0; +} /* dns_sshfp_parse() */ + + +int dns_sshfp_push(struct dns_packet *P, struct dns_sshfp *fp) { + unsigned p = P->end, pe = P->size, n; + + if (pe - p < 4) + return DNS_ENOBUFS; + + p += 2; + P->data[p++] = 0xff & fp->algo; + P->data[p++] = 0xff & fp->type; + + switch (fp->type) { + case DNS_SSHFP_SHA1: + if (pe - p < sizeof fp->digest.sha1) + return DNS_ENOBUFS; + + memcpy(&P->data[p], fp->digest.sha1, sizeof fp->digest.sha1); + p += sizeof fp->digest.sha1; + + break; + default: + return DNS_EILLEGAL; + } /* switch() */ + + n = p - P->end - 2; + P->data[P->end++] = 0xff & (n >> 8); + P->data[P->end++] = 0xff & (n >> 0); + P->end = p; + + return 0; +} /* dns_sshfp_push() */ + + +int dns_sshfp_cmp(const struct dns_sshfp *a, const struct dns_sshfp *b) { + int cmp; + + if ((cmp = a->algo - b->algo) || (cmp - a->type - b->type)) + return cmp; + + switch (a->type) { + case DNS_SSHFP_SHA1: + return memcmp(a->digest.sha1, b->digest.sha1, sizeof a->digest.sha1); + default: + return 0; + } /* switch() */ + + /* NOT REACHED */ +} /* dns_sshfp_cmp() */ + + +size_t dns_sshfp_print(void *dst, size_t lim, struct dns_sshfp *fp) { + static const unsigned char hex[16] = "0123456789abcdef"; + size_t i, p = 0; + + p += dns__print10(dst, lim, p, fp->algo, 0); + p += dns__printchar(dst, lim, p, ' '); + p += dns__print10(dst, lim, p, fp->type, 0); + p += dns__printchar(dst, lim, p, ' '); + + switch (fp->type) { + case DNS_SSHFP_SHA1: + for (i = 0; i < sizeof fp->digest.sha1; i++) { + p += dns__printchar(dst, lim, p, hex[0x0f & (fp->digest.sha1[i] >> 4)]); + p += dns__printchar(dst, lim, p, hex[0x0f & (fp->digest.sha1[i] >> 0)]); + } + + break; + default: + p += dns__printchar(dst, lim, p, '0'); + + break; + } /* switch() */ + + dns__printnul(dst, lim, p); + + return p; +} /* dns_sshfp_print() */ + + +struct dns_txt *dns_txt_init(struct dns_txt *txt, size_t size) { + assert(size > offsetof(struct dns_txt, data)); + + txt->size = size - offsetof(struct dns_txt, data); + txt->len = 0; + + return txt; +} /* dns_txt_init() */ + + +int dns_txt_parse(struct dns_txt *txt, struct dns_rr *rr, struct dns_packet *P) { + struct { unsigned char *b; size_t p, end; } dst, src; + unsigned n; + + dst.b = txt->data; + dst.p = 0; + dst.end = txt->size; + + src.b = P->data; + src.p = rr->rd.p; + src.end = src.p + rr->rd.len; + + while (src.p < src.end) { + n = 0xff & P->data[src.p++]; + + if (src.end - src.p < n || dst.end - dst.p < n) + return DNS_EILLEGAL; + + memcpy(&dst.b[dst.p], &src.b[src.p], n); + + dst.p += n; + src.p += n; + } + + txt->len = dst.p; + + return 0; +} /* dns_txt_parse() */ + + +int dns_txt_push(struct dns_packet *P, struct dns_txt *txt) { + struct { unsigned char *b; size_t p, end; } dst, src; + unsigned n; + + dst.b = P->data; + dst.p = P->end; + dst.end = P->size; + + src.b = txt->data; + src.p = 0; + src.end = txt->len; + + if (dst.end - dst.p < 2) + return DNS_ENOBUFS; + + n = txt->len + ((txt->len + 254) / 255); + + dst.b[dst.p++] = 0xff & (n >> 8); + dst.b[dst.p++] = 0xff & (n >> 0); + + while (src.p < src.end) { + n = MIN(255, src.end - src.p); + + if (dst.p >= dst.end) + return DNS_ENOBUFS; + + dst.b[dst.p++] = n; + + if (dst.end - dst.p < n) + return DNS_ENOBUFS; + + memcpy(&dst.b[dst.p], &src.b[src.p], n); + + dst.p += n; + src.p += n; + } + + P->end = dst.p; + + return 0; +} /* dns_txt_push() */ + + +int dns_txt_cmp(const struct dns_txt *a EINA_UNUSED, const struct dns_txt *b EINA_UNUSED) { + return -1; +} /* dns_txt_cmp() */ + + +size_t dns_txt_print(void *dst_, size_t lim, struct dns_txt *txt) { + struct { unsigned char *b; size_t p, end; } dst, src; + unsigned ch; + + dst.b = dst_; + dst.end = lim; + dst.p = 0; + + src.b = txt->data; + src.end = txt->len; + src.p = 0; + + dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); + + while (src.p < src.end) { + ch = src.b[src.p]; + + if (0 == (src.p++ % 255) && src.p != 1) { + dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); + dst.p += dns__printchar(dst.b, dst.end, dst.p, ' '); + dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); + } + + if (ch < 32 || ch > 126 || ch == '"' || ch == '\\') { + dst.p += dns__printchar(dst.b, dst.end, dst.p, '\\'); + dst.p += dns__print10(dst.b, dst.end, dst.p, ch, 3); + } else { + dst.p += dns__printchar(dst.b, dst.end, dst.p, ch); + } + } + + dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); + + dns__printnul(dst.b, dst.end, dst.p); + + return dst.p; +} /* dns_txt_print() */ + + +static const struct { + enum dns_type type; + const char *name; + int (*parse)(); + int (*push)(); + int (*cmp)(); + size_t (*print)(); + size_t (*cname)(); +} dns_rrtypes[] = { + { DNS_T_A, "A", &dns_a_parse, &dns_a_push, &dns_a_cmp, &dns_a_print, 0 }, + { DNS_T_AAAA, "AAAA", &dns_aaaa_parse, &dns_aaaa_push, &dns_aaaa_cmp, &dns_aaaa_print, 0 }, + { DNS_T_MX, "MX", &dns_mx_parse, &dns_mx_push, &dns_mx_cmp, &dns_mx_print, &dns_mx_cname }, + { DNS_T_NS, "NS", &dns_ns_parse, &dns_ns_push, &dns_ns_cmp, &dns_ns_print, &dns_ns_cname }, + { DNS_T_CNAME, "CNAME", &dns_cname_parse, &dns_cname_push, &dns_cname_cmp, &dns_cname_print, &dns_cname_cname }, + { DNS_T_SOA, "SOA", &dns_soa_parse, &dns_soa_push, &dns_soa_cmp, &dns_soa_print, 0 }, + { DNS_T_SRV, "SRV", &dns_srv_parse, &dns_srv_push, &dns_srv_cmp, &dns_srv_print, &dns_srv_cname }, + { DNS_T_PTR, "PTR", &dns_ptr_parse, &dns_ptr_push, &dns_ptr_cmp, &dns_ptr_print, &dns_ptr_cname }, + { DNS_T_TXT, "TXT", &dns_txt_parse, &dns_txt_push, &dns_txt_cmp, &dns_txt_print, 0 }, + { DNS_T_SPF, "SPF", &dns_txt_parse, &dns_txt_push, &dns_txt_cmp, &dns_txt_print, 0 }, + { DNS_T_SSHFP, "SSHFP", &dns_sshfp_parse, &dns_sshfp_push, &dns_sshfp_cmp, &dns_sshfp_print, 0 }, +}; /* dns_rrtypes[] */ + + +union dns_any *dns_any_init(union dns_any *any, size_t size) { + return (union dns_any *)dns_txt_init(&any->rdata, size); +} /* dns_any_init() */ + + +int dns_any_parse(union dns_any *any, struct dns_rr *rr, struct dns_packet *P) { + unsigned i; + + for (i = 0; i < lengthof(dns_rrtypes); i++) { + if (dns_rrtypes[i].type == rr->type) + return dns_rrtypes[i].parse(any, rr, P); + } + + if (rr->rd.len > any->rdata.size) + return DNS_EILLEGAL; + + memcpy(any->rdata.data, &P->data[rr->rd.p], rr->rd.len); + any->rdata.len = rr->rd.len; + + return 0; +} /* dns_any_parse() */ + + +int dns_any_push(struct dns_packet *P, union dns_any *any, enum dns_type type) { + unsigned i; + + for (i = 0; i < lengthof(dns_rrtypes); i++) { + if (dns_rrtypes[i].type == type) + return dns_rrtypes[i].push(P, any); + } + + if (P->size - P->end < any->rdata.len + 2) + return DNS_ENOBUFS; + + P->data[P->end++] = 0xff & (any->rdata.len >> 8); + P->data[P->end++] = 0xff & (any->rdata.len >> 0); + + memcpy(&P->data[P->end], any->rdata.data, any->rdata.len); + P->end += any->rdata.len; + + return 0; +} /* dns_any_push() */ + + +int dns_any_cmp(const union dns_any *a, enum dns_type x, const union dns_any *b, enum dns_type y) { + unsigned i; + int cmp; + + if ((cmp = x - y)) + return cmp; + + for (i = 0; i < lengthof(dns_rrtypes); i++) { + if (dns_rrtypes[i].type == x) + return dns_rrtypes[i].cmp(a, b); + } + + return -1; +} /* dns_any_cmp() */ + + +size_t dns_any_print(void *dst_, size_t lim, union dns_any *any, enum dns_type type) { + struct { unsigned char *b; size_t p, end; } dst, src; + unsigned i, ch; + + for (i = 0; i < lengthof(dns_rrtypes); i++) { + if (dns_rrtypes[i].type == type) + return dns_rrtypes[i].print(dst_, lim, any); + } + + dst.b = dst_; + dst.end = lim; + dst.p = 0; + + src.b = any->rdata.data; + src.end = any->rdata.len; + src.p = 0; + + dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); + + while (src.p < src.end) { + ch = src.b[src.p++]; + + dst.p += dns__printchar(dst.b, dst.end, dst.p, '\\'); + dst.p += dns__print10(dst.b, dst.end, dst.p, ch, 3); + } + + dst.p += dns__printchar(dst.b, dst.end, dst.p, '"'); + + dns__printnul(dst.b, dst.end, dst.p); + + return dst.p; +} /* dns_any_print() */ + + +size_t dns_any_cname(void *dst, size_t lim, union dns_any *any, enum dns_type type) { + unsigned i; + + for (i = 0; i < lengthof(dns_rrtypes); i++) { + if (dns_rrtypes[i].type == type) + return (dns_rrtypes[i].cname)? dns_rrtypes[i].cname(dst, lim, any) : 0; + } + + return 0; +} /* dns_any_cname() */ + + +/* + * H O S T S R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_hosts { + struct dns_hosts_entry { + char host[DNS_D_MAXNAME + 1]; + char arpa[73 + 1]; + + int af; + + union { + struct in_addr a4; + struct in6_addr a6; + } addr; + + _Bool alias; + + struct dns_hosts_entry *next; + } *head, **tail; + + dns_atomic_t refcount; +}; /* struct dns_hosts */ + + +struct dns_hosts *dns_hosts_open(int *error) { + static const struct dns_hosts hosts_initializer = { .refcount = 1 }; + struct dns_hosts *hosts; + + if (!(hosts = malloc(sizeof *hosts))) + goto syerr; + + *hosts = hosts_initializer; + + hosts->tail = &hosts->head; + + return hosts; +syerr: + *error = dns_syerr(); + + free(hosts); + + return 0; +} /* dns_hosts_open() */ + + +void dns_hosts_close(struct dns_hosts *hosts) { + struct dns_hosts_entry *ent, *xnt; + + if (!hosts || 1 != dns_hosts_release(hosts)) + return; + + for (ent = hosts->head; ent; ent = xnt) { + xnt = ent->next; + + free(ent); + } + + free(hosts); + + return; +} /* dns_hosts_close() */ + + +unsigned dns_hosts_acquire(struct dns_hosts *hosts) { + return dns_atomic_inc(&hosts->refcount); +} /* dns_hosts_acquire() */ + + +unsigned dns_hosts_release(struct dns_hosts *hosts) { + return dns_atomic_dec(&hosts->refcount); +} /* dns_hosts_release() */ + + +struct dns_hosts *dns_hosts_mortal(struct dns_hosts *hosts) { + if (hosts) + dns_hosts_release(hosts); + + return hosts; +} /* dns_hosts_mortal() */ + + +struct dns_hosts *dns_hosts_local(int *error_) { + struct dns_hosts *hosts; + int error; + + if (!(hosts = dns_hosts_open(&error))) + goto error; + + if ((error = dns_hosts_loadpath(hosts, "/etc/hosts"))) + goto error; + + return hosts; +error: + *error_ = error; + + dns_hosts_close(hosts); + + return 0; +} /* dns_hosts_local() */ + + +#define dns_hosts_issep(ch) (isspace(ch)) +#define dns_hosts_iscom(ch) ((ch) == '#' || (ch) == ';') + +int dns_hosts_loadfile(struct dns_hosts *hosts, FILE *fp) { + struct dns_hosts_entry ent; + char word[MAX(INET6_ADDRSTRLEN, DNS_D_MAXNAME) + 1]; + unsigned wp, wc, skip; + int ch, error; + + rewind(fp); + + do { + memset(&ent, '\0', sizeof ent); + wc = 0; + skip = 0; + + do { + memset(word, '\0', sizeof word); + wp = 0; + + while (EOF != (ch = fgetc(fp)) && ch != '\n') { + skip |= !!dns_hosts_iscom(ch); + + if (skip) + continue; + + if (dns_hosts_issep(ch)) + break; + + if (wp < sizeof word - 1) + word[wp] = ch; + wp++; + } + + if (!wp) + continue; + + wc++; + + switch (wc) { + case 0: + break; + case 1: + ent.af = (strchr(word, ':'))? AF_INET6 : AF_INET; + skip = (1 != dns_inet_pton(ent.af, word, &ent.addr)); + + break; + default: + if (!wp) + break; + + dns_d_anchor(ent.host, sizeof ent.host, word, wp); + + if ((error = dns_hosts_insert(hosts, ent.af, &ent.addr, ent.host, (wc > 2)))) + return error; + + break; + } /* switch() */ + } while (ch != EOF && ch != '\n'); + } while (ch != EOF); + + return 0; +} /* dns_hosts_loadfile() */ + + +int dns_hosts_loadpath(struct dns_hosts *hosts, const char *path) { + FILE *fp; + int error; + + if (!(fp = fopen(path, "r"))) + return dns_syerr(); + + error = dns_hosts_loadfile(hosts, fp); + + fclose(fp); + + return error; +} /* dns_hosts_loadpath() */ + + +int dns_hosts_dump(struct dns_hosts *hosts, FILE *fp) { + struct dns_hosts_entry *ent, *xnt; + char addr[INET6_ADDRSTRLEN + 1]; + unsigned i; + + for (ent = hosts->head; ent; ent = xnt) { + xnt = ent->next; + + dns_inet_ntop(ent->af, &ent->addr, addr, sizeof addr); + + fputs(addr, fp); + + for (i = strlen(addr); i < INET_ADDRSTRLEN; i++) + fputc(' ', fp); + + fputc(' ', fp); + + fputs(ent->host, fp); + fputc('\n', fp); + } + + return 0; +} /* dns_hosts_dump() */ + + +int dns_hosts_insert(struct dns_hosts *hosts, int af, const void *addr, const void *host, _Bool alias) { + struct dns_hosts_entry *ent; + int error; + + if (!(ent = malloc(sizeof *ent))) + goto syerr; + + dns_d_anchor(ent->host, sizeof ent->host, host, strlen(host)); + + switch ((ent->af = af)) { + case AF_INET6: + memcpy(&ent->addr.a6, addr, sizeof ent->addr.a6); + + dns_aaaa_arpa(ent->arpa, sizeof ent->arpa, addr); + + break; + case AF_INET: + memcpy(&ent->addr.a4, addr, sizeof ent->addr.a4); + + dns_a_arpa(ent->arpa, sizeof ent->arpa, addr); + + break; + default: + error = EINVAL; + + goto error; + } /* switch() */ + + ent->alias = alias; + + ent->next = 0; + *hosts->tail = ent; + hosts->tail = &ent->next; + + return 0; +syerr: + error = dns_syerr(); +error: + free(ent); + + return error; +} /* dns_hosts_insert() */ + + +struct dns_packet *dns_hosts_query(struct dns_hosts *hosts, struct dns_packet *Q, int *error_) { + struct dns_packet *P = dns_p_new(512); + struct dns_packet *A = 0; + struct dns_rr rr; + struct dns_hosts_entry *ent; + int error, af; + char qname[DNS_D_MAXNAME + 1]; + size_t qlen; + + if ((error = dns_rr_parse(&rr, 12, Q))) + goto error; + + if (!(qlen = dns_d_expand(qname, sizeof qname, rr.dn.p, Q, &error))) + goto error; + else if (qlen >= sizeof qname) + goto toolong; + + if ((error = dns_p_push(P, DNS_S_QD, qname, qlen, rr.type, rr.class, 0, 0))) + goto error; + + switch (rr.type) { + case DNS_T_PTR: + for (ent = hosts->head; ent; ent = ent->next) { + if (ent->alias || 0 != strcasecmp(qname, ent->arpa)) + continue; + + if ((error = dns_p_push(P, DNS_S_AN, qname, qlen, rr.type, rr.class, 0, ent->host))) + goto error; + } + + break; + case DNS_T_AAAA: + af = AF_INET6; + + goto loop; + case DNS_T_A: + af = AF_INET; + +loop: for (ent = hosts->head; ent; ent = ent->next) { + if (ent->af != af || 0 != strcasecmp(qname, ent->host)) + continue; + + if ((error = dns_p_push(P, DNS_S_AN, qname, qlen, rr.type, rr.class, 0, &ent->addr))) + goto error; + } + + break; + default: + break; + } /* switch() */ + + + if (!(A = dns_p_copy(dns_p_make(P->end, &error), P))) + goto error; + + return A; +toolong: + error = DNS_EILLEGAL; +error: + *error_ = error; + + free(A); + + return 0; +} /* dns_hosts_query() */ + + +/* + * R E S O L V . C O N F R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_resolv_conf *dns_resconf_open(int *error) { + static const struct dns_resolv_conf resconf_initializer + = { .lookup = "bf", .options = { .ndots = 1, .timeout = 5, .attempts = 2, .tcp = DNS_RESCONF_TCP_ENABLE, }, + .iface = { .ss_family = AF_INET }, }; + struct dns_resolv_conf *resconf; + struct sockaddr_in *sin; + + if (!(resconf = malloc(sizeof *resconf))) + goto syerr; + + *resconf = resconf_initializer; + + sin = (struct sockaddr_in *)&resconf->nameserver[0]; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = INADDR_ANY; + sin->sin_port = htons(53); +#if defined(SA_LEN) + sin->sin_len = sizeof *sin; +#endif + + if (0 != gethostname(resconf->search[0], sizeof resconf->search[0])) + goto syerr; + + dns_d_anchor(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); + dns_d_cleave(resconf->search[0], sizeof resconf->search[0], resconf->search[0], strlen(resconf->search[0])); + + /* + * XXX: If gethostname() returned a string without any label + * separator, then search[0][0] should be NUL. + */ + + dns_resconf_acquire(resconf); + + return resconf; +syerr: + *error = dns_syerr(); + + free(resconf); + + return 0; +} /* dns_resconf_open() */ + + +void dns_resconf_close(struct dns_resolv_conf *resconf) { + if (!resconf || 1 != dns_resconf_release(resconf)) + return /* void */; + + free(resconf); +} /* dns_resconf_close() */ + + +unsigned dns_resconf_acquire(struct dns_resolv_conf *resconf) { + return dns_atomic_inc(&resconf->_.refcount); +} /* dns_resconf_acquire() */ + + +unsigned dns_resconf_release(struct dns_resolv_conf *resconf) { + return dns_atomic_dec(&resconf->_.refcount); +} /* dns_resconf_release() */ + + +struct dns_resolv_conf *dns_resconf_mortal(struct dns_resolv_conf *resconf) { + if (resconf) + dns_resconf_release(resconf); + + return resconf; +} /* dns_resconf_mortal() */ + + +struct dns_resolv_conf *dns_resconf_local(int *error_) { + struct dns_resolv_conf *resconf; + int error; + + if (!(resconf = dns_resconf_open(&error))) + goto error; + + if ((error = dns_resconf_loadpath(resconf, "/etc/resolv.conf"))) + goto error; + + return resconf; +error: + *error_ = error; + + dns_resconf_close(resconf); + + return 0; +} /* dns_resconf_local() */ + + +struct dns_resolv_conf *dns_resconf_root(int *error_) { + struct dns_resolv_conf *resconf; + int error; + + if (!(resconf = dns_resconf_open(&error))) + goto error; + + if ((error = dns_resconf_loadpath(resconf, "/etc/resolv.conf"))) + goto error; + + resconf->options.recurse = 1; + + return resconf; +error: + *error_ = error; + + dns_resconf_close(resconf); + + return 0; +} /* dns_resconf_root() */ + + +enum dns_resconf_keyword { + DNS_RESCONF_NAMESERVER, + DNS_RESCONF_DOMAIN, + DNS_RESCONF_SEARCH, + DNS_RESCONF_LOOKUP, + DNS_RESCONF_FILE, + DNS_RESCONF_BIND, + DNS_RESCONF_CACHE, + DNS_RESCONF_OPTIONS, + DNS_RESCONF_EDNS0, + DNS_RESCONF_NDOTS, + DNS_RESCONF_TIMEOUT, + DNS_RESCONF_ATTEMPTS, + DNS_RESCONF_ROTATE, + DNS_RESCONF_RECURSE, + DNS_RESCONF_SMART, + DNS_RESCONF_TCP, + DNS_RESCONF_TCPx, + DNS_RESCONF_INTERFACE, + DNS_RESCONF_ZERO, + DNS_RESCONF_ONE, + DNS_RESCONF_ENABLE, + DNS_RESCONF_ONLY, + DNS_RESCONF_DISABLE, +}; /* enum dns_resconf_keyword */ + +static enum dns_resconf_keyword dns_resconf_keyword(const char *word) { + static const char *words[] = { + [DNS_RESCONF_NAMESERVER] = "nameserver", + [DNS_RESCONF_DOMAIN] = "domain", + [DNS_RESCONF_SEARCH] = "search", + [DNS_RESCONF_LOOKUP] = "lookup", + [DNS_RESCONF_FILE] = "file", + [DNS_RESCONF_BIND] = "bind", + [DNS_RESCONF_CACHE] = "cache", + [DNS_RESCONF_OPTIONS] = "options", + [DNS_RESCONF_EDNS0] = "edns0", + [DNS_RESCONF_ROTATE] = "rotate", + [DNS_RESCONF_RECURSE] = "recurse", + [DNS_RESCONF_SMART] = "smart", + [DNS_RESCONF_TCP] = "tcp", + [DNS_RESCONF_INTERFACE] = "interface", + [DNS_RESCONF_ZERO] = "0", + [DNS_RESCONF_ONE] = "1", + [DNS_RESCONF_ENABLE] = "enable", + [DNS_RESCONF_ONLY] = "only", + [DNS_RESCONF_DISABLE] = "disable", + }; + unsigned i; + + for (i = 0; i < lengthof(words); i++) { + if (words[i] && 0 == strcasecmp(words[i], word)) + return i; + } + + if (0 == strncasecmp(word, "ndots:", sizeof "ndots:" - 1)) + return DNS_RESCONF_NDOTS; + + if (0 == strncasecmp(word, "timeout:", sizeof "timeout:" - 1)) + return DNS_RESCONF_TIMEOUT; + + if (0 == strncasecmp(word, "attempts:", sizeof "attempts:" - 1)) + return DNS_RESCONF_ATTEMPTS; + + if (0 == strncasecmp(word, "tcp:", sizeof "tcp:" - 1)) + return DNS_RESCONF_TCPx; + + return -1; +} /* dns_resconf_keyword() */ + + +/** OpenBSD-style "[1.2.3.4]:53" nameserver syntax */ +static int dns_resconf_pton(struct sockaddr_storage *ss, const char *src) { + struct { char buf[128], *p; } addr = { "", addr.buf }; + unsigned short port = 0; + int ch, af = AF_INET; + + while ((ch = *src++)) { + switch (ch) { + case ' ': + /* FALL THROUGH */ + case '\t': + break; + case '[': + break; + case ']': + while ((ch = *src++)) { + if (isdigit((unsigned char)ch)) { + port *= 10; + port += ch - '0'; + } + } + + goto inet; + case ':': + af = AF_INET6; + + /* FALL THROUGH */ + default: + if (addr.p < endof(addr.buf) - 1) + *addr.p++ = ch; + + break; + } /* switch() */ + } /* while() */ +inet: + + switch (dns_inet_pton(af, addr.buf, dns_sa_addr(af, ss))) { + case -1: + return errno; + case 0: + return EINVAL; + } /* switch() */ + + port = (!port)? 53 : port; + *dns_sa_port(af, ss) = htons(port); + dns_sa_family(ss) = af; + + return 0; +} /* dns_resconf_pton() */ + +#define dns_resconf_issep(ch) (isspace(ch) || (ch) == ',') +#define dns_resconf_iscom(ch) ((ch) == '#' || (ch) == ';') + +int dns_resconf_loadfile(struct dns_resolv_conf *resconf, FILE *fp) { + unsigned sa_count = 0; + char words[6][DNS_D_MAXNAME + 1]; + unsigned wp, wc, i, j, n; + int ch, error; + + rewind(fp); + + do { + memset(words, '\0', sizeof words); + wp = 0; + wc = 0; + + while (EOF != (ch = getc(fp)) && ch != '\n') { + if (dns_resconf_issep(ch)) { + if (wp > 0) { + wp = 0; + + if (++wc >= lengthof(words)) + goto skip; + } + } else if (dns_resconf_iscom(ch)) { +skip: + do { + ch = getc(fp); + } while (ch != EOF && ch != '\n'); + + break; + } else { + dns__printchar(words[wc], sizeof words[wc], wp, ch); + wp++; + } + } + + if (wp > 0) + wc++; + + if (wc < 2) + continue; + + switch (dns_resconf_keyword(words[0])) { + case DNS_RESCONF_NAMESERVER: + if (sa_count >= lengthof(resconf->nameserver)) + continue; + + if ((error = dns_resconf_pton(&resconf->nameserver[sa_count], words[1]))) + continue; + + sa_count++; + + break; + case DNS_RESCONF_DOMAIN: + case DNS_RESCONF_SEARCH: + memset(resconf->search, '\0', sizeof resconf->search); + + for (i = 1, j = 0; i < wc && j < lengthof(resconf->search); i++, j++) + dns_d_anchor(resconf->search[j], sizeof resconf->search[j], words[i], strlen(words[i])); + + break; + case DNS_RESCONF_LOOKUP: + for (i = 1, j = 0; i < wc && j < lengthof(resconf->lookup); i++) { + switch (dns_resconf_keyword(words[i])) { + case DNS_RESCONF_FILE: + resconf->lookup[j++] = 'f'; + + break; + case DNS_RESCONF_BIND: + resconf->lookup[j++] = 'b'; + + break; + case DNS_RESCONF_CACHE: + resconf->lookup[j++] = 'c'; + + break; + default: + break; + } /* switch() */ + } /* for() */ + + break; + case DNS_RESCONF_OPTIONS: + for (i = 1; i < wc; i++) { + switch (dns_resconf_keyword(words[i])) { + case DNS_RESCONF_EDNS0: + resconf->options.edns0 = 1; + + break; + case DNS_RESCONF_NDOTS: + for (j = sizeof "ndots:" - 1, n = 0; isdigit((int)words[i][j]); j++) { + n *= 10; + n += words[i][j] - '0'; + } /* for() */ + + resconf->options.ndots = n; + + break; + case DNS_RESCONF_TIMEOUT: + for (j = sizeof "timeout:" - 1, n = 0; isdigit((int)words[i][j]); j++) { + n *= 10; + n += words[i][j] - '0'; + } /* for() */ + + resconf->options.timeout = n; + + break; + case DNS_RESCONF_ATTEMPTS: + for (j = sizeof "attempts:" - 1, n = 0; isdigit((int)words[i][j]); j++) { + n *= 10; + n += words[i][j] - '0'; + } /* for() */ + + resconf->options.attempts = n; + + break; + case DNS_RESCONF_ROTATE: + resconf->options.rotate = 1; + + break; + case DNS_RESCONF_RECURSE: + resconf->options.recurse = 1; + + break; + case DNS_RESCONF_SMART: + resconf->options.smart = 1; + + break; + case DNS_RESCONF_TCP: + resconf->options.tcp = DNS_RESCONF_TCP_ONLY; + + break; + case DNS_RESCONF_TCPx: + switch (dns_resconf_keyword(&words[i][sizeof "tcp:" - 1])) { + case DNS_RESCONF_ENABLE: + resconf->options.tcp = DNS_RESCONF_TCP_ENABLE; + + break; + case DNS_RESCONF_ONE: + case DNS_RESCONF_ONLY: + resconf->options.tcp = DNS_RESCONF_TCP_ONLY; + + break; + case DNS_RESCONF_ZERO: + case DNS_RESCONF_DISABLE: + resconf->options.tcp = DNS_RESCONF_TCP_DISABLE; + + break; + default: + break; + } /* switch() */ + + break; + default: + break; + } /* switch() */ + } /* for() */ + + break; + case DNS_RESCONF_INTERFACE: + for (i = 0, n = 0; isdigit((int)words[2][i]); i++) { + n *= 10; + n += words[2][i] - '0'; + } + + dns_resconf_setiface(resconf, words[1], n); + + break; + default: + break; + } /* switch() */ + } while (ch != EOF); + + return 0; +} /* dns_resconf_loadfile() */ + + +int dns_resconf_loadpath(struct dns_resolv_conf *resconf, const char *path) { + FILE *fp; + int error; + + if (!(fp = fopen(path, "r"))) + return dns_syerr(); + + error = dns_resconf_loadfile(resconf, fp); + + fclose(fp); + + return error; +} /* dns_resconf_loadpath() */ + + +int dns_resconf_setiface(struct dns_resolv_conf *resconf, const char *addr, unsigned short port) { + int af = (strchr(addr, ':'))? AF_INET6 : AF_INET; + + if (1 != dns_inet_pton(af, addr, dns_sa_addr(af, &resconf->iface))) + return dns_soerr(); + + *dns_sa_port(af, &resconf->iface) = htons(port); + resconf->iface.ss_family = af; + + return 0; +} /* dns_resconf_setiface() */ + + +size_t dns_resconf_search(void *dst, size_t lim, const void *qname, size_t qlen, struct dns_resolv_conf *resconf, dns_resconf_i_t *state) { + unsigned srchi = 0xff & (*state >> 8); + unsigned ndots = 0xff & (*state >> 16); + unsigned slen, len = 0; + const char *qp, *qe; + +// assert(0xff > lengthof(resconf->search)); + + switch (0xff & *state) { + case 0: + qp = qname; + qe = qp + qlen; + + while ((qp = memchr(qp, '.', qe - qp))) + { ndots++; qp++; } + + ++*state; + + if (ndots >= resconf->options.ndots) { + len = dns_d_anchor(dst, lim, qname, qlen); + + break; + } + + /* FALL THROUGH */ + case 1: + if (srchi < lengthof(resconf->search) && (slen = strlen(resconf->search[srchi]))) { + len = dns__printstring(dst, lim, 0, qname, qlen); + len = dns_d_anchor(dst, lim, dst, len); + len += dns__printstring(dst, lim, len, resconf->search[srchi], slen); + + srchi++; + + break; + } + + ++*state; + + /* FALL THROUGH */ + case 2: + ++*state; + + if (ndots < resconf->options.ndots) { + len = dns_d_anchor(dst, lim, qname, qlen); + + break; + } + + /* FALL THROUGH */ + default: + break; + } /* switch() */ + + dns__printnul(dst, lim, len); + + *state = ((0xff & *state) << 0) + | ((0xff & srchi) << 8) + | ((0xff & ndots) << 16); + + return len; +} /* dns_resconf_search() */ + + +int dns_resconf_dump(struct dns_resolv_conf *resconf, FILE *fp) { + unsigned i; + int af; + + for (i = 0; i < lengthof(resconf->nameserver) && (af = resconf->nameserver[i].ss_family) != AF_UNSPEC; i++) { + char addr[INET6_ADDRSTRLEN + 1] = "[INVALID]"; + unsigned short port; + + dns_inet_ntop(af, dns_sa_addr(af, &resconf->nameserver[i]), addr, sizeof addr); + port = ntohs(*dns_sa_port(af, &resconf->nameserver[i])); + + if (port == 53) + fprintf(fp, "nameserver %s\n", addr); + else + fprintf(fp, "nameserver [%s]:%hu\n", addr, port); + } + + + fprintf(fp, "search"); + + for (i = 0; i < lengthof(resconf->search) && resconf->search[i][0]; i++) + fprintf(fp, " %s", resconf->search[i]); + + fputc('\n', fp); + + + fprintf(fp, "lookup"); + + for (i = 0; i < lengthof(resconf->lookup) && resconf->lookup[i]; i++) { + switch (resconf->lookup[i]) { + case 'b': + fprintf(fp, " bind"); break; + case 'f': + fprintf(fp, " file"); break; + case 'c': + fprintf(fp, " cache"); break; + } + } + + fputc('\n', fp); + + + fprintf(fp, "options ndots:%u timeout:%u attempts:%u", resconf->options.ndots, resconf->options.timeout, resconf->options.attempts); + + if (resconf->options.edns0) + fprintf(fp, " edns0"); + if (resconf->options.rotate) + fprintf(fp, " rotate"); + if (resconf->options.recurse) + fprintf(fp, " recurse"); + if (resconf->options.smart) + fprintf(fp, " smart"); + + fputc('\n', fp); + + + if ((af = resconf->iface.ss_family) != AF_UNSPEC) { + char addr[INET6_ADDRSTRLEN + 1] = "[INVALID]"; + + dns_inet_ntop(af, dns_sa_addr(af, &resconf->iface), addr, sizeof addr); + + fprintf(fp, "interface %s %hu\n", addr, ntohs(*dns_sa_port(af, &resconf->iface))); + } + + return 0; +} /* dns_resconf_dump() */ + + +/* + * H I N T S E R V E R R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_hints_soa { + unsigned char zone[DNS_D_MAXNAME + 1]; + + struct { + struct sockaddr_storage ss; + unsigned priority; + } addrs[16]; + + unsigned count; + + struct dns_hints_soa *next; +}; /* struct dns_hints_soa */ + + +struct dns_hints { + dns_atomic_t refcount; + + struct dns_hints_soa *head; +}; /* struct dns_hints */ + + +struct dns_hints *dns_hints_open(struct dns_resolv_conf *resconf EINA_UNUSED, int *error) { + static const struct dns_hints H_initializer; + struct dns_hints *H; + + if (!(H = malloc(sizeof *H))) + goto syerr; + + *H = H_initializer; + + dns_hints_acquire(H); + + return H; +syerr: + *error = dns_syerr(); + + free(H); + + return 0; +} /* dns_hints_open() */ + + +void dns_hints_close(struct dns_hints *H) { + struct dns_hints_soa *soa, *nxt; + + if (!H || 1 != dns_hints_release(H)) + return /* void */; + + for (soa = H->head; soa; soa = nxt) { + nxt = soa->next; + + free(soa); + } + + free(H); + + return /* void */; +} /* dns_hints_close() */ + + +unsigned dns_hints_acquire(struct dns_hints *H) { + return dns_atomic_inc(&H->refcount); +} /* dns_hints_acquire() */ + + +unsigned dns_hints_release(struct dns_hints *H) { + return dns_atomic_dec(&H->refcount); +} /* dns_hints_release() */ + + +struct dns_hints *dns_hints_mortal(struct dns_hints *hints) { + if (hints) + dns_hints_release(hints); + + return hints; +} /* dns_hints_mortal() */ + + +struct dns_hints *dns_hints_local(struct dns_resolv_conf *resconf, int *error_) { + struct dns_hints *hints = 0; + int error; + + if (resconf) + dns_resconf_acquire(resconf); + else if (!(resconf = dns_resconf_local(&error))) + goto error; + + if (!(hints = dns_hints_open(resconf, &error))) + goto error; + + error = 0; + + if (0 == dns_hints_insert_resconf(hints, ".", resconf, &error) && error) + goto error; + + dns_resconf_close(resconf); + + return hints; +error: + *error_ = error; + + dns_resconf_close(resconf); + dns_hints_close(hints); + + return 0; +} /* dns_hints_local() */ + + +struct dns_hints *dns_hints_root(struct dns_resolv_conf *resconf, int *error_) { + static const struct { + int af; + char addr[INET6_ADDRSTRLEN]; + } root_hints[] = { + { AF_INET, "198.41.0.4" }, /* A.ROOT-SERVERS.NET. */ + { AF_INET6, "2001:503:ba3e::2:30" }, /* A.ROOT-SERVERS.NET. */ + { AF_INET, "192.228.79.201" }, /* B.ROOT-SERVERS.NET. */ + { AF_INET, "192.33.4.12" }, /* C.ROOT-SERVERS.NET. */ + { AF_INET, "128.8.10.90" }, /* D.ROOT-SERVERS.NET. */ + { AF_INET, "192.203.230.10" }, /* E.ROOT-SERVERS.NET. */ + { AF_INET, "192.5.5.241" }, /* F.ROOT-SERVERS.NET. */ + { AF_INET6, "2001:500:2f::f" }, /* F.ROOT-SERVERS.NET. */ + { AF_INET, "192.112.36.4" }, /* G.ROOT-SERVERS.NET. */ + { AF_INET, "128.63.2.53" }, /* H.ROOT-SERVERS.NET. */ + { AF_INET6, "2001:500:1::803f:235" }, /* H.ROOT-SERVERS.NET. */ + { AF_INET, "192.36.148.17" }, /* I.ROOT-SERVERS.NET. */ + { AF_INET, "192.58.128.30" }, /* J.ROOT-SERVERS.NET. */ + { AF_INET6, "2001:503:c27::2:30" }, /* J.ROOT-SERVERS.NET. */ + }; + struct dns_hints *hints = 0; + struct sockaddr_storage ss; + unsigned i; + int error, af; + + if (!(hints = dns_hints_open(resconf, &error))) + goto error; + + for (i = 0; i < lengthof(root_hints); i++) { + af = root_hints[i].af; + + if (1 != dns_inet_pton(af, root_hints[i].addr, dns_sa_addr(af, &ss))) + goto soerr; + + *dns_sa_port(af, &ss) = htons(53); + ss.ss_family = af; + + if ((error = dns_hints_insert(hints, ".", (struct sockaddr *)&ss, 1))) + goto error; + } + + return hints; +soerr: + error = dns_soerr(); + + goto error; +error: + *error_ = error; + + dns_hints_close(hints); + + return 0; +} /* dns_hints_root() */ + + +static struct dns_hints_soa *dns_hints_fetch(struct dns_hints *H, const char *zone) { + struct dns_hints_soa *soa; + + for (soa = H->head; soa; soa = soa->next) { + if (0 == strcasecmp(zone, (char *)soa->zone)) + return soa; + } + + return 0; +} /* dns_hints_fetch() */ + + +int dns_hints_insert(struct dns_hints *H, const char *zone, const struct sockaddr *sa, unsigned priority) { + static const struct dns_hints_soa soa_initializer; + struct dns_hints_soa *soa; + unsigned i; + + if (!(soa = dns_hints_fetch(H, zone))) { + if (!(soa = malloc(sizeof *soa))) + return dns_syerr(); + + *soa = soa_initializer; + + dns__printstring(soa->zone, sizeof soa->zone, 0, zone); + + soa->next = H->head; + H->head = soa; + } + + i = soa->count % lengthof(soa->addrs); + + memcpy(&soa->addrs[i].ss, sa, dns_sa_len(sa)); + + soa->addrs[i].priority = MAX(1, priority); + + if (soa->count < lengthof(soa->addrs)) + soa->count++; + + return 0; +} /* dns_hints_insert() */ + + +unsigned dns_hints_insert_resconf(struct dns_hints *H, const char *zone, const struct dns_resolv_conf *resconf, int *error_) { + unsigned i, n, p; + int error; + + for (i = 0, n = 0, p = 1; i < lengthof(resconf->nameserver) && resconf->nameserver[i].ss_family != AF_UNSPEC; i++, n++) { + if ((error = dns_hints_insert(H, zone, (struct sockaddr *)&resconf->nameserver[i], p))) + goto error; + + p += !resconf->options.rotate; + } + + return n; +error: + *error_ = error; + + return n; +} /* dns_hints_insert_resconf() */ + + +static int dns_hints_i_cmp(unsigned a, unsigned b, struct dns_hints_i *i, struct dns_hints_soa *soa) { + int cmp; + + if ((cmp = soa->addrs[a].priority - soa->addrs[b].priority)) + return cmp; + + return dns_k_shuffle16(a, i->state.seed) - dns_k_shuffle16(b, i->state.seed); +} /* dns_hints_i_cmp() */ + + +static unsigned dns_hints_i_start(struct dns_hints_i *i, struct dns_hints_soa *soa) { + unsigned p0, p; + + p0 = 0; + + for (p = 1; p < soa->count; p++) { + if (dns_hints_i_cmp(p, p0, i, soa) < 0) + p0 = p; + } + + return p0; +} /* dns_hints_i_start() */ + + +static unsigned dns_hints_i_skip(unsigned p0, struct dns_hints_i *i, struct dns_hints_soa *soa) { + unsigned pZ, p; + + for (pZ = 0; pZ < soa->count; pZ++) { + if (dns_hints_i_cmp(pZ, p0, i, soa) > 0) + goto cont; + } + + return soa->count; +cont: + for (p = pZ + 1; p < soa->count; p++) { + if (dns_hints_i_cmp(p, p0, i, soa) <= 0) + continue; + + if (dns_hints_i_cmp(p, pZ, i, soa) >= 0) + continue; + + pZ = p; + } + + + return pZ; +} /* dns_hints_i_skip() */ + + +struct dns_hints_i *dns_hints_i_init(struct dns_hints_i *i, struct dns_hints *hints) { + static const struct dns_hints_i i_initializer; + struct dns_hints_soa *soa; + + i->state = i_initializer.state; + + do { + i->state.seed = dns_random(); + } while (0 == i->state.seed); + + if ((soa = dns_hints_fetch(hints, i->zone))) { + i->state.next = dns_hints_i_start(i, soa); + } + + return i; +} /* dns_hints_i_init() */ + + +unsigned dns_hints_grep(struct sockaddr **sa, socklen_t *sa_len, unsigned lim, struct dns_hints_i *i, struct dns_hints *H) { + struct dns_hints_soa *soa; + unsigned n; + + if (!(soa = dns_hints_fetch(H, i->zone))) + return 0; + + n = 0; + + while (i->state.next < soa->count && n < lim) { + *sa = (struct sockaddr *)&soa->addrs[i->state.next].ss; + *sa_len = dns_sa_len(*sa); + + sa++; + sa_len++; + n++; + + i->state.next = dns_hints_i_skip(i->state.next, i, soa); + } + + return n; +} /* dns_hints_grep() */ + + +struct dns_packet *dns_hints_query(struct dns_hints *hints, struct dns_packet *Q, int *error_) { + struct dns_packet *A, *P; + struct dns_rr rr; + char zone[DNS_D_MAXNAME + 1]; + size_t zlen; + struct dns_hints_i i; + struct sockaddr *sa; + socklen_t slen; + int error; + + if (!dns_rr_grep(&rr, 1, dns_rr_i_new(Q, .section = DNS_S_QUESTION), Q, &error)) + goto error; + + if (!(zlen = dns_d_expand(zone, sizeof zone, rr.dn.p, Q, &error))) + goto error; + else if (zlen >= sizeof zone) + goto toolong; + + P = dns_p_new(512); + dns_header(P)->qr = 1; + + if ((error = dns_rr_copy(P, &rr, Q))) + goto error; + + if ((error = dns_p_push(P, DNS_S_AUTHORITY, ".", strlen("."), DNS_T_NS, DNS_C_IN, 0, "hints.local."))) + goto error; + + do { + i.zone = zone; + + dns_hints_i_init(&i, hints); + + while (dns_hints_grep(&sa, &slen, 1, &i, hints)) { + int af = sa->sa_family; + int rtype = (af == AF_INET6)? DNS_T_AAAA : DNS_T_A; + + if ((error = dns_p_push(P, DNS_S_ADDITIONAL, "hints.local.", strlen("hints.local."), rtype, DNS_C_IN, 0, dns_sa_addr(af, sa)))) + goto error; + } + } while ((zlen = dns_d_cleave(zone, sizeof zone, zone, zlen))); + + if (!(A = dns_p_copy(dns_p_make(P->end, &error), P))) + goto error; + + return A; +toolong: + error = DNS_EILLEGAL; +error: + *error_ = error; + + return 0; +} /* dns_hints_query() */ + + +/** ugly hack to support specifying ports other than 53 in resolv.conf. */ +static unsigned short dns_hints_port(struct dns_hints *hints, int af, void *addr) { + struct dns_hints_soa *soa; + unsigned short port; + unsigned i; + + for (soa = hints->head; soa; soa = soa->next) { + for (i = 0; i < soa->count; i++) { + if (af != soa->addrs[i].ss.ss_family) + continue; + + if (memcmp(addr, dns_sa_addr(af, &soa->addrs[i].ss), (af == AF_INET6)? sizeof (struct in6_addr) : sizeof (struct in_addr))) + continue; + + port = *dns_sa_port(af, &soa->addrs[i].ss); + + return (port)? port : htons(53); + } + } + + return htons(53); +} /* dns_hints_port() */ + + +int dns_hints_dump(struct dns_hints *hints, FILE *fp) { + struct dns_hints_soa *soa; + char addr[INET6_ADDRSTRLEN]; + unsigned i; + int af; + + for (soa = hints->head; soa; soa = soa->next) { + fprintf(fp, "ZONE \"%s\"\n", soa->zone); + + for (i = 0; i < soa->count; i++) { + af = soa->addrs[i].ss.ss_family; + if (!dns_inet_ntop(af, dns_sa_addr(af, &soa->addrs[i].ss), addr, sizeof addr)) + return dns_soerr(); + + fprintf(fp, "\t(%d) [%s]:%hu\n", (int)soa->addrs[i].priority, addr, ntohs(*dns_sa_port(af, &soa->addrs[i].ss))); + } + } + + return 0; +} /* dns_hints_dump() */ + + +/* + * C A C H E R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static dns_atomic_t dns_cache_acquire(struct dns_cache *cache EINA_UNUSED) { + return 0; +} /* dns_cache_acquire() */ + + +static dns_atomic_t dns_cache_release(struct dns_cache *cache EINA_UNUSED) { + return 0; +} /* dns_cache_release() */ + + +static struct dns_packet *dns_cache_query(struct dns_packet *query EINA_UNUSED, struct dns_cache *cache EINA_UNUSED, int *error EINA_UNUSED) { + return 0; +} /* dns_cache_submit() */ + + +static int dns_cache_submit(struct dns_packet *query EINA_UNUSED, struct dns_cache *cache EINA_UNUSED) { + return 0; +} /* dns_cache_submit() */ + + +static int dns_cache_check(struct dns_cache *cache EINA_UNUSED) { + return 0; +} /* dns_cache_check() */ + + +static struct dns_packet *dns_cache_fetch(struct dns_cache *cache EINA_UNUSED, int *error EINA_UNUSED) { + return 0; +} /* dns_cache_fetch() */ + + +static int dns_cache_pollfd(struct dns_cache *cache EINA_UNUSED) { + return -1; +} /* dns_cache_pollfd() */ + + +static short dns_cache_events(struct dns_cache *cache EINA_UNUSED) { + return 0; +} /* dns_cache_events() */ + + +static void dns_cache_clear(struct dns_cache *cache EINA_UNUSED) { + return; +} /* dns_cache_clear() */ + + +struct dns_cache *dns_cache_init(struct dns_cache *cache) { + static const struct dns_cache c_init = { + .acquire = &dns_cache_acquire, + .release = &dns_cache_release, + .query = &dns_cache_query, + .submit = &dns_cache_submit, + .check = &dns_cache_check, + .fetch = &dns_cache_fetch, + .pollfd = &dns_cache_pollfd, + .events = &dns_cache_events, + .clear = &dns_cache_clear, + }; + + *cache = c_init; + + return cache; +} /* dns_cache_init() */ + + +void dns_cache_close(struct dns_cache *cache) { + if (cache) + cache->release(cache); +} /* dns_cache_close() */ + + +/* + * S O C K E T R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static void dns_socketclose(int *fd) { + if (*fd != -1) { +#if _WIN32 + closesocket(*fd); +#else + close(*fd); +#endif + *fd = -1; + } +} /* dns_socketclose() */ + + +#define DNS_SO_MAXTRY 7 + +static int dns_socket(struct sockaddr *local, int type, int *error_) { + int error, fd = -1; +#if defined(O_NONBLOCK) + int flags; +#elif defined(FIONBIO) + unsigned long opt; +#endif + + if (-1 == (fd = socket(local->sa_family, type, 0))) + goto soerr; + +#if defined(F_SETFD) + if (-1 == fcntl(fd, F_SETFD, 1)) + goto syerr; +#endif + +#if defined(O_NONBLOCK) + if (-1 == (flags = fcntl(fd, F_GETFL))) + goto syerr; + + if (-1 == fcntl(fd, F_SETFL, flags | O_NONBLOCK)) + goto syerr; +#elif defined(FIONBIO) + opt = 1; + + if (0 != ioctlsocket(fd, FIONBIO, &opt)) + goto soerr; +#endif + + if (local->sa_family != AF_INET && local->sa_family != AF_INET6) + return fd; + + if (type != SOCK_DGRAM) + return fd; + + if (*dns_sa_port(local->sa_family, local) == 0) { + struct sockaddr_storage tmp; + unsigned i, port; + + memcpy(&tmp, local, dns_sa_len(local)); + + for (i = 0; i < DNS_SO_MAXTRY; i++) { + port = 1025 + (dns_random() % 64510); + + *dns_sa_port(tmp.ss_family, &tmp) = htons(port); + + if (0 == bind(fd, (struct sockaddr *)&tmp, dns_sa_len(&tmp))) + return fd; + } + } + + if (0 == bind(fd, local, dns_sa_len(local))) + return fd; + + /* FALL THROUGH */ +soerr: + error = dns_soerr(); + + goto error; +syerr: + error = dns_syerr(); + + goto error; +error: + *error_ = error; + + dns_socketclose(&fd); + + return -1; +} /* dns_socket() */ + + +enum { + DNS_SO_UDP_INIT = 1, + DNS_SO_UDP_CONN, + DNS_SO_UDP_SEND, + DNS_SO_UDP_RECV, + DNS_SO_UDP_DONE, + + DNS_SO_TCP_INIT, + DNS_SO_TCP_CONN, + DNS_SO_TCP_SEND, + DNS_SO_TCP_RECV, + DNS_SO_TCP_DONE, +}; + +struct dns_socket { + struct dns_options opts; + + int udp; + int tcp; + + int *old; + unsigned onum, olim; + + int type; + + struct sockaddr_storage local, remote; + + struct dns_k_permutor qids; + + struct dns_stat stat; + + /* + * NOTE: dns_so_reset() zeroes everything from here down. + */ + int state; + + unsigned short qid; + char qname[DNS_D_MAXNAME + 1]; + size_t qlen; + enum dns_type qtype; + enum dns_class qclass; + + struct dns_packet *query; + size_t qout; + + time_t began; + + struct dns_packet *answer; + size_t alen, apos; +}; /* struct dns_socket() */ + + +/* + * NOTE: Actual closure delayed so that kqueue(2) and epoll(2) callers have + * a chance to recognize a state change after installing a persistent event + * and where sequential descriptors with the same integer value returned + * from _pollfd() would be ambiguous. See dns_so_closefds(). + */ +static int dns_so_closefd(struct dns_socket *so, int *fd) { + int error; + + if (*fd == -1) + return 0; + + if (so->opts.closefd.cb) { + if ((error = so->opts.closefd.cb(fd, so->opts.closefd.arg))) { + return error; + } else if (*fd == -1) + return 0; + } + + if (!(so->onum < so->olim)) { + unsigned olim = MAX(4, so->olim * 2); + void *old; + + if (!(old = realloc(so->old, sizeof so->old[0] * olim))) + return dns_syerr(); + + so->old = old; + so->olim = olim; + } + + so->old[so->onum++] = *fd; + *fd = -1; + + return 0; +} /* dns_so_closefd() */ + + +#define DNS_SO_CLOSE_UDP 0x01 +#define DNS_SO_CLOSE_TCP 0x02 +#define DNS_SO_CLOSE_OLD 0x04 +#define DNS_SO_CLOSE_ALL (DNS_SO_CLOSE_UDP|DNS_SO_CLOSE_TCP|DNS_SO_CLOSE_OLD) + +static void dns_so_closefds(struct dns_socket *so, int which) { + if (DNS_SO_CLOSE_UDP & which) + dns_socketclose(&so->udp); + if (DNS_SO_CLOSE_TCP & which) + dns_socketclose(&so->tcp); + if (DNS_SO_CLOSE_OLD & which) { + unsigned i; + for (i = 0; i < so->onum; i++) + dns_socketclose(&so->old[i]); + so->onum = 0; + free(so->old); + so->old = 0; + so->olim = 0; + } +} /* dns_so_closefds() */ + + +static void dns_so_destroy(struct dns_socket *); + +static struct dns_socket *dns_so_init(struct dns_socket *so, const struct sockaddr *local, int type, const struct dns_options *opts, int *error) { + static const struct dns_socket so_initializer = { .opts = DNS_OPTS_INITIALIZER, .udp = -1, .tcp = -1, }; + + *so = so_initializer; + so->type = type; + + if (opts) + so->opts = *opts; + + if (local) + memcpy(&so->local, local, dns_sa_len(local)); + + if (-1 == (so->udp = dns_socket((struct sockaddr *)&so->local, SOCK_DGRAM, error))) + goto error; + + dns_k_permutor_init(&so->qids, 1, 65535); + + return so; +error: + dns_so_destroy(so); + + return 0; +} /* dns_so_init() */ + + +struct dns_socket *dns_so_open(const struct sockaddr *local, int type, const struct dns_options *opts, int *error) { + struct dns_socket *so; + + if (!(so = malloc(sizeof *so))) + goto syerr; + + if (!dns_so_init(so, local, type, opts, error)) + goto error; + + return so; +syerr: + *error = dns_syerr(); +error: + dns_so_close(so); + + return 0; +} /* dns_so_open() */ + + +static void dns_so_destroy(struct dns_socket *so) { + dns_so_reset(so); + dns_so_closefds(so, DNS_SO_CLOSE_ALL); +} /* dns_so_destroy() */ + + +void dns_so_close(struct dns_socket *so) { + if (!so) + return; + + dns_so_destroy(so); + + free(so); +} /* dns_so_close() */ + + +void dns_so_reset(struct dns_socket *so) { + free(so->answer); + + memset(&so->state, '\0', sizeof *so - offsetof(struct dns_socket, state)); +} /* dns_so_reset() */ + + +unsigned short dns_so_mkqid(struct dns_socket *so) { + return dns_k_permutor_step(&so->qids); +} /* dns_so_mkqid() */ + + +#define DNS_SO_MINBUF 768 + +static int dns_so_newanswer(struct dns_socket *so, size_t len) { + size_t size = offsetof(struct dns_packet, data) + MAX(len, DNS_SO_MINBUF); + void *p; + + if (!(p = realloc(so->answer, size))) + return dns_syerr(); + + so->answer = dns_p_init(p, size); + + return 0; +} /* dns_so_newanswer() */ + + +int dns_so_submit(struct dns_socket *so, struct dns_packet *Q, struct sockaddr *host) { + struct dns_rr rr; + int error = -1; + + dns_so_reset(so); + + if ((error = dns_rr_parse(&rr, 12, Q))) + goto error; + + if (!(so->qlen = dns_d_expand(so->qname, sizeof so->qname, rr.dn.p, Q, &error))) + goto error; + /* + * NOTE: don't bail if expansion is too long; caller may be + * intentionally sending long names. However, we won't be able to + * verify it on return. + */ + + so->qtype = rr.type; + so->qclass = rr.class; + + if ((error = dns_so_newanswer(so, DNS_SO_MINBUF))) + goto syerr; + + memcpy(&so->remote, host, dns_sa_len(host)); + + so->query = Q; + so->qout = 0; + so->began = dns_now(); + + if (dns_header(so->query)->qid == 0) + dns_header(so->query)->qid = dns_so_mkqid(so); + + so->qid = dns_header(so->query)->qid; + so->state = (so->type == SOCK_STREAM)? DNS_SO_TCP_INIT : DNS_SO_UDP_INIT; + + so->stat.queries++; + + return 0; +syerr: + error = dns_syerr(); +error: + dns_so_reset(so); + + return error; +} /* dns_so_submit() */ + + +static int dns_so_verify(struct dns_socket *so, struct dns_packet *P) { + char qname[DNS_D_MAXNAME + 1]; + size_t qlen; + struct dns_rr rr; + int error = -1; + + if (so->qid != dns_header(so->answer)->qid) + return DNS_EUNKNOWN; + + if (!dns_p_count(so->answer, DNS_S_QD)) + return DNS_EUNKNOWN; + + if (0 != dns_rr_parse(&rr, 12, so->answer)) + return DNS_EUNKNOWN; + + if (rr.type != so->qtype || rr.class != so->qclass) + return DNS_EUNKNOWN; + + if (!(qlen = dns_d_expand(qname, sizeof qname, rr.dn.p, P, &error))) + return error; + else if (qlen >= sizeof qname || qlen != so->qlen) + return DNS_EUNKNOWN; + + if (0 != strcasecmp(so->qname, qname)) + return DNS_EUNKNOWN; + + return 0; +} /* dns_so_verify() */ + + +static int dns_so_tcp_send(struct dns_socket *so) { + unsigned char *qsrc; + size_t qend; + long n; + + so->query->data[-2] = 0xff & (so->query->end >> 8); + so->query->data[-1] = 0xff & (so->query->end >> 0); + + qsrc = &so->query->data[-2] + so->qout; + qend = so->query->end + 2; + + while (so->qout < qend) { + if (0 > (n = send(so->tcp, (void *)&qsrc[so->qout], qend - so->qout, 0))) + return dns_soerr(); + + so->qout += n; + so->stat.tcp.sent.bytes += n; + } + + so->stat.tcp.sent.count++; + + return 0; +} /* dns_so_tcp_send() */ + + +static int dns_so_tcp_recv(struct dns_socket *so) { + unsigned char *asrc; + size_t aend, alen; + int error; + long n; + + aend = so->alen + 2; + + while (so->apos < aend) { + asrc = &so->answer->data[-2]; + + if (0 > (n = recv(so->tcp, (void *)&asrc[so->apos], aend - so->apos, 0))) + return dns_soerr(); + else if (n == 0) + return DNS_EUNKNOWN; /* FIXME */ + + so->apos += n; + so->stat.tcp.rcvd.bytes += n; + + if (so->alen == 0 && so->apos >= 2) { + alen = ((0xff & so->answer->data[-2]) << 8) + | ((0xff & so->answer->data[-1]) << 0); + + if ((error = dns_so_newanswer(so, alen))) + return error; + + so->alen = alen; + aend = alen + 2; + } + } + + so->answer->end = so->alen; + so->stat.tcp.rcvd.count++; + + return 0; +} /* dns_so_tcp_recv() */ + + +int dns_so_check(struct dns_socket *so) { + int error; + long n; + +retry: + switch (so->state) { + case DNS_SO_UDP_INIT: + so->state++; + case DNS_SO_UDP_CONN: + if (0 != connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote))) + goto soerr; + + so->state++; + case DNS_SO_UDP_SEND: + if (0 > (n = send(so->udp, (void *)so->query->data, so->query->end, 0))) + goto soerr; + + so->stat.udp.sent.bytes += n; + so->stat.udp.sent.count++; + + so->state++; + case DNS_SO_UDP_RECV: + if (0 > (n = recv(so->udp, (void *)so->answer->data, so->answer->size, 0))) + goto soerr; + + so->stat.udp.rcvd.bytes += n; + so->stat.udp.rcvd.count++; + + if ((so->answer->end = n) < 12) + goto trash; + + if ((error = dns_so_verify(so, so->answer))) + goto trash; + + so->state++; + case DNS_SO_UDP_DONE: + if (!dns_header(so->answer)->tc || so->type == SOCK_DGRAM) + return 0; + + so->state++; + case DNS_SO_TCP_INIT: + if ((error = dns_so_closefd(so, &so->tcp))) + goto error; + + if (-1 == (so->tcp = dns_socket((struct sockaddr *)&so->local, SOCK_STREAM, &error))) + goto error; + + so->state++; + case DNS_SO_TCP_CONN: + if (0 != connect(so->tcp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote))) { + if (dns_soerr() != DNS_EISCONN) + goto soerr; + } + + so->state++; + case DNS_SO_TCP_SEND: + if ((error = dns_so_tcp_send(so))) + goto error; + + so->state++; + case DNS_SO_TCP_RECV: + if ((error = dns_so_tcp_recv(so))) + goto error; + + so->state++; + case DNS_SO_TCP_DONE: + if ((error = dns_so_closefd(so, &so->tcp))) + goto error; + + if (so->answer->end < 12) + return DNS_EILLEGAL; + + if ((error = dns_so_verify(so, so->answer))) + goto error; + + return 0; + default: + error = DNS_EUNKNOWN; + + goto error; + } /* switch() */ + +trash: + goto retry; +soerr: + error = dns_soerr(); + + goto error; +error: + switch (error) { + case DNS_EINTR: + goto retry; + case DNS_EINPROGRESS: + /* FALL THROUGH */ + case DNS_EALREADY: + /* FALL THROUGH */ +#if DNS_EWOULDBLOCK != DNS_EAGAIN + case DNS_EWOULDBLOCK: + /* FALL THROUGH */ +#endif + error = DNS_EAGAIN; + + break; + } /* switch() */ + + return error; +} /* dns_so_check() */ + + +struct dns_packet *dns_so_fetch(struct dns_socket *so, int *error) { + struct dns_packet *answer; + + switch (so->state) { + case DNS_SO_UDP_DONE: + case DNS_SO_TCP_DONE: + answer = so->answer; + so->answer = 0; + + return answer; + default: + *error = DNS_EUNKNOWN; + + return 0; + } +} /* dns_so_fetch() */ + + +struct dns_packet *dns_so_query(struct dns_socket *so, struct dns_packet *Q, struct sockaddr *host, int *error_) { + struct dns_packet *A; + int error; + + if (!so->state) { + if ((error = dns_so_submit(so, Q, host))) + goto error; + } + + if ((error = dns_so_check(so))) + goto error; + + if (!(A = dns_so_fetch(so, &error))) + goto error; + + dns_so_reset(so); + + return A; +error: + *error_ = error; + + return 0; +} /* dns_so_query() */ + + +time_t dns_so_elapsed(struct dns_socket *so) { + return dns_elapsed(so->began); +} /* dns_so_elapsed() */ + + +void dns_so_clear(struct dns_socket *so) { + dns_so_closefds(so, DNS_SO_CLOSE_OLD); +} /* dns_so_clear() */ + + +static int dns_so_events2(struct dns_socket *so, enum dns_events type) { + int events = 0; + + switch (so->state) { + case DNS_SO_UDP_CONN: + case DNS_SO_UDP_SEND: + events |= DNS_POLLOUT; + + break; + case DNS_SO_UDP_RECV: + events |= DNS_POLLIN; + + break; + case DNS_SO_TCP_CONN: + case DNS_SO_TCP_SEND: + events |= DNS_POLLOUT; + + break; + case DNS_SO_TCP_RECV: + events |= DNS_POLLIN; + + break; + } /* switch() */ + + switch (type) { + case DNS_LIBEVENT: + return DNS_POLL2EV(events); + default: + return events; + } /* switch() */ +} /* dns_so_events2() */ + + +int dns_so_events(struct dns_socket *so) { + return dns_so_events2(so, so->opts.events); +} /* dns_so_events() */ + + +int dns_so_pollfd(struct dns_socket *so) { + switch (so->state) { + case DNS_SO_UDP_CONN: + case DNS_SO_UDP_SEND: + case DNS_SO_UDP_RECV: + return so->udp; + case DNS_SO_TCP_CONN: + case DNS_SO_TCP_SEND: + case DNS_SO_TCP_RECV: + return so->tcp; + } /* switch() */ + + return -1; +} /* dns_so_pollfd() */ + + +int dns_so_poll(struct dns_socket *so, int timeout) { + return dns_poll(dns_so_pollfd(so), dns_so_events2(so, DNS_SYSPOLL), timeout); +} /* dns_so_poll() */ + + +const struct dns_stat *dns_so_stat(struct dns_socket *so) { + return &so->stat; +} /* dns_so_stat() */ + + +/* + * R E S O L V E R R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +enum dns_res_state { + DNS_R_INIT, + DNS_R_GLUE, + DNS_R_SWITCH, /* (B)IND, (F)ILE, (C)ACHE */ + + DNS_R_FILE, /* Lookup in local hosts database */ + + DNS_R_CACHE, /* Lookup in application cache */ + DNS_R_SUBMIT, + DNS_R_CHECK, + DNS_R_FETCH, + + DNS_R_BIND, /* Lookup in the network */ + DNS_R_SEARCH, + DNS_R_HINTS, + DNS_R_ITERATE, + DNS_R_FOREACH_NS, + DNS_R_RESOLV0_NS, /* Prologue: Setup next frame and recurse */ + DNS_R_RESOLV1_NS, /* Epilog: Inspect answer */ + DNS_R_FOREACH_A, + DNS_R_QUERY_A, + DNS_R_CNAME0_A, + DNS_R_CNAME1_A, + + DNS_R_FINISH, + DNS_R_SMART0_A, + DNS_R_SMART1_A, + DNS_R_DONE, + DNS_R_SERVFAIL, +}; /* enum dns_res_state */ + + +#define DNS_R_MAXDEPTH 8 +#define DNS_R_ENDFRAME (DNS_R_MAXDEPTH - 1) + +struct dns_resolver { + struct dns_socket so; + + struct dns_resolv_conf *resconf; + struct dns_hosts *hosts; + struct dns_hints *hints; + struct dns_cache *cache; + + dns_atomic_t refcount; + + /* Reset zeroes everything below here. */ + + char qname[DNS_D_MAXNAME + 1]; + size_t qlen; + + enum dns_type qtype; + enum dns_class qclass; + + time_t began; + + dns_resconf_i_t search; + + struct dns_rr_i smart; + + struct dns_res_frame { + enum dns_res_state state; + + int error; + int which; /* (B)IND, (F)ILE; index into resconf->lookup */ + + unsigned attempts; + + struct dns_packet *query, *answer, *hints; + + struct dns_rr_i hints_i, hints_j; + struct dns_rr hints_ns, ans_cname; + } stack[DNS_R_MAXDEPTH]; + + unsigned sp; +}; /* struct dns_resolver */ + + +static int dns_res_tcp2type(int tcp) { + switch (tcp) { + case DNS_RESCONF_TCP_ONLY: + return SOCK_STREAM; + case DNS_RESCONF_TCP_DISABLE: + return SOCK_DGRAM; + default: + return 0; + } +} /* dns_res_tcp2type() */ + +struct dns_resolver *dns_res_open(struct dns_resolv_conf *resconf, struct dns_hosts *hosts, struct dns_hints *hints, struct dns_cache *cache, const struct dns_options *opts, int *error_) { + static const struct dns_resolver R_initializer + = { .refcount = 1, }; + struct dns_resolver *R = 0; + int type, error; + + /* + * Grab ref count early because the caller may have passed us a mortal + * reference, and we want to do the right thing if we return early + * from an error. + */ + if (resconf) + dns_resconf_acquire(resconf); + if (hosts) + dns_hosts_acquire(hosts); + if (hints) + dns_hints_acquire(hints); + if (cache) + dns_cache_acquire(cache); + + /* + * Don't try to load it ourselves because a NULL object might be an + * error from, say, dns_resconf_root(), and loading + * dns_resconf_local() by default would create undesirable surpises. + */ + if (!resconf || !hosts || !hints) + goto error; + + if (!(R = malloc(sizeof *R))) + goto syerr; + + *R = R_initializer; + type = dns_res_tcp2type(resconf->options.tcp); + + if (!dns_so_init(&R->so, (struct sockaddr *)&resconf->iface, type, opts, &error)) + goto error; + + R->resconf = resconf; + R->hosts = hosts; + R->hints = hints; + R->cache = cache; + + return R; +syerr: + error = dns_syerr(); +error: + *error_ = error; + + dns_res_close(R); + + dns_resconf_close(resconf); + dns_hosts_close(hosts); + dns_hints_close(hints); + dns_cache_close(cache); + + return 0; +} /* dns_res_open() */ + + +struct dns_resolver *dns_res_stub(const struct dns_options *opts, int *error) { + struct dns_resolv_conf *resconf = 0; + struct dns_hosts *hosts = 0; + struct dns_hints *hints = 0; + struct dns_resolver *res = 0; + + if (!(resconf = dns_resconf_local(error))) + goto epilog; + + if (!(hosts = dns_hosts_local(error))) + goto epilog; + + if (!(hints = dns_hints_local(resconf, error))) + goto epilog; + + if (!(res = dns_res_open(resconf, hosts, hints, NULL, opts, error))) + goto epilog; + +epilog: + dns_resconf_close(resconf); + dns_hosts_close(hosts); + dns_hints_close(hints); + + return res; +} /* dns_res_stub() */ + + +static void dns_res_reset_frame(struct dns_resolver *R EINA_UNUSED, struct dns_res_frame *frame) { + free(frame->query); + free(frame->answer); + free(frame->hints); + + memset(frame, '\0', sizeof *frame); +} /* dns_res_reset_frame() */ + + +void dns_res_reset(struct dns_resolver *R) { + unsigned i; + + dns_so_reset(&R->so); + + for (i = 0; i < lengthof(R->stack); i++) + dns_res_reset_frame(R, &R->stack[i]); + + memset(&R->qname, '\0', sizeof *R - offsetof(struct dns_resolver, qname)); +} /* dns_res_reset() */ + + +void dns_res_close(struct dns_resolver *R) { + if (!R || 1 < dns_res_release(R)) + return; + + dns_res_reset(R); + + dns_so_destroy(&R->so); + + dns_hints_close(R->hints); + dns_hosts_close(R->hosts); + dns_resconf_close(R->resconf); + dns_cache_close(R->cache); + + free(R); +} /* dns_res_close() */ + + +unsigned dns_res_acquire(struct dns_resolver *R) { + return dns_atomic_inc(&R->refcount); +} /* dns_res_acquire() */ + + +unsigned dns_res_release(struct dns_resolver *R) { + return dns_atomic_dec(&R->refcount); +} /* dns_res_release() */ + + +struct dns_resolver *dns_res_mortal(struct dns_resolver *res) { + if (res) + dns_res_release(res); + return res; +} /* dns_res_mortal() */ + + +static struct dns_packet *dns_res_merge(struct dns_packet *P0, struct dns_packet *P1, int *error_) { + size_t bufsiz = P0->end + P1->end; + struct dns_packet *P[3] = { P0, P1, 0 }; + struct dns_rr rr[3]; + int error, copy, i; + enum dns_section section; + +retry: + if (!(P[2] = dns_p_make(bufsiz, &error))) + goto error; + + dns_rr_foreach(&rr[0], P[0], .section = DNS_S_QD) { + if ((error = dns_rr_copy(P[2], &rr[0], P[0]))) + goto error; + } + + for (section = DNS_S_AN; (DNS_S_ALL & section); section <<= 1) { + for (i = 0; i < 2; i++) { + dns_rr_foreach(&rr[i], P[i], .section = section) { + copy = 1; + + dns_rr_foreach(&rr[2], P[2], .type = rr[i].type, .section = (DNS_S_ALL & ~DNS_S_QD)) { + if (0 == dns_rr_cmp(&rr[i], P[i], &rr[2], P[2])) { + copy = 0; + + break; + } + } + + if (copy && (error = dns_rr_copy(P[2], &rr[i], P[i]))) { + if (error == DNS_ENOBUFS && bufsiz < 65535) { + free(P[2]); P[2] = 0; + + bufsiz = MAX(65535, bufsiz * 2); + + goto retry; + } + + goto error; + } + } /* foreach(rr) */ + } /* foreach(packet) */ + } /* foreach(section) */ + + return P[2]; +error: + *error_ = error; + + free(P[2]); + + return 0; +} /* dns_res_merge() */ + + +static struct dns_packet *dns_res_glue(struct dns_resolver *R, struct dns_packet *Q) { + struct dns_packet *P = dns_p_new(512); + char qname[DNS_D_MAXNAME + 1]; + size_t qlen; + enum dns_type qtype; + struct dns_rr rr; + unsigned sp; + int error; + + if (!(qlen = dns_d_expand(qname, sizeof qname, 12, Q, &error)) + || qlen >= sizeof qname) + return 0; + + if (!(qtype = dns_rr_type(12, Q))) + return 0; + + if ((error = dns_p_push(P, DNS_S_QD, qname, strlen(qname), qtype, DNS_C_IN, 0, 0))) + return 0; + + for (sp = 0; sp <= R->sp; sp++) { + if (!R->stack[sp].answer) + continue; + + dns_rr_foreach(&rr, R->stack[sp].answer, .name = qname, .type = qtype, .section = (DNS_S_ALL & ~DNS_S_QD)) { + rr.section = DNS_S_AN; + + if ((error = dns_rr_copy(P, &rr, R->stack[sp].answer))) + return 0; + } + } + + if (dns_p_count(P, DNS_S_AN) > 0) + goto copy; + + /* Otherwise, look for a CNAME */ + for (sp = 0; sp <= R->sp; sp++) { + if (!R->stack[sp].answer) + continue; + + dns_rr_foreach(&rr, R->stack[sp].answer, .name = qname, .type = DNS_T_CNAME, .section = (DNS_S_ALL & ~DNS_S_QD)) { + rr.section = DNS_S_AN; + + if ((error = dns_rr_copy(P, &rr, R->stack[sp].answer))) + return 0; + } + } + + if (!dns_p_count(P, DNS_S_AN)) + return 0; + +copy: + return dns_p_copy(dns_p_make(P->end, &error), P); +} /* dns_res_glue() */ + + +static struct dns_packet *dns_res_mkquery(struct dns_resolver *R, const char *qname, enum dns_type qtype, enum dns_class qclass, int *error_) { + struct dns_packet *Q = 0; + int error; + + if (!(Q = dns_p_init(malloc(DNS_P_QBUFSIZ), DNS_P_QBUFSIZ))) + goto syerr; + + if ((error = dns_p_push(Q, DNS_S_QD, qname, strlen(qname), qtype, qclass, 0, 0))) + goto error; + + dns_header(Q)->rd = !R->resconf->options.recurse; + + return Q; +syerr: + error = dns_syerr(); +error: + free(Q); + + *error_ = error; + + return 0; +} /* dns_res_mkquery() */ + + +/* + * Sort NS records by three criteria: + * + * 1) Whether glue is present. + * 2) Whether glue record is original or of recursive lookup. + * 3) Randomly shuffle records which share the above criteria. + * + * NOTE: Assumes only NS records passed, AND ASSUMES no new NS records will + * be added during an iteration. + * + * FIXME: Only groks A glue, not AAAA glue. + */ +static int dns_res_nameserv_cmp(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i, struct dns_packet *P) { + _Bool glued[2] = { 0 }; + struct dns_ns ns; + struct dns_rr x, y; + int cmp, error; + + if (!(error = dns_ns_parse(&ns, a, P))) + if (!(glued[0] = !!dns_rr_grep(&x, 1, dns_rr_i_new(P, .section = (DNS_S_ALL & ~DNS_S_QD), .name = ns.host, .type = DNS_T_A), P, &error))) + x.dn.p = 0; + + if (!(error = dns_ns_parse(&ns, b, P))) + if (!(glued[1] = !!dns_rr_grep(&y, 1, dns_rr_i_new(P, .section = (DNS_S_ALL & ~DNS_S_QD), .name = ns.host, .type = DNS_T_A), P, &error))) + y.dn.p = 0; + + if ((cmp = glued[1] - glued[0])) + return cmp; + else if ((cmp = (dns_rr_offset(&y) < i->args[0]) - (dns_rr_offset(&x) < i->args[0]))) + return cmp; + else + return dns_rr_i_shuffle(a, b, i, P); +} /* dns_res_nameserv_cmp() */ + + +#define goto(sp, i) \ + do { R->stack[(sp)].state = (i); goto exec; } while (0) + +static int dns_res_exec(struct dns_resolver *R) { + struct dns_res_frame *F; + struct dns_packet *P; + char host[DNS_D_MAXNAME + 1]; + size_t len; + struct dns_rr rr; + struct sockaddr_in sin; + int error; + +exec: + + F = &R->stack[R->sp]; + + switch (F->state) { + case DNS_R_INIT: + F->state++; + case DNS_R_GLUE: + if (R->sp == 0) + goto(R->sp, DNS_R_SWITCH); + + assert(F->query); + + if (!(F->answer = dns_res_glue(R, F->query))) + goto(R->sp, DNS_R_SWITCH); + + if (!(len = dns_d_expand(host, sizeof host, 12, F->query, &error))) + goto error; + else if (len >= sizeof host) + goto toolong; + + dns_rr_foreach(&rr, F->answer, .name = host, .type = dns_rr_type(12, F->query), .section = DNS_S_AN) { + goto(R->sp, DNS_R_FINISH); + } + + dns_rr_foreach(&rr, F->answer, .name = host, .type = DNS_T_CNAME, .section = DNS_S_AN) { + F->ans_cname = rr; + + goto(R->sp, DNS_R_CNAME0_A); + } + + F->state++; + case DNS_R_SWITCH: + while (F->which < (int)sizeof R->resconf->lookup) { + switch (R->resconf->lookup[F->which++]) { + case 'b': case 'B': + goto(R->sp, DNS_R_BIND); + case 'f': case 'F': + goto(R->sp, DNS_R_FILE); + case 'c': case 'C': + if (R->cache) + goto(R->sp, DNS_R_CACHE); + + break; + default: + break; + } + } + + goto(R->sp, DNS_R_SERVFAIL); /* FIXME: Right behavior? */ + case DNS_R_FILE: + if (R->sp > 0) { + free(F->answer); + + if (!(F->answer = dns_hosts_query(R->hosts, F->query, &error))) + goto error; + + if (dns_p_count(F->answer, DNS_S_AN) > 0) + goto(R->sp, DNS_R_FINISH); + + free(F->answer); F->answer = 0; + } else { + R->search = 0; + + while ((len = dns_resconf_search(host, sizeof host, R->qname, R->qlen, R->resconf, &R->search))) { +/* + * FIXME: Some sort of bug, either with this code or with GCC 3.3.5 on + * OpenBSD 4.4, overwites the stack guard. If the bug is in this file, it + * appears to be localized somewhere around here. It can also be mitigated + * in dns_hosts_query(). In any event, the bug manifests only when using + * compound literals. alloca(), malloc(), calloc(), etc, all work fine. + * Valgrind (tested on Linux) cannot detect any issues, but stack issues are + * not Valgrind's forte. Neither can I spot anything in the assembly, but + * that's not my forte. + */ +#if __OpenBSD__ && __GNUC__ + struct dns_packet *query = __builtin_alloca(DNS_P_QBUFSIZ); + + dns_p_init(query, DNS_P_QBUFSIZ); +#else + struct dns_packet *query = dns_p_new(DNS_P_QBUFSIZ); +#endif + + if ((error = dns_p_push(query, DNS_S_QD, host, len, R->qtype, R->qclass, 0, 0))) + goto error; + + free(F->answer); + + if (!(F->answer = dns_hosts_query(R->hosts, query, &error))) + goto error; + + if (dns_p_count(F->answer, DNS_S_AN) > 0) + goto(R->sp, DNS_R_FINISH); + + free(F->answer); F->answer = 0; + } + } + + goto(R->sp, DNS_R_SWITCH); + case DNS_R_CACHE: + error = 0; + + if (!F->query && !(F->query = dns_res_mkquery(R, R->qname, R->qtype, R->qclass, &error))) + goto error; + + free(F->answer); + + if ((F->answer = R->cache->query(F->query, R->cache, &error))) { + if (dns_p_count(F->answer, DNS_S_AN) > 0) + goto(R->sp, DNS_R_FINISH); + + free(F->answer); F->answer = 0; + + goto(R->sp, DNS_R_SWITCH); + } else if (error) + goto error; + + F->state++; + case DNS_R_SUBMIT: + if ((error = R->cache->submit(F->query, R->cache))) + goto error; + + F->state++; + case DNS_R_CHECK: + if ((error = R->cache->check(R->cache))) + goto error; + + F->state++; + case DNS_R_FETCH: + error = 0; + + free(F->answer); + + if ((F->answer = R->cache->fetch(R->cache, &error))) { + if (dns_p_count(F->answer, DNS_S_AN) > 0) + goto(R->sp, DNS_R_FINISH); + + free(F->answer); F->answer = 0; + + goto(R->sp, DNS_R_SWITCH); + } else if (error) + goto error; + + goto(R->sp, DNS_R_SWITCH); + case DNS_R_BIND: + if (R->sp > 0) { + assert(F->query); + + goto(R->sp, DNS_R_HINTS); + } + + R->search = 0; + + F->state++; + case DNS_R_SEARCH: + if (!(len = dns_resconf_search(host, sizeof host, R->qname, R->qlen, R->resconf, &R->search))) + goto(R->sp, DNS_R_SWITCH); + + if (!(P = dns_p_make(DNS_P_QBUFSIZ, &error))) + goto error; + + dns_header(P)->rd = !R->resconf->options.recurse; + + free(F->query); F->query = P; + + if ((error = dns_p_push(F->query, DNS_S_QD, host, len, R->qtype, R->qclass, 0, 0))) + goto error; + + F->state++; + case DNS_R_HINTS: + if (!(F->hints = dns_hints_query(R->hints, F->query, &error))) + goto error; + + F->state++; + case DNS_R_ITERATE: + dns_rr_i_init(&F->hints_i, F->hints); + + F->hints_i.section = DNS_S_AUTHORITY; + F->hints_i.type = DNS_T_NS; + F->hints_i.sort = &dns_res_nameserv_cmp; + F->hints_i.args[0] = F->hints->end; + + F->state++; + case DNS_R_FOREACH_NS: + dns_rr_i_save(&F->hints_i); + + /* Load our next nameserver host. */ + if (!dns_rr_grep(&F->hints_ns, 1, &F->hints_i, F->hints, &error)) { + if (++F->attempts < R->resconf->options.attempts) + goto(R->sp, DNS_R_ITERATE); + + goto(R->sp, DNS_R_SWITCH); + } + + dns_rr_i_init(&F->hints_j, F->hints); + + /* Assume there are glue records */ + goto(R->sp, DNS_R_FOREACH_A); + case DNS_R_RESOLV0_NS: + /* Have we reached our max depth? */ + if (&F[1] >= endof(R->stack)) + goto(R->sp, DNS_R_FOREACH_NS); + + dns_res_reset_frame(R, &F[1]); + + if (!(F[1].query = dns_p_make(DNS_P_QBUFSIZ, &error))) + goto error; + + if ((error = dns_ns_parse((struct dns_ns *)host, &F->hints_ns, F->hints))) + goto error; + + if ((error = dns_p_push(F[1].query, DNS_S_QD, host, strlen(host), DNS_T_A, DNS_C_IN, 0, 0))) + goto error; + + F->state++; + + goto(++R->sp, DNS_R_INIT); + case DNS_R_RESOLV1_NS: + if (!(len = dns_d_expand(host, sizeof host, 12, F[1].query, &error))) + goto error; + else if (len >= sizeof host) + goto toolong; + + dns_rr_foreach(&rr, F[1].answer, .name = host, .type = DNS_T_A, .section = (DNS_S_ALL & ~DNS_S_QD)) { + rr.section = DNS_S_AR; + + if ((error = dns_rr_copy(F->hints, &rr, F[1].answer))) + goto error; + + dns_rr_i_rewind(&F->hints_i); /* Now there's glue. */ + } + + goto(R->sp, DNS_R_FOREACH_NS); + case DNS_R_FOREACH_A: + /* + * NOTE: Iterator initialized in DNS_R_FOREACH_NS because + * this state is re-entrant, but we need to reset + * .name to a valid pointer each time. + */ + if ((error = dns_ns_parse((struct dns_ns *)host, &F->hints_ns, F->hints))) + goto error; + + F->hints_j.name = host; + F->hints_j.type = DNS_T_A; + F->hints_j.section = DNS_S_ALL & ~DNS_S_QD; + + if (!dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) { + if (!dns_rr_i_count(&F->hints_j)) + goto(R->sp, DNS_R_RESOLV0_NS); + + goto(R->sp, DNS_R_FOREACH_NS); + } + + sin.sin_family = AF_INET; + + if ((error = dns_a_parse((struct dns_a *)&sin.sin_addr, &rr, F->hints))) + goto error; + + if (R->sp == 0) + sin.sin_port = dns_hints_port(R->hints, AF_INET, (struct sockaddr *)&sin.sin_addr); + else + sin.sin_port = htons(53); + + if (DNS_DEBUG) { + char addr[INET_ADDRSTRLEN + 1]; + dns_a_print(addr, sizeof addr, (struct dns_a *)&sin.sin_addr); + DNS_SHOW(F->query, "ASKING: %s/%s @ DEPTH: %u)", host, addr, R->sp); + } + + if ((error = dns_so_submit(&R->so, F->query, (struct sockaddr *)&sin))) + goto error; + + F->state++; + case DNS_R_QUERY_A: + if (dns_so_elapsed(&R->so) >= (time_t)R->resconf->options.timeout) + goto(R->sp, DNS_R_FOREACH_A); + + if ((error = dns_so_check(&R->so))) + goto error; + + free(F->answer); + + if (!(F->answer = dns_so_fetch(&R->so, &error))) + goto error; + + if (DNS_DEBUG) { + DNS_SHOW(F->answer, "ANSWER @ DEPTH: %u)", R->sp); + } + + if ((error = dns_rr_parse(&rr, 12, F->query))) + goto error; + + if (!(len = dns_d_expand(host, sizeof host, rr.dn.p, F->query, &error))) + goto error; + else if (len >= sizeof host) + goto toolong; + + dns_rr_foreach(&rr, F->answer, .section = DNS_S_AN, .name = host, .type = rr.type) { + goto(R->sp, DNS_R_FINISH); /* Found */ + } + + dns_rr_foreach(&rr, F->answer, .section = DNS_S_AN, .name = host, .type = DNS_T_CNAME) { + F->ans_cname = rr; + + goto(R->sp, DNS_R_CNAME0_A); + } + + if (!R->resconf->options.recurse) + goto(R->sp, DNS_R_SWITCH); + + dns_rr_foreach(&rr, F->answer, .section = DNS_S_NS, .type = DNS_T_NS) { + free(F->hints); + + F->hints = F->answer; + F->answer = 0; + + goto(R->sp, DNS_R_ITERATE); + } + + /* XXX: Should this go further up? */ + if (dns_header(F->answer)->aa) + goto(R->sp, DNS_R_FINISH); + + goto(R->sp, DNS_R_FOREACH_A); + case DNS_R_CNAME0_A: + if (&F[1] >= endof(R->stack)) + goto(R->sp, DNS_R_FINISH); + + if ((error = dns_cname_parse((struct dns_cname *)host, &F->ans_cname, F->answer))) + goto error; + + dns_res_reset_frame(R, &F[1]); + + if (!(F[1].query = dns_p_make(DNS_P_QBUFSIZ, &error))) + goto error; + + if ((error = dns_p_push(F[1].query, DNS_S_QD, host, strlen(host), dns_rr_type(12, F->query), DNS_C_IN, 0, 0))) + goto error; + + F->state++; + + goto(++R->sp, DNS_R_INIT); + case DNS_R_CNAME1_A: + if (!(P = dns_res_merge(F->answer, F[1].answer, &error))) + goto error; + + free(F->answer); F->answer = P; + + goto(R->sp, DNS_R_FINISH); + case DNS_R_FINISH: + assert(F->answer); + + if (!R->resconf->options.smart || R->sp > 0) + goto(R->sp, DNS_R_DONE); + + R->smart.section = DNS_S_AN; + R->smart.type = R->qtype; + + dns_rr_i_init(&R->smart, F->answer); + + F->state++; + case DNS_R_SMART0_A: + if (&F[1] >= endof(R->stack)) + goto(R->sp, DNS_R_DONE); + + while (dns_rr_grep(&rr, 1, &R->smart, F->answer, &error)) { + union { + struct dns_ns ns; + struct dns_mx mx; + struct dns_srv srv; + } rd; + const char *qname; + enum dns_type qtype; + enum dns_class qclass; + + switch (rr.type) { + case DNS_T_NS: + if ((error = dns_ns_parse(&rd.ns, &rr, F->answer))) + goto error; + + qname = rd.ns.host; + qtype = DNS_T_A; + qclass = DNS_C_IN; + + break; + case DNS_T_MX: + if ((error = dns_mx_parse(&rd.mx, &rr, F->answer))) + goto error; + + qname = rd.mx.host; + qtype = DNS_T_A; + qclass = DNS_C_IN; + + break; + case DNS_T_SRV: + if ((error = dns_srv_parse(&rd.srv, &rr, F->answer))) + goto error; + + qname = rd.srv.target; + qtype = DNS_T_A; + qclass = DNS_C_IN; + + break; + default: + continue; + } /* switch() */ + + dns_res_reset_frame(R, &F[1]); + + if (!(F[1].query = dns_res_mkquery(R, qname, qtype, qclass, &error))) + goto error; + + F->state++; + + goto(++R->sp, DNS_R_INIT); + } /* while() */ + + /* + * NOTE: SMTP specification says to fallback to A record. + * + * XXX: Should we add a mock MX answer? + */ + if (R->qtype == DNS_T_MX && R->smart.state.count == 0) { + dns_res_reset_frame(R, &F[1]); + + if (!(F[1].query = dns_res_mkquery(R, R->qname, DNS_T_A, DNS_C_IN, &error))) + goto error; + + R->smart.state.count++; + F->state++; + + goto(++R->sp, DNS_R_INIT); + } + + goto(R->sp, DNS_R_DONE); + case DNS_R_SMART1_A: + assert(F[1].answer); + + /* + * FIXME: For CNAME chains (which are typically illegal in + * this context), we should rewrite the record host name + * to the original smart qname. All the user cares about + * is locating that A/AAAA record. + */ + dns_rr_foreach(&rr, F[1].answer, .section = DNS_S_AN, .type = DNS_T_A) { + rr.section = DNS_S_AR; + + if (dns_rr_exists(&rr, F[1].answer, F->answer)) + continue; + + while ((error = dns_rr_copy(F->answer, &rr, F[1].answer))) { + if (error != DNS_ENOBUFS) + goto error; + if ((error = dns_p_grow(&F->answer))) + goto error; + } + } + + goto(R->sp, DNS_R_SMART0_A); + case DNS_R_DONE: + assert(F->answer); + + if (R->sp > 0) + goto(--R->sp, F[-1].state); + + break; + case DNS_R_SERVFAIL: + free(F->answer); + + if (!(F->answer = dns_p_make(DNS_P_QBUFSIZ, &error))) + goto error; + + dns_header(F->answer)->qr = 1; + dns_header(F->answer)->rcode = DNS_RC_SERVFAIL; + + if ((error = dns_p_push(F->answer, DNS_S_QD, R->qname, strlen(R->qname), R->qtype, R->qclass, 0, 0))) + goto error; + + goto(R->sp, DNS_R_DONE); + default: + error = EINVAL; + + goto error; + } /* switch () */ + + return 0; +toolong: + error = DNS_EILLEGAL; +error: + return error; +} /* dns_res_exec() */ + +#undef goto + + +void dns_res_clear(struct dns_resolver *R) { + switch (R->stack[R->sp].state) { + case DNS_R_CHECK: + return R->cache->clear(R->cache); + default: + return dns_so_clear(&R->so); + } +} /* dns_res_clear() */ + + +static int dns_res_events2(struct dns_resolver *R, enum dns_events type) { + int events; + + switch (R->stack[R->sp].state) { + case DNS_R_CHECK: + events = R->cache->events(R->cache); + + return (type == DNS_LIBEVENT)? DNS_POLL2EV(events) : events; + default: + return dns_so_events2(&R->so, type); + } +} /* dns_res_events2() */ + + +int dns_res_events(struct dns_resolver *R) { + return dns_res_events2(R, R->so.opts.events); +} /* dns_res_events() */ + + +int dns_res_pollfd(struct dns_resolver *R) { + switch (R->stack[R->sp].state) { + case DNS_R_CHECK: + return R->cache->pollfd(R->cache); + default: + return dns_so_pollfd(&R->so); + } +} /* dns_res_pollfd() */ + + +time_t dns_res_elapsed(struct dns_resolver *R) { + return dns_elapsed(R->began); +} /* dns_res_elapsed() */ + + +int dns_res_poll(struct dns_resolver *R, int timeout) { + return dns_poll(dns_res_pollfd(R), dns_res_events2(R, DNS_SYSPOLL), timeout); +} /* dns_res_poll() */ + + +int dns_res_submit(struct dns_resolver *R, const char *qname, enum dns_type qtype, enum dns_class qclass) { + dns_res_reset(R); + + /* Don't anchor; that can conflict with searchlist generation. */ + dns_d_init(R->qname, sizeof R->qname, qname, (R->qlen = strlen(qname)), 0); + + R->qtype = qtype; + R->qclass = qclass; + + R->began = dns_now(); + + return 0; +} /* dns_res_submit() */ + + +int dns_res_check(struct dns_resolver *R) { + int error; + + if ((error = dns_res_exec(R))) + return error; + + return 0; +} /* dns_res_check() */ + + +struct dns_packet *dns_res_fetch(struct dns_resolver *R, int *error) { + struct dns_packet *answer; + + if (R->stack[0].state != DNS_R_DONE) { + *error = DNS_EUNKNOWN; + + return 0; + } + + answer = R->stack[0].answer; + R->stack[0].answer = 0; + + return answer; +} /* dns_res_fetch() */ + + +struct dns_packet *dns_res_query(struct dns_resolver *res, const char *qname, enum dns_type qtype, enum dns_class qclass, int timeout, int *error_) { + int error; + + if ((error = dns_res_submit(res, qname, qtype, qclass))) + goto error; + + while ((error = dns_res_check(res))) { + if (dns_res_elapsed(res) > timeout) + error = DNS_ETIMEDOUT; + + if (error != DNS_EAGAIN) + goto error; + + if ((error = dns_res_poll(res, 1))) + goto error; + } + + return dns_res_fetch(res, error_); +error: + *error_ = error; + + return 0; +} /* dns_res_query() */ + + +const struct dns_stat *dns_res_stat(struct dns_resolver *res) { + return dns_so_stat(&res->so); +} /* dns_res_stat() */ + + +/* + * A D D R I N F O R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_addrinfo { + struct addrinfo hints; + struct dns_resolver *res; + + char qname[DNS_D_MAXNAME + 1]; + enum dns_type qtype; + unsigned short qport, port; + + struct dns_packet *answer; + struct dns_packet *glue; + + struct dns_rr_i i, g; + struct dns_rr rr; + + char cname[DNS_D_MAXNAME + 1]; + + int state; +}; /* struct dns_addrinfo */ + + +struct dns_addrinfo *dns_ai_open(const char *host, const char *serv, enum dns_type qtype, const struct addrinfo *hints, struct dns_resolver *res, int *error_) { + static const struct dns_addrinfo ai_initializer; + struct dns_addrinfo *ai; + int error; + + if (!res) + return 0; + + dns_res_acquire(res); + + if (!(ai = malloc(sizeof *ai))) + goto syerr; + + *ai = ai_initializer; + ai->hints = *hints; + + ai->res = res; + res = 0; + + if (sizeof ai->qname <= dns_strlcpy(ai->qname, host, sizeof ai->qname)) + { error = ENAMETOOLONG; goto error; } + + ai->qtype = qtype; + ai->qport = 0; + + if (serv) { + while (isdigit((unsigned char)*serv)) { + ai->qport *= 10; + ai->qport += *serv++ - '0'; + } + } + + ai->port = ai->qport; + + return ai; +syerr: + error = dns_syerr(); +error: + *error_ = error; + + dns_ai_close(ai); + dns_res_close(res); + + return 0; +} /* dns_ai_open() */ + + +void dns_ai_close(struct dns_addrinfo *ai) { + if (!ai) + return; + + dns_res_close(ai->res); + + if (ai->answer != ai->glue) + free(ai->glue); + + free(ai->answer); + free(ai); +} /* dns_ai_close() */ + + +static int dns_ai_setent(struct addrinfo **ent, union dns_any *any, enum dns_type type, struct dns_addrinfo *ai) { + struct sockaddr *saddr; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + const char *cname; + size_t clen; + + switch (type) { + case DNS_T_A: + saddr = memset(&sin, '\0', sizeof sin); + + sin.sin_family = AF_INET; + sin.sin_port = htons(ai->port); + + memcpy(&sin.sin_addr, any, sizeof sin.sin_addr); + + break; + case DNS_T_AAAA: + saddr = memset(&sin6, '\0', sizeof sin6); + + sin6.sin6_family = AF_INET6; + sin6.sin6_port = htons(ai->port); + + memcpy(&sin6.sin6_addr, any, sizeof sin6.sin6_addr); + + break; + default: + return EINVAL; + } /* switch() */ + + if (ai->hints.ai_flags & AI_CANONNAME) { + cname = (*ai->cname)? ai->cname : ai->qname; + clen = strlen(cname); + } else { + cname = NULL; + clen = 0; + } + + if (!(*ent = malloc(sizeof **ent + dns_sa_len(saddr) + ((ai->hints.ai_flags & AI_CANONNAME)? clen + 1 : 0)))) + return dns_syerr(); + + memset(*ent, '\0', sizeof **ent); + + (*ent)->ai_family = saddr->sa_family; + (*ent)->ai_socktype = ai->hints.ai_socktype; + (*ent)->ai_protocol = ai->hints.ai_protocol; + + (*ent)->ai_addr = memcpy((unsigned char *)*ent + sizeof **ent, saddr, dns_sa_len(saddr)); + (*ent)->ai_addrlen = dns_sa_len(saddr); + + if (ai->hints.ai_flags & AI_CANONNAME) + (*ent)->ai_canonname = memcpy((unsigned char *)*ent + sizeof **ent + dns_sa_len(saddr), cname, clen + 1); + + return 0; +} /* dns_ai_setent() */ + + +enum dns_ai_state { + DNS_AI_S_INIT, + DNS_AI_S_NUMERIC, + DNS_AI_S_SUBMIT, + DNS_AI_S_CHECK, + DNS_AI_S_FETCH, + DNS_AI_S_FOREACH_I, + DNS_AI_S_FOREACH_G, + DNS_AI_S_SUBMIT_G, + DNS_AI_S_CHECK_G, + DNS_AI_S_FETCH_G, + DNS_AI_S_DONE, +}; /* enum dns_ai_state */ + +#define dns_ai_goto(which) do { ai->state = (which); goto exec; } while (0) + +int dns_ai_nextent(struct addrinfo **ent, struct dns_addrinfo *ai) { + struct dns_packet *ans, *glue; + struct dns_rr rr; + char qname[DNS_D_MAXNAME + 1]; + union dns_any any; + size_t len; + int error; + + *ent = 0; + +exec: + + switch (ai->state) { + case DNS_AI_S_INIT: + ai->state++; + case DNS_AI_S_NUMERIC: + if (1 == dns_inet_pton(AF_INET, ai->qname, &any.a)) { + ai->state = DNS_AI_S_DONE; + + return dns_ai_setent(ent, &any, DNS_T_A, ai); + } + + if (1 == dns_inet_pton(AF_INET6, ai->qname, &any.aaaa)) { + ai->state = DNS_AI_S_DONE; + + return dns_ai_setent(ent, &any, DNS_T_AAAA, ai); + } + + if (ai->hints.ai_flags & AI_NUMERICHOST) + dns_ai_goto(DNS_AI_S_DONE); + + ai->state++; + case DNS_AI_S_SUBMIT: + if ((error = dns_res_submit(ai->res, ai->qname, ai->qtype, DNS_C_IN))) + return error; + + ai->state++; + case DNS_AI_S_CHECK: + if ((error = dns_res_check(ai->res))) + return error; + + ai->state++; + case DNS_AI_S_FETCH: + if (!(ai->answer = dns_res_fetch(ai->res, &error))) + return error; + + if ((error = dns_p_study(ai->answer))) + return error; + + ai->glue = ai->answer; + + dns_rr_i_init(&ai->i, ai->answer); + + ai->i.section = DNS_S_AN; + ai->i.type = ai->qtype; + ai->i.sort = &dns_rr_i_order; + + ai->state++; + case DNS_AI_S_FOREACH_I: + /* Search generator may have changed our qname. */ + if (!(len = dns_d_expand(qname, sizeof qname, 12, ai->answer, &error))) + return error; + else if (len >= sizeof qname) + return DNS_EILLEGAL; + + if (!dns_d_cname(ai->cname, sizeof ai->cname, qname, strlen(qname), ai->answer, &error)) + return error; + + ai->i.name = ai->cname; + + if (!dns_rr_grep(&rr, 1, &ai->i, ai->answer, &error)) + dns_ai_goto(DNS_AI_S_DONE); + + if ((error = dns_any_parse(&any, &rr, ai->answer))) + return error; + + ai->port = ai->qport; + + switch (rr.type) { + case DNS_T_A: + case DNS_T_AAAA: + return dns_ai_setent(ent, &any, rr.type, ai); + default: + if (!dns_any_cname(ai->cname, sizeof ai->cname, &any, rr.type)) + dns_ai_goto(DNS_AI_S_FOREACH_I); + + /* + * Find the "real" canonical name. Some authorities + * publish aliases where an RFC defines a canonical + * name. We trust that the resolver followed any + * CNAME chains on it's own, regardless of whether + * the "smart" option is enabled. + */ + if (!dns_d_cname(ai->cname, sizeof ai->cname, ai->cname, strlen(ai->cname), ai->answer, &error)) + return error; + + if (rr.type == DNS_T_SRV) + ai->port = any.srv.port; + + break; + } /* switch() */ + + dns_rr_i_init(&ai->g, ai->glue); + + ai->g.section = DNS_S_ALL & ~DNS_S_QD; + ai->g.name = ai->cname; + ai->g.type = (ai->hints.ai_family == AF_INET6)? DNS_T_AAAA : DNS_T_A; + + ai->state++; + case DNS_AI_S_FOREACH_G: + if (!dns_rr_grep(&rr, 1, &ai->g, ai->glue, &error)) { + if (dns_rr_i_count(&ai->g) > 0) + dns_ai_goto(DNS_AI_S_FOREACH_I); + else + dns_ai_goto(DNS_AI_S_SUBMIT_G); + } + + if ((error = dns_any_parse(&any, &rr, ai->glue))) + return error; + + return dns_ai_setent(ent, &any, rr.type, ai); + case DNS_AI_S_SUBMIT_G: + if (dns_rr_grep(&rr, 1, dns_rr_i_new(ai->glue, .section = DNS_S_QD, .name = ai->g.name, .type = ai->g.type), ai->glue, &error)) + dns_ai_goto(DNS_AI_S_FOREACH_I); + + if ((error = dns_res_submit(ai->res, ai->g.name, ai->g.type, DNS_C_IN))) + return error; + + ai->state++; + case DNS_AI_S_CHECK_G: + if ((error = dns_res_check(ai->res))) + return error; + + ai->state++; + case DNS_AI_S_FETCH_G: + if (!(ans = dns_res_fetch(ai->res, &error))) + return error; + + dns_p_study(ans); + + glue = dns_p_merge(ai->glue, DNS_S_ALL, ans, DNS_S_ALL, &error); + + free(ans); + + if (!glue) + return error; + + if (ai->glue != ai->answer) + free(ai->glue); + + ai->glue = glue; + + dns_rr_i_init(&ai->g, ai->glue); + + /* ai->g.name should already point to ai->cname */ + if (!dns_d_cname(ai->cname, sizeof ai->cname, ai->cname, strlen(ai->cname), ai->glue, &error)) + dns_ai_goto(DNS_AI_S_FOREACH_I); + + /* NOTE: Keep all the other iterator filters */ + + dns_ai_goto(DNS_AI_S_FOREACH_G); + case DNS_AI_S_DONE: + return ENOENT; + default: + return EINVAL; + } /* switch() */ +} /* dns_ai_nextent() */ + + +time_t dns_ai_elapsed(struct dns_addrinfo *ai) { + return dns_res_elapsed(ai->res); +} /* dns_ai_elapsed() */ + + +void dns_ai_clear(struct dns_addrinfo *ai) { + return dns_res_clear(ai->res); +} /* dns_ai_clear() */ + + +int dns_ai_events(struct dns_addrinfo *ai) { + return dns_res_events(ai->res); +} /* dns_ai_events() */ + + +int dns_ai_pollfd(struct dns_addrinfo *ai) { + return dns_res_pollfd(ai->res); +} /* dns_ai_pollfd() */ + + +int dns_ai_poll(struct dns_addrinfo *ai, int timeout) { + return dns_res_poll(ai->res, timeout); +} /* dns_ai_poll() */ + + +size_t dns_ai_print(void *dst, size_t lim, struct addrinfo *ent, struct dns_addrinfo *ai) { + char addr[MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1]; + size_t cp = 0; + + cp += dns__printstring(dst, lim, cp, "[ "); + cp += dns__printstring(dst, lim, cp, ai->qname); + cp += dns__printstring(dst, lim, cp, " IN "); + cp += dns__printstring(dst, lim, cp, dns_strtype(ai->qtype)); + cp += dns__printstring(dst, lim, cp, " ]\n"); + + cp += dns__printstring(dst, lim, cp, ".ai_family = "); + + switch (ent->ai_family) { + case AF_INET: + cp += dns__printstring(dst, lim, cp, "AF_INET"); + break; + case AF_INET6: + cp += dns__printstring(dst, lim, cp, "AF_INET6"); + break; + default: + cp += dns__print10(dst, lim, cp, ent->ai_family, 0); + break; + } + + cp += dns__printchar(dst, lim, cp, '\n'); + + cp += dns__printstring(dst, lim, cp, ".ai_socktype = "); + + switch (ent->ai_socktype) { + case SOCK_STREAM: + cp += dns__printstring(dst, lim, cp, "SOCK_STREAM"); + break; + case SOCK_DGRAM: + cp += dns__printstring(dst, lim, cp, "SOCK_DGRAM"); + break; + default: + cp += dns__print10(dst, lim, cp, ent->ai_socktype, 0); + break; + } + + cp += dns__printchar(dst, lim, cp, '\n'); + + cp += dns__printstring(dst, lim, cp, ".ai_addr = ["); + + dns_inet_ntop(dns_sa_family(ent->ai_addr), dns_sa_addr(dns_sa_family(ent->ai_addr), ent->ai_addr), addr, sizeof addr); + + cp += dns__printstring(dst, lim, cp, addr); + cp += dns__printstring(dst, lim, cp, "]:"); + + cp += dns__print10(dst, lim, cp, ntohs(*dns_sa_port(dns_sa_family(ent->ai_addr), ent->ai_addr)), 0); + cp += dns__printchar(dst, lim, cp, '\n'); + + cp += dns__printstring(dst, lim, cp, ".ai_canonname = "); + cp += dns__printstring(dst, lim, cp, (ent->ai_canonname)? ent->ai_canonname : "[NULL]"); + cp += dns__printchar(dst, lim, cp, '\n'); + + dns__printnul(dst, lim, cp); + + return cp; +} /* dns_ai_print() */ + + +const struct dns_stat *dns_ai_stat(struct dns_addrinfo *ai) { + return dns_res_stat(ai->res); +} /* dns_ai_stat() */ + + +/* + * M I S C E L L A N E O U S R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static const struct { + char name[16]; + enum dns_section type; +} dns_sections[] = { + { "QUESTION", DNS_S_QUESTION }, + { "QD", DNS_S_QUESTION }, + { "ANSWER", DNS_S_ANSWER }, + { "AN", DNS_S_ANSWER }, + { "AUTHORITY", DNS_S_AUTHORITY }, + { "NS", DNS_S_AUTHORITY }, + { "ADDITIONAL", DNS_S_ADDITIONAL }, + { "AR", DNS_S_ADDITIONAL }, +}; + +const char *(dns_strsection)(enum dns_section section, void *dst, size_t lim) { + unsigned i, p = 0; + + for (i = 0; i < lengthof(dns_sections); i++) { + if (dns_sections[i].type & section) { + if (p > 0) + p += dns__printchar(dst, lim, p, '|'); + + p += dns__printstring(dst, lim, p, dns_sections[i].name); + + section &= ~dns_sections[i].type; + } + } + + if (!p) + p += dns__print10(dst, lim, 0, (0xffff & section), 0); + + dns__printnul(dst, lim, p); + + return dst; +} /* dns_strsection() */ + + +enum dns_section dns_isection(const char *src) { + enum dns_section section = 0; + char sbuf[128]; + char *name, *next; + unsigned i; + + dns_strlcpy(sbuf, src, sizeof sbuf); + next = sbuf; + + while ((name = dns_strsep(&next, "|+, \t"))) { + for (i = 0; i < lengthof(dns_sections); i++) { + if (!strcasecmp(dns_sections[i].name, name)) { + section |= dns_sections[i].type; + break; + } + } + } + + return section; +} /* dns_isection() */ + + +static const struct { + char name[8]; + enum dns_class type; +} dns_classes[] = { + { "IN", DNS_C_IN }, +}; + +const char *(dns_strclass)(enum dns_class type, void *dst, size_t lim) { + unsigned i; + + for (i = 0; i < lengthof(dns_classes); i++) { + if (dns_classes[i].type == type) { + dns__printnul(dst, lim, dns__printstring(dst, lim, 0, dns_classes[i].name)); + + return dst; + } + } + + dns__printnul(dst, lim, dns__print10(dst, lim, 0, (0xffff & type), 0)); + + return dst; +} /* dns_strclass() */ + + +enum dns_class dns_iclass(const char *name) { + unsigned i; + + for (i = 0; i < lengthof(dns_classes); i++) { + if (!strcasecmp(dns_classes[i].name, name)) + return dns_classes[i].type; + } + + return 0; +} /* dns_iclass() */ + + +const char *(dns_strtype)(enum dns_type type, void *dst, size_t lim) { + unsigned i; + + for (i = 0; i < lengthof(dns_rrtypes); i++) { + if (dns_rrtypes[i].type == type) { + dns__printnul(dst, lim, dns__printstring(dst, lim, 0, dns_rrtypes[i].name)); + + return dst; + } + } + + dns__printnul(dst, lim, dns__print10(dst, lim, 0, (0xffff & type), 0)); + + return dst; +} /* dns_strtype() */ + + +enum dns_type dns_itype(const char *type) { + unsigned i; + + for (i = 0; i < lengthof(dns_rrtypes); i++) { + if (!strcasecmp(dns_rrtypes[i].name, type)) + return dns_rrtypes[i].type; + } + + return 0; +} /* dns_itype() */ + + +static char dns_opcodes[16][16] = { + [DNS_OP_QUERY] = "QUERY", + [DNS_OP_IQUERY] = "IQUERY", + [DNS_OP_STATUS] = "STATUS", + [DNS_OP_NOTIFY] = "NOTIFY", + [DNS_OP_UPDATE] = "UPDATE", +}; + +const char *dns_stropcode(enum dns_opcode opcode) { + opcode &= 0xf; + + if ('\0' == dns_opcodes[opcode][0]) + dns__printnul(dns_opcodes[opcode], sizeof dns_opcodes[opcode], dns__print10(dns_opcodes[opcode], sizeof dns_opcodes[opcode], 0, opcode, 0)); + + return dns_opcodes[opcode]; +} /* dns_stropcode() */ + + +enum dns_opcode dns_iopcode(const char *name) { + unsigned opcode; + + for (opcode = 0; opcode < lengthof(dns_opcodes); opcode++) { + if (!strcasecmp(name, dns_opcodes[opcode])) + return opcode; + } + + return lengthof(dns_opcodes) - 1; +} /* dns_iopcode() */ + + +static char dns_rcodes[16][16] = { + [DNS_RC_NOERROR] = "NOERROR", + [DNS_RC_FORMERR] = "FORMERR", + [DNS_RC_SERVFAIL] = "SERVFAIL", + [DNS_RC_NXDOMAIN] = "NXDOMAIN", + [DNS_RC_NOTIMP] = "NOTIMP", + [DNS_RC_REFUSED] = "REFUSED", + [DNS_RC_YXDOMAIN] = "YXDOMAIN", + [DNS_RC_YXRRSET] = "YXRRSET", + [DNS_RC_NXRRSET] = "NXRRSET", + [DNS_RC_NOTAUTH] = "NOTAUTH", + [DNS_RC_NOTZONE] = "NOTZONE", +}; + +const char *dns_strrcode(enum dns_rcode rcode) { + rcode &= 0xf; + + if ('\0' == dns_rcodes[rcode][0]) + dns__printnul(dns_rcodes[rcode], sizeof dns_rcodes[rcode], dns__print10(dns_rcodes[rcode], sizeof dns_rcodes[rcode], 0, rcode, 0)); + + return dns_rcodes[rcode]; +} /* dns_strrcode() */ + + +enum dns_rcode dns_ircode(const char *name) { + unsigned rcode; + + for (rcode = 0; rcode < lengthof(dns_rcodes); rcode++) { + if (!strcasecmp(name, dns_rcodes[rcode])) + return rcode; + } + + return lengthof(dns_rcodes) - 1; +} /* dns_ircode() */ + + +/* + * C O M M A N D - L I N E / R E G R E S S I O N R O U T I N E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#if DNS_MAIN + +#include +#include +#include + +#include + +#if _WIN32 +#include +#endif + +#if !_WIN32 +#include +#endif + + +struct { + struct { + const char *path[8]; + unsigned count; + } resconf; + + struct { + const char *path[8]; + unsigned count; + } hosts; + + struct { + const char *path[8]; + unsigned count; + } cache; + + const char *qname; + enum dns_type qtype; + + int (*sort)(); + + int verbose; +} MAIN = { + .sort = &dns_rr_i_packet, +}; + + +void hexdump(const unsigned char *src, size_t len, FILE *fp) { + static const unsigned char hex[] = "0123456789abcdef"; + static const unsigned char tmpl[] = " | |\n"; + unsigned char ln[sizeof tmpl]; + const unsigned char *sp, *se; + unsigned char *h, *g; + unsigned i, n; + + sp = src; + se = sp + len; + + while (sp < se) { + memcpy(ln, tmpl, sizeof ln); + + h = &ln[2]; + g = &ln[53]; + + for (n = 0; n < 2; n++) { + for (i = 0; i < 8 && se - sp > 0; i++, sp++) { + h[0] = hex[0x0f & (*sp >> 4)]; + h[1] = hex[0x0f & (*sp >> 0)]; + h += 3; + + *g++ = (isgraph(*sp))? *sp : '.'; + } + + h++; + } + + fputs((char *)ln, fp); + } + + return /* void */; +} /* hexdump() */ + + +static void panic(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + +#if _WIN32 + vfprintf(stderr, fmt, ap); + + exit(EXIT_FAILURE); +#else + verrx(EXIT_FAILURE, fmt, ap); +#endif +} /* panic() */ + +#define panic_(fn, ln, fmt, ...) \ + panic(fmt "%0s", (fn), (ln), __VA_ARGS__) +#define panic(...) \ + panic_(__func__, __LINE__, "(%s:%d) " __VA_ARGS__, "") + + +static void *grow(unsigned char *p, size_t size) { + void *tmp; + + if (!(tmp = realloc(p, size))) + panic("realloc(%zu): %s", size, dns_strerror(errno)); + + return tmp; +} /* grow() */ + + +static size_t add(size_t a, size_t b) { + if (~a < b) + panic("%zu + %zu: integer overflow", a, b); + + return a + b; +} /* add() */ + + +static size_t append(unsigned char **dst, size_t osize, const void *src, size_t len) { + size_t size = add(osize, len); + + *dst = grow(*dst, size); + memcpy(*dst + osize, src, len); + + return size; +} /* append() */ + + +static size_t slurp(unsigned char **dst, size_t osize, FILE *fp, const char *path) { + size_t size = osize; + unsigned char buf[1024]; + size_t count; + + while ((count = fread(buf, 1, sizeof buf, fp))) + size = append(dst, size, buf, count); + + if (ferror(fp)) + panic("%s: %s", path, dns_strerror(errno)); + + return size; +} /* slurp() */ + + +static struct dns_resolv_conf *resconf(void) { + static struct dns_resolv_conf *resconf; + const char *path; + unsigned i; + int error; + + if (resconf) + return resconf; + + if (!(resconf = dns_resconf_open(&error))) + panic("dns_resconf_open: %s", dns_strerror(error)); + + if (!MAIN.resconf.count) + MAIN.resconf.path[MAIN.resconf.count++] = "/etc/resolv.conf"; + + for (i = 0; i < MAIN.resconf.count; i++) { + path = MAIN.resconf.path[i]; + + if (0 == strcmp(path, "-")) + error = dns_resconf_loadfile(resconf, stdin); + else + error = dns_resconf_loadpath(resconf, path); + + if (error) + panic("%s: %s", path, dns_strerror(error)); + } + + return resconf; +} /* resconf() */ + + +static struct dns_hosts *hosts(void) { + static struct dns_hosts *hosts; + const char *path; + unsigned i; + int error; + + if (hosts) + return hosts; + + if (!MAIN.hosts.count) { + MAIN.hosts.path[MAIN.hosts.count++] = "/etc/hosts"; + + /* Explicitly test dns_hosts_local() */ + if (!(hosts = dns_hosts_local(&error))) + panic("%s: %s", "/etc/hosts", dns_strerror(error)); + + return hosts; + } + + if (!(hosts = dns_hosts_open(&error))) + panic("dns_hosts_open: %s", dns_strerror(error)); + + for (i = 0; i < MAIN.hosts.count; i++) { + path = MAIN.hosts.path[i]; + + if (0 == strcmp(path, "-")) + error = dns_hosts_loadfile(hosts, stdin); + else + error = dns_hosts_loadpath(hosts, path); + + if (error) + panic("%s: %s", path, dns_strerror(error)); + } + + return hosts; +} /* hosts() */ + + +#if DNS_CACHE +#include "cache.h" + +struct dns_cache *cache(void) { + static struct cache *cache; + const char *path; + unsigned i; + int error; + + if (cache) + return cache_resi(cache); + if (!MAIN.cache.count) + return NULL; + + if (!(cache = cache_open(&error))) + panic("%s: %s", MAIN.cache.path[0], dns_strerror(error)); + + for (i = 0; i < MAIN.cache.count; i++) { + path = MAIN.cache.path[i]; + + if (!strcmp(path, "-")) { + if ((error = cache_loadfile(cache, stdin, NULL, 0))) + panic("%s: %s", path, dns_strerror(error)); + } else if ((error = cache_loadpath(cache, path, NULL, 0))) + panic("%s: %s", path, dns_strerror(error)); + } + + return cache_resi(cache); +} /* cache() */ +#else +struct dns_cache *cache(void) { return NULL; } +#endif + + +static void print_packet(struct dns_packet *P, FILE *fp) { + dns_p_dump3(P, dns_rr_i_new(P, .sort = MAIN.sort), fp); + + if (MAIN.verbose > 2) + hexdump(P->data, P->end, fp); +} /* print_packet() */ + + +static int parse_packet(int argc, char *argv[]) { + struct dns_packet *P = dns_p_new(512); + struct dns_packet *Q = dns_p_new(512); + enum dns_section section; + struct dns_rr rr; + int error; + union dns_any any; + char pretty[sizeof any * 2]; + size_t len; + + P->end = fread(P->data, 1, P->size, stdin); + + fputs(";; [HEADER]\n", stdout); + fprintf(stdout, ";; qr : %s(%d)\n", (dns_header(P)->qr)? "QUERY" : "RESPONSE", dns_header(P)->qr); + fprintf(stdout, ";; opcode : %s(%d)\n", dns_stropcode(dns_header(P)->opcode), dns_header(P)->opcode); + fprintf(stdout, ";; aa : %s(%d)\n", (dns_header(P)->aa)? "AUTHORITATIVE" : "NON-AUTHORITATIVE", dns_header(P)->aa); + fprintf(stdout, ";; tc : %s(%d)\n", (dns_header(P)->tc)? "TRUNCATED" : "NOT-TRUNCATED", dns_header(P)->tc); + fprintf(stdout, ";; rd : %s(%d)\n", (dns_header(P)->rd)? "RECURSION-DESIRED" : "RECURSION-NOT-DESIRED", dns_header(P)->rd); + fprintf(stdout, ";; ra : %s(%d)\n", (dns_header(P)->ra)? "RECURSION-ALLOWED" : "RECURSION-NOT-ALLOWED", dns_header(P)->ra); + fprintf(stdout, ";; rcode : %s(%d)\n", dns_strrcode(dns_header(P)->rcode), dns_header(P)->rcode); + + section = 0; + + dns_rr_foreach(&rr, P, .sort = MAIN.sort) { + if (section != rr.section) + fprintf(stdout, "\n;; [%s:%d]\n", dns_strsection(rr.section), dns_p_count(P, rr.section)); + + if ((len = dns_rr_print(pretty, sizeof pretty, &rr, P, &error))) + fprintf(stdout, "%s\n", pretty); + + dns_rr_copy(Q, &rr, P); + + section = rr.section; + } + + fputs("; ; ; ; ; ; ; ;\n\n", stdout); + + section = 0; + +#if 0 + dns_rr_foreach(&rr, Q, .name = "ns8.yahoo.com.") { +#else + struct dns_rr rrset[32]; + struct dns_rr_i *rri = dns_rr_i_new(Q, .name = dns_d_new("ns8.yahoo.com", DNS_D_ANCHOR), .sort = MAIN.sort); + unsigned rrcount = dns_rr_grep(rrset, lengthof(rrset), rri, Q, &error); + unsigned i; + + for (i = 0; i < rrcount; i++) { + rr = rrset[i]; +#endif + if (section != rr.section) + fprintf(stdout, "\n;; [%s:%d]\n", dns_strsection(rr.section), dns_p_count(Q, rr.section)); + + if ((len = dns_rr_print(pretty, sizeof pretty, &rr, Q, &error))) + fprintf(stdout, "%s\n", pretty); + + section = rr.section; + } + + if (MAIN.verbose > 1) { + fprintf(stderr, "orig:%zu\n", P->end); + hexdump(P->data, P->end, stdout); + + fprintf(stderr, "copy:%zu\n", Q->end); + hexdump(Q->data, Q->end, stdout); + } + + return 0; +} /* parse_packet() */ + + +static int parse_domain(int argc, char *argv[]) { + char *dn; + + dn = (argc > 1)? argv[1] : "f.l.google.com"; + + printf("[%s]\n", dn); + + dn = dns_d_new(dn); + + do { + puts(dn); + } while (dns_d_cleave(dn, strlen(dn) + 1, dn, strlen(dn))); + + return 0; +} /* parse_domain() */ + + +static int expand_domain(int argc, char *argv[]) { + unsigned short rp = 0; + unsigned char *src = NULL; + unsigned char *dst; + struct dns_packet *pkt; + size_t lim = 0, len; + int error; + + if (argv[1]) + rp = atoi(argv[1]); + + len = slurp(&src, 0, stdin, "-"); + + if (!(pkt = dns_p_make(len, &error))) + panic("malloc(%zu): %s", len, dns_strerror(error)); + + memcpy(pkt->data, src, len); + pkt->end = len; + + lim = 1; + dst = grow(NULL, lim); + + while (lim <= (len = dns_d_expand(dst, lim, rp, pkt, &error))) { + lim = add(len, 1); + dst = grow(dst, lim); + } + + if (!len) + panic("expand: %s", dns_strerror(error)); + + fwrite(dst, 1, len, stdout); + fflush(stdout); + + free(src); + free(dst); + free(pkt); + + return 0; +} /* expand_domain() */ + + +static int show_resconf(int argc, char *argv[]) { + unsigned i; + + resconf(); /* load it */ + + fputs("; SOURCES\n", stdout); + + for (i = 0; i < MAIN.resconf.count; i++) + fprintf(stdout, "; %s\n", MAIN.resconf.path[i]); + + fputs(";\n", stdout); + + dns_resconf_dump(resconf(), stdout); + + return 0; +} /* show_resconf() */ + + +static int show_hosts(int argc, char *argv[]) { + unsigned i; + + hosts(); + + fputs("# SOURCES\n", stdout); + + for (i = 0; i < MAIN.hosts.count; i++) + fprintf(stdout, "# %s\n", MAIN.hosts.path[i]); + + fputs("#\n", stdout); + + dns_hosts_dump(hosts(), stdout); + + return 0; +} /* show_hosts() */ + + +static int query_hosts(int argc, char *argv[]) { + struct dns_packet *Q = dns_p_new(512); + struct dns_packet *A; + char qname[DNS_D_MAXNAME + 1]; + size_t qlen; + int error; + + if (!MAIN.qname) + MAIN.qname = (argc > 1)? argv[1] : "localhost"; + if (!MAIN.qtype) + MAIN.qtype = DNS_T_A; + + hosts(); + + if (MAIN.qtype == DNS_T_PTR && !strstr(MAIN.qname, "arpa")) { + union { struct in_addr a; struct in6_addr a6; } addr; + int af = (strchr(MAIN.qname, ':'))? AF_INET6 : AF_INET; + + if (1 != dns_inet_pton(af, MAIN.qname, &addr)) + panic("%s: %s", MAIN.qname, dns_strerror(error)); + + qlen = dns_ptr_qname(qname, sizeof qname, af, &addr); + } else + qlen = dns__printstring(qname, sizeof qname, 0, MAIN.qname); + + if ((error = dns_p_push(Q, DNS_S_QD, qname, qlen, MAIN.qtype, DNS_C_IN, 0, 0))) + panic("%s: %s", qname, dns_strerror(error)); + + if (!(A = dns_hosts_query(hosts(), Q, &error))) + panic("%s: %s", qname, dns_strerror(error)); + + print_packet(A, stdout); + + free(A); + + return 0; +} /* query_hosts() */ + + +static int search_list(int argc, char *argv[]) { + const char *qname = (argc > 1)? argv[1] : "f.l.google.com"; + unsigned long i = 0; + char name[DNS_D_MAXNAME + 1]; + + printf("[%s]\n", qname); + + while (dns_resconf_search(name, sizeof name, qname, strlen(qname), resconf(), &i)) + puts(name); + + return 0; +} /* search_list() */ + + +int permute_set(int argc, char *argv[]) { + unsigned lo, hi, i; + struct dns_k_permutor p; + + hi = (--argc > 0)? atoi(argv[argc]) : 8; + lo = (--argc > 0)? atoi(argv[argc]) : 0; + + fprintf(stderr, "[%u .. %u]\n", lo, hi); + + dns_k_permutor_init(&p, lo, hi); + + for (i = lo; i <= hi; i++) + fprintf(stdout, "%u\n", dns_k_permutor_step(&p)); +// printf("%u -> %u -> %u\n", i, dns_k_permutor_E(&p, i), dns_k_permutor_D(&p, dns_k_permutor_E(&p, i))); + + return 0; +} /* permute_set() */ + + +int shuffle_16(int argc, char *argv[]) { + unsigned n, r; + + if (--argc > 0) { + n = 0xffff & atoi(argv[argc]); + r = (--argc > 0)? (unsigned)atoi(argv[argc]) : dns_random(); + + fprintf(stdout, "%hu\n", dns_k_shuffle16(n, r)); + } else { + r = dns_random(); + + for (n = 0; n < 65536; n++) + fprintf(stdout, "%hu\n", dns_k_shuffle16(n, r)); + } + + return 0; +} /* shuffle_16() */ + + +int dump_random(int argc, char *argv[]) { + unsigned char b[32]; + unsigned i, j, n, r; + + n = (argc > 1)? atoi(argv[1]) : 32; + + while (n) { + i = 0; + + do { + r = dns_random(); + + for (j = 0; j < sizeof r && i < n && i < sizeof b; i++, j++) { + b[i] = 0xff & r; + r >>= 8; + } + } while (i < n && i < sizeof b); + + hexdump(b, i, stdout); + + n -= i; + } + + return 0; +} /* dump_random() */ + + +static int send_query(int argc, char *argv[]) { + struct dns_packet *A, *Q = dns_p_new(512); + char host[INET6_ADDRSTRLEN + 1]; + struct sockaddr_storage ss; + struct dns_socket *so; + int error, type; + + if (argc > 1) { + ss.ss_family = (strchr(argv[1], ':'))? AF_INET6 : AF_INET; + + if (1 != dns_inet_pton(ss.ss_family, argv[1], dns_sa_addr(ss.ss_family, &ss))) + panic("%s: invalid host address", argv[1]); + + *dns_sa_port(ss.ss_family, &ss) = htons(53); + } else + memcpy(&ss, &resconf()->nameserver[0], dns_sa_len(&resconf()->nameserver[0])); + + if (!dns_inet_ntop(ss.ss_family, dns_sa_addr(ss.ss_family, &ss), host, sizeof host)) + panic("bad host address, or none provided"); + + if (!MAIN.qname) + MAIN.qname = "ipv6.google.com"; + if (!MAIN.qtype) + MAIN.qtype = DNS_T_AAAA; + + if ((error = dns_p_push(Q, DNS_S_QD, MAIN.qname, strlen(MAIN.qname), MAIN.qtype, DNS_C_IN, 0, 0))) + panic("dns_p_push: %s", dns_strerror(error)); + + dns_header(Q)->rd = 1; + + if (strstr(argv[0], "udp")) + type = SOCK_DGRAM; + else if (strstr(argv[0], "tcp")) + type = SOCK_STREAM; + else + type = dns_res_tcp2type(resconf()->options.tcp); + + fprintf(stderr, "querying %s for %s IN %s\n", host, MAIN.qname, dns_strtype(MAIN.qtype)); + + if (!(so = dns_so_open((struct sockaddr *)&resconf()->iface, type, dns_opts(), &error))) + panic("dns_so_open: %s", dns_strerror(error)); + + while (!(A = dns_so_query(so, Q, (struct sockaddr *)&ss, &error))) { + if (error != EAGAIN) + panic("dns_so_query: %s (%d)", dns_strerror(error), error); + if (dns_so_elapsed(so) > 10) + panic("query timed-out"); + + dns_so_poll(so, 1); + } + + print_packet(A, stdout); + + dns_so_close(so); + + return 0; +} /* send_query() */ + + +static int print_arpa(int argc, char *argv[]) { + const char *ip = (argc > 1)? argv[1] : "::1"; + int af = (strchr(ip, ':'))? AF_INET6 : AF_INET; + union { struct in_addr a4; struct in6_addr a6; } addr; + char host[DNS_D_MAXNAME + 1]; + + if (1 != dns_inet_pton(af, ip, &addr) || 0 == dns_ptr_qname(host, sizeof host, af, &addr)) + panic("%s: invalid address", ip); + + fprintf(stdout, "%s\n", host); + + return 0; +} /* print_arpa() */ + + +static int show_hints(int argc, char *argv[]) { + struct dns_hints *(*load)(struct dns_resolv_conf *, int *); + const char *which, *how, *who; + struct dns_hints *hints; + int error; + + which = (argc > 1)? argv[1] : "local"; + how = (argc > 2)? argv[2] : "plain"; + who = (argc > 3)? argv[3] : "google.com"; + + load = (0 == strcmp(which, "local")) + ? &dns_hints_local + : &dns_hints_root; + + if (!(hints = load(resconf(), &error))) + panic("%s: %s", argv[0], dns_strerror(error)); + + if (0 == strcmp(how, "plain")) { + dns_hints_dump(hints, stdout); + } else { + struct dns_packet *query, *answer; + + query = dns_p_new(512); + + if ((error = dns_p_push(query, DNS_S_QUESTION, who, strlen(who), DNS_T_A, DNS_C_IN, 0, 0))) + panic("%s: %s", who, dns_strerror(error)); + + if (!(answer = dns_hints_query(hints, query, &error))) + panic("%s: %s", who, dns_strerror(error)); + + print_packet(answer, stdout); + + free(answer); + } + + dns_hints_close(hints); + + return 0; +} /* show_hints() */ + + +static int resolve_query(int argc, char *argv[]) { + struct dns_hints *(*hints)() = (strstr(argv[0], "recurse"))? &dns_hints_root : &dns_hints_local; + struct dns_resolver *R; + struct dns_packet *ans; + const struct dns_stat *st; + int error; + + if (!MAIN.qname) + MAIN.qname = "www.google.com"; + if (!MAIN.qtype) + MAIN.qtype = DNS_T_A; + + resconf()->options.recurse = (0 != strstr(argv[0], "recurse")); + + if (!(R = dns_res_open(resconf(), hosts(), dns_hints_mortal(hints(resconf(), &error)), cache(), dns_opts(), &error))) + panic("%s: %s", MAIN.qname, dns_strerror(error)); + + if ((error = dns_res_submit(R, MAIN.qname, MAIN.qtype, DNS_C_IN))) + panic("%s: %s", MAIN.qname, dns_strerror(error)); + + while ((error = dns_res_check(R))) { + if (error != EAGAIN) + panic("dns_res_check: %s (%d)", dns_strerror(error), error); + if (dns_res_elapsed(R) > 30) + panic("query timed-out"); + + dns_res_poll(R, 1); + } + + ans = dns_res_fetch(R, &error); + print_packet(ans, stdout); + free(ans); + + st = dns_res_stat(R); + putchar('\n'); + printf(";; queries: %zu\n", st->queries); + printf(";; udp sent: %zu in %zu bytes\n", st->udp.sent.count, st->udp.sent.bytes); + printf(";; udp rcvd: %zu in %zu bytes\n", st->udp.rcvd.count, st->udp.rcvd.bytes); + printf(";; tcp sent: %zu in %zu bytes\n", st->tcp.sent.count, st->tcp.sent.bytes); + printf(";; tcp rcvd: %zu in %zu bytes\n", st->tcp.rcvd.count, st->tcp.rcvd.bytes); + + dns_res_close(R); + + return 0; +} /* resolve_query() */ + + +static int resolve_addrinfo(int argc, char *argv[]) { + struct dns_hints *(*hints)() = (strstr(argv[0], "recurse"))? &dns_hints_root : &dns_hints_local; + struct dns_resolver *res = 0; + struct dns_addrinfo *ai = 0; + struct addrinfo ai_hints = { .ai_family = PF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_flags = AI_CANONNAME }; + struct addrinfo *ent; + char pretty[512]; + int error; + + if (!MAIN.qname) + MAIN.qname = "www.google.com"; + if (!MAIN.qtype) + MAIN.qtype = DNS_T_A; + + resconf()->options.recurse = (0 != strstr(argv[0], "recurse")); + + if (!(res = dns_res_open(resconf(), hosts(), dns_hints_mortal(hints(resconf(), &error)), cache(), dns_opts(), &error))) + panic("%s: %s", MAIN.qname, dns_strerror(error)); + + if (!(ai = dns_ai_open(MAIN.qname, "80", MAIN.qtype, &ai_hints, res, &error))) + panic("%s: %s", MAIN.qname, dns_strerror(error)); + + do { + switch (error = dns_ai_nextent(&ent, ai)) { + case 0: + dns_ai_print(pretty, sizeof pretty, ent, ai); + + fputs(pretty, stdout); + + free(ent); + + break; + case ENOENT: + break; + case EAGAIN: + if (dns_ai_elapsed(ai) > 30) + panic("query timed-out"); + + dns_ai_poll(ai, 1); + + break; + default: + panic("dns_ai_nextent: %s (%d)", dns_strerror(error), error); + } + } while (error != ENOENT); + + dns_res_close(res); + dns_ai_close(ai); + + return 0; +} /* resolve_addrinfo() */ + + +static int echo_port(int argc, char *argv[]) { + union { + struct sockaddr sa; + struct sockaddr_in sin; + } port; + int fd; + + memset(&port, 0, sizeof port); + port.sin.sin_family = AF_INET; + port.sin.sin_port = htons(5354); + port.sin.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (-1 == (fd = socket(PF_INET, SOCK_DGRAM, 0))) + panic("socket: %s", strerror(errno)); + + if (0 != bind(fd, &port.sa, sizeof port.sa)) + panic("127.0.0.1:5353: %s", dns_strerror(errno)); + + for (;;) { + struct dns_packet *pkt = dns_p_new(512); + struct sockaddr_storage ss; + socklen_t slen = sizeof ss; + ssize_t count; +#if defined(MSG_WAITALL) /* MinGW issue */ + int rflags = MSG_WAITALL; +#else + int rflags = 0; +#endif + + count = recvfrom(fd, (char *)pkt->data, pkt->size, rflags, (struct sockaddr *)&ss, &slen); + + + if (!count || count < 0) + panic("recvfrom: %s", strerror(errno)); + + pkt->end = count; + + dns_p_dump(pkt, stdout); + + (void)sendto(fd, (char *)pkt->data, pkt->end, 0, (struct sockaddr *)&ss, slen); + } + + return 0; +} /* echo_port() */ + + +static int isection(int argc, char *argv[]) { + const char *name = (argv[1])? argv[1] : ""; + int type; + + type = dns_isection(name); + name = dns_strsection(type); + + printf("%s (%d)\n", name, type); + + return 0; +} /* isection() */ + + +static int iclass(int argc, char *argv[]) { + const char *name = (argv[1])? argv[1] : ""; + int type; + + type = dns_iclass(name); + name = dns_strclass(type); + + printf("%s (%d)\n", name, type); + + return 0; +} /* iclass() */ + + +static int itype(int argc, char *argv[]) { + const char *name = (argv[1])? argv[1] : ""; + int type; + + type = dns_itype(name); + name = dns_strtype(type); + + printf("%s (%d)\n", name, type); + + return 0; +} /* itype() */ + + +static int iopcode(int argc, char *argv[]) { + const char *name = (argv[1])? argv[1] : ""; + int type; + + type = dns_iopcode(name); + name = dns_stropcode(type); + + printf("%s (%d)\n", name, type); + + return 0; +} /* iopcode() */ + + +static int ircode(int argc, char *argv[]) { + const char *name = (argv[1])? argv[1] : ""; + int type; + + type = dns_ircode(name); + name = dns_strrcode(type); + + printf("%s (%d)\n", name, type); + + return 0; +} /* ircode() */ + + +#define SIZE1(x) { DNS_PP_STRINGIFY(x), sizeof (x) } +#define SIZE2(x, ...) SIZE1(x), SIZE1(__VA_ARGS__) +#define SIZE3(x, ...) SIZE1(x), SIZE2(__VA_ARGS__) +#define SIZE4(x, ...) SIZE1(x), SIZE3(__VA_ARGS__) +#define SIZE(...) DNS_PP_CALL(DNS_PP_XPASTE(SIZE, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) + +static int sizes(int argc, char *argv[]) { + static const struct { const char *name; size_t size; } type[] = { + SIZE(struct dns_header, struct dns_packet, struct dns_rr, struct dns_rr_i), + SIZE(struct dns_a, struct dns_aaaa, struct dns_mx, struct dns_ns), + SIZE(struct dns_cname, struct dns_soa, struct dns_ptr, struct dns_srv), + SIZE(struct dns_sshfp, struct dns_txt, union dns_any), + SIZE(struct dns_resolv_conf, struct dns_hosts, struct dns_hints, struct dns_hints_i), + SIZE(struct dns_options, struct dns_socket, struct dns_resolver, struct dns_addrinfo), + SIZE(struct dns_cache), + }; + unsigned i, max; + + for (i = 0, max = 0; i < lengthof(type); i++) + max = MAX(max, strlen(type[i].name)); + + for (i = 0; i < lengthof(type); i++) + printf("%*s : %zu\n", max, type[i].name, type[i].size); + + return 0; +} /* sizes() */ + + +static const struct { const char *cmd; int (*run)(); const char *help; } cmds[] = { + { "parse-packet", &parse_packet, "parse binary packet from stdin" }, + { "parse-domain", &parse_domain, "anchor and iteratively cleave domain" }, + { "expand-domain", &expand_domain, "expand domain at offset NN in packet from stdin" }, + { "show-resconf", &show_resconf, "show resolv.conf data" }, + { "show-hosts", &show_hosts, "show hosts data" }, + { "query-hosts", &query_hosts, "query A, AAAA or PTR in hosts data" }, + { "search-list", &search_list, "generate query search list from domain" }, + { "permute-set", &permute_set, "generate random permutation -> (0 .. N or N .. M)" }, + { "shuffle-16", &shuffle_16, "simple 16-bit permutation" }, + { "dump-random", &dump_random, "generate random bytes" }, + { "send-query", &send_query, "send query to host" }, + { "send-query-udp", &send_query, "send udp query to host" }, + { "send-query-tcp", &send_query, "send tcp query to host" }, + { "print-arpa", &print_arpa, "print arpa. zone name of address" }, + { "show-hints", &show_hints, "print hints: show-hints [local|root] [plain|packet]" }, + { "resolve-stub", &resolve_query, "resolve as stub resolver" }, + { "resolve-recurse", &resolve_query, "resolve as recursive resolver" }, + { "addrinfo-stub", &resolve_addrinfo, "resolve through getaddrinfo clone" }, + { "addrinfo-recurse", &resolve_addrinfo, "resolve through getaddrinfo clone" }, +/* { "resolve-nameinfo", &resolve_query, "resolve as recursive resolver" }, */ + { "echo", &echo_port, "server echo mode, for nmap fuzzing" }, + { "isection", &isection, "parse section string" }, + { "iclass", &iclass, "parse class string" }, + { "itype", &itype, "parse type string" }, + { "iopcode", &iopcode, "parse opcode string" }, + { "ircode", &ircode, "parse rcode string" }, + { "sizes", &sizes, "print data structure sizes" }, +}; + + +static void print_usage(const char *progname, FILE *fp) { + static const char *usage = + " [OPTIONS] COMMAND [ARGS]\n" + " -c PATH Path to resolv.conf\n" + " -l PATH Path to local hosts\n" + " -z PATH Path to zone cache\n" + " -q QNAME Query name\n" + " -t QTYPE Query type\n" + " -s HOW Sort records\n" + " -v Be more verbose (-vv show packets; -vvv hexdump packets)\n" + " -V Print version info\n" + " -h Print this usage message\n" + "\n"; + unsigned i, n, m; + + fputs(progname, fp); + fputs(usage, fp); + + for (i = 0, m = 0; i < lengthof(cmds); i++) { + if (strlen(cmds[i].cmd) > m) + m = strlen(cmds[i].cmd); + } + + for (i = 0; i < lengthof(cmds); i++) { + fprintf(fp, " %s ", cmds[i].cmd); + + for (n = strlen(cmds[i].cmd); n < m; n++) + putc(' ', fp); + + fputs(cmds[i].help, fp); + putc('\n', fp); + } + + fputs("\nReport bugs to William Ahern \n", fp); +} /* print_usage() */ + + +static void print_version(const char *progname, FILE *fp) { + fprintf(fp, "%s (dns.c) %.8X\n", progname, dns_v_rel()); + fprintf(fp, "vendor %s\n", dns_vendor()); + fprintf(fp, "release %.8X\n", dns_v_rel()); + fprintf(fp, "abi %.8X\n", dns_v_abi()); + fprintf(fp, "api %.8X\n", dns_v_api()); +} /* print_version() */ + + +int main(int argc, char **argv) { + extern int optind; + extern char *optarg; + const char *progname = argv[0]; + unsigned i; + int ch; + + while (-1 != (ch = getopt(argc, argv, "q:t:c:l:z:s:vVh"))) { + switch (ch) { + case 'c': + assert(MAIN.resconf.count < lengthof(MAIN.resconf.path)); + + MAIN.resconf.path[MAIN.resconf.count++] = optarg; + + break; + case 'l': + assert(MAIN.hosts.count < lengthof(MAIN.hosts.path)); + + MAIN.hosts.path[MAIN.hosts.count++] = optarg; + + break; + case 'z': + assert(MAIN.cache.count < lengthof(MAIN.cache.path)); + + MAIN.cache.path[MAIN.cache.count++] = optarg; + + break; + case 'q': + MAIN.qname = optarg; + + break; + case 't': + for (i = 0; i < lengthof(dns_rrtypes); i++) { + if (0 == strcasecmp(dns_rrtypes[i].name, optarg)) + { MAIN.qtype = dns_rrtypes[i].type; break; } + } + + if (MAIN.qtype) + break; + + for (i = 0; isdigit((int)optarg[i]); i++) { + MAIN.qtype *= 10; + MAIN.qtype += optarg[i] - '0'; + } + + if (!MAIN.qtype) + panic("%s: invalid query type", optarg); + + break; + case 's': + if (0 == strcasecmp(optarg, "packet")) + MAIN.sort = &dns_rr_i_packet; + else if (0 == strcasecmp(optarg, "shuffle")) + MAIN.sort = &dns_rr_i_shuffle; + else if (0 == strcasecmp(optarg, "order")) + MAIN.sort = &dns_rr_i_order; + else + panic("%s: invalid sort method", optarg); + + break; + case 'v': + dns_debug = ++MAIN.verbose; + + break; + case 'V': + print_version(progname, stdout); + + return 0; + case 'h': + print_usage(progname, stdout); + + return 0; + default: + print_usage(progname, stderr); + + return EXIT_FAILURE; + } /* switch() */ + } /* while() */ + + argc -= optind; + argv += optind; + + for (i = 0; i < lengthof(cmds) && argv[0]; i++) { + if (0 == strcmp(cmds[i].cmd, argv[0])) + return cmds[i].run(argc, argv); + } + + print_usage(progname, stderr); + + return EXIT_FAILURE; +} /* main() */ + + +#endif /* DNS_MAIN */ diff --git a/src/lib/ecore_con/dns.h b/src/lib/ecore_con/dns.h new file mode 100644 index 0000000000..f9213167e5 --- /dev/null +++ b/src/lib/ecore_con/dns.h @@ -0,0 +1,1076 @@ +/* ========================================================================== + * dns.h - Recursive, Reentrant DNS Resolver. + * -------------------------------------------------------------------------- + * Copyright (c) 2009, 2010 William Ahern + * + * 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 or substantial portions of the Software. + * + * 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 OR COPYRIGHT HOLDERS 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. + * ========================================================================== + */ +#ifndef DNS_H +#define DNS_H + +#include /* size_t offsetof() */ +#include /* FILE */ + +#include /* strlen(3) */ + +#include /* time_t */ + +#if _WIN32 +#include +#include +#else +#include /* socklen_t */ +#include /* struct socket */ + +#include /* POLLIN POLLOUT */ + +#include /* struct in_addr struct in6_addr */ + +#include /* struct addrinfo */ +#endif + +#include /* EINA_UNUSED */ + + +/* + * V E R S I O N + * + * Vendor: Entity for which versions numbers are relevant. (If forking + * change DNS_VENDOR to avoid confusion.) + * + * Three versions: + * + * REL Official "release"--bug fixes, new features, etc. + * ABI Changes to existing object sizes or parameter types. + * API Changes that might effect application source. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define DNS_VENDOR "william@25thandClement.com" + +#define DNS_V_REL 0x20110117 +#define DNS_V_ABI 0x20100709 +#define DNS_V_API 0x20100709 + + +const char *dns_vendor(void); + +int dns_v_rel(void); +int dns_v_abi(void); +int dns_v_api(void); + + +/* + * E R R O R S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +enum dns_errno { + DNS_ENOBUFS = -(('d' << 24) | ('n' << 16) | ('s' << 8) | 64), + DNS_EILLEGAL, + DNS_EORDER, + DNS_ESECTION, + DNS_EUNKNOWN, +}; /* dns_errno */ + +const char *dns_strerror(int); + +extern int dns_debug; + + +/* + * E V E N T S I N T E R F A C E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#if defined(POLLIN) +#define DNS_POLLIN POLLIN +#else +#define DNS_POLLIN 1 +#endif + +#if defined(POLLOUT) +#define DNS_POLLOUT POLLOUT +#else +#define DNS_POLLOUT 2 +#endif + + +/* + * See Application Interface below for configuring libevent bitmasks instead + * of poll(2) bitmasks. + */ +#define DNS_EVREAD 2 +#define DNS_EVWRITE 4 + + +#define DNS_POLL2EV(set) \ + (((set) & DNS_POLLIN)? DNS_EVREAD : 0) | (((set) & DNS_POLLOUT)? DNS_EVWRITE : 0) + +#define DNS_EV2POLL(set) \ + (((set) & DNS_EVREAD)? DNS_POLLIN : 0) | (((set) & DNS_EVWRITE)? DNS_POLLOUT : 0) + + +/* + * E N U M E R A T I O N I N T E R F A C E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +enum dns_section { + DNS_S_QD = 0x01, +#define DNS_S_QUESTION DNS_S_QD + + DNS_S_AN = 0x02, +#define DNS_S_ANSWER DNS_S_AN + + DNS_S_NS = 0x04, +#define DNS_S_AUTHORITY DNS_S_NS + + DNS_S_AR = 0x08, +#define DNS_S_ADDITIONAL DNS_S_AR + + DNS_S_ALL = 0x0f +}; /* enum dns_section */ + + +enum dns_class { + DNS_C_IN = 1, + + DNS_C_ANY = 255 +}; /* enum dns_class */ + + +enum dns_type { + DNS_T_A = 1, + DNS_T_NS = 2, + DNS_T_CNAME = 5, + DNS_T_SOA = 6, + DNS_T_PTR = 12, + DNS_T_MX = 15, + DNS_T_TXT = 16, + DNS_T_AAAA = 28, + DNS_T_SRV = 33, + DNS_T_SSHFP = 44, + DNS_T_SPF = 99, + + DNS_T_ALL = 255 +}; /* enum dns_type */ + + +enum dns_opcode { + DNS_OP_QUERY = 0, + DNS_OP_IQUERY = 1, + DNS_OP_STATUS = 2, + DNS_OP_NOTIFY = 4, + DNS_OP_UPDATE = 5, +}; /* dns_opcode */ + + +enum dns_rcode { + DNS_RC_NOERROR = 0, + DNS_RC_FORMERR = 1, + DNS_RC_SERVFAIL = 2, + DNS_RC_NXDOMAIN = 3, + DNS_RC_NOTIMP = 4, + DNS_RC_REFUSED = 5, + DNS_RC_YXDOMAIN = 6, + DNS_RC_YXRRSET = 7, + DNS_RC_NXRRSET = 8, + DNS_RC_NOTAUTH = 9, + DNS_RC_NOTZONE = 10, +}; /* dns_rcode */ + + +/* + * NOTE: These string functions need a small buffer in case the literal + * integer value needs to be printed and returned. UNLESS this buffer is + * SPECIFIED, the returned string has ONLY BLOCK SCOPE. + */ +#define DNS_STRMAXLEN 47 /* "QUESTION|ANSWER|AUTHORITY|ADDITIONAL" */ + +const char *dns_strsection(enum dns_section, void *, size_t); +#define dns_strsection3(a, b, c) \ + dns_strsection((a), (b), (c)) +#define dns_strsection1(a) dns_strsection((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) +#define dns_strsection(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strsection, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) + +enum dns_section dns_isection(const char *); + +const char *dns_strclass(enum dns_class, void *, size_t); +#define dns_strclass3(a, b, c) dns_strclass((a), (b), (c)) +#define dns_strclass1(a) dns_strclass((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) +#define dns_strclass(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strclass, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) + +enum dns_class dns_iclass(const char *); + +const char *dns_strtype(enum dns_type, void *, size_t); +#define dns_strtype3(a, b, c) dns_strtype((a), (b), (c)) +#define dns_strtype1(a) dns_strtype((a), (char [DNS_STRMAXLEN + 1]){ 0 }, DNS_STRMAXLEN + 1) +#define dns_strtype(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_strtype, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) + +enum dns_type dns_itype(const char *); + +const char *dns_stropcode(enum dns_opcode); + +enum dns_opcode dns_iopcode(const char *); + +const char *dns_strrcode(enum dns_rcode); + +enum dns_rcode dns_ircode(const char *); + + +/* + * A T O M I C I N T E R F A C E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +typedef unsigned long dns_atomic_t; + + +/* + * C R Y P T O I N T E R F A C E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +extern unsigned (*dns_random)(void); + + +/* + * P A C K E T I N T E R F A C E + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_header { + unsigned qid:16; + +#if BYTE_ORDER == BIG_ENDIAN + unsigned qr:1; + unsigned opcode:4; + unsigned aa:1; + unsigned tc:1; + unsigned rd:1; + + unsigned ra:1; + unsigned unused:3; + unsigned rcode:4; +#else + unsigned rd:1; + unsigned tc:1; + unsigned aa:1; + unsigned opcode:4; + unsigned qr:1; + + unsigned rcode:4; + unsigned unused:3; + unsigned ra:1; +#endif + + unsigned qdcount:16; + unsigned ancount:16; + unsigned nscount:16; + unsigned arcount:16; +}; /* struct dns_header */ + +#define dns_header(p) (&(p)->header) + + +#ifndef DNS_P_QBUFSIZ +#define DNS_P_QBUFSIZ dns_p_calcsize(256 + 4) +#endif + +#ifndef DNS_P_DICTSIZE +#define DNS_P_DICTSIZE 16 +#endif + +struct dns_packet { + unsigned short dict[DNS_P_DICTSIZE]; + + struct dns_s_memo { + unsigned short base, end; + } qd, an, ns, ar; + + struct { struct dns_packet *cqe_next, *cqe_prev; } cqe; + + size_t size, end; + + int:16; /* tcp padding */ + + union { + struct dns_header header; + unsigned char data[1]; + }; +}; /* struct dns_packet */ + +#define dns_p_calcsize(n) (offsetof(struct dns_packet, data) + DNS_PP_MAX(12, (n))) + +#define dns_p_sizeof(P) dns_p_calcsize((P)->end) + +/** takes size of maximum desired payload */ +#define dns_p_new(n) (dns_p_init((struct dns_packet *)&(union { unsigned char b[dns_p_calcsize((n))]; struct dns_packet p; }){ { 0 } }, dns_p_calcsize((n)))) + +/** takes size of entire packet structure as allocated */ +struct dns_packet *dns_p_init(struct dns_packet *, size_t); + +/** takes size of maximum desired payload */ +struct dns_packet *dns_p_make(size_t, int *); + +int dns_p_grow(struct dns_packet **); + +struct dns_packet *dns_p_copy(struct dns_packet *, const struct dns_packet *); + +#define dns_p_opcode(P) (dns_header(P)->opcode) + +#define dns_p_rcode(P) (dns_header(P)->rcode) + +unsigned dns_p_count(struct dns_packet *, enum dns_section); + +int dns_p_push(struct dns_packet *, enum dns_section, const void *, size_t, enum dns_type, enum dns_class, unsigned, const void *); + +void dns_p_dictadd(struct dns_packet *, unsigned short); + +struct dns_packet *dns_p_merge(struct dns_packet *, enum dns_section, struct dns_packet *, enum dns_section, int *); + +void dns_p_dump(struct dns_packet *, FILE *); + +int dns_p_study(struct dns_packet *); + + +/* + * D O M A I N N A M E I N T E R F A C E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define DNS_D_MAXLABEL 63 /* + 1 '\0' */ +#define DNS_D_MAXNAME 255 /* + 1 '\0' */ + +#define DNS_D_ANCHOR 1 /* anchor domain w/ root "." */ +#define DNS_D_CLEAVE 2 /* cleave sub-domain */ +#define DNS_D_TRIM 4 /* remove superfluous dots */ + +#define dns_d_new3(a, b, f) dns_d_init(&(char[DNS_D_MAXNAME + 1]){ 0 }, DNS_D_MAXNAME + 1, (a), (b), (f)) +#define dns_d_new2(a, f) dns_d_new3((a), strlen((a)), (f)) +#define dns_d_new1(a) dns_d_new3((a), strlen((a)), DNS_D_ANCHOR) +#define dns_d_new(...) DNS_PP_CALL(DNS_PP_XPASTE(dns_d_new, DNS_PP_NARG(__VA_ARGS__)), __VA_ARGS__) + +char *dns_d_init(void *, size_t, const void *, size_t, int); + +size_t dns_d_anchor(void *, size_t, const void *, size_t); + +size_t dns_d_cleave(void *, size_t, const void *, size_t); + +size_t dns_d_comp(void *, size_t, const void *, size_t, struct dns_packet *, int *); + +size_t dns_d_expand(void *, size_t, unsigned short, struct dns_packet *, int *); + +unsigned short dns_d_skip(unsigned short, struct dns_packet *); + +int dns_d_push(struct dns_packet *, const void *, size_t); + +size_t dns_d_cname(void *, size_t, const void *, size_t, struct dns_packet *, int *error); + + +/* + * R E S O U R C E R E C O R D I N T E R F A C E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_rr { + enum dns_section section; + + struct { + unsigned short p; + unsigned short len; + } dn; + + enum dns_type type; + enum dns_class class; + unsigned ttl; + + struct { + unsigned short p; + unsigned short len; + } rd; +}; /* struct dns_rr */ + + +int dns_rr_copy(struct dns_packet *, struct dns_rr *, struct dns_packet *); + +int dns_rr_parse(struct dns_rr *, unsigned short, struct dns_packet *); + +unsigned short dns_rr_skip(unsigned short, struct dns_packet *); + +int dns_rr_cmp(struct dns_rr *, struct dns_packet *, struct dns_rr *, struct dns_packet *); + +size_t dns_rr_print(void *, size_t, struct dns_rr *, struct dns_packet *, int *); + + +#define dns_rr_i_new(P, ...) dns_rr_i_init(&(struct dns_rr_i){ 0, __VA_ARGS__ }, (P)) + +struct dns_rr_i { + enum dns_section section; + const void *name; + enum dns_type type; + enum dns_class class; + const void *data; + + int follow; + + int (*sort)(); + unsigned args[2]; + + struct { + unsigned short next; + unsigned short count; + + unsigned exec; + unsigned regs[2]; + } state, saved; +}; /* struct dns_rr_i */ + +int dns_rr_i_packet(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); + +int dns_rr_i_order(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); + +int dns_rr_i_shuffle(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); + +struct dns_rr_i *dns_rr_i_init(struct dns_rr_i *, struct dns_packet *); + +#define dns_rr_i_save(i) ((i)->saved = (i)->state) +#define dns_rr_i_rewind(i) ((i)->state = (i)->saved) +#define dns_rr_i_count(i) ((i)->state.count) + +unsigned dns_rr_grep(struct dns_rr *, unsigned, struct dns_rr_i *, struct dns_packet *, int *); + +#define dns_rr_foreach_(rr, P, ...) \ + for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); ) + +#define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__) + + +/* + * A R E S O U R C E R E C O R D + */ + +struct dns_a { + struct in_addr addr; +}; /* struct dns_a */ + +int dns_a_parse(struct dns_a *, struct dns_rr *, struct dns_packet *); + +int dns_a_push(struct dns_packet *, struct dns_a *); + +int dns_a_cmp(const struct dns_a *, const struct dns_a *); + +size_t dns_a_print(void *, size_t, struct dns_a *); + + +/* + * AAAA R E S O U R C E R E C O R D + */ + +struct dns_aaaa { + struct in6_addr addr; +}; /* struct dns_aaaa */ + +int dns_aaaa_parse(struct dns_aaaa *, struct dns_rr *, struct dns_packet *); + +int dns_aaaa_push(struct dns_packet *, struct dns_aaaa *); + +int dns_aaaa_cmp(const struct dns_aaaa *, const struct dns_aaaa *); + +size_t dns_aaaa_print(void *, size_t, struct dns_aaaa *); + + +/* + * MX R E S O U R C E R E C O R D + */ + +struct dns_mx { + unsigned short preference; + char host[DNS_D_MAXNAME + 1]; +}; /* struct dns_mx */ + +int dns_mx_parse(struct dns_mx *, struct dns_rr *, struct dns_packet *); + +int dns_mx_push(struct dns_packet *, struct dns_mx *); + +int dns_mx_cmp(const struct dns_mx *, const struct dns_mx *); + +size_t dns_mx_print(void *, size_t, struct dns_mx *); + +size_t dns_mx_cname(void *, size_t, struct dns_mx *); + + +/* + * NS R E S O U R C E R E C O R D + */ + +struct dns_ns { + char host[DNS_D_MAXNAME + 1]; +}; /* struct dns_ns */ + +int dns_ns_parse(struct dns_ns *, struct dns_rr *, struct dns_packet *); + +int dns_ns_push(struct dns_packet *, struct dns_ns *); + +int dns_ns_cmp(const struct dns_ns *, const struct dns_ns *); + +size_t dns_ns_print(void *, size_t, struct dns_ns *); + +size_t dns_ns_cname(void *, size_t, struct dns_ns *); + + +/* + * CNAME R E S O U R C E R E C O R D + */ + +struct dns_cname { + char host[DNS_D_MAXNAME + 1]; +}; /* struct dns_cname */ + +int dns_cname_parse(struct dns_cname *, struct dns_rr *, struct dns_packet *); + +int dns_cname_push(struct dns_packet *, struct dns_cname *); + +int dns_cname_cmp(const struct dns_cname *, const struct dns_cname *); + +size_t dns_cname_print(void *, size_t, struct dns_cname *); + +size_t dns_cname_cname(void *, size_t, struct dns_cname *); + + +/* + * SOA R E S O U R C E R E C O R D + */ + +struct dns_soa { + char mname[DNS_D_MAXNAME + 1]; + char rname[DNS_D_MAXNAME + 1]; + unsigned serial, refresh, retry, expire, minimum; +}; /* struct dns_soa */ + +int dns_soa_parse(struct dns_soa *, struct dns_rr *, struct dns_packet *); + +int dns_soa_push(struct dns_packet *, struct dns_soa *); + +int dns_soa_cmp(const struct dns_soa *, const struct dns_soa *); + +size_t dns_soa_print(void *, size_t, struct dns_soa *); + + +/* + * PTR R E S O U R C E R E C O R D + */ + +struct dns_ptr { + char host[DNS_D_MAXNAME + 1]; +}; /* struct dns_ptr */ + +int dns_ptr_parse(struct dns_ptr *, struct dns_rr *, struct dns_packet *); + +int dns_ptr_push(struct dns_packet *, struct dns_ptr *); + +int dns_ptr_cmp(const struct dns_ptr *, const struct dns_ptr *); + +size_t dns_ptr_print(void *, size_t, struct dns_ptr *); + +size_t dns_ptr_cname(void *, size_t, struct dns_ptr *); + + +/* + * SRV R E S O U R C E R E C O R D + */ + +struct dns_srv { + unsigned short priority; + unsigned short weight; + unsigned short port; + char target[DNS_D_MAXNAME + 1]; +}; /* struct dns_srv */ + +int dns_srv_parse(struct dns_srv *, struct dns_rr *, struct dns_packet *); + +int dns_srv_push(struct dns_packet *, struct dns_srv *); + +int dns_srv_cmp(const struct dns_srv *, const struct dns_srv *); + +size_t dns_srv_print(void *, size_t, struct dns_srv *); + +size_t dns_srv_cname(void *, size_t, struct dns_srv *); + + +/* + * SSHFP R E S O U R C E R E C O R D + */ + +struct dns_sshfp { + enum dns_sshfp_key { + DNS_SSHFP_RSA = 1, + DNS_SSHFP_DSA = 2, + } algo; + + enum dns_sshfp_digest { + DNS_SSHFP_SHA1 = 1, + } type; + + union { + unsigned char sha1[20]; + } digest; +}; /* struct dns_sshfp */ + +int dns_sshfp_parse(struct dns_sshfp *, struct dns_rr *, struct dns_packet *); + +int dns_sshfp_push(struct dns_packet *, struct dns_sshfp *); + +int dns_sshfp_cmp(const struct dns_sshfp *, const struct dns_sshfp *); + +size_t dns_sshfp_print(void *, size_t, struct dns_sshfp *); + + +/* + * TXT R E S O U R C E R E C O R D + */ + +#ifndef DNS_TXT_MINDATA +#define DNS_TXT_MINDATA 1024 +#endif + +struct dns_txt { + size_t size, len; + unsigned char data[DNS_TXT_MINDATA]; +}; /* struct dns_txt */ + +struct dns_txt *dns_txt_init(struct dns_txt *, size_t); + +int dns_txt_parse(struct dns_txt *, struct dns_rr *, struct dns_packet *); + +int dns_txt_push(struct dns_packet *, struct dns_txt *); + +int dns_txt_cmp(const struct dns_txt *, const struct dns_txt *); + +size_t dns_txt_print(void *, size_t, struct dns_txt *); + + +/* + * ANY R E S O U R C E R E C O R D + */ + +union dns_any { + struct dns_a a; + struct dns_aaaa aaaa; + struct dns_mx mx; + struct dns_ns ns; + struct dns_cname cname; + struct dns_soa soa; + struct dns_ptr ptr; + struct dns_srv srv; + struct dns_sshfp sshfp; + struct dns_txt txt, spf, rdata; +}; /* union dns_any */ + +#define DNS_ANY_INIT(any) { .rdata = { .size = sizeof *(any) } } + +union dns_any *dns_any_init(union dns_any *, size_t); + +int dns_any_parse(union dns_any *, struct dns_rr *, struct dns_packet *); + +int dns_any_push(struct dns_packet *, union dns_any *, enum dns_type); + +int dns_any_cmp(const union dns_any *, enum dns_type, const union dns_any *, enum dns_type); + +size_t dns_any_print(void *, size_t, union dns_any *, enum dns_type); + +size_t dns_any_cname(void *, size_t, union dns_any *, enum dns_type); + + +/* + * H O S T S I N T E R F A C E + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_hosts; + +struct dns_hosts *dns_hosts_open(int *); + +void dns_hosts_close(struct dns_hosts *); + +unsigned dns_hosts_acquire(struct dns_hosts *); + +unsigned dns_hosts_release(struct dns_hosts *); + +struct dns_hosts *dns_hosts_mortal(struct dns_hosts *); + +struct dns_hosts *dns_hosts_local(int *); + +int dns_hosts_loadfile(struct dns_hosts *, FILE *); + +int dns_hosts_loadpath(struct dns_hosts *, const char *); + +int dns_hosts_dump(struct dns_hosts *, FILE *); + +int dns_hosts_insert(struct dns_hosts *, int, const void *, const void *, _Bool); + +struct dns_packet *dns_hosts_query(struct dns_hosts *, struct dns_packet *, int *); + + +/* + * R E S O L V . C O N F I N T E R F A C E + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_resolv_conf { + struct sockaddr_storage nameserver[3]; + + char search[4][DNS_D_MAXNAME + 1]; + + /* (f)ile, (b)ind, (c)ache */ + char lookup[3]; + + struct { + _Bool edns0; + + unsigned ndots; + + unsigned timeout; + + unsigned attempts; + + _Bool rotate; + + _Bool recurse; + + _Bool smart; + + enum { + DNS_RESCONF_TCP_ENABLE, + DNS_RESCONF_TCP_ONLY, + DNS_RESCONF_TCP_DISABLE, + } tcp; + } options; + + struct sockaddr_storage iface; + + struct { /* PRIVATE */ + dns_atomic_t refcount; + } _; +}; /* struct dns_resolv_conf */ + +struct dns_resolv_conf *dns_resconf_open(int *); + +void dns_resconf_close(struct dns_resolv_conf *); + +unsigned dns_resconf_acquire(struct dns_resolv_conf *); + +unsigned dns_resconf_release(struct dns_resolv_conf *); + +struct dns_resolv_conf *dns_resconf_mortal(struct dns_resolv_conf *); + +struct dns_resolv_conf *dns_resconf_local(int *); + +struct dns_resolv_conf *dns_resconf_root(int *); + +int dns_resconf_loadfile(struct dns_resolv_conf *, FILE *); + +int dns_resconf_loadpath(struct dns_resolv_conf *, const char *); + +int dns_resconf_dump(struct dns_resolv_conf *, FILE *); + +int dns_resconf_setiface(struct dns_resolv_conf *, const char *, unsigned short); + +typedef unsigned long dns_resconf_i_t; + +size_t dns_resconf_search(void *, size_t, const void *, size_t, struct dns_resolv_conf *, dns_resconf_i_t *); + + +/* + * H I N T S E R V E R I N T E R F A C E + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_hints; + +struct dns_hints *dns_hints_open(struct dns_resolv_conf *, int *); + +void dns_hints_close(struct dns_hints *); + +unsigned dns_hints_acquire(struct dns_hints *); + +unsigned dns_hints_release(struct dns_hints *); + +struct dns_hints *dns_hints_mortal(struct dns_hints *); + +int dns_hints_insert(struct dns_hints *, const char *, const struct sockaddr *, unsigned); + +unsigned dns_hints_insert_resconf(struct dns_hints *, const char *, const struct dns_resolv_conf *, int *); + +struct dns_hints *dns_hints_local(struct dns_resolv_conf *, int *); + +struct dns_hints *dns_hints_root(struct dns_resolv_conf *, int *); + + +struct dns_hints_i { + const char *zone; + + struct { + unsigned next; + unsigned seed; + } state; +}; /* struct dns_hints_i */ + +#define dns_hints_i_new(...) (&(struct dns_hints_i){ __VA_ARGS__ }) + +unsigned dns_hints_grep(struct sockaddr **, socklen_t *, unsigned, struct dns_hints_i *, struct dns_hints *); + + +/* + * C A C H E I N T E R F A C E + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_cache { + void *state; + + dns_atomic_t (*acquire)(struct dns_cache *); + dns_atomic_t (*release)(struct dns_cache *); + + struct dns_packet *(*query)(struct dns_packet *, struct dns_cache *, int *); + + int (*submit)(struct dns_packet *, struct dns_cache *); + int (*check)(struct dns_cache *); + struct dns_packet *(*fetch)(struct dns_cache *, int *); + + int (*pollfd)(struct dns_cache *); + short (*events)(struct dns_cache *); + void (*clear)(struct dns_cache *); + + union { + long i; + void *p; + } arg[3]; +}; /* struct dns_cache */ + + +struct dns_cache *dns_cache_init(struct dns_cache *); + +void dns_cache_close(struct dns_cache *); + + +/* + * A P P L I C A T I O N I N T E R F A C E + * + * Options to change the behavior of the API. Applies across all the + * different components. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define DNS_OPTS_INITIALIZER_ { 0, 0 }, 0 +#define DNS_OPTS_INITIALIZER { DNS_OPTS_INITIALIZER_ } +#define DNS_OPTS_INIT(...) { DNS_OPTS_INITIALIZER_, __VA_ARGS__ } + +#define dns_opts(...) (&(struct dns_options)DNS_OPTS_INIT(__VA_ARGS__)) + +struct dns_options { + /* + * If the callback closes *fd, it must set it to -1. Otherwise, the + * descriptor is queued and lazily closed at object destruction or + * by an explicit call to _clear(). This allows safe use of + * kqueue(2), epoll(2), et al -style persistent events. + */ + struct { + void *arg; + int (*cb)(int *fd, void *arg); + } closefd; + + /* bitmask for _events() routines */ + enum dns_events { + DNS_SYSPOLL, + DNS_LIBEVENT, + } events; +}; /* struct dns_options */ + + +/* + * S T A T S I N T E R F A C E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_stat { + size_t queries; + + struct { + struct { + size_t count, bytes; + } sent, rcvd; + } udp, tcp; +}; /* struct dns_stat */ + + +/* + * S O C K E T I N T E R F A C E + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_socket; + +struct dns_socket *dns_so_open(const struct sockaddr *, int, const struct dns_options *, int *error); + +void dns_so_close(struct dns_socket *); + +void dns_so_reset(struct dns_socket *); + +unsigned short dns_so_mkqid(struct dns_socket *so); + +struct dns_packet *dns_so_query(struct dns_socket *, struct dns_packet *, struct sockaddr *, int *); + +int dns_so_submit(struct dns_socket *, struct dns_packet *, struct sockaddr *); + +int dns_so_check(struct dns_socket *); + +struct dns_packet *dns_so_fetch(struct dns_socket *, int *); + +time_t dns_so_elapsed(struct dns_socket *); + +void dns_so_clear(struct dns_socket *); + +int dns_so_events(struct dns_socket *); + +int dns_so_pollfd(struct dns_socket *); + +int dns_so_poll(struct dns_socket *, int); + +const struct dns_stat *dns_so_stat(struct dns_socket *); + + +/* + * R E S O L V E R I N T E R F A C E + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_resolver; + +struct dns_resolver *dns_res_open(struct dns_resolv_conf *, struct dns_hosts *hosts, struct dns_hints *, struct dns_cache *, const struct dns_options *, int *); + +struct dns_resolver *dns_res_stub(const struct dns_options *, int *); + +void dns_res_reset(struct dns_resolver *); + +void dns_res_close(struct dns_resolver *); + +unsigned dns_res_acquire(struct dns_resolver *); + +unsigned dns_res_release(struct dns_resolver *); + +struct dns_resolver *dns_res_mortal(struct dns_resolver *); + +int dns_res_submit(struct dns_resolver *, const char *, enum dns_type, enum dns_class); + +int dns_res_check(struct dns_resolver *); + +struct dns_packet *dns_res_fetch(struct dns_resolver *, int *); + +time_t dns_res_elapsed(struct dns_resolver *); + +void dns_res_clear(struct dns_resolver *); + +int dns_res_events(struct dns_resolver *); + +int dns_res_pollfd(struct dns_resolver *); + +int dns_res_poll(struct dns_resolver *, int); + +struct dns_packet *dns_res_query(struct dns_resolver *, const char *, enum dns_type, enum dns_class, int, int *); + +const struct dns_stat *dns_res_stat(struct dns_resolver *); + + +/* + * A D D R I N F O I N T E R F A C E + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct dns_addrinfo; + +struct dns_addrinfo *dns_ai_open(const char *, const char *, enum dns_type, const struct addrinfo *, struct dns_resolver *, int *); + +void dns_ai_close(struct dns_addrinfo *); + +int dns_ai_nextent(struct addrinfo **, struct dns_addrinfo *); + +size_t dns_ai_print(void *, size_t, struct addrinfo *, struct dns_addrinfo *); + +time_t dns_ai_elapsed(struct dns_addrinfo *); + +void dns_ai_clear(struct dns_addrinfo *); + +int dns_ai_events(struct dns_addrinfo *); + +int dns_ai_pollfd(struct dns_addrinfo *); + +int dns_ai_poll(struct dns_addrinfo *, int); + +const struct dns_stat *dns_ai_stat(struct dns_addrinfo *); + +void *dns_sa_addr(int af, void *sa); +unsigned short *dns_sa_port(int af, void *sa); +#if _WIN32 +const char *dns_inet_ntop(int af, const void *src, void *dst, unsigned long lim); +#else +#define dns_inet_pton(...) inet_pton(__VA_ARGS__) +#define dns_inet_ntop(...) inet_ntop(__VA_ARGS__) +#endif +#define dns_sa_family(sa) (((struct sockaddr *)(sa))->sa_family) +/* + * U T I L I T Y I N T E R F A C E S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +size_t dns_strlcpy(char *, const char *, size_t); + +size_t dns_strlcat(char *, const char *, size_t); + + +/* + * M A C R O M A G I C S + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define DNS_PP_MAX(a, b) (((a) > (b))? (a) : (b)) +#define DNS_PP_NARG_(a, b, c, d, e, f, g, h, i, j, k, N,...) N +#define DNS_PP_NARG(...) DNS_PP_NARG_(__VA_ARGS__, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define DNS_PP_CALL(F, ...) F(__VA_ARGS__) +#define DNS_PP_PASTE(x, y) x##y +#define DNS_PP_XPASTE(x, y) DNS_PP_PASTE(x, y) +#define DNS_PP_STRINGIFY_(s) #s +#define DNS_PP_STRINGIFY(s) DNS_PP_STRINGIFY_(s) +#define DNS_PP_D1 0 +#define DNS_PP_D2 1 +#define DNS_PP_D3 2 +#define DNS_PP_D4 3 +#define DNS_PP_D5 4 +#define DNS_PP_D6 5 +#define DNS_PP_D7 6 +#define DNS_PP_D8 7 +#define DNS_PP_D9 8 +#define DNS_PP_D10 9 +#define DNS_PP_D11 10 +#define DNS_PP_DEC(N) DNS_PP_XPASTE(DNS_PP_D, N) + +#endif /* DNS_H */ diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c new file mode 100644 index 0000000000..056db2eec0 --- /dev/null +++ b/src/lib/ecore_con/ecore_con.c @@ -0,0 +1,2596 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_NETINET_TCP_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +#ifdef HAVE_SYS_UN_H +# include +#endif + +#ifdef HAVE_WS2TCPIP_H +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Con.h" +#include "ecore_con_private.h" + +static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl); +static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl); +static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr); +static void _ecore_con_server_timer_update(Ecore_Con_Server *svr); + +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 void _ecore_con_cl_read(Ecore_Con_Server *svr); +static Eina_Bool _ecore_con_svr_tcp_handler(void *data, + Ecore_Fd_Handler *fd_handler); +static Eina_Bool _ecore_con_cl_handler(void *data, + Ecore_Fd_Handler *fd_handler); +static Eina_Bool _ecore_con_cl_udp_handler(void *data, + Ecore_Fd_Handler *fd_handler); +static Eina_Bool _ecore_con_svr_udp_handler(void *data, + Ecore_Fd_Handler *fd_handler); + +static void _ecore_con_svr_cl_read(Ecore_Con_Client *cl); +static Eina_Bool _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(Ecore_Con_Server *svr, + void *ev); +static void _ecore_con_event_client_del_free(Ecore_Con_Server *svr, + void *ev); +static void _ecore_con_event_client_data_free(Ecore_Con_Server *svr, + 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); +static void _ecore_con_event_server_error_free(void *data, + Ecore_Con_Event_Server_Error *e); +static void _ecore_con_event_client_error_free(Ecore_Con_Server *svr, + Ecore_Con_Event_Client_Error *e); +static void _ecore_con_event_server_write_free(void *data, + Ecore_Con_Event_Server_Write *e); +static void _ecore_con_event_client_write_free(Ecore_Con_Server *svr, + Ecore_Con_Event_Client_Write *e); + +static void _ecore_con_lookup_done(void *data, + Ecore_Con_Info *infos); + +static const char * _ecore_con_pretty_ip(struct sockaddr *client_addr); + + +void +_ecore_con_client_kill(Ecore_Con_Client *cl) +{ + if (cl->delete_me) + DBG("Multi kill request for client %p", cl); + else + { + ecore_con_event_client_del(cl); + if (cl->buf) return; + } + INF("Lost client %s", (cl->ip) ? cl->ip : ""); + if (cl->fd_handler) + ecore_main_fd_handler_del(cl->fd_handler); + + cl->fd_handler = NULL; +} + +void +_ecore_con_server_kill(Ecore_Con_Server *svr) +{ + if (svr->delete_me) + DBG("Multi kill request for svr %p", svr); + else + ecore_con_event_server_del(svr); + + if (svr->fd_handler) + ecore_main_fd_handler_del(svr->fd_handler); + + svr->fd_handler = NULL; +} + +#define _ecore_con_server_kill(svr) do { \ + DBG("KILL %p", (svr)); \ + _ecore_con_server_kill((svr)); \ +} while (0) + +#define _ecore_con_client_kill(cl) do { \ + DBG("KILL %p", (cl)); \ + _ecore_con_client_kill((cl)); \ +} while (0) + +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; +EAPI int ECORE_CON_EVENT_CLIENT_WRITE = 0; +EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0; +EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0; +EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0; +EAPI int ECORE_CON_EVENT_PROXY_BIND = 0; + +static Eina_List *servers = NULL; +static int _ecore_con_init_count = 0; +static int _ecore_con_event_count = 0; +int _ecore_con_log_dom = -1; +Ecore_Con_Socks *_ecore_con_proxy_once = NULL; +Ecore_Con_Socks *_ecore_con_proxy_global = NULL; + +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 + ("ecore_con", 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_mempool_init(); + + 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(); + ECORE_CON_EVENT_CLIENT_WRITE = ecore_event_type_new(); + ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new(); + ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new(); + ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new(); + ECORE_CON_EVENT_PROXY_BIND = ecore_event_type_new(); + + + eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server"); + eina_magic_string_set(ECORE_MAGIC_CON_CLIENT, "Ecore_Con_Client"); + eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url"); + + /* TODO Remember return value, if it fails, use gethostbyname() */ + ecore_con_socks_init(); + ecore_con_ssl_init(); + ecore_con_info_init(); + + return _ecore_con_init_count; +} + +EAPI int +ecore_con_shutdown(void) +{ + Eina_List *l, *l2; + Ecore_Con_Server *svr; + + if (--_ecore_con_init_count != 0) + return _ecore_con_init_count; + + EINA_LIST_FOREACH_SAFE(servers, l, l2, svr) + { + Ecore_Con_Event_Server_Add *ev; + + svr->delete_me = EINA_TRUE; + INF("svr %p is dead", svr); + /* some pointer hacks here to prevent double frees if people are being stupid */ + EINA_LIST_FREE(svr->event_count, ev) + ev->server = NULL; + _ecore_con_server_free(svr); + } + + ecore_con_socks_shutdown(); + if (!_ecore_con_event_count) ecore_con_mempool_shutdown(); + + 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; +} + +EAPI Eina_Bool +ecore_con_lookup(const char *name, + Ecore_Con_Dns_Cb done_cb, + const void *data) +{ + Ecore_Con_Server *svr; + Ecore_Con_Lookup *lk; + struct addrinfo hints; + + if (!name || !done_cb) + return EINA_FALSE; + + svr = calloc(1, sizeof(Ecore_Con_Server)); + if (!svr) + return EINA_FALSE; + + lk = malloc(sizeof (Ecore_Con_Lookup)); + if (!lk) + { + free(svr); + return EINA_FALSE; + } + + lk->done_cb = done_cb; + lk->data = data; + + svr->name = strdup(name); + if (!svr->name) + goto on_error; + + svr->type = ECORE_CON_REMOTE_TCP; + svr->port = 1025; + svr->data = lk; + svr->created = EINA_TRUE; + svr->reject_excess_clients = EINA_FALSE; + svr->client_limit = -1; + svr->clients = NULL; + svr->ppid = getpid(); + + 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; + + if (ecore_con_info_get(svr, _ecore_con_lookup_done, svr, + &hints)) + return EINA_TRUE; + + free(svr->name); +on_error: + free(lk); + free(svr); + return EINA_FALSE; +} + +/** + * @addtogroup Ecore_Con_Server_Group Ecore Connection Server Functions + * + * Functions that operate on Ecore server objects. + * + * @{ + */ + +/** + * @example ecore_con_server_example.c + * Shows how to write a simple server using the Ecore_Con library. + */ + +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 = EINA_TRUE; + svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT; + svr->reject_excess_clients = EINA_FALSE; + svr->client_limit = -1; + svr->clients = NULL; + svr->ppid = getpid(); + if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL)) + goto error; + + type = compl_type & ECORE_CON_TYPE; + + if ((type == ECORE_CON_LOCAL_USER) || + (type == ECORE_CON_LOCAL_SYSTEM) || + (type == ECORE_CON_LOCAL_ABSTRACT)) + /* Local */ +#ifdef _WIN32 + if (!ecore_con_local_listen(svr)) + goto error; +#else + if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr)) + goto error; +#endif + + if ((type == ECORE_CON_REMOTE_TCP) || + (type == ECORE_CON_REMOTE_NODELAY) || + (type == ECORE_CON_REMOTE_CORK)) + { + /* 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); + + + if (svr->fd_handler) + ecore_main_fd_handler_del(svr->fd_handler); + + if (svr->fd > 0) + close(svr->fd); + + if (svr->buf) + eina_binbuf_free(svr->buf); + + if (svr->ip) + eina_stringshare_del(svr->ip); + + ecore_con_ssl_server_shutdown(svr); + free(svr); + return NULL; +} + +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) || (!name[0])) + 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 = EINA_FALSE; + svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT; + svr->disable_proxy = (compl_type & ECORE_CON_SUPER_SSL & ECORE_CON_NO_PROXY) == ECORE_CON_NO_PROXY; + svr->reject_excess_clients = EINA_FALSE; + svr->clients = NULL; + svr->client_limit = -1; + + type = compl_type & ECORE_CON_TYPE; + + if ((!svr->disable_proxy) && (type > ECORE_CON_LOCAL_ABSTRACT)) + { + /* never use proxies on local connections */ + if (_ecore_con_proxy_once) + svr->ecs = _ecore_con_proxy_once; + else if (_ecore_con_proxy_global) + svr->ecs = _ecore_con_proxy_global; + _ecore_con_proxy_once = NULL; + if (svr->ecs) + { + if ((!svr->ecs->lookup) && + (!ecore_con_lookup(svr->name, (Ecore_Con_Dns_Cb)ecore_con_socks_dns_cb, svr))) + goto error; + if (svr->ecs->lookup) + svr->ecs_state = ECORE_CON_PROXY_STATE_RESOLVED; + } + } + EINA_SAFETY_ON_TRUE_GOTO(ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL), error); + + EINA_SAFETY_ON_TRUE_GOTO(((type == ECORE_CON_REMOTE_TCP) || + (type == ECORE_CON_REMOTE_NODELAY) || + (type == ECORE_CON_REMOTE_CORK) || + (type == ECORE_CON_REMOTE_UDP) || + (type == ECORE_CON_REMOTE_BROADCAST)) && + (port < 0), error); + + if ((type == ECORE_CON_LOCAL_USER) || + (type == ECORE_CON_LOCAL_SYSTEM) || + (type == ECORE_CON_LOCAL_ABSTRACT)) + /* Local */ +#ifdef _WIN32 + EINA_SAFETY_ON_FALSE_GOTO(ecore_con_local_connect(svr, _ecore_con_cl_handler), error); +#else + EINA_SAFETY_ON_FALSE_GOTO(ecore_con_local_connect(svr, _ecore_con_cl_handler, svr), error); +#endif + + if ((type == ECORE_CON_REMOTE_TCP) || + (type == ECORE_CON_REMOTE_NODELAY) || + (type == ECORE_CON_REMOTE_CORK)) + { + /* TCP */ + EINA_SAFETY_ON_FALSE_GOTO(ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, svr), error); + } + else if ((type == ECORE_CON_REMOTE_UDP) || (type == ECORE_CON_REMOTE_BROADCAST)) + /* UDP and MCAST */ + EINA_SAFETY_ON_FALSE_GOTO(ecore_con_info_udp_connect(svr, _ecore_con_cb_udp_connect, svr), 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_handler) + ecore_main_fd_handler_del(svr->fd_handler); + + if (svr->fd > 0) + close(svr->fd); + + ecore_con_ssl_server_shutdown(svr); + free(svr); + return NULL; +} + +EAPI void +ecore_con_server_timeout_set(Ecore_Con_Server *svr, + double timeout) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_timeout_set"); + return; + } + + if (svr->created) + svr->client_disconnect_time = timeout; + else + svr->disconnect_time = timeout; +} + +EAPI double +ecore_con_server_timeout_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_timeout_get"); + return 0; + } + + return svr->created ? svr->client_disconnect_time : svr->disconnect_time; +} + +EAPI void * +ecore_con_server_del(Ecore_Con_Server *svr) +{ + 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; + + _ecore_con_server_kill(svr); + return svr->data; +} + +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; +} + +EAPI void * +ecore_con_server_data_set(Ecore_Con_Server *svr, + void *data) +{ + void *ret = NULL; + + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get"); + return NULL; + } + + ret = svr->data; + svr->data = data; + return ret; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + + if (svr->connecting) + return EINA_FALSE; + + return EINA_TRUE; +} + +EAPI const 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; +} + +EAPI const char * +ecore_con_server_name_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_name_get"); + return NULL; + } + + return svr->name; +} + +EAPI int +ecore_con_server_port_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_port_get"); + return -1; + } + return svr->port; +} + +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; + } + + EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->delete_me, 0); + + EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); + + EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0); + + if (svr->fd_handler) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); + + if (!svr->buf) + { + svr->buf = eina_binbuf_new(); + EINA_SAFETY_ON_NULL_RETURN_VAL(svr->buf, 0); +#ifdef TCP_CORK + if ((svr->fd >= 0) && ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)) + { + int state = 1; + if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) + /* realistically this isn't anything serious so we can just log and continue */ + ERR("corking failed! %s", strerror(errno)); + } +#endif + } + eina_binbuf_append_length(svr->buf, data, size); + + return size; +} + +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; +} + +EAPI const 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; +} + +EAPI double +ecore_con_server_uptime_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_uptime_get"); + return -1; + } + + return ecore_time_get() - svr->start_time; +} + +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); +} + +/** + * @} + */ + +/** + * @addtogroup Ecore_Con_Client_Group Ecore Connection Client Functions + * + * Functions that operate on Ecore connection client objects. + * + * @{ + */ + +/** + * @example ecore_con_client_example.c + * Shows how to write a simple client that connects to the example server. + */ + +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; + } + + EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->delete_me, 0); + + EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); + + EINA_SAFETY_ON_TRUE_RETURN_VAL(size < 1, 0); + + if (cl->fd_handler) + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); + + if (cl->host_server && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP)) + sendto(cl->host_server->fd, data, size, 0, (struct sockaddr *)cl->client_addr, + cl->client_addr_len); + else if (!cl->buf) + { + cl->buf = eina_binbuf_new(); + EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0); +#ifdef TCP_CORK + if ((cl->fd >= 0) && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)) + { + int state = 1; + if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) + /* realistically this isn't anything serious so we can just log and continue */ + ERR("corking failed! %s", strerror(errno)); + } +#endif + } + eina_binbuf_append_length(cl->buf, data, size); + + return size; +} + +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->host_server; +} + +EAPI Eina_Bool +ecore_con_client_connected_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_connected_get"); + return EINA_FALSE; + } + + return !cl->delete_me; +} + +EAPI void +ecore_con_client_timeout_set(Ecore_Con_Client *cl, + double timeout) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, + "ecore_con_client_timeout_set"); + return; + } + + cl->disconnect_time = timeout; + + _ecore_con_cl_timer_update(cl); +} + +EAPI double +ecore_con_client_timeout_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_timeout_get"); + return 0; + } + + return cl->disconnect_time; +} + +EAPI void * +ecore_con_client_del(Ecore_Con_Client *cl) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); + return NULL; + } + + _ecore_con_client_kill(cl); + return cl->data; +} + +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; +} + +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; +} + +EAPI const 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; + } + if (!cl->ip) + cl->ip = _ecore_con_pretty_ip(cl->client_addr); + + return cl->ip; +} + +EAPI int +ecore_con_client_port_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_port_get"); + return -1; + } + if (cl->client_addr->sa_family == AF_INET) + return ((struct sockaddr_in*)cl->client_addr)->sin_port; +#ifdef HAVE_IPV6 + return ((struct sockaddr_in6*)cl->client_addr)->sin6_port; +#else + return -1; +#endif +} + +EAPI double +ecore_con_client_uptime_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_uptime_get"); + return -1; + } + + return ecore_time_get() - cl->start_time; +} + +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); +} + +EAPI int +ecore_con_server_fd_get(Ecore_Con_Server *svr) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); + return -1; + } + if (svr->created) return -1; + if (svr->delete_me) return -1; + return ecore_main_fd_handler_fd_get(svr->fd_handler); +} + +EAPI int +ecore_con_client_fd_get(Ecore_Con_Client *cl) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__); + return -1; + } + return ecore_main_fd_handler_fd_get(cl->fd_handler); +} + +/** + * @} + */ + +void +ecore_con_event_proxy_bind(Ecore_Con_Server *svr) +{ + Ecore_Con_Event_Proxy_Bind *e; + int ev = ECORE_CON_EVENT_PROXY_BIND; + + e = ecore_con_event_proxy_bind_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + svr->event_count = eina_list_append(svr->event_count, e); + _ecore_con_server_timer_update(svr); + e->server = svr; + e->ip = svr->proxyip; + e->port = svr->proxyport; + ecore_event_add(ev, e, + _ecore_con_event_server_add_free, NULL); + _ecore_con_event_count++; +} + +void +ecore_con_event_server_add(Ecore_Con_Server *svr) +{ + /* we got our server! */ + Ecore_Con_Event_Server_Add *e; + int ev = ECORE_CON_EVENT_SERVER_ADD; + + e = ecore_con_event_server_add_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + svr->connecting = EINA_FALSE; + svr->start_time = ecore_time_get(); + svr->event_count = eina_list_append(svr->event_count, e); + _ecore_con_server_timer_update(svr); + e->server = svr; + if (svr->upgrade) ev = ECORE_CON_EVENT_SERVER_UPGRADE; + ecore_event_add(ev, e, + _ecore_con_event_server_add_free, NULL); + _ecore_con_event_count++; +} + +void +ecore_con_event_server_del(Ecore_Con_Server *svr) +{ + Ecore_Con_Event_Server_Del *e; + + svr->delete_me = EINA_TRUE; + INF("svr %p is dead", svr); + e = ecore_con_event_server_del_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + svr->event_count = eina_list_append(svr->event_count, e); + _ecore_con_server_timer_update(svr); + e->server = svr; + if (svr->ecs) + { + svr->ecs_state = svr->ecs->lookup ? ECORE_CON_PROXY_STATE_RESOLVED : ECORE_CON_PROXY_STATE_DONE; + eina_stringshare_replace(&svr->proxyip, NULL); + svr->proxyport = 0; + } + ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e, + _ecore_con_event_server_del_free, NULL); + _ecore_con_event_count++; +} + +void +ecore_con_event_server_write(Ecore_Con_Server *svr, int num) +{ + Ecore_Con_Event_Server_Write *e; + + e = ecore_con_event_server_write_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + INF("Wrote %d bytes", num); + svr->event_count = eina_list_append(svr->event_count, e); + e->server = svr; + e->size = num; + ecore_event_add(ECORE_CON_EVENT_SERVER_WRITE, e, + (Ecore_End_Cb)_ecore_con_event_server_write_free, NULL); + _ecore_con_event_count++; +} + +void +ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate) +{ + Ecore_Con_Event_Server_Data *e; + + e = ecore_con_event_server_data_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + svr->event_count = eina_list_append(svr->event_count, e); + _ecore_con_server_timer_update(svr); + e->server = svr; + if (duplicate) + { + e->data = malloc(num); + if (!e->data) + { + ERR("server data allocation failure !"); + _ecore_con_event_server_data_free(NULL, e); + return; + } + memcpy(e->data, buf, num); + } + else + e->data = buf; + e->size = num; + ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e, + _ecore_con_event_server_data_free, NULL); + _ecore_con_event_count++; +} + +void +ecore_con_event_client_add(Ecore_Con_Client *cl) +{ + Ecore_Con_Event_Client_Add *e; + int ev = ECORE_CON_EVENT_CLIENT_ADD; + + e = ecore_con_event_client_add_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + cl->event_count = eina_list_append(cl->event_count, e); + cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); + _ecore_con_cl_timer_update(cl); + e->client = cl; + if (cl->upgrade) ev = ECORE_CON_EVENT_CLIENT_UPGRADE; + ecore_event_add(ev, e, + (Ecore_End_Cb)_ecore_con_event_client_add_free, cl->host_server); + _ecore_con_event_count++; +} + +void +ecore_con_event_client_del(Ecore_Con_Client *cl) +{ + Ecore_Con_Event_Client_Del *e; + + if (!cl) return; + cl->delete_me = EINA_TRUE; + INF("cl %p is dead", cl); + e = ecore_con_event_client_del_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + cl->event_count = eina_list_append(cl->event_count, e); + + cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); + _ecore_con_cl_timer_update(cl); + e->client = cl; + ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, + (Ecore_End_Cb)_ecore_con_event_client_del_free, cl->host_server); + _ecore_con_event_count++; +} + +void +ecore_con_event_client_write(Ecore_Con_Client *cl, int num) +{ + Ecore_Con_Event_Client_Write *e; + + e = ecore_con_event_client_write_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + cl->event_count = eina_list_append(cl->event_count, e); + cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); + e->client = cl; + e->size = num; + ecore_event_add(ECORE_CON_EVENT_CLIENT_WRITE, e, + (Ecore_End_Cb)_ecore_con_event_client_write_free, cl->host_server); + _ecore_con_event_count++; +} + +void +ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate) +{ + Ecore_Con_Event_Client_Data *e; + + e = ecore_con_event_client_data_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + cl->event_count = eina_list_append(cl->event_count, e); + cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); + _ecore_con_cl_timer_update(cl); + e->client = cl; + if (duplicate) + { + e->data = malloc(num); + if (!e->data) + { + ERR("client data allocation failure !"); + _ecore_con_event_client_data_free(cl->host_server, e); + return; + } + memcpy(e->data, buf, num); + } + else + e->data = buf; + e->size = num; + ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e, + (Ecore_End_Cb)_ecore_con_event_client_data_free, cl->host_server); + _ecore_con_event_count++; +} + + +void +ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info) +{ + svr->infos = eina_list_remove(svr->infos, info); +} + +void +_ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate) +{ + Ecore_Con_Event_Server_Error *e; + + e = ecore_con_event_server_error_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + e->server = svr; + e->error = duplicate ? strdup(error) : error; + ERR("%s", error); + svr->event_count = eina_list_append(svr->event_count, e); + ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL); + _ecore_con_event_count++; +} + +void +ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error) +{ + Ecore_Con_Event_Client_Error *e; + + e = ecore_con_event_client_error_alloc(); + EINA_SAFETY_ON_NULL_RETURN(e); + + e->client = cl; + e->error = strdup(error); + ERR("%s", error); + cl->event_count = eina_list_append(cl->event_count, e); + cl->host_server->event_count = eina_list_append(cl->host_server->event_count, e); + ecore_event_add(ECORE_CON_EVENT_CLIENT_ERROR, e, (Ecore_End_Cb)_ecore_con_event_client_error_free, cl->host_server); + _ecore_con_event_count++; +} + +static void +_ecore_con_server_free(Ecore_Con_Server *svr) +{ + Ecore_Con_Client *cl; + double t_start, t; + + if (svr->event_count) return; + + while (svr->infos) + { + ecore_con_info_data_clear(svr->infos->data); + svr->infos = eina_list_remove_list(svr->infos, svr->infos); + } + + t_start = ecore_time_get(); + while (svr->buf && (!svr->delete_me)) + { + _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; + } + } + +#ifdef _WIN32 + ecore_con_local_win32_server_del(svr); +#endif + if (svr->event_count) return; + ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE); + + if (svr->buf) + eina_binbuf_free(svr->buf); + + EINA_LIST_FREE(svr->clients, cl) + { + Ecore_Con_Event_Server_Add *ev; + + /* some pointer hacks here to prevent double frees if people are being stupid */ + EINA_LIST_FREE(cl->event_count, ev) + ev->server = NULL; + cl->delete_me = EINA_TRUE; + INF("cl %p is dead", cl); + _ecore_con_client_free(cl); + } + if ((svr->created) && (svr->path) && (svr->ppid == getpid())) + unlink(svr->path); + + ecore_con_ssl_server_shutdown(svr); + free(svr->name); + + free(svr->path); + + eina_stringshare_del(svr->ip); + eina_stringshare_del(svr->verify_name); + + if (svr->ecs_buf) eina_binbuf_free(svr->ecs_buf); + if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); + + if (svr->fd_handler) + ecore_main_fd_handler_del(svr->fd_handler); + + if (svr->fd > 0) + close(svr->fd); + + if (svr->until_deletion) + ecore_timer_del(svr->until_deletion); + + servers = eina_list_remove(servers, svr); + svr->data = NULL; + free(svr); +} + +static void +_ecore_con_client_free(Ecore_Con_Client *cl) +{ + double t_start, t; + + if (cl->event_count) return; + + t_start = ecore_time_get(); + while ((cl->buf) && (!cl->delete_me)) + { + _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; + } + } + cl->host_server->clients = eina_list_remove(cl->host_server->clients, cl); + +#ifdef _WIN32 + ecore_con_local_win32_client_del(cl); +#endif + + if (cl->event_count) return; + ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE); + + if (cl->buf) eina_binbuf_free(cl->buf); + + if (cl->host_server->type & ECORE_CON_SSL) + ecore_con_ssl_client_shutdown(cl); + + if (cl->fd_handler) + ecore_main_fd_handler_del(cl->fd_handler); + + if (cl->fd > 0) + close(cl->fd); + + free(cl->client_addr); + cl->client_addr = NULL; + + if (cl->until_deletion) + ecore_timer_del(cl->until_deletion); + + eina_stringshare_del(cl->ip); + cl->data = NULL; + free(cl); + return; +} + +static Eina_Bool +_ecore_con_server_timer(Ecore_Con_Server *svr) +{ + ecore_con_server_del(svr); + + svr->until_deletion = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void +_ecore_con_server_timer_update(Ecore_Con_Server *svr) +{ + if (svr->disconnect_time) + { + if (svr->disconnect_time > 0) + { + if (svr->until_deletion) + ecore_timer_interval_set(svr->until_deletion, svr->disconnect_time); + else + svr->until_deletion = ecore_timer_add(svr->disconnect_time, (Ecore_Task_Cb)_ecore_con_server_timer, svr); + } + else if (svr->until_deletion) + { + ecore_timer_del(svr->until_deletion); + svr->until_deletion = NULL; + } + } + else + { + if (svr->until_deletion) + { + ecore_timer_del(svr->until_deletion); + svr->until_deletion = NULL; + } + } +} + +static Eina_Bool +_ecore_con_client_timer(Ecore_Con_Client *cl) +{ + ecore_con_client_del(cl); + + cl->until_deletion = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void +_ecore_con_cl_timer_update(Ecore_Con_Client *cl) +{ + if (cl->disconnect_time) + { + if (cl->disconnect_time > 0) + { + if (cl->until_deletion) + ecore_timer_interval_set(cl->until_deletion, cl->disconnect_time); + else + cl->until_deletion = ecore_timer_add(cl->disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl); + } + else if (cl->until_deletion) + { + ecore_timer_del(cl->until_deletion); + cl->until_deletion = NULL; + } + } + else + { + if (cl->host_server->client_disconnect_time > 0) + { + if (cl->until_deletion) + ecore_timer_interval_set(cl->until_deletion, cl->host_server->client_disconnect_time); + else + cl->until_deletion = ecore_timer_add(cl->host_server->client_disconnect_time, (Ecore_Task_Cb)_ecore_con_client_timer, cl); + } + else if (cl->until_deletion) + { + ecore_timer_del(cl->until_deletion); + cl->until_deletion = NULL; + } + } +} + +static void +_ecore_con_cb_tcp_listen(void *data, + Ecore_Con_Info *net_info) +{ + Ecore_Con_Server *svr; + struct linger lin; + const char *memerr = NULL; + + svr = data; + + errno = 0; + if (!net_info) /* error message has already been handled */ + { + svr->delete_me = EINA_TRUE; + 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_TYPE) == ECORE_CON_REMOTE_NODELAY) + { +#ifdef HAVE_NETINET_TCP_H + int flag = 1; + + if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, + sizeof(int)) < 0) +#endif + { + 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_tcp_handler, svr, NULL, NULL); + if (!svr->fd_handler) + { + memerr = "Memory allocation failure"; + goto error; + } + + return; + +error: + if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); + ecore_con_ssl_server_shutdown(svr); + _ecore_con_server_kill(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; +#ifdef HAVE_IPV6 + struct ipv6_mreq mreq6; +#endif + const int on = 1; + const char *memerr = NULL; + + svr = data; + type = svr->type; + type &= ECORE_CON_TYPE; + + errno = 0; + if (!net_info) /* error message has already been handled */ + { + svr->delete_me = EINA_TRUE; + 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; + } +#ifdef HAVE_IPV6 + 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; + } +#endif + } + + 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) + { + memerr = "Memory allocation failure"; + goto error; + } + + svr->ip = eina_stringshare_add(net_info->ip); + + return; + +error: + if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); + ecore_con_ssl_server_shutdown(svr); + _ecore_con_server_kill(svr); +} + +static void +_ecore_con_cb_tcp_connect(void *data, + Ecore_Con_Info *net_info) +{ + Ecore_Con_Server *svr; + int res; + int curstate = 0; + const char *memerr = NULL; + + svr = data; + + errno = 0; + if (!net_info) /* error message has already been handled */ + { + svr->delete_me = EINA_TRUE; + 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_TYPE) == ECORE_CON_REMOTE_NODELAY) + { +#ifdef HAVE_NETINET_TCP_H + int flag = 1; + + if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0) +#endif + { + 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) + { + char *err; + err = evil_format_message(WSAGetLastError()); + _ecore_con_event_server_error(svr, err, EINA_FALSE); + ecore_con_ssl_server_shutdown(svr); + _ecore_con_server_kill(svr); + return; + } + +#else + if (res < 0) + { + if (errno != EINPROGRESS) goto error; +#endif + svr->connecting = EINA_TRUE; + 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) + { + svr->handshaking = EINA_TRUE; + svr->ssl_state = ECORE_CON_SSL_STATE_INIT; + DBG("%s ssl handshake", svr->ecs_state ? "Queuing" : "Beginning"); + if ((!svr->ecs_state) && ecore_con_ssl_server_init(svr)) + goto error; + } + + if (!svr->fd_handler) + { + memerr = "Memory allocation failure"; + goto error; + } + + if ((!svr->ecs) || (svr->ecs->lookup)) + svr->ip = eina_stringshare_add(net_info->ip); + + return; + +error: + if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); + ecore_con_ssl_server_shutdown(svr); + _ecore_con_server_kill(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; + const char *memerr = NULL; + svr = data; + + errno = 0; + if (!net_info) /* error message has already been handled */ + { + svr->delete_me = EINA_TRUE; + 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_TYPE) == ECORE_CON_REMOTE_BROADCAST) + { + if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST, + (const void *)&broadcast, + sizeof(broadcast)) < 0) + { + goto error; + } + } + 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; + + 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) + { + memerr = "Memory allocation failure"; + goto error; + } + + if ((!svr->ecs) || (svr->ecs->lookup)) + svr->ip = eina_stringshare_add(net_info->ip); + + return; + +error: + if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno)); + ecore_con_ssl_server_shutdown(svr); + _ecore_con_server_kill(svr); +} + +static Ecore_Con_State +svr_try_connect_plain(Ecore_Con_Server *svr) +{ + int res; + int so_err = 0; + socklen_t size = sizeof(int); + + res = getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, (void *)&so_err, &size); +#ifdef _WIN32 + if (res == SOCKET_ERROR) + so_err = WSAGetLastError(); + + if ((so_err == WSAEINPROGRESS) && !svr->delete_me) + return ECORE_CON_INPROGRESS; + +#else + if (res < 0) + so_err = errno; + + if ((so_err == EINPROGRESS) && !svr->delete_me) + return ECORE_CON_INPROGRESS; + +#endif + + if (so_err) + { + /* we lost our server! */ + ecore_con_event_server_error(svr, strerror(so_err)); + ERR("Connection lost: %s", strerror(so_err)); + _ecore_con_server_kill(svr); + return ECORE_CON_DISCONNECTED; + } + + if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting) + { + if (svr->ecs) + { + if (ecore_con_socks_svr_init(svr)) + return ECORE_CON_INPROGRESS; + } + else + ecore_con_event_server_add(svr); + } + + if (svr->fd_handler && (!svr->buf)) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); + + if (!svr->delete_me) + return ECORE_CON_CONNECTED; + else + return ECORE_CON_DISCONNECTED; +} + +static const char * +_ecore_con_pretty_ip(struct sockaddr *client_addr) +{ +#ifndef HAVE_IPV6 + char ipbuf[INET_ADDRSTRLEN + 1]; +#else + char ipbuf[INET6_ADDRSTRLEN + 1]; +#endif + int family = client_addr->sa_family; + void *src; + + switch(family) + { + case AF_INET: + src = &(((struct sockaddr_in *)client_addr)->sin_addr); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + src = &(((struct sockaddr_in6 *)client_addr)->sin6_addr); + + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) + { + family = AF_INET; + src = (char*)src + 12; + } + break; +#endif + default: + return eina_stringshare_add("0.0.0.0"); + } + + if (!inet_ntop(family, src, ipbuf, sizeof(ipbuf))) + return eina_stringshare_add("0.0.0.0"); + + ipbuf[sizeof(ipbuf) - 1] = 0; + return eina_stringshare_add(ipbuf); +} + +static Eina_Bool +_ecore_con_svr_tcp_handler(void *data, + Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + Ecore_Con_Server *svr; + Ecore_Con_Client *cl = NULL; + unsigned char client_addr[256]; + unsigned int client_addr_len; + const char *clerr = NULL; + + svr = data; + if (svr->delete_me) + return ECORE_CALLBACK_RENEW; + + if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && + (svr->client_count >= (unsigned int)svr->client_limit)) + return ECORE_CALLBACK_RENEW; + + /* a new client */ + + cl = calloc(1, sizeof(Ecore_Con_Client)); + if (!cl) + { + ecore_con_event_server_error(svr, "Memory allocation failure when attempting to add a new client"); + return ECORE_CALLBACK_RENEW; + } + cl->host_server = svr; + + client_addr_len = sizeof(client_addr); + memset(&client_addr, 0, client_addr_len); + cl->fd = accept(svr->fd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addr_len); + if (cl->fd < 0) goto error; + if ((svr->client_limit >= 0) && (svr->reject_excess_clients) && + (svr->client_count >= (unsigned int)svr->client_limit)) + { + clerr = "Maximum client limit reached"; + goto error; + } + + if (fcntl(cl->fd, F_SETFL, O_NONBLOCK) < 0) goto error; + if (fcntl(cl->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; + cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ, + _ecore_con_svr_cl_handler, cl, NULL, NULL); + if (!cl->fd_handler) goto error; + ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); + + if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL)) + { + cl->handshaking = EINA_TRUE; + cl->ssl_state = ECORE_CON_SSL_STATE_INIT; + if (ecore_con_ssl_client_init(cl)) + goto error; + } + + cl->client_addr = malloc(client_addr_len); + if (!cl->client_addr) + { + clerr = "Memory allocation failure when attempting to add a new client"; + goto error; + } + cl->client_addr_len = client_addr_len; + memcpy(cl->client_addr, &client_addr, client_addr_len); + + svr->clients = eina_list_append(svr->clients, cl); + svr->client_count++; + + if ((!cl->delete_me) && (!cl->handshaking)) + ecore_con_event_client_add(cl); + + return ECORE_CALLBACK_RENEW; + +error: + if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler); + if (cl->fd >= 0) close(cl->fd); + { + Ecore_Event *ev; + + EINA_LIST_FREE(cl->event_count, ev) + { + svr->event_count = eina_list_remove(svr->event_count, ev); + ecore_event_del(ev); + } + } + free(cl); + if (clerr || errno) ecore_con_event_server_error(svr, clerr ?: strerror(errno)); + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_con_cl_read(Ecore_Con_Server *svr) +{ + int num = 0; + Eina_Bool lost_server = EINA_TRUE; + unsigned char buf[READBUFSIZ]; + + DBG("svr=%p", svr); + + /* only possible with non-ssl connections */ + if (svr->connecting && (svr_try_connect_plain(svr) != ECORE_CON_CONNECTED)) + return; + + if (svr->handshaking && (!svr->ecs_state)) + { + DBG("Continuing ssl handshake"); + if (!ecore_con_ssl_server_init(svr)) + lost_server = EINA_FALSE; + _ecore_con_server_timer_update(svr); + } + + if (svr->ecs_state || !(svr->type & ECORE_CON_SSL)) + { + errno = 0; + num = read(svr->fd, buf, sizeof(buf)); + /* 0 is not a valid return value for a tcp socket */ + if ((num > 0) || ((num < 0) && (errno == EAGAIN))) + lost_server = EINA_FALSE; + else if (num < 0) + ecore_con_event_server_error(svr, strerror(errno)); + } + else + { + num = ecore_con_ssl_server_read(svr, buf, sizeof(buf)); + /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */ + if (num >= 0) + lost_server = EINA_FALSE; + } + + if ((!svr->delete_me) && (num > 0)) + { + if (svr->ecs_state) + ecore_con_socks_read(svr, buf, num); + else + ecore_con_event_server_data(svr, buf, num, EINA_TRUE); + } + + if (lost_server) + _ecore_con_server_kill(svr); +} + +static Eina_Bool +_ecore_con_cl_handler(void *data, + Ecore_Fd_Handler *fd_handler) +{ + Ecore_Con_Server *svr; + Eina_Bool want_read, want_write; + + svr = data; + if (svr->delete_me) + return ECORE_CALLBACK_RENEW; + + if (svr->delete_me) + return ECORE_CALLBACK_RENEW; + + want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); + want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); + + if ((!svr->ecs_state) && svr->handshaking && (want_read || want_write)) + { + DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write"); +#ifdef ISCOMFITOR + if (want_read) + { + char buf[READBUFSIZ]; + ssize_t len; + len = recv(svr->fd, buf, sizeof(buf), MSG_DONTWAIT | MSG_PEEK); + DBG("%zu bytes in buffer", len); + } +#endif + if (ecore_con_ssl_server_init(svr)) + { + ERR("ssl handshaking failed!"); + svr->handshaking = EINA_FALSE; + } + else if (!svr->ssl_state) + ecore_con_event_server_add(svr); + return ECORE_CALLBACK_RENEW; + } + if (svr->ecs && svr->ecs_state && (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) && (!svr->ecs_buf)) + { + if (svr->ecs_state < ECORE_CON_PROXY_STATE_INIT) + { + INF("PROXY STATE++"); + svr->ecs_state++; + } + if (ecore_con_socks_svr_init(svr)) return ECORE_CALLBACK_RENEW; + } + if (want_read) + _ecore_con_cl_read(svr); + else if (want_write) /* only possible with non-ssl connections */ + { + if (svr->connecting && (!svr_try_connect_plain(svr)) && (!svr->ecs_state)) + return ECORE_CALLBACK_RENEW; + + _ecore_con_server_flush(svr); + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_ecore_con_cl_udp_handler(void *data, + Ecore_Fd_Handler *fd_handler) +{ + unsigned char buf[READBUFSIZ]; + int num; + Ecore_Con_Server *svr; + Eina_Bool want_read, want_write; + + want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); + want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); + + svr = data; + if (svr->delete_me || ((!want_read) && (!want_write))) + return ECORE_CALLBACK_RENEW; + + if (want_write) + { + _ecore_con_server_flush(svr); + return ECORE_CALLBACK_RENEW; + } + + num = read(svr->fd, buf, READBUFSIZ); + + if ((!svr->delete_me) && (num > 0)) + ecore_con_event_server_data(svr, buf, num, EINA_TRUE); + + if (num < 0 && (errno != EAGAIN) && (errno != EINTR)) + { + ecore_con_event_server_error(svr, strerror(errno)); + _ecore_con_server_kill(svr); + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_ecore_con_svr_udp_handler(void *data, + Ecore_Fd_Handler *fd_handler) +{ + unsigned char buf[READBUFSIZ]; + unsigned char client_addr[256]; + socklen_t client_addr_len = sizeof(client_addr); + int num; + Ecore_Con_Server *svr; + Ecore_Con_Client *cl = NULL; + + svr = data; + + if (svr->delete_me) + return ECORE_CALLBACK_RENEW; + + if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) + { + _ecore_con_client_flush(cl); + return ECORE_CALLBACK_RENEW; + } + + if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) + return ECORE_CALLBACK_RENEW; + +#ifdef _WIN32 + num = fcntl(svr->fd, F_SETFL, O_NONBLOCK); + if (num >= 0) + num = recvfrom(svr->fd, (char *)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 && (errno != EAGAIN) && (errno != EINTR)) + { + ecore_con_event_server_error(svr, strerror(errno)); + if (!svr->delete_me) + ecore_con_event_client_del(NULL); + _ecore_con_server_kill(svr); + return ECORE_CALLBACK_CANCEL; + } + + +/* Create a new client for use in the client data event */ + cl = calloc(1, sizeof(Ecore_Con_Client)); + EINA_SAFETY_ON_NULL_RETURN_VAL(cl, ECORE_CALLBACK_RENEW); + + cl->host_server = svr; + cl->client_addr = malloc(client_addr_len); + if (!cl->client_addr) + { + free(cl); + return ECORE_CALLBACK_RENEW; + } + cl->client_addr_len = client_addr_len; + + 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); + svr->client_count++; + + ecore_con_event_client_add(cl); + ecore_con_event_client_data(cl, buf, num, EINA_TRUE); + + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_con_svr_cl_read(Ecore_Con_Client *cl) +{ + int num = 0; + Eina_Bool lost_client = EINA_TRUE; + unsigned char buf[READBUFSIZ]; + + DBG("cl=%p", cl); + + if (cl->handshaking) + { + /* add an extra handshake attempt just before read, even though + * read also attempts to handshake, to try to finish sooner + */ + if (ecore_con_ssl_client_init(cl)) + lost_client = EINA_FALSE; + + _ecore_con_cl_timer_update(cl); + } + + if (!(cl->host_server->type & ECORE_CON_SSL) && (!cl->upgrade)) + { + num = read(cl->fd, buf, sizeof(buf)); + /* 0 is not a valid return value for a tcp socket */ + if ((num > 0) || ((num < 0) && ((errno == EAGAIN) || (errno == EINTR)))) + lost_client = EINA_FALSE; + else if (num < 0) + ecore_con_event_client_error(cl, strerror(errno)); + } + else + { + num = ecore_con_ssl_client_read(cl, buf, sizeof(buf)); + /* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */ + if (num >= 0) + lost_client = EINA_FALSE; + } + + if ((!cl->delete_me) && (num > 0)) + ecore_con_event_client_data(cl, buf, num, EINA_TRUE); + + if (lost_client) _ecore_con_client_kill(cl); +} + +static Eina_Bool +_ecore_con_svr_cl_handler(void *data, + Ecore_Fd_Handler *fd_handler) +{ + Ecore_Con_Client *cl; + + cl = data; + if (cl->delete_me) + return ECORE_CALLBACK_RENEW; + + if (cl->handshaking && ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ | ECORE_FD_WRITE)) + { + if (ecore_con_ssl_client_init(cl)) + { + ERR("ssl handshaking failed!"); + _ecore_con_client_kill(cl); + return ECORE_CALLBACK_RENEW; + } + else if (!cl->ssl_state) + ecore_con_event_client_add(cl); + } + else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) + _ecore_con_svr_cl_read(cl); + + else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) + _ecore_con_client_flush(cl); + + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_con_server_flush(Ecore_Con_Server *svr) +{ + int count, num; + size_t buf_len, buf_offset; + const unsigned char *buf; + + DBG("(svr=%p,buf=%p)", svr, svr->buf); +#ifdef _WIN32 + if (ecore_con_local_win32_server_flush(svr)) + return; +#endif + + if ((!svr->buf) && (!svr->ecs_buf) && svr->fd_handler) + { + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); + return; + } + + buf = svr->buf ? eina_binbuf_string_get(svr->buf) : eina_binbuf_string_get(svr->ecs_buf); + buf_len = svr->buf ? eina_binbuf_length_get(svr->buf) : eina_binbuf_length_get(svr->ecs_buf); + buf_offset = svr->buf ? svr->write_buf_offset : svr->ecs_buf_offset; + num = buf_len - buf_offset; + + /* check whether we need to write anything at all. + * we must not write zero bytes with SSL_write() since it + * causes undefined behaviour + */ + /* we thank Tommy[D] for needing to check negative buffer sizes + * here because his system is amazing. + */ + if (num <= 0) return; + + if ((!svr->ecs_state) && svr->handshaking) + { + DBG("Continuing ssl handshake"); + if (ecore_con_ssl_server_init(svr)) + _ecore_con_server_kill(svr); + _ecore_con_server_timer_update(svr); + return; + } + + if (svr->ecs_state || (!(svr->type & ECORE_CON_SSL))) + count = write(svr->fd, buf + buf_offset, num); + else + count = ecore_con_ssl_server_write(svr, buf + buf_offset, num); + + if (count < 0) + { + if ((errno != EAGAIN) && (errno != EINTR)) + { + ecore_con_event_server_error(svr, strerror(errno)); + _ecore_con_server_kill(svr); + } + return; + } + + if (count && (!svr->ecs_state)) ecore_con_event_server_write(svr, count); + if (svr->ecs_buf) + buf_offset = svr->ecs_buf_offset += count; + else + buf_offset = svr->write_buf_offset += count; + if (buf_offset >= buf_len) + { + if (svr->ecs_buf) + { + svr->ecs_buf_offset = 0; + eina_binbuf_free(svr->ecs_buf); + svr->ecs_buf = NULL; + INF("PROXY STATE++"); + svr->ecs_state++; + } + else + { + svr->write_buf_offset = 0; + eina_binbuf_free(svr->buf); + svr->buf = NULL; +#ifdef TCP_CORK + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK) + { + int state = 0; + if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) + /* realistically this isn't anything serious so we can just log and continue */ + ERR("uncorking failed! %s", strerror(errno)); + } +#endif + } + if (svr->fd_handler) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); + } + else if ((count < num) && svr->fd_handler) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); +} + +static void +_ecore_con_client_flush(Ecore_Con_Client *cl) +{ + int num = 0, count = 0; + +#ifdef _WIN32 + if (ecore_con_local_win32_client_flush(cl)) + return; +#endif + + if (!cl->buf && cl->fd_handler) + { + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); + return; + } + + if (cl->handshaking) + { + if (ecore_con_ssl_client_init(cl)) + count = -1; + + _ecore_con_cl_timer_update(cl); + } + + if (!count) + { + if (!cl->buf) return; + num = eina_binbuf_length_get(cl->buf) - cl->buf_offset; + if (num <= 0) return; + if (!(cl->host_server->type & ECORE_CON_SSL) && (!cl->upgrade)) + count = write(cl->fd, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); + else + count = ecore_con_ssl_client_write(cl, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num); + } + + if (count < 0) + { + if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me)) + { + ecore_con_event_client_error(cl, strerror(errno)); + _ecore_con_client_kill(cl); + } + + return; + } + + if (count) ecore_con_event_client_write(cl, count); + cl->buf_offset += count, num -= count; + if (cl->buf_offset >= eina_binbuf_length_get(cl->buf)) + { + cl->buf_offset = 0; + eina_binbuf_free(cl->buf); + cl->buf = NULL; +#ifdef TCP_CORK + if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK) + { + int state = 0; + if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0) + /* realistically this isn't anything serious so we can just log and continue */ + ERR("uncorking failed! %s", strerror(errno)); + } +#endif + if (cl->fd_handler) + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); + } + else if (cl->fd_handler && (num >= 0)) + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); +} + +static void +_ecore_con_event_client_add_free(Ecore_Con_Server *svr, + void *ev) +{ + Ecore_Con_Event_Client_Add *e; + + e = ev; + if (e->client) + { + e->client->event_count = eina_list_remove(e->client->event_count, e); + if (e->client->host_server) + { + e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); + if ((!svr->event_count) && (svr->delete_me)) + _ecore_con_server_free(svr); + } + if ((!e->client->event_count) && (e->client->delete_me)) + ecore_con_client_del(e->client); + } + + ecore_con_event_client_add_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_event_client_del_free(Ecore_Con_Server *svr, + void *ev) +{ + Ecore_Con_Event_Client_Del *e; + + e = ev; + if (e->client) + { + e->client->event_count = eina_list_remove(e->client->event_count, e); + if (e->client->host_server) + { + e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); + if ((!svr->event_count) && (svr->delete_me)) + _ecore_con_server_free(svr); + } + if (!e->client->event_count) + _ecore_con_client_free(e->client); + } + ecore_con_event_client_del_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_event_client_write_free(Ecore_Con_Server *svr, + Ecore_Con_Event_Client_Write *e) +{ + if (e->client) + { + e->client->event_count = eina_list_remove(e->client->event_count, e); + if (e->client->host_server) + { + e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, e); + if ((!svr->event_count) && (svr->delete_me)) + _ecore_con_server_free(svr); + } + if (((!e->client->event_count) && (e->client->delete_me)) || + ((e->client->host_server && + ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || + (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) + ecore_con_client_del(e->client); + } + ecore_con_event_client_write_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_event_client_data_free(Ecore_Con_Server *svr, + void *ev) +{ + Ecore_Con_Event_Client_Data *e; + + e = ev; + if (e->client) + { + e->client->event_count = eina_list_remove(e->client->event_count, e); + if (e->client->host_server) + { + e->client->host_server->event_count = eina_list_remove(e->client->host_server->event_count, ev); + } + if ((!svr->event_count) && (svr->delete_me)) + _ecore_con_server_free(svr); + if (((!e->client->event_count) && (e->client->delete_me)) || + ((e->client->host_server && + ((e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_UDP || + (e->client->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_MCAST)))) + ecore_con_client_del(e->client); + } + free(e->data); + ecore_con_event_client_data_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_event_server_add_free(void *data EINA_UNUSED, + void *ev) +{ + Ecore_Con_Event_Server_Add *e; + + e = ev; + if (e->server) + { + e->server->event_count = eina_list_remove(e->server->event_count, ev); + if ((!e->server->event_count) && (e->server->delete_me)) + _ecore_con_server_free(e->server); + } + ecore_con_event_server_add_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_event_server_del_free(void *data EINA_UNUSED, + void *ev) +{ + Ecore_Con_Event_Server_Del *e; + + e = ev; + if (e->server) + { + e->server->event_count = eina_list_remove(e->server->event_count, ev); + if (!e->server->event_count) + _ecore_con_server_free(e->server); + } + ecore_con_event_server_del_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_event_server_write_free(void *data EINA_UNUSED, + Ecore_Con_Event_Server_Write *e) +{ + if (e->server) + { + e->server->event_count = eina_list_remove(e->server->event_count, e); + if ((!e->server->event_count) && (e->server->delete_me)) + _ecore_con_server_free(e->server); + } + + ecore_con_event_server_write_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_event_server_data_free(void *data EINA_UNUSED, + void *ev) +{ + Ecore_Con_Event_Server_Data *e; + + e = ev; + if (e->server) + { + e->server->event_count = eina_list_remove(e->server->event_count, ev); + if ((!e->server->event_count) && (e->server->delete_me)) + _ecore_con_server_free(e->server); + } + + free(e->data); + ecore_con_event_server_data_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + + +static void +_ecore_con_event_server_error_free(void *data EINA_UNUSED, Ecore_Con_Event_Server_Error *e) +{ + if (e->server) + { + e->server->event_count = eina_list_remove(e->server->event_count, e); + if ((!e->server->event_count) && (e->server->delete_me)) + _ecore_con_server_free(e->server); + } + free(e->error); + ecore_con_event_server_error_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_event_client_error_free(Ecore_Con_Server *svr, Ecore_Con_Event_Client_Error *e) +{ + if (e->client) + { + if (eina_list_data_find(svr->clients, e->client)) + { + e->client->event_count = eina_list_remove(e->client->event_count, e); + if ((!e->client->event_count) && (e->client->delete_me)) + _ecore_con_client_free(e->client); + } + svr->event_count = eina_list_remove(svr->event_count, e); + if ((!svr->event_count) && (svr->delete_me)) + _ecore_con_server_free(svr); + } + free(e->error); + ecore_con_event_client_error_free(e); + _ecore_con_event_count--; + if ((!_ecore_con_event_count) && (!_ecore_con_init_count)) + ecore_con_mempool_shutdown(); +} + +static void +_ecore_con_lookup_done(void *data, + Ecore_Con_Info *infos) +{ + Ecore_Con_Server *svr; + Ecore_Con_Lookup *lk; + + svr = data; + lk = svr->data; + + if (infos) + lk->done_cb(infos->info.ai_canonname, infos->ip, + infos->info.ai_addr, infos->info.ai_addrlen, + (void *)lk->data); + else + lk->done_cb(NULL, NULL, NULL, 0, (void *)lk->data); + + free(svr->name); + free(lk); + free(svr); +} + diff --git a/src/lib/ecore_con/ecore_con_alloc.c b/src/lib/ecore_con/ecore_con_alloc.c new file mode 100644 index 0000000000..324d47d100 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_alloc.c @@ -0,0 +1,101 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Con.h" +#include "ecore_con_private.h" + +typedef struct _Ecore_Con_Mempool Ecore_Con_Mempool; +struct _Ecore_Con_Mempool +{ + const char *name; + Eina_Mempool *mp; + size_t size; +}; + +#define GENERIC_ALLOC_FREE(TYPE, Type) \ + Ecore_Con_Mempool Type##_mp = { #TYPE, NULL, sizeof (TYPE) }; \ + \ + TYPE * \ + Type##_alloc(void) \ + { \ + return eina_mempool_malloc(Type##_mp.mp, sizeof (TYPE)); \ + } \ + \ + void \ + Type##_free(TYPE *e) \ + { \ + eina_mempool_free(Type##_mp.mp, e); \ + } + +GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Add, ecore_con_event_client_add); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Del, ecore_con_event_client_del); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Write, ecore_con_event_client_write); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Data, ecore_con_event_client_data); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Error, ecore_con_event_server_error); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Error, ecore_con_event_client_error); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); +GENERIC_ALLOC_FREE(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind); + +static Ecore_Con_Mempool *mempool_array[] = { + &ecore_con_event_client_add_mp, + &ecore_con_event_client_del_mp, + &ecore_con_event_client_write_mp, + &ecore_con_event_client_data_mp, + &ecore_con_event_server_error_mp, + &ecore_con_event_client_error_mp, + &ecore_con_event_server_add_mp, + &ecore_con_event_server_del_mp, + &ecore_con_event_server_write_mp, + &ecore_con_event_server_data_mp, + &ecore_con_event_proxy_bind_mp +}; + +void +ecore_con_mempool_init(void) +{ + const char *choice; + unsigned int i; + + choice = getenv("EINA_MEMPOOL"); + if (!choice || !choice[0]) + choice = "chained_mempool"; + + for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) + { + retry: + mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 16); + if (!mempool_array[i]->mp) + { + if (!(!strcmp(choice, "pass_through"))) + { + ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice); + choice = "pass_through"; + goto retry; + } + else + { + ERR("Impossible to allocate mempool '%s' !", choice); + return ; + } + } + } +} + +void +ecore_con_mempool_shutdown(void) +{ + unsigned int i; + + for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i) + { + eina_mempool_del(mempool_array[i]->mp); + mempool_array[i]->mp = NULL; + } +} + diff --git a/src/lib/ecore_con/ecore_con_ares.c b/src/lib/ecore_con/ecore_con_ares.c new file mode 100644 index 0000000000..3c0ca22c85 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_ares.c @@ -0,0 +1,628 @@ +#ifdef HAVE_CONFIG_H +# include +#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 +#include + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#include + +#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; + Ecore_Timer *timer; + 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; +#ifdef HAVE_IPV6 + struct in6_addr v6; +#endif + } addr; + + Eina_Bool byaddr : 1; + Eina_Bool isv6 : 1; +}; + +static ares_channel info_channel; +static int info_init = 0; +static Eina_List *info_fds = NULL; + +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 Eina_Bool _ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf, + Ecore_Fd_Handler *fd_handler); +static Eina_Bool _ecore_con_info_cares_timeout_cb(void *data); + +static void +_ecore_con_info_cares_state_cb(void *data, + ares_socket_t fd, + int readable, + int writable); +static int +_ecore_con_info_fds_search(const Ecore_Con_FD *fd1, + const Ecore_Con_FD *fd2); + +int +ecore_con_info_init(void) +{ + struct ares_options opts; + + if (!info_init) + { + if (ares_library_init(ARES_LIB_INIT_ALL)) + return 0; + + opts.lookups = "fb"; /* hosts file then dns */ + opts.sock_state_cb = _ecore_con_info_cares_state_cb; + + if (ares_init_options(&info_channel, &opts, + ARES_OPT_LOOKUPS | ARES_OPT_SOCK_STATE_CB) != 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); + + /* 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + 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); +} + +static Eina_Bool +_ecore_con_info_ares_getnameinfo(Ecore_Con_CAres *arg, + int addrtype, + const char *name, + struct sockaddr *addr, + int addrlen) +{ + int length = 0; + + if (name) + length = strlen(name) + 1; + else + length = 1; + + arg->result = malloc(sizeof(Ecore_Con_Info) + length); + if (!arg->result) + return EINA_FALSE; + + /* 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 = addrtype; + arg->result->info.ai_addrlen = addrlen; + arg->result->info.ai_addr = addr; + arg->result->info.ai_canonname = (char *)(arg->result + 1); + + if (!name) + *arg->result->info.ai_canonname = '\0'; + else + strcpy(arg->result->info.ai_canonname, 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); + + return EINA_TRUE; +} + +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; +#ifdef HAVE_IPV6 + int ai_family = AF_INET6; +#else + int ai_family = AF_INET; +#endif + + 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->ecs ? svr->ecs->ip : svr->name, &cares->addr.v4) == 1) + { + cares->byaddr = EINA_TRUE; + cares->isv6 = EINA_FALSE; + ares_gethostbyaddr(info_channel, &cares->addr.v4, + sizeof(cares->addr.v4), + AF_INET, + (ares_host_callback)_ecore_con_info_ares_host_cb, + cares); + } +#ifdef HAVE_IPV6 + else if (inet_pton(AF_INET6, svr->ecs ? svr->ecs->ip : svr->name, &cares->addr.v6) == 1) + { + cares->byaddr = EINA_TRUE; + cares->isv6 = 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); + } +#endif + else + { + cares->byaddr = EINA_FALSE; + ares_gethostbyname(info_channel, svr->ecs ? svr->ecs->ip : svr->name, ai_family, + (ares_host_callback)_ecore_con_info_ares_host_cb, + cares); + } + + svr->infos = eina_list_append(svr->infos, cares); + return 1; +} + +void +ecore_con_info_data_clear(void *info) +{ + Ecore_Con_CAres *cares = info; + if (cares) cares->data = NULL; +} + +static Eina_Bool +_ecore_con_info_cares_timeout_cb(void *data EINA_UNUSED) +{ + ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf, + Ecore_Fd_Handler *fd_handler) +{ + ares_socket_t read_fd, write_fd; + + read_fd = write_fd = ARES_SOCKET_BAD; + + if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) + read_fd = ecf->fd; + if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) + write_fd = ecf->fd; + + ares_process_fd(info_channel, read_fd, write_fd); + + return ECORE_CALLBACK_RENEW; +} + +static int +_ecore_con_info_fds_search(const Ecore_Con_FD *fd1, + const Ecore_Con_FD *fd2) +{ + return fd1->fd - fd2->fd; +} + +static void +_ecore_con_info_cares_state_cb(void *data EINA_UNUSED, + ares_socket_t fd, + int readable, + int writable) +{ + int flags = 0; + Ecore_Con_FD *search = NULL, *ecf = NULL; + + search = eina_list_search_unsorted(info_fds, + (Eina_Compare_Cb)_ecore_con_info_fds_search, &ecf); + + if (!(readable | writable)) + { + ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); + if (search) + { + info_fds = eina_list_remove(info_fds, search); + ecore_timer_del(search->timer); + ecore_main_fd_handler_del(search->handler); + free(search); + } + return; + } + + if (!search) + { + search = malloc(sizeof(Ecore_Con_FD)); + EINA_SAFETY_ON_NULL_RETURN(search); + + search->fd = fd; + search->handler = ecore_main_fd_handler_add(fd, ECORE_FD_WRITE | ECORE_FD_READ, + (Ecore_Fd_Cb)_ecore_con_info_cares_fd_cb, search, NULL, NULL); + /* c-ares default timeout is 5 seconds */ + search->timer = ecore_timer_add(5, _ecore_con_info_cares_timeout_cb, NULL); + info_fds = eina_list_append(info_fds, search); + } + + if (readable) flags |= ECORE_FD_READ; + if (writable) flags |= ECORE_FD_WRITE; + ecore_main_fd_handler_active_set(search->handler, flags); +} + +static void +_ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg, + int status, + int timeouts EINA_UNUSED, + struct hostent *hostent) +{ + struct sockaddr *addr; + int addrlen; + + /* Found something ? */ + switch (status) + { + case ARES_SUCCESS: + if (!hostent->h_addr_list[0]) + { + ERR("No IP found"); + goto on_error; + } + + switch (hostent->h_addrtype) + { + case AF_INET: + { + struct sockaddr_in *addri; + + addrlen = sizeof(struct sockaddr_in); + addri = malloc(addrlen); + + if (!addri) + goto on_mem_error; + + addri->sin_family = AF_INET; + addri->sin_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port); + + memcpy(&addri->sin_addr.s_addr, + hostent->h_addr_list[0], sizeof(struct in_addr)); + + addr = (struct sockaddr *)addri; + break; + } +#ifdef HAVE_IPV6 + case AF_INET6: + { + struct sockaddr_in6 *addri6; + + addrlen = sizeof(struct sockaddr_in6); + addri6 = malloc(addrlen); + + if (!addri6) + goto on_mem_error; + + addri6->sin6_family = AF_INET6; + addri6->sin6_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port); + addri6->sin6_flowinfo = 0; + addri6->sin6_scope_id = 0; + + memcpy(&addri6->sin6_addr.s6_addr, + hostent->h_addr_list[0], sizeof(struct in6_addr)); + + addr = (struct sockaddr *)addri6; + break; + } +#endif + default: + ERR("Unknown addrtype %i", hostent->h_addrtype); + goto on_error; + } + + if (!_ecore_con_info_ares_getnameinfo(arg, hostent->h_addrtype, + hostent->h_name, + addr, addrlen)) + goto on_error; + + break; + + case ARES_ENOTFOUND: /* address notfound */ + if (arg->byaddr) + { +#ifdef HAVE_IPV6 + /* This happen when host doesn't have a reverse. */ + if (arg->isv6) + { + struct sockaddr_in6 *addri6; + + addrlen = sizeof(struct sockaddr_in6); + addri6 = malloc(addrlen); + + if (!addri6) + goto on_mem_error; + + addri6->sin6_family = AF_INET6; + addri6->sin6_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port); + addri6->sin6_flowinfo = 0; + addri6->sin6_scope_id = 0; + + memcpy(&addri6->sin6_addr.s6_addr, + &arg->addr.v6, sizeof(struct in6_addr)); + + addr = (struct sockaddr *)addri6; + } + else +#endif + { + struct sockaddr_in *addri; + + addrlen = sizeof(struct sockaddr_in); + addri = malloc(addrlen); + + if (!addri) + goto on_mem_error; + + addri->sin_family = AF_INET; + addri->sin_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port); + + memcpy(&addri->sin_addr.s_addr, + &arg->addr.v4, sizeof(struct in_addr)); + + addr = (struct sockaddr *)addri; + } + + if (!_ecore_con_info_ares_getnameinfo(arg, +#ifdef HAVE_IPV6 + arg->isv6 ? AF_INET6 : +#endif + AF_INET, + NULL, addr, + addrlen)) + goto on_error; + + break; + } + + case ARES_ENOTIMP: /* unknown family */ + case ARES_EBADNAME: /* not a valid internet address */ + case ARES_ENOMEM: /* not enough memory */ + case ARES_EDESTRUCTION: /* request canceled, shuting down */ + case ARES_ENODATA: /* no data returned */ + case ARES_ECONNREFUSED: /* connection refused */ + case ARES_ETIMEOUT: /* connection timed out */ + ecore_con_event_server_error(arg->svr, ares_strerror(status)); + goto on_error; + + default: + ERR("Unknown status returned by c-ares: %i assuming error", status); + ecore_con_event_server_error(arg->svr, ares_strerror(status)); + goto on_error; + } + + return; + +on_mem_error: + ERR("Not enough memory"); + +on_error: + if (arg->data) + { + ecore_con_server_infos_del(arg->data, arg); + arg->done_cb(arg->data, NULL); + } + free(arg); +} + +static void +_ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg, + int status, + int timeouts EINA_UNUSED, + 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'; + + if (arg->data) arg->done_cb(arg->data, arg->result); + break; + + case ARES_ENOTIMP: + case ARES_ENOTFOUND: + case ARES_ENOMEM: + case ARES_EDESTRUCTION: + case ARES_EBADFLAGS: + ecore_con_event_server_error(arg->svr, ares_strerror(status)); + if (arg->data) arg->done_cb(arg->data, NULL); + break; + } + + free(arg->result->info.ai_addr); + free(arg->result); + if (arg->data) ecore_con_server_infos_del(arg->data, arg); + free(arg); +} + diff --git a/src/lib/ecore_con/ecore_con_dns.c b/src/lib/ecore_con/ecore_con_dns.c new file mode 100644 index 0000000000..7851d0db82 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_dns.c @@ -0,0 +1,344 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + * This version of ecore_con_info uses dns.c to provide asynchronous dns lookup. + * + * dns.c is written by William Ahern: + * http://25thandclement.com/~william/projects/dns.c.html + */ + +#include +#include + +#ifdef HAVE_ERRNO_H +# include /* for EAGAIN */ +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#ifdef HAVE_ERRNO_H +# include +#endif + +#include "dns.h" + +#include "Ecore.h" +#include "Ecore_Con.h" +#include "ecore_con_private.h" + +typedef struct dns_addrinfo dns_addrinfo; +typedef struct dns_resolv_conf dns_resolv_conf; +typedef struct dns_resolver dns_resolver; +typedef struct dns_hosts dns_hosts; + +typedef struct _Ecore_Con_DNS Ecore_Con_DNS; + +struct _Ecore_Con_DNS +{ + Ecore_Con_Server *svr; + Ecore_Con_Info_Cb done_cb; + void *data; + dns_addrinfo *ai; + dns_resolver *resolv; + struct addrinfo hints; + Ecore_Fd_Handler *fdh; + Ecore_Timer *timer; +}; + +static int _ecore_con_dns_init = 0; +static dns_resolv_conf *resconf = NULL; +static dns_hosts *hosts = NULL; + +static void +_ecore_con_dns_free(Ecore_Con_DNS *dns) +{ + if (dns->svr->infos) dns->svr->infos = eina_list_remove(dns->svr->infos, dns); + if (dns->timer) ecore_timer_del(dns->timer); + if (dns->fdh) ecore_main_fd_handler_del(dns->fdh); + dns_res_close(dns_res_mortal(dns->resolv)); + free(dns); +} + +static Eina_Bool +_dns_addrinfo_get(Ecore_Con_DNS *dns, const char *addr, int port) +{ + int error = 0; + char service[NI_MAXSERV]; + + snprintf(service, sizeof(service), "%d", port); + dns->ai = dns_ai_open(addr, service, DNS_T_A, (const struct addrinfo *)&dns->hints, dns->resolv, &error); + return error; +} + +static int +_ecore_con_dns_check(Ecore_Con_DNS *dns) +{ + struct addrinfo *ent = NULL; + int error = 0; + + error = dns_ai_nextent(&ent, dns->ai); + + switch (error) + { + case 0: + break; + case EAGAIN: + return 1; + default: + ERR("resolve failed: %s", dns_strerror(error)); + goto error; + } + + { + Ecore_Con_Info result = {0, .ip = {0}, .service = {0}}; +#if 0 + char pretty[512]; + dns_ai_print(pretty, sizeof(pretty), ent, dns->ai); + printf("%s\n", pretty); +#endif + result.size = 0; + dns_inet_ntop(dns_sa_family(ent->ai_addr), dns_sa_addr(dns_sa_family(ent->ai_addr), ent->ai_addr), result.ip, sizeof(result.ip)); + snprintf(result.service, sizeof(result.service), "%u", ntohs(*dns_sa_port(dns_sa_family(ent->ai_addr), ent->ai_addr))); + memcpy(&result.info, ent, sizeof(result.info)); + if (dns->fdh) ecore_main_fd_handler_del(dns->fdh); + dns->fdh = NULL; + dns->done_cb(dns->data, &result); + free(ent); + _ecore_con_dns_free(dns); + } + + return 0; +error: + dns->done_cb(dns->data, NULL); + _ecore_con_dns_free(dns); + return -1; +} + +static Eina_Bool +_dns_fd_cb(Ecore_Con_DNS *dns, Ecore_Fd_Handler *fdh EINA_UNUSED) +{ + if (_ecore_con_dns_check(dns) != 1) return ECORE_CALLBACK_RENEW; + if (ecore_main_fd_handler_fd_get(dns->fdh) != dns_ai_pollfd(dns->ai)) + { + ecore_main_fd_handler_del(dns->fdh); + dns->fdh = ecore_main_fd_handler_add(dns_ai_pollfd(dns->ai), dns_ai_events(dns->ai), (Ecore_Fd_Cb)_dns_fd_cb, dns, NULL, NULL); + } + else + ecore_main_fd_handler_active_set(dns->fdh, dns_ai_events(dns->ai)); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_dns_timer_cb(Ecore_Con_DNS *dns) +{ + dns->done_cb(dns->data, NULL); + _ecore_con_dns_free(dns); + dns->timer = NULL; + return EINA_FALSE; +} + +int +ecore_con_info_init(void) +{ + int err; + if (_ecore_con_dns_init) return ++_ecore_con_dns_init; + + resconf = dns_resconf_local(&err); + if (!resconf) + { + ERR("resconf_open: %s", dns_strerror(err)); + return 0; + } + hosts = dns_hosts_local(&err); + if (!hosts) + { + ERR("hosts_open: %s", dns_strerror(err)); + dns_resconf_close(resconf); + resconf = NULL; + return 0; + } + /* this is super slow don't do it */ + //resconf->options.recurse = 1; + return ++_ecore_con_dns_init; +} + +int +ecore_con_info_shutdown(void) +{ + if (!_ecore_con_dns_init) return 0; + if (--_ecore_con_dns_init) return _ecore_con_dns_init; + dns_resconf_close(resconf); + resconf = NULL; + dns_hosts_close(hosts); + hosts = NULL; + return 0; +} + +void +ecore_con_info_data_clear(void *info) +{ + Ecore_Con_DNS *dns = info; + if (dns) dns->data = NULL; +} + +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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + hints.ai_protocol = IPPROTO_TCP; + + 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = IPPROTO_TCP; + + 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_CANONNAME; + hints.ai_protocol = IPPROTO_UDP; + + 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = IPPROTO_UDP; + + 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)); +#ifdef HAVE_IPV6 + hints.ai_family = AF_INET6; +#else + hints.ai_family = AF_INET; +#endif + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + + 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_DNS *dns; + int error = 0; + + dns = calloc(1, sizeof(Ecore_Con_DNS)); + if (!dns) return 0; + + dns->svr = svr; + dns->done_cb = done_cb; + dns->data = data; + + if (hints) + memcpy(&dns->hints, hints, sizeof(struct addrinfo)); + + if (!(dns->resolv = dns_res_open(resconf, hosts, dns_hints_mortal(dns_hints_local(resconf, &error)), NULL, dns_opts(), &error))) + { + ERR("res_open: %s", dns_strerror(error)); + goto reserr; + + } + + error = _dns_addrinfo_get(dns, svr->ecs ? svr->ecs->ip : svr->name, dns->svr->ecs ? dns->svr->ecs->port : dns->svr->port); + if (error && (error != EAGAIN)) + { + ERR("resolver: %s", dns_strerror(error)); + goto seterr; + } + + switch (_ecore_con_dns_check(dns)) + { + case 0: + break; + case 1: + dns->fdh = ecore_main_fd_handler_add(dns_ai_pollfd(dns->ai), dns_ai_events(dns->ai), (Ecore_Fd_Cb)_dns_fd_cb, dns, NULL, NULL); + svr->infos = eina_list_append(svr->infos, dns); + dns->timer = ecore_timer_add(5.0, (Ecore_Task_Cb)_dns_timer_cb, dns); + break; + default: + return 0; + } + + return 1; +seterr: + if (dns->resolv) dns_res_close(dns_res_mortal(dns->resolv)); +reserr: + free(dns); + return 0; +} + diff --git a/src/lib/ecore_con/ecore_con_eet.c b/src/lib/ecore_con/ecore_con_eet.c new file mode 100644 index 0000000000..3a958f3663 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_eet.c @@ -0,0 +1,822 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include + +#include "Ecore_Con_Eet.h" + +#define ECORE_CON_EET_RAW_MAGIC 0xDEAD007 + +typedef struct _Ecore_Con_Eet_Data Ecore_Con_Eet_Data; +typedef struct _Ecore_Con_Eet_Raw_Data Ecore_Con_Eet_Raw_Data; +typedef struct _Ecore_Con_Eet_Client Ecore_Con_Eet_Client; +typedef struct _Ecore_Con_Eet_Server Ecore_Con_Eet_Server; + +struct _Ecore_Con_Reply +{ + Ecore_Con_Eet *ece; + Ecore_Con_Client *client; + + Eet_Connection *econn; + + char *buffer_section; + unsigned char *buffer; + unsigned int buffer_length; + unsigned int buffer_current; + Ecore_Con_Eet_Raw_Data *buffer_handler; +}; + +struct _Ecore_Con_Eet_Data +{ + Ecore_Con_Eet_Data_Cb func; + const char *name; + const void *data; +}; + +struct _Ecore_Con_Eet_Raw_Data +{ + Ecore_Con_Eet_Raw_Data_Cb func; + const char *name; + const void *data; +}; + +struct _Ecore_Con_Eet_Client +{ + Ecore_Con_Eet_Client_Cb func; + const void *data; +}; + +struct _Ecore_Con_Eet_Server +{ + Ecore_Con_Eet_Server_Cb func; + const void *data; +}; + +struct _Ecore_Con_Eet +{ + Ecore_Con_Server *server; + + Ecore_Event_Handler *handler_add; + Ecore_Event_Handler *handler_del; + Ecore_Event_Handler *handler_data; + + Eet_Data_Descriptor *edd; + Eet_Data_Descriptor *matching; + + Eina_Hash *data_callbacks; + Eina_Hash *raw_data_callbacks; + + union { + struct { + Eina_List *connections; + Eina_List *client_connect_callbacks; + Eina_List *client_disconnect_callbacks; + } server; + struct { + Ecore_Con_Reply *r; + Eina_List *server_connect_callbacks; + Eina_List *server_disconnect_callbacks; + } client; + } u; + + const void *data; + + Eina_Bool client : 1; +}; + +static void +_ecore_con_eet_data_free(void *data) +{ + Ecore_Con_Eet_Data *eced = data; + + eina_stringshare_del(eced->name); + free(eced); +} + +static void +_ecore_con_eet_raw_data_free(void *data) +{ + Ecore_Con_Eet_Raw_Data *eced = data; + + eina_stringshare_del(eced->name); + free(eced); +} +static void +_ecore_con_eet_reply_cleanup(Ecore_Con_Reply *n) +{ + if (n->buffer_handler) free(n->buffer); + n->buffer = NULL; + n->buffer_handler = NULL; + free(n->buffer_section); + n->buffer_section = NULL; +} + +typedef struct _Ecore_Con_Eet_Protocol Ecore_Con_Eet_Protocol; +struct _Ecore_Con_Eet_Protocol { + const char *type; + void *data; +}; + +static const char * +_ecore_con_eet_data_type_get(const void *data, Eina_Bool *unknow EINA_UNUSED) +{ + const Ecore_Con_Eet_Protocol *p = data; + + return p->type; +} + +static Eina_Bool +_ecore_con_eet_data_type_set(const char *type, void *data, Eina_Bool unknow EINA_UNUSED) +{ + Ecore_Con_Eet_Protocol *p = data; + + p->type = type; + return EINA_TRUE; +} + +static void +_ecore_con_eet_data_descriptor_setup(Ecore_Con_Eet *ece) +{ + Eet_Data_Descriptor_Class eddc; + + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Ecore_Con_Eet_Protocol); + ece->edd = eet_data_descriptor_stream_new(&eddc); + + eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; + eddc.func.type_get = _ecore_con_eet_data_type_get; + eddc.func.type_set = _ecore_con_eet_data_type_set; + ece->matching = eet_data_descriptor_stream_new(&eddc); + + EET_DATA_DESCRIPTOR_ADD_VARIANT(ece->edd, Ecore_Con_Eet_Protocol, "data", data, type, ece->matching); +} + +/* Dealing with a server listening to connection */ +static Eina_Bool +_ecore_con_eet_read_cb(const void *eet_data, size_t size, void *user_data) +{ + Ecore_Con_Reply *n = user_data; + Ecore_Con_Eet_Protocol *protocol; + Ecore_Con_Eet_Data *cb; + + protocol = eet_data_descriptor_decode(n->ece->edd, eet_data, size); + if (!protocol) return EINA_TRUE; + + cb = eina_hash_find(n->ece->data_callbacks, protocol->type); + if (!cb) return EINA_TRUE; /* Should I report unknow protocol communication ? */ + + cb->func((void*)cb->data, n, cb->name, protocol->data); + + eina_stringshare_del(protocol->type); + free(protocol); + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_server_write_cb(const void *data, size_t size, void *user_data) +{ + Ecore_Con_Reply *n = user_data; + + if (ecore_con_client_send(n->client, data, size) != (int) size) + return EINA_FALSE; + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_client_write_cb(const void *data, size_t size, void *user_data) +{ + Ecore_Con_Reply *n = user_data; + + if (ecore_con_server_send(n->ece->server, data, size) != (int) size) + return EINA_FALSE; + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_server_connected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Add *ev) +{ + Ecore_Con_Eet_Client *ecec; + Eina_List *ll; + Ecore_Con_Eet *r = data; + Ecore_Con_Reply *n; + + if (ecore_con_client_server_get(ev->client) != r->server) + return EINA_TRUE; + + n = calloc(1, sizeof (Ecore_Con_Reply)); + if (!n) return EINA_TRUE; + + n->client = ev->client; + n->ece = r; + n->econn = eet_connection_new(_ecore_con_eet_read_cb, _ecore_con_eet_server_write_cb, n); + ecore_con_client_data_set(n->client, n); + + EINA_LIST_FOREACH(r->u.server.client_connect_callbacks, ll, ecec) + if (!ecec->func((void*) ecec->data, n, n->client)) + { + eet_connection_close(n->econn, NULL); + free(n); + return EINA_TRUE; + } + + r->u.server.connections = eina_list_append(r->u.server.connections, n); + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_server_disconnected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Del *ev) +{ + Ecore_Con_Eet *r = data; + Ecore_Con_Reply *n; + Eina_List *l; + + if (ecore_con_client_server_get(ev->client) != r->server) + return EINA_TRUE; + + EINA_LIST_FOREACH(r->u.server.connections, l, n) + if (n->client == ev->client) + { + Ecore_Con_Eet_Client *ecec; + Eina_List *ll; + + EINA_LIST_FOREACH(r->u.server.client_disconnect_callbacks, ll, ecec) + ecec->func((void*) ecec->data, n, n->client); + + eet_connection_close(n->econn, NULL); + free(n); + r->u.server.connections = eina_list_remove_list(r->u.server.connections, l); + return EINA_TRUE; + } + + return EINA_TRUE; +} + +static void +_ecore_con_eet_raw_data_push(Ecore_Con_Reply *n, void *data, int size) +{ + if (n->buffer_handler) + memcpy(n->buffer + n->buffer_current, data, size); + n->buffer_current += size; + + if (n->buffer_current == n->buffer_length) + { + if (n->buffer_handler) + n->buffer_handler->func((void*) n->buffer_handler->data, n, n->buffer_handler->name, n->buffer_section, n->buffer, n->buffer_length); + _ecore_con_eet_reply_cleanup(n); + } +} + +static void +_ecore_con_eet_data(Ecore_Con_Reply *n, void *data, unsigned int size) +{ + /* FIXME: Enforce detection of attack and kill connection on that case */ + if (n->buffer) + { + if (n->buffer_current + size > n->buffer_length) + { + _ecore_con_eet_reply_cleanup(n); + return ; + } + + _ecore_con_eet_raw_data_push(n, data, size); + return ; + } + else if (eet_connection_empty(n->econn) && size > (int) (4 * sizeof (unsigned int) + 2)) + { + unsigned int *tmp = data; + size -= 4 * sizeof (unsigned int) + 2; + + if (ntohl(tmp[0]) == ECORE_CON_EET_RAW_MAGIC) + { + unsigned int protocol_length = ntohl(tmp[1]); + unsigned int section_length = ntohl(tmp[2]); + unsigned int data_length = ntohl(tmp[3]); + + if (protocol_length > 1 && section_length > 1 && protocol_length + section_length <= size && data_length < 10 * 1024 * 1024) + { + char *buffer = (char*) &tmp[4]; + char *protocol; + char *section; + + protocol = buffer; + section = buffer + protocol_length; + + if (protocol[protocol_length - 1] == '\0' && + section[section_length - 1] == '\0') + { + size -= protocol_length + section_length; + buffer = section + section_length; + + n->buffer_handler = eina_hash_find(n->ece->raw_data_callbacks, protocol); + n->buffer_section = strdup(section); + n->buffer_length = data_length; + n->buffer_current = 0; + if (n->buffer_handler) + n->buffer = malloc(sizeof (data_length)); + else + n->buffer = (void*) 1; + if (n->buffer) + { + _ecore_con_eet_raw_data_push(n, buffer, size); + return ; + } + _ecore_con_eet_reply_cleanup(n); + + size += protocol_length + section_length; + } + } + } + + size += 4 * sizeof (unsigned int) + 2; + } + + eet_connection_received(n->econn, data, size); +} + +static Eina_Bool +_ecore_con_eet_server_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Client_Data *ev) +{ + Ecore_Con_Eet *r = data; + Ecore_Con_Reply *n; + + if (ecore_con_client_server_get(ev->client) != r->server) + return EINA_TRUE; + + n = ecore_con_client_data_get(ev->client); + + _ecore_con_eet_data(n, ev->data, ev->size); + + return EINA_TRUE; +} + +/* Dealing connection to a server */ + +static Eina_Bool +_ecore_con_eet_client_connected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev) +{ + Ecore_Con_Eet_Server *eces; + Ecore_Con_Eet *r = data; + Ecore_Con_Reply *n; + Eina_List *ll; + + /* Client did connect */ + if (r->server != ev->server) return EINA_TRUE; + if (r->u.client.r) return EINA_TRUE; + + n = calloc(1, sizeof (Ecore_Con_Reply)); + if (!n) return EINA_TRUE; + + n->client = NULL; + n->ece = r; + n->econn = eet_connection_new(_ecore_con_eet_read_cb, _ecore_con_eet_client_write_cb, n); + + EINA_LIST_FOREACH(r->u.client.server_connect_callbacks, ll, eces) + if (!eces->func((void*) eces->data, n, n->ece->server)) + { + eet_connection_close(n->econn, NULL); + free(n); + return EINA_TRUE; + } + + r->u.client.r = n; + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_client_disconnected(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Del *ev) +{ + Ecore_Con_Eet *r = data; + Ecore_Con_Eet_Server *eces; + Eina_List *ll; + + if (r->server != ev->server) return EINA_TRUE; + if (!r->u.client.r) return EINA_TRUE; + + /* Client disconnected */ + EINA_LIST_FOREACH(r->u.client.server_disconnect_callbacks, ll, eces) + eces->func((void*) eces->data, r->u.client.r, r->server); + + eet_connection_close(r->u.client.r->econn, NULL); + free(r->u.client.r); + r->u.client.r = NULL; + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_eet_client_data(void *data, int type EINA_UNUSED, Ecore_Con_Event_Server_Data *ev) +{ + Ecore_Con_Eet *r = data; + + if (r->server != ev->server) return EINA_TRUE; + if (!r->u.client.r) return EINA_TRUE; + + /* Got some data */ + _ecore_con_eet_data(r->u.client.r, ev->data, ev->size); + + return EINA_TRUE; +} + +/************** + * Global API * + **************/ + +EAPI Ecore_Con_Eet * +ecore_con_eet_server_new(Ecore_Con_Server *server) +{ + Ecore_Con_Eet *r; + + if (!server) return NULL; + + r = calloc(1, sizeof (Ecore_Con_Eet)); + if (!r) return NULL; + + r->server = server; + r->handler_add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, + (Ecore_Event_Handler_Cb)_ecore_con_eet_server_connected, r); + r->handler_del = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, + (Ecore_Event_Handler_Cb)_ecore_con_eet_server_disconnected, r); + r->handler_data = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, + (Ecore_Event_Handler_Cb)_ecore_con_eet_server_data, r); + r->data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_data_free); + r->raw_data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_raw_data_free); + + _ecore_con_eet_data_descriptor_setup(r); + + return r; +} + +EAPI Ecore_Con_Eet * +ecore_con_eet_client_new(Ecore_Con_Server *server) +{ + Ecore_Con_Eet *r; + + if (!server) return NULL; + + r = calloc(1, sizeof (Ecore_Con_Eet)); + if (!r) return NULL; + + r->client = EINA_TRUE; + r->server = server; + r->handler_add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, + (Ecore_Event_Handler_Cb)_ecore_con_eet_client_connected, r); + r->handler_del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, + (Ecore_Event_Handler_Cb)_ecore_con_eet_client_disconnected, r); + r->handler_data = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, + (Ecore_Event_Handler_Cb)_ecore_con_eet_client_data, r); + r->data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_data_free); + r->raw_data_callbacks = eina_hash_stringshared_new(_ecore_con_eet_raw_data_free); + + _ecore_con_eet_data_descriptor_setup(r); + + return r; +} + +EAPI void +ecore_con_eet_server_free(Ecore_Con_Eet *r) +{ + if (!r) return ; + + eet_data_descriptor_free(r->edd); + eet_data_descriptor_free(r->matching); + eina_hash_free(r->data_callbacks); + eina_hash_free(r->raw_data_callbacks); + + if (r->client) + { + Ecore_Con_Eet_Server *s; + + if (r->u.client.r) + { + _ecore_con_eet_reply_cleanup(r->u.client.r); + eet_connection_close(r->u.client.r->econn, NULL); + free(r->u.client.r); + } + EINA_LIST_FREE(r->u.client.server_connect_callbacks, s) + free(s); + EINA_LIST_FREE(r->u.client.server_disconnect_callbacks, s) + free(s); + } + else + { + Ecore_Con_Reply *n; + Ecore_Con_Eet_Client *c; + + EINA_LIST_FREE(r->u.server.connections, n) + { + _ecore_con_eet_reply_cleanup(n); + eet_connection_close(n->econn, NULL); + free(n); + } + EINA_LIST_FREE(r->u.server.client_connect_callbacks, c) + free(c); + EINA_LIST_FREE(r->u.server.client_disconnect_callbacks, c) + free(c); + } + + ecore_event_handler_del(r->handler_add); + ecore_event_handler_del(r->handler_del); + ecore_event_handler_del(r->handler_data); + free(r); +} + +EAPI void +ecore_con_eet_register(Ecore_Con_Eet *ece, const char *name, Eet_Data_Descriptor *edd) +{ + if (!ece) return ; + + EET_DATA_DESCRIPTOR_ADD_MAPPING(ece->matching, name, edd); +} + +EAPI void +ecore_con_eet_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Data_Cb func, const void *data) +{ + Ecore_Con_Eet_Data *eced; + + if (!ece) return ; + + eced = calloc(1, sizeof (Ecore_Con_Eet_Data));; + if (!eced) return ; + + eced->func = func; + eced->data = data; + eced->name = eina_stringshare_add(name); + + eina_hash_direct_add(ece->data_callbacks, eced->name, eced); +} + +EAPI void +ecore_con_eet_data_callback_del(Ecore_Con_Eet *ece, const char *name) +{ + if (!ece) return ; + eina_hash_del(ece->data_callbacks, name, NULL); +} + +EAPI void +ecore_con_eet_raw_data_callback_add(Ecore_Con_Eet *ece, const char *name, Ecore_Con_Eet_Raw_Data_Cb func, const void *data) +{ + Ecore_Con_Eet_Raw_Data *eced; + + if (!ece) return ; + + eced = calloc(1, sizeof (Ecore_Con_Eet_Raw_Data));; + if (!eced) return ; + + eced->func = func; + eced->data = data; + eced->name = eina_stringshare_add(name); + + eina_hash_direct_add(ece->raw_data_callbacks, eced->name, eced); +} + +EAPI void +ecore_con_eet_raw_data_callback_del(Ecore_Con_Eet *ece, const char *name) +{ + if (!ece) return ; + + if (ece->client && ece->u.client.r->buffer_handler && !strcmp(ece->u.client.r->buffer_handler->name, name)) + { + ece->u.client.r->buffer_handler = NULL; + free(ece->u.client.r->buffer); + ece->u.client.r->buffer = (void*) 1; + } + eina_hash_del(ece->raw_data_callbacks, name, NULL); +} + +EAPI void +ecore_con_eet_client_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) +{ + Ecore_Con_Eet_Client *c; + + if (!ece || !func) return ; + + c = calloc(1, sizeof (Ecore_Con_Eet_Client)); + if (!c) return ; + + c->func = func; + c->data = data; + + ece->u.server.client_connect_callbacks = eina_list_append(ece->u.server.client_connect_callbacks, c); +} + +EAPI void +ecore_con_eet_client_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) +{ + Ecore_Con_Eet_Client *c; + Eina_List *l; + + if (!ece || !func) return ; + + EINA_LIST_FOREACH(ece->u.server.client_connect_callbacks, l, c) + if (c->func == func && c->data == data) + { + ece->u.server.client_connect_callbacks = eina_list_remove_list(ece->u.server.client_connect_callbacks, l); + free(c); + return ; + } +} + +EAPI void +ecore_con_eet_client_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) +{ + Ecore_Con_Eet_Client *c; + + if (!ece || !func) return ; + + c = calloc(1, sizeof (Ecore_Con_Eet_Client)); + if (!c) return ; + + c->func = func; + c->data = data; + + ece->u.server.client_connect_callbacks = eina_list_append(ece->u.server.client_disconnect_callbacks, c); +} + +EAPI void +ecore_con_eet_client_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Client_Cb func, const void *data) +{ + Ecore_Con_Eet_Client *c; + Eina_List *l; + + if (!ece || !func) return ; + + EINA_LIST_FOREACH(ece->u.server.client_disconnect_callbacks, l, c) + if (c->func == func && c->data == data) + { + ece->u.server.client_disconnect_callbacks = eina_list_remove_list(ece->u.server.client_disconnect_callbacks, + l); + free(c); + return ; + } +} + +EAPI void +ecore_con_eet_server_connect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) +{ + Ecore_Con_Eet_Server *s; + + if (!ece || !func) return ; + + s = calloc(1, sizeof (Ecore_Con_Eet_Server)); + if (!s) return ; + + s->func = func; + s->data = data; + + ece->u.client.server_connect_callbacks = eina_list_append(ece->u.client.server_connect_callbacks, s); +} + +EAPI void +ecore_con_eet_server_connect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) +{ + Ecore_Con_Eet_Server *s; + Eina_List *l; + + if (!ece || !func) return ; + + EINA_LIST_FOREACH(ece->u.client.server_connect_callbacks, l, s) + if (s->func == func && s->data == data) + { + ece->u.client.server_connect_callbacks = eina_list_remove_list(ece->u.client.server_connect_callbacks, l); + free(s); + return ; + } +} + +EAPI void +ecore_con_eet_server_disconnect_callback_add(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) +{ + Ecore_Con_Eet_Server *s; + + if (!ece || !func) return ; + + s = calloc(1, sizeof (Ecore_Con_Eet_Server)); + if (!s) return ; + + s->func = func; + s->data = data; + + ece->u.client.server_disconnect_callbacks = eina_list_append(ece->u.client.server_disconnect_callbacks, s); +} + +EAPI void +ecore_con_eet_server_disconnect_callback_del(Ecore_Con_Eet *ece, Ecore_Con_Eet_Server_Cb func, const void *data) +{ + Ecore_Con_Eet_Server *s; + Eina_List *l; + + if (!ece || !func) return ; + + EINA_LIST_FOREACH(ece->u.client.server_disconnect_callbacks, l, s) + if (s->func == func && s->data == data) + { + ece->u.client.server_disconnect_callbacks = eina_list_remove_list(ece->u.client.server_disconnect_callbacks, l); + free(s); + return ; + } +} + +EAPI void +ecore_con_eet_data_set(Ecore_Con_Eet *ece, const void *data) +{ + if (!ece) return; + + ece->data = data; +} + +EAPI void * +ecore_con_eet_data_get(Ecore_Con_Eet *ece) +{ + if (!ece) return NULL; + return (void*) ece->data; +} + +EAPI Ecore_Con_Eet * +ecore_con_eet_reply(Ecore_Con_Reply *reply) +{ + if (!reply) return NULL; + return reply->ece; +} + +EAPI void +ecore_con_eet_send(Ecore_Con_Reply *reply, const char *name, void *value) +{ + Ecore_Con_Eet_Protocol protocol; + + if (!reply) return ; + + protocol.type = name; + protocol.data = value; + + eet_connection_send(reply->econn, reply->ece->edd, &protocol, NULL); +} + +EAPI void +ecore_con_eet_raw_send(Ecore_Con_Reply *reply, const char *protocol_name, const char *section, void *value, unsigned int length) +{ + unsigned int protocol[4]; + unsigned int protocol_length; + unsigned int section_length; + unsigned int size; + char *tmp; + + if (!reply) return ; + if (!protocol_name) return ; + if (!section) return ; + + protocol_length = strlen(protocol_name) + 1; + if (protocol_length == 1) return ; + section_length = strlen(section) + 1; + + protocol[0] = htonl(ECORE_CON_EET_RAW_MAGIC); + protocol[1] = htonl(protocol_length); + protocol[2] = htonl(section_length); + protocol[3] = htonl(length); + + size = sizeof (protocol) + protocol_length + section_length; + tmp = alloca(size); + memcpy(tmp, protocol, sizeof (protocol)); + memcpy(tmp + sizeof (protocol), protocol, protocol_length); + memcpy(tmp + sizeof (protocol) + protocol_length, section, section_length); + + if (reply->client) + { + ecore_con_client_send(reply->client, tmp, size); + ecore_con_client_send(reply->client, value, length); + } + else + { + ecore_con_server_send(reply->ece->server, tmp, size); + ecore_con_server_send(reply->ece->server, value, length); + } +} + diff --git a/src/lib/ecore_con/ecore_con_info.c b/src/lib/ecore_con/ecore_con_info.c new file mode 100644 index 0000000000..80e199a411 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_info.c @@ -0,0 +1,458 @@ +/* + * getaddrinfo with callback + * + * man getaddrinfo + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include +#include +#include +#include +#ifdef __OpenBSD__ +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#ifdef HAVE_ARPA_NAMESER_H +# include +#endif + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +#ifdef HAVE_NETDB_H +# include +#endif + +#include + +#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 Eina_Bool _ecore_con_info_data_handler(void *data, + Ecore_Fd_Handler *fd_handler); +static Eina_Bool _ecore_con_info_exit_handler(void *data, + int type EINA_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) + { + ecore_con_event_server_error(svr, strerror(errno)); + 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))) + { + ecore_con_event_server_error(svr, "Memory allocation failure"); + 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] = {0}; + char hbuf[NI_MAXHOST] = {0}; + char sbuf[NI_MAXSERV] = {0}; + unsigned char *tosend = NULL; + int tosend_len; + int canonname_len = 0; + + eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, service); + /* CHILD */ + if (!getaddrinfo(svr->ecs ? svr->ecs->ip : 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; + + tosend = alloca(tosend_len); + memset(tosend, 0, tosend_len); + + container = (Ecore_Con_Info *)tosend; + container->size = tosend_len; + + memcpy(&container->info, + result, + sizeof(struct addrinfo)); + memcpy(tosend + sizeof(Ecore_Con_Info), + result->ai_addr, + result->ai_addrlen); + if (result->ai_canonname) /* FIXME: else... */ + memcpy(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)); + } + + if (write(fd[1], tosend, tosend_len) < 0) perror("write"); + } + + if (result) + freeaddrinfo(result); + + if (write(fd[1], "", 1) < 0) perror("write"); + close(fd[1]); +#if defined(__USE_ISOC99) && !defined(__UCLIBC__) + _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)); + svr->infos = eina_list_append(svr->infos, cbdata); + return 1; +} + +void +ecore_con_info_data_clear(void *info) +{ + CB_Data *cbdata = info; + cbdata->data = NULL; +} + +static void +_ecore_con_info_readdata(CB_Data *cbdata) +{ + Ecore_Con_Info container; + Ecore_Con_Info *recv_info; + unsigned char *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), + torecv + sizeof(Ecore_Con_Info), + torecv_len - sizeof(Ecore_Con_Info)); + if ((size > 0) && + ((size_t)size == torecv_len - sizeof(Ecore_Con_Info))) + { + recv_info = (Ecore_Con_Info *)torecv; + + recv_info->info.ai_addr = + (struct sockaddr *)(torecv + sizeof(Ecore_Con_Info)); + if ((size_t)torecv_len != + (sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen)) + recv_info->info.ai_canonname = (char *) + (torecv + sizeof(Ecore_Con_Info) + recv_info->info.ai_addrlen); + else + recv_info->info.ai_canonname = NULL; + + recv_info->info.ai_next = NULL; + + if (cbdata->data) + { + cbdata->cb_done(cbdata->data, recv_info); + ecore_con_server_infos_del(cbdata->data, cbdata); + } + + free(torecv); + } + else + { + if (cbdata->data) + { + cbdata->cb_done(cbdata->data, NULL); + ecore_con_server_infos_del(cbdata->data, cbdata); + } + } + } + else + { + if (cbdata->data) + { + ecore_con_event_server_error(cbdata->data, strerror(errno)); + cbdata->cb_done(cbdata->data, NULL); + ecore_con_server_infos_del(cbdata->data, cbdata); + } + } + + 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)); + ecore_main_fd_handler_del(cbdata->fdh); + ecore_event_handler_del(cbdata->handler); + close(ecore_main_fd_handler_fd_get(cbdata->fdh)); + if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata); + free(cbdata); +} + +static Eina_Bool +_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 + { + if (cbdata->data) + { + cbdata->cb_done(cbdata->data, NULL); + cbdata->cb_done = NULL; + ecore_con_server_infos_del(cbdata->data, cbdata); + } + } + } + + _ecore_con_info_slave_free(cbdata); + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_ecore_con_info_exit_handler(void *data, + int type EINA_UNUSED, + void *event) +{ + CB_Data *cbdata; + Ecore_Exe_Event_Del *ev; + + ev = event; + cbdata = data; + if (cbdata->pid != ev->pid) + return ECORE_CALLBACK_RENEW; + + return ECORE_CALLBACK_CANCEL; /* FIXME: Woot ??? */ + _ecore_con_info_slave_free(cbdata); + return ECORE_CALLBACK_CANCEL; +} + diff --git a/src/lib/ecore_con/ecore_con_local.c b/src/lib/ecore_con/ecore_con_local.c new file mode 100644 index 0000000000..fff0059d66 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_local.c @@ -0,0 +1,325 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ERRNO_H +# include +#endif + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +#ifdef HAVE_SYS_UN_H +# include +#endif + +#ifdef HAVE_WS2TCPIP_H +# include +#endif + +#include +#include + +#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, + Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler), + void *data EINA_UNUSED) +{ +#ifndef HAVE_LOCAL_SOCKETS + return 0; +#else + char buf[4096]; + struct sockaddr_un socket_unix; + int curstate = 0; + const char *homedir; + int socket_unix_len; + + if ((svr->type & ECORE_CON_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_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_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_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) + { + ERR("local connection failed: %s", strerror(errno)); + 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) ecore_con_event_server_add(svr); + + return 1; +#endif +} + +int +ecore_con_local_listen( + Ecore_Con_Server *svr, + Eina_Bool (* + cb_listen)(void *data, + Ecore_Fd_Handler * + fd_handler), + void *data + EINA_UNUSED) +{ +#ifdef HAVE_LOCAL_SOCKETS + 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_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_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_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_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_TYPE) == ECORE_CON_LOCAL_USER) || + ((svr->type & ECORE_CON_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: +#endif /* HAVE_LOCAL_SOCKETS */ + return 0; +} + diff --git a/src/lib/ecore_con/ecore_con_local_win32.c b/src/lib/ecore_con/ecore_con_local_win32.c new file mode 100644 index 0000000000..2b7e5c5bd2 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_local_win32.c @@ -0,0 +1,754 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include + +#include "Ecore_Con.h" +#include "ecore_con_private.h" + +#define BUFSIZE 512 + + +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; +} + + +static Eina_Bool +_ecore_con_local_win32_server_read_client_handler(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Client *cl; + void *buf; + DWORD n; + Eina_Bool broken_pipe = EINA_FALSE; + + cl = (Ecore_Con_Client *)data; + + if (!ResetEvent(cl->host_server->event_read)) + return ECORE_CALLBACK_RENEW; + + buf = malloc(cl->host_server->nbr_bytes); + if (!buf) + return ECORE_CALLBACK_RENEW; + + if (ReadFile(cl->host_server->pipe, buf, cl->host_server->nbr_bytes, &n, NULL)) + { + if (!cl->delete_me) + ecore_con_event_client_data(cl, buf, cl->host_server->nbr_bytes, EINA_FALSE); + cl->host_server->want_write = 1; + } + else + { + if (GetLastError() == ERROR_BROKEN_PIPE) + broken_pipe = EINA_TRUE; + } + + if (broken_pipe) + { +#if 0 + char *msg; + + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_client_error(cl, msg); + free(msg); + } +#endif + _ecore_con_client_kill(cl); + return ECORE_CALLBACK_CANCEL; + } + + if (cl->host_server->want_write) + ecore_con_local_win32_client_flush(cl); + + ecore_main_win32_handler_del(wh); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Client *cl; +#if 0 + char *msg; +#endif + + cl = (Ecore_Con_Client *)data; + + if (!ResetEvent(cl->host_server->event_peek)) + return ECORE_CALLBACK_RENEW; + +#if 0 + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_server_error(cl->host_server, msg); + free(msg); + } +#endif + _ecore_con_server_kill(cl->host_server); + return ECORE_CALLBACK_CANCEL; + + ecore_main_win32_handler_del(wh); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Server *svr; +#if 0 + char *msg; +#endif + + svr = (Ecore_Con_Server *)data; + + if (!ResetEvent(svr->event_peek)) + return ECORE_CALLBACK_RENEW; +#if 0 + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_server_error(svr, msg); + free(msg); + } +#endif + _ecore_con_server_kill(svr); + return ECORE_CALLBACK_CANCEL; + + ecore_main_win32_handler_del(wh); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Server *svr; + void *buf; + DWORD n; + Eina_Bool broken_pipe = EINA_FALSE; + + svr = (Ecore_Con_Server *)data; + + if (!ResetEvent(svr->event_read)) + return ECORE_CALLBACK_RENEW; + + buf = malloc(svr->nbr_bytes); + if (!buf) + return ECORE_CALLBACK_RENEW; + + if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL)) + { + if (!svr->delete_me) + ecore_con_event_server_data(svr, buf, svr->nbr_bytes, EINA_FALSE); + svr->want_write = 1; + } + else + { + if (GetLastError() == ERROR_BROKEN_PIPE) + broken_pipe = EINA_TRUE; + } + + if (broken_pipe) + { +#if 0 + char *msg; + + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_server_error(svr, msg); + free(msg); + } +#endif + _ecore_con_server_kill(svr); + return ECORE_CALLBACK_CANCEL; + } + + if (svr->want_write) + ecore_con_local_win32_server_flush(svr); + + ecore_main_win32_handler_del(wh); + + return ECORE_CALLBACK_DONE; +} + +/* thread to read data sent by the server to the client */ +static unsigned int __stdcall +_ecore_con_local_win32_client_read_server_thread(void *data) +{ + Ecore_Con_Server *svr; + DWORD nbr_bytes = 0; + + svr = (Ecore_Con_Server *)data; + + svr->read_stopped = EINA_FALSE; + + while (!svr->read_stop) + { + if (PeekNamedPipe(svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL)) + { + if (nbr_bytes <= 0) + continue; + + svr->nbr_bytes = nbr_bytes; + if (!SetEvent(svr->event_read)) + continue; + } + else + { + if (GetLastError() == ERROR_BROKEN_PIPE) + { + if (!SetEvent(svr->event_peek)) + continue; + break; + } + } + } + + printf(" ### %s\n", __FUNCTION__); + svr->read_stopped = EINA_TRUE; + _endthreadex(0); + return 0; +} + +/* thread to read data sent by the client to the server */ +static unsigned int __stdcall +_ecore_con_local_win32_server_read_client_thread(void *data) +{ + Ecore_Con_Client *cl; + DWORD nbr_bytes = 0; + + cl = (Ecore_Con_Client *)data; + + cl->host_server->read_stopped = EINA_FALSE; + + while (!cl->host_server->read_stop) + { + if (PeekNamedPipe(cl->host_server->pipe, NULL, 0, NULL, &nbr_bytes, NULL)) + { + if (nbr_bytes <= 0) + continue; + + cl->host_server->nbr_bytes = nbr_bytes; + if (!SetEvent(cl->host_server->event_read)) + continue; + } + else + { + if (GetLastError() == ERROR_BROKEN_PIPE) + { + if (!SetEvent(cl->host_server->event_peek)) + continue; + break; + } + } + } + + printf(" ### %s\n", __FUNCTION__); + cl->host_server->read_stopped = EINA_TRUE; + _endthreadex(0); + return 0; +} + +static Eina_Bool +_ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Client *cl = NULL; + Ecore_Con_Server *svr; + Ecore_Win32_Handler *handler_read; + Ecore_Win32_Handler *handler_peek; + + svr = (Ecore_Con_Server *)data; + + if (!svr->pipe) + return ECORE_CALLBACK_CANCEL; + + if (svr->delete_me) + return ECORE_CALLBACK_CANCEL; + + if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && + (svr->client_count >= (unsigned int)svr->client_limit)) + return ECORE_CALLBACK_CANCEL; + + cl = calloc(1, sizeof(Ecore_Con_Client)); + if (!cl) + { + ERR("allocation failed"); + return ECORE_CALLBACK_CANCEL; + } + + cl->host_server = svr; + ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); + + cl->host_server->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!cl->host_server->event_read) + { + ERR("Can not create event read"); + goto free_cl; + } + + handler_read = ecore_main_win32_handler_add(cl->host_server->event_read, + _ecore_con_local_win32_server_read_client_handler, + cl); + if (!handler_read) + { + ERR("Can not create handler read"); + goto close_event_read; + } + + cl->host_server->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!cl->host_server->event_peek) + { + ERR("Can not create event peek"); + goto del_handler_read; + } + + handler_peek = ecore_main_win32_handler_add(cl->host_server->event_peek, + _ecore_con_local_win32_server_peek_client_handler, + cl); + if (!handler_peek) + { + ERR("Can not create handler peek"); + goto close_event_peek; + } + + cl->host_server->read_stopped = EINA_TRUE; + cl->host_server->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_server_read_client_thread, cl, CREATE_SUSPENDED, NULL); + if (!cl->host_server->thread_read) + { + ERR("Can not launch thread"); + goto del_handler_peek; + } + + svr->clients = eina_list_append(svr->clients, cl); + svr->client_count++; + + if (!cl->delete_me) + ecore_con_event_client_add(cl); + + ecore_main_win32_handler_del(wh); + + ResumeThread(cl->host_server->thread_read); + return ECORE_CALLBACK_DONE; + + del_handler_peek: + ecore_main_win32_handler_del(handler_peek); + close_event_peek: + CloseHandle(cl->host_server->event_peek); + del_handler_read: + ecore_main_win32_handler_del(handler_read); + close_event_read: + CloseHandle(cl->host_server->event_read); + free_cl: + free(cl); + + return ECORE_CALLBACK_CANCEL; +} + +static unsigned int __stdcall +_ecore_con_local_win32_listening(void *data) +{ + Ecore_Con_Server *svr; + BOOL res; + + svr = (Ecore_Con_Server *)data; + + while (1) + { + res = ConnectNamedPipe(svr->pipe, NULL); + if (!res) + { + ERR("Opening the connection to the client failed"); + CloseHandle(svr->pipe); + svr->pipe = NULL; + } + break; + } + + DBG("Client connected"); + + printf(" ### %s\n", __FUNCTION__); + _endthreadex(0); + return 0; +} + +Eina_Bool +ecore_con_local_listen(Ecore_Con_Server *svr) +{ + char buf[256]; + HANDLE thread_listening; + Ecore_Win32_Handler *handler; + + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + { + ERR("Your system does not support abstract sockets!"); + return EINA_FALSE; + } + + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) + snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); + else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) + { + const char *computername; + + computername = getenv("CoMPUTERNAME"); + snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); + } + + svr->path = strdup(buf); + if (!svr->path) + { + ERR("Allocation failed"); + return EINA_FALSE; + } + + /* + * synchronuous + * block mode + * wait mode + */ + svr->pipe = CreateNamedPipe(svr->path, + PIPE_ACCESS_DUPLEX, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + BUFSIZE, + BUFSIZE, + 5000, + NULL); + if (svr->pipe == INVALID_HANDLE_VALUE) + { + ERR("Creation of the named pipe failed"); + goto free_path; + } + + /* + * We use ConnectNamedPipe() to wait for a client to connect. + * As the function is blocking, to let the main loop continuing + * its iterations, we call ConnectNamedPipe() in a thread + */ + thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, svr, CREATE_SUSPENDED, NULL); + if (!thread_listening) + { + ERR("Creation of the listening thread failed"); + goto close_pipe; + } + + handler = ecore_main_win32_handler_add(thread_listening, + _ecore_con_local_win32_client_add, + svr); + if (!handler) + { + ERR("Creation of the client add handler failed"); + goto del_handler; + } + + svr->read_stopped = EINA_TRUE; + ResumeThread(thread_listening); + + return EINA_TRUE; + + del_handler: + ecore_main_win32_handler_del(handler); + close_pipe: + CloseHandle(svr->pipe); + free_path: + free(svr->path); + svr->path = NULL; + + return EINA_FALSE; +} + +void +ecore_con_local_win32_server_del(Ecore_Con_Server *svr) +{ + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + return; + + if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && + ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) + return; + + svr->read_stop = 1; + while (!svr->read_stopped) + Sleep(100); + + if (svr->event_peek) + CloseHandle(svr->event_peek); + svr->event_peek = NULL; + if (svr->event_read) + CloseHandle(svr->event_read); + svr->event_read = NULL; + free(svr->path); + svr->path = NULL; + if (svr->pipe) + CloseHandle(svr->pipe); + svr->pipe = NULL; +} + +void +ecore_con_local_win32_client_del(Ecore_Con_Client *cl) +{ + if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + return; + + if (((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && + ((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) + return; + + cl->host_server->read_stop = 1; + while (!cl->host_server->read_stopped) + Sleep(100); + + if (cl->host_server->event_peek) + CloseHandle(cl->host_server->event_peek); + cl->host_server->event_peek = NULL; + if (cl->host_server->event_read) + CloseHandle(cl->host_server->event_read); + cl->host_server->event_read = NULL; + free(cl->host_server->path); + cl->host_server->path = NULL; + if (cl->host_server->pipe) + CloseHandle(cl->host_server->pipe); + cl->host_server->pipe = NULL; +} + +Eina_Bool +ecore_con_local_connect(Ecore_Con_Server *svr, + Eina_Bool (*cb_done)(void *data, + Ecore_Fd_Handler *fd_handler)) +{ + char buf[256]; + Ecore_Win32_Handler *handler_read; + Ecore_Win32_Handler *handler_peek; + + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + { + ERR("Your system does not support abstract sockets!"); + return EINA_FALSE; + } + + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) + snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); + else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) + { + const char *computername; + + computername = getenv("COMPUTERNAME"); + snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); + } + + while (1) + { + svr->pipe = CreateFile(buf, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL); + if (svr->pipe != INVALID_HANDLE_VALUE) + break; + + /* if pipe not busy, we exit */ + if (GetLastError() != ERROR_PIPE_BUSY) + { + ERR("Connection to a server failed"); + return EINA_FALSE; + } + + /* pipe busy, so we wait for it */ + if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER)) + { + ERR("Can not wait for a server"); + goto close_pipe; + } + } + + svr->path = strdup(buf); + if (!svr->path) + { + ERR("Allocation failed"); + goto close_pipe; + } + + svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!svr->event_read) + { + ERR("Can not create event read"); + goto free_path; + } + + handler_read = ecore_main_win32_handler_add(svr->event_read, + _ecore_con_local_win32_client_read_server_handler, + svr); + if (!handler_read) + { + ERR("Can not create handler read"); + goto close_event_read; + } + + svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!svr->event_peek) + { + ERR("Can not create event peek"); + goto del_handler_read; + } + + handler_peek = ecore_main_win32_handler_add(svr->event_peek, + _ecore_con_local_win32_client_peek_server_handler, + svr); + if (!handler_peek) + { + ERR("Can not create handler peek"); + goto close_event_peek; + } + + svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_client_read_server_thread, svr, CREATE_SUSPENDED, NULL); + if (!svr->thread_read) + { + ERR("Can not launch thread"); + goto del_handler_peek; + } + + if (!svr->delete_me) ecore_con_event_server_add(svr); + + ResumeThread(svr->thread_read); + + return EINA_TRUE; + + del_handler_peek: + ecore_main_win32_handler_del(handler_peek); + close_event_peek: + CloseHandle(svr->event_peek); + del_handler_read: + ecore_main_win32_handler_del(handler_read); + close_event_read: + CloseHandle(svr->event_read); + free_path: + free(svr->path); + svr->path = NULL; + close_pipe: + CloseHandle(svr->pipe); + + return EINA_FALSE; +} + +Eina_Bool +ecore_con_local_win32_server_flush(Ecore_Con_Server *svr) +{ + int num; + BOOL res; + DWORD written; + + /* This check should never be true */ + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + return EINA_TRUE; + + if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && + ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) + return EINA_FALSE; + + num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset; + if (num <= 0) return EINA_TRUE; + + res = WriteFile(svr->pipe, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num, &written, NULL); + if (!res) + { + char *msg; + + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_server_error(svr, msg); + free(msg); + } + _ecore_con_server_kill(svr); + } + + svr->write_buf_offset += written; + if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) + { + svr->write_buf_offset = 0; + eina_binbuf_free(svr->buf); + svr->buf = NULL; + svr->want_write = 0; + } + else if (written < (DWORD)num) + svr->want_write = 1; + + return EINA_TRUE; +} + +Eina_Bool +ecore_con_local_win32_client_flush(Ecore_Con_Client *cl) +{ + Ecore_Con_Type type; + int num; + BOOL res; + DWORD written; + + type = cl->host_server->type & ECORE_CON_TYPE; + + /* This check should never be true */ + if (type == ECORE_CON_LOCAL_ABSTRACT) + return EINA_TRUE; + + if ((type != ECORE_CON_LOCAL_USER) && + (type != ECORE_CON_LOCAL_SYSTEM)) + return EINA_FALSE; + + num = eina_binbuf_length_get(cl->buf) - cl->buf_offset; + if (num <= 0) return EINA_TRUE; + + res = WriteFile(cl->host_server->pipe, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num, &written, NULL); + if (!res) + { + char *msg; + + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_client_error(cl, msg); + free(msg); + } + _ecore_con_client_kill(cl); + } + + cl->buf_offset += written; + if (cl->buf_offset >= eina_binbuf_length_get(cl->buf)) + { + cl->buf_offset = 0; + eina_binbuf_free(cl->buf); + cl->buf = NULL; + cl->host_server->want_write = 0; + } + else if (written < (DWORD)num) + cl->host_server->want_write = 1; + + return EINA_TRUE; +} diff --git a/src/lib/ecore_con/ecore_con_private.h b/src/lib/ecore_con/ecore_con_private.h new file mode 100644 index 0000000000..d8b0abb5c3 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_private.h @@ -0,0 +1,390 @@ +#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 +#define ECORE_CON_SUPER_SSL 0xf00 + +#if USE_GNUTLS +# include +#elif USE_OPENSSL +# include +#endif +#ifdef HAVE_CURL +#include +#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 struct _Ecore_Con_Lookup Ecore_Con_Lookup; +typedef struct _Ecore_Con_Info Ecore_Con_Info; +typedef struct Ecore_Con_Socks Ecore_Con_Socks_v4; +typedef struct Ecore_Con_Socks_v5 Ecore_Con_Socks_v5; +typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos); + +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; + +typedef enum _Ecore_Con_Ssl_Handshake +{ + ECORE_CON_SSL_STATE_DONE = 0, + ECORE_CON_SSL_STATE_HANDSHAKING, + ECORE_CON_SSL_STATE_INIT +} Ecore_Con_Ssl_State; + +typedef enum Ecore_Con_Proxy_State +{ /* named PROXY instead of SOCKS in case some handsome and enterprising + * developer decides to add HTTP CONNECT support + */ + ECORE_CON_PROXY_STATE_DONE = 0, + ECORE_CON_PROXY_STATE_RESOLVED, + ECORE_CON_PROXY_STATE_INIT, + ECORE_CON_PROXY_STATE_READ, + ECORE_CON_PROXY_STATE_AUTH, + ECORE_CON_PROXY_STATE_REQUEST, + ECORE_CON_PROXY_STATE_CONFIRM, +} Ecore_Con_Proxy_State; + +struct _Ecore_Con_Client +{ + ECORE_MAGIC; + int fd; + Ecore_Con_Server *host_server; + void *data; + Ecore_Fd_Handler *fd_handler; + unsigned int buf_offset; + Eina_Binbuf *buf; + const char *ip; + Eina_List *event_count; + struct sockaddr *client_addr; + int client_addr_len; + double start_time; + Ecore_Timer *until_deletion; + double disconnect_time; +#if USE_GNUTLS + gnutls_datum_t session_ticket; + gnutls_session_t session; +#elif USE_OPENSSL + SSL *ssl; + int ssl_err; +#endif + Ecore_Con_Ssl_State ssl_state; + Eina_Bool handshaking : 1; + Eina_Bool upgrade : 1; /* STARTTLS queued */ + Eina_Bool delete_me : 1; /* del event has been queued */ +}; + +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; + unsigned int client_count; + Eina_Binbuf *buf; + unsigned int write_buf_offset; + Eina_List *infos; + Eina_List *event_count; + int client_limit; + pid_t ppid; + /* socks */ + Ecore_Con_Socks *ecs; + Ecore_Con_Proxy_State ecs_state; + int ecs_addrlen; + unsigned char ecs_addr[16]; + unsigned int ecs_buf_offset; + Eina_Binbuf *ecs_buf; + Eina_Binbuf *ecs_recvbuf; + const char *proxyip; + int proxyport; + /* endsocks */ + const char *verify_name; +#if USE_GNUTLS + gnutls_session_t session; + gnutls_anon_client_credentials_t anoncred_c; + gnutls_anon_server_credentials_t anoncred_s; + gnutls_psk_client_credentials_t pskcred_c; + gnutls_psk_server_credentials_t pskcred_s; + gnutls_certificate_credentials_t cert; + char *cert_file; + gnutls_dh_params_t dh_params; +#elif USE_OPENSSL + SSL_CTX *ssl_ctx; + SSL *ssl; + int ssl_err; +#endif + double start_time; + Ecore_Timer *until_deletion; + double disconnect_time; + double client_disconnect_time; + const char *ip; + Eina_Bool created : 1; /* @c EINA_TRUE if server is our listening server */ + Eina_Bool connecting : 1; /* @c EINA_FALSE if just initialized or connected */ + Eina_Bool handshaking : 1; /* @c EINA_TRUE if server is ssl handshaking */ + Eina_Bool upgrade : 1; /* STARTTLS queued */ + Eina_Bool disable_proxy : 1; /* proxy should never be used with this connection */ + Eina_Bool ssl_prepared : 1; + Eina_Bool use_cert : 1; /* @c EINA_TRUE if using certificate auth */ + Ecore_Con_Ssl_State ssl_state; /* current state of ssl handshake on the server */ + Eina_Bool verify : 1; /* @c EINA_TRUE if certificates will be verified */ + Eina_Bool verify_basic : 1; /* @c EINA_TRUE if certificates will be verified only against the hostname */ + Eina_Bool reject_excess_clients : 1; + Eina_Bool delete_me : 1; /* del event has been queued */ +#ifdef _WIN32 + Eina_Bool want_write : 1; + Eina_Bool read_stop : 1; + Eina_Bool read_stopped : 1; + HANDLE pipe; + HANDLE thread_read; + HANDLE event_read; + HANDLE event_peek; + DWORD nbr_bytes; +#endif +}; + +#ifdef HAVE_CURL +struct _Ecore_Con_Url +{ + ECORE_MAGIC; + CURL *curl_easy; + struct curl_slist *headers; + Eina_List *additional_headers; + Eina_List *response_headers; + const char *url; + long proxy_type; + int status; + + Ecore_Timer *timer; + + Ecore_Con_Url_Time time_condition; + double timestamp; + void *data; + + void *post_data; + + int received; + int write_fd; + + unsigned int event_count; + Eina_Bool dead : 1; + Eina_Bool multi : 1; +}; +#endif + +struct _Ecore_Con_Info +{ + unsigned int size; + struct addrinfo info; + char ip[NI_MAXHOST]; + char service[NI_MAXSERV]; +}; + +struct _Ecore_Con_Lookup +{ + Ecore_Con_Dns_Cb done_cb; + const void *data; +}; + +struct Ecore_Con_Socks /* v4 */ +{ + unsigned char version; + + const char *ip; + int port; + const char *username; + unsigned int ulen; + Eina_Bool lookup : 1; + Eina_Bool bind : 1; +}; + +struct Ecore_Con_Socks_v5 +{ + unsigned char version; + + const char *ip; + int port; + const char *username; + unsigned int ulen; + Eina_Bool lookup : 1; + Eina_Bool bind : 1; + /* v5 only */ + unsigned char method; + const char *password; + unsigned int plen; +}; + +extern Ecore_Con_Socks *_ecore_con_proxy_once; +extern Ecore_Con_Socks *_ecore_con_proxy_global; +void ecore_con_socks_init(void); +void ecore_con_socks_shutdown(void); +Eina_Bool ecore_con_socks_svr_init(Ecore_Con_Server *svr); +void ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num); +void ecore_con_socks_dns_cb(const char *canonname, const char *ip, struct sockaddr *addr, int addrlen, Ecore_Con_Server *svr); +/* from ecore_con.c */ +void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info); +void ecore_con_event_proxy_bind(Ecore_Con_Server *svr); +void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate); +void ecore_con_event_server_del(Ecore_Con_Server *svr); +#define ecore_con_event_server_error(svr, error) _ecore_con_event_server_error((svr), (char*)(error), EINA_TRUE) +void _ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate); +void ecore_con_event_client_add(Ecore_Con_Client *cl); +void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate); +void ecore_con_event_client_del(Ecore_Con_Client *cl); +void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error); +void _ecore_con_server_kill(Ecore_Con_Server *svr); +void _ecore_con_client_kill(Ecore_Con_Client *cl); +/* from ecore_local_win32.c */ +#ifdef _WIN32 +Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr); +Eina_Bool ecore_con_local_connect(Ecore_Con_Server *svr, + Eina_Bool (*cb_done)(void *data, + Ecore_Fd_Handler *fd_handler)); +Eina_Bool ecore_con_local_win32_server_flush(Ecore_Con_Server *svr); +Eina_Bool ecore_con_local_win32_client_flush(Ecore_Con_Client *cl); +void ecore_con_local_win32_server_del(Ecore_Con_Server *svr); +void ecore_con_local_win32_client_del(Ecore_Con_Client *cl); +#else +/* 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, + Eina_Bool (*cb_done)( + void *data, + Ecore_Fd_Handler *fd_handler), + void *data); +int ecore_con_local_listen(Ecore_Con_Server *svr, + Eina_Bool (*cb_listen)( + void *data, + Ecore_Fd_Handler *fd_handler), + void *data); +#endif + +/* 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); +void ecore_con_info_data_clear(void *info); + +void ecore_con_event_server_add(Ecore_Con_Server *svr); + + +/* from ecore_con_ssl.c */ +Ecore_Con_Ssl_Error ecore_con_ssl_init(void); +Ecore_Con_Ssl_Error ecore_con_ssl_shutdown(void); +Ecore_Con_Ssl_Error ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, int ssl_type); +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); +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, + const 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); +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, + const unsigned char *buf, + int size); + +int ecore_con_info_get(Ecore_Con_Server *svr, + Ecore_Con_Info_Cb done_cb, + void *data, + struct addrinfo *hints); + + +#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \ + TYPE *Type##_alloc(void); \ + void Type##_free(TYPE *e); + +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Add, ecore_con_event_client_add); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Del, ecore_con_event_client_del); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Write, ecore_con_event_client_write); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Data, ecore_con_event_client_data); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Error, ecore_con_event_server_error); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Error, ecore_con_event_client_error); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Add, ecore_con_event_server_add); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); +GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind); + +void ecore_con_mempool_init(void); +void ecore_con_mempool_shutdown(void); + +#undef GENERIC_ALLOC_FREE_HEADER + +#endif diff --git a/src/lib/ecore_con/ecore_con_socks.c b/src/lib/ecore_con/ecore_con_socks.c new file mode 100644 index 0000000000..a6df8a9640 --- /dev/null +++ b/src/lib/ecore_con/ecore_con_socks.c @@ -0,0 +1,962 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +#ifdef HAVE_NETINET_TCP_H +# include +#endif + +#ifdef HAVE_NET_IF_H +# include +#endif + +/* if net/if.h is not found or if an older versions of net/if.h is provided + which does not define IF_NAMESIZE. We must define it ourselves */ +#ifndef IF_NAMESIZE +# ifdef IFNAMSIZ +# define IF_NAMESIZE IFNAMSIZ +# else +# define IF_NAMESIZE 16 +# endif +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#ifdef HAVE_SYS_UN_H +# include +#endif + +#ifdef HAVE_WS2TCPIP_H +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Con.h" +#include "ecore_con_private.h" + +/* http://tools.ietf.org/html/rfc1928 + o X'00' NO AUTHENTICATION REQUIRED + o X'01' GSSAPI + o X'02' USERNAME/PASSWORD + o X'03' to X'7F' IANA ASSIGNED + o X'80' to X'FE' RESERVED FOR PRIVATE METHODS + o X'FF' NO ACCEPTABLE METHODS +*/ +#define ECORE_CON_SOCKS_V5_METHOD_NONE 0 +#define ECORE_CON_SOCKS_V5_METHOD_GSSAPI 1 +#define ECORE_CON_SOCKS_V5_METHOD_USERPASS 2 + +static int ECORE_CON_SOCKS_V5_METHODS[] = +{ + ECORE_CON_SOCKS_V5_METHOD_NONE, +// ECORE_CON_SOCKS_V5_METHOD_GSSAPI, TODO + ECORE_CON_SOCKS_V5_METHOD_USERPASS +}; + +#define ECORE_CON_SOCKS_V5_TOTAL_METHODS sizeof(ECORE_CON_SOCKS_V5_METHODS) + +#define _ecore_con_server_kill(svr) do { \ + DBG("KILL %p", (svr)); \ + _ecore_con_server_kill((svr)); \ +} while (0) + +#define ECORE_CON_SOCKS_VERSION_CHECK(X) do { \ + if (!(X) || ((X)->version < 4) || ((X)->version > 5)) \ + return; \ +} while (0) +#define ECORE_CON_SOCKS_VERSION_CHECK_RETURN(X, ret) do { \ + if (!(X) || ((X)->version < 4) || ((X)->version > 5)) \ + return (ret); \ +} while (0) + +#define ECORE_CON_SOCKS_CAST(X) \ + Ecore_Con_Socks_v4 *v4 = NULL; \ + Ecore_Con_Socks_v5 *v5 = NULL; \ + if ((X) && ((X)->version == 4)) \ + v4 = (Ecore_Con_Socks_v4 *)(X); \ + else if ((X) && ((X)->version == 5)) \ + v5 = (Ecore_Con_Socks_v5 *)(X); + +Eina_List *ecore_con_socks_proxies = NULL; + +static Ecore_Con_Socks * +_ecore_con_socks_find(unsigned char version, const char *ip, int port, const char *username, size_t ulen, const char *password, size_t plen) +{ + Eina_List *l; + Ecore_Con_Socks_v5 *ecs; + + if (!ecore_con_socks_proxies) return NULL; + + EINA_LIST_FOREACH(ecore_con_socks_proxies, l, ecs) + { + if (ecs->version != version) continue; + if (strcmp(ecs->ip, ip)) continue; + if ((port != -1) && (port != ecs->port)) continue; + if (ulen != ecs->ulen) continue; + if (username && strcmp(ecs->username, username)) continue; + if (version == 5) + { + if (plen != ecs->plen) continue; + if (password && strcmp(ecs->password, password)) continue; + } + return (Ecore_Con_Socks*)ecs; + } + return NULL; +} + +static void +_ecore_con_socks_free(Ecore_Con_Socks *ecs) +{ + ECORE_CON_SOCKS_VERSION_CHECK(ecs); + + if (_ecore_con_proxy_once == ecs) _ecore_con_proxy_once = NULL; + if (_ecore_con_proxy_global == ecs) _ecore_con_proxy_global = NULL; + eina_stringshare_del(ecs->ip); + eina_stringshare_del(ecs->username); + free(ecs); +} + +static Eina_Bool +_ecore_con_socks_svr_init_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4) +{ + size_t addrlen, buflen, ulen = 1; + unsigned char *sbuf; + + addrlen = v4->lookup ? strlen(svr->name) + 1 : 0; + if (v4->username) ulen += v4->ulen; + buflen = sizeof(char) * (8 + ulen + addrlen); + sbuf = malloc(buflen); + if (!sbuf) + { + ecore_con_event_server_error(svr, "Memory allocation failure!"); + _ecore_con_server_kill(svr); + return EINA_FALSE; + } + /* http://en.wikipedia.org/wiki/SOCKS */ + sbuf[0] = 4; + sbuf[1] = v4->bind ? 2 : 1; + sbuf[2] = svr->port >> 8; + sbuf[3] = svr->port & 0xff; + if (addrlen) + { + sbuf[4] = sbuf[5] = sbuf[6] = 0; + sbuf[7] = 1; + } + else + /* SOCKSv4 only handles IPV4, so addrlen is always 4 */ + memcpy(sbuf + 4, svr->ecs_addr, 4); + if (v4->username) + memcpy(sbuf + 8, v4->username, ulen); + else + sbuf[8] = 0; + if (addrlen) memcpy(sbuf + 8 + ulen, svr->name, addrlen); + + svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); + return EINA_TRUE; +} + +static Eina_Bool +_ecore_con_socks_svr_init_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5) +{ + size_t buflen; + unsigned int x; + unsigned char *sbuf; + + if (v5->username) + buflen = sizeof(char) * (2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS); + else + buflen = 3; + sbuf = malloc(buflen); + if (!sbuf) + { + ecore_con_event_server_error(svr, "Memory allocation failure!"); + _ecore_con_server_kill(svr); + return EINA_FALSE; + } + /* http://en.wikipedia.org/wiki/SOCKS + * http://tools.ietf.org/html/rfc1928 + */ + sbuf[0] = 5; + if (v5->username) + { + sbuf[1] = ECORE_CON_SOCKS_V5_TOTAL_METHODS; + for (x = 2; x < 2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS; x++) + sbuf[x] = ECORE_CON_SOCKS_V5_METHODS[x - 2]; + } + else + { + sbuf[1] = 1; + sbuf[2] = ECORE_CON_SOCKS_V5_METHOD_NONE; + } + + svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); + return EINA_TRUE; +} + +#define ECORE_CON_SOCKS_READ(EXACT) \ + if (num < EXACT) \ + { \ + if (!svr->ecs_recvbuf) svr->ecs_recvbuf = eina_binbuf_new(); \ + if (!svr->ecs_recvbuf) goto error; \ + eina_binbuf_append_length(svr->ecs_recvbuf, buf, num); \ + /* the slowest connection on earth */ \ + if (eina_binbuf_length_get(svr->ecs_recvbuf) != EXACT) return; \ + data = eina_binbuf_string_get(svr->ecs_recvbuf); \ + } \ + else if (num > EXACT) goto error; \ + else \ + data = buf + +static void +_ecore_con_socks_read_v4(Ecore_Con_Server *svr, Ecore_Con_Socks_v4 *v4 EINA_UNUSED, const unsigned char *buf, unsigned int num) +{ + const unsigned char *data; + DBG("SOCKS: %d bytes", num); + ECORE_CON_SOCKS_READ(8); + +/* http://ufasoft.com/doc/socks4_protocol.htm */ + if (data[0]) goto error; + switch (data[1]) + { + case 90: + /* success! */ + break; + case 91: + ecore_con_event_server_error(svr, "proxy request rejected or failed"); + goto error; + case 92: + ecore_con_event_server_error(svr, "proxying SOCKS server could not perform authentication"); + goto error; + case 93: + ecore_con_event_server_error(svr, "proxy request authentication rejected"); + goto error; + default: + ecore_con_event_server_error(svr, "garbage data from proxy"); + goto error; + } + if (svr->ecs->bind) + { + unsigned int nport; + char naddr[IF_NAMESIZE]; + + memcpy(&nport, &data[2], 2); + svr->proxyport = ntohl(nport); + + if (!inet_ntop(AF_INET, &data[4], naddr, sizeof(naddr))) goto error; + svr->proxyip = eina_stringshare_add(naddr); + ecore_con_event_proxy_bind(svr); + } + svr->ecs_state = ECORE_CON_PROXY_STATE_DONE; + INF("PROXY CONNECTED"); + if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); + svr->ecs_recvbuf = NULL; + svr->ecs_buf_offset = svr->ecs_addrlen = 0; + memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr)); + if (!svr->ssl_state) + ecore_con_event_server_add(svr); + if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf))) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); + return; +error: + _ecore_con_server_kill(svr); +} + +static Eina_Bool +_ecore_con_socks_auth_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5) +{ + size_t size; + unsigned char *data; + switch (v5->method) + { + case ECORE_CON_SOCKS_V5_METHOD_NONE: + svr->ecs_state = ECORE_CON_PROXY_STATE_REQUEST; + return EINA_TRUE; + case ECORE_CON_SOCKS_V5_METHOD_GSSAPI: + return EINA_TRUE; + case ECORE_CON_SOCKS_V5_METHOD_USERPASS: + if (!v5->username) return EINA_FALSE; + if (!v5->password) v5->plen = 1; + /* http://tools.ietf.org/html/rfc1929 */ + size = sizeof(char) * (3 + v5->ulen + v5->plen); + data = malloc(size); + if (!data) break; + data[0] = 1; + data[1] = v5->ulen; + memcpy(&data[2], v5->username, v5->ulen); + data[1 + v5->ulen] = v5->plen; + if (v5->password) + memcpy(&data[2 + v5->ulen], v5->password, v5->plen); + else + data[2 + v5->ulen] = 0; + svr->ecs_buf = eina_binbuf_manage_new_length(data, size); + return EINA_TRUE; + default: + break; + } + return EINA_FALSE; +} + +static void +_ecore_con_socks_read_v5(Ecore_Con_Server *svr, Ecore_Con_Socks_v5 *v5, const unsigned char *buf, unsigned int num) +{ + const unsigned char *data; + + DBG("SOCKS: %d bytes", num); + switch (svr->ecs_state) + { + + case ECORE_CON_PROXY_STATE_READ: + ECORE_CON_SOCKS_READ(2); + /* http://en.wikipedia.org/wiki/SOCKS */ + if (data[0] != 5) goto error; + if (data[1] == 0xFF) + { + ecore_con_event_server_error(svr, "proxy authentication methods rejected"); + goto error; + } + v5->method = data[1]; + if (!_ecore_con_socks_auth_v5(svr, v5)) goto error; + if (svr->ecs_state == ECORE_CON_PROXY_STATE_REQUEST) + { + /* run again to skip auth reading */ + _ecore_con_socks_read_v5(svr, v5, NULL, 0); + return; + } + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); + svr->ecs_state = ECORE_CON_PROXY_STATE_AUTH; + break; + case ECORE_CON_PROXY_STATE_AUTH: + ECORE_CON_SOCKS_READ(2); + switch (v5->method) + { + case ECORE_CON_SOCKS_V5_METHOD_NONE: + CRIT("HOW DID THIS HAPPEN?????????"); + goto error; + case ECORE_CON_SOCKS_V5_METHOD_GSSAPI: + /* TODO: this */ + break; + case ECORE_CON_SOCKS_V5_METHOD_USERPASS: + if (data[0] != 1) + { + ecore_con_event_server_error(svr, "protocol error"); + goto error; /* wrong version */ + } + if (data[1]) + { + ecore_con_event_server_error(svr, "proxy request authentication rejected"); + goto error; + } + default: + break; + } + case ECORE_CON_PROXY_STATE_REQUEST: + { + size_t addrlen, buflen; + unsigned char *sbuf; + addrlen = v5->lookup ? strlen(svr->name) + 1 : (unsigned int)svr->ecs_addrlen; + buflen = sizeof(char) * (6 + addrlen); + sbuf = malloc(buflen); + if (!sbuf) + { + ecore_con_event_server_error(svr, "Memory allocation failure!"); + goto error; + } + sbuf[0] = 5; + sbuf[1] = v5->bind ? 2 : 1; /* TODO: 0x03 for UDP port association */ + sbuf[2] = 0; + if (v5->lookup) /* domain name */ + { + sbuf[3] = 3; + sbuf[4] = addrlen - 1; + memcpy(sbuf + 5, svr->name, addrlen - 1); + } + else + { + sbuf[3] = (svr->ecs_addrlen == 4) ? 1 : 4; + memcpy(sbuf + 4, svr->ecs_addr, addrlen); + } + sbuf[addrlen + 4] = svr->port >> 8; + sbuf[addrlen + 5] = svr->port & 0xff; + + svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); + break; + } + case ECORE_CON_PROXY_STATE_CONFIRM: + { + /* this is ugly because we have to read an exact number of bytes, + * but we don't know what that number is until we've already read + * at least 5 bytes to determine the length of the unknown stream. + * yep. + */ + size_t to_read, len = svr->ecs_recvbuf ? eina_binbuf_length_get(svr->ecs_recvbuf) : 0; + if (num + len < 5) + { + /* guarantees we get called again */ + ECORE_CON_SOCKS_READ(5); + } + if (len >= 5) + { + data = eina_binbuf_string_get(svr->ecs_recvbuf); + data += 3; + } + else + data = buf + 3 - len; + switch (data[0]) + { + case 1: + to_read = 4; + break; + case 3: + to_read = data[1] + 1; + break; + case 4: + to_read = 16; + /* lazy debugging stub comment */ + break; + default: + ecore_con_event_server_error(svr, "protocol error"); + goto error; + } + /* at this point, we finally know exactly how much we need to read */ + ECORE_CON_SOCKS_READ(6 + to_read); + + if (data[0] != 5) + { + ecore_con_event_server_error(svr, "protocol error"); + goto error; /* wrong version */ + } + switch (data[1]) + { + case 0: + break; + case 1: + ecore_con_event_server_error(svr, "general proxy failure"); + goto error; + case 2: + ecore_con_event_server_error(svr, "connection not allowed by ruleset"); + goto error; + case 3: + ecore_con_event_server_error(svr, "network unreachable"); + goto error; + case 4: + ecore_con_event_server_error(svr, "host unreachable"); + goto error; + case 5: + ecore_con_event_server_error(svr, "connection refused by destination host"); + goto error; + case 6: + ecore_con_event_server_error(svr, "TTL expired"); + goto error; + case 7: + ecore_con_event_server_error(svr, "command not supported / protocol error"); + goto error; + case 8: + ecore_con_event_server_error(svr, "address type not supported"); + default: + goto error; + } + if (data[2]) + { + ecore_con_event_server_error(svr, "protocol error"); + goto error; + } + memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr)); + if (!svr->ssl_state) + ecore_con_event_server_add(svr); + if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf))) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); + svr->ecs_buf_offset = svr->ecs_addrlen = 0; + svr->ecs_state = ECORE_CON_PROXY_STATE_DONE; + INF("PROXY CONNECTED"); + break; + } + default: + break; + } + if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); + svr->ecs_recvbuf = NULL; + + return; +error: + _ecore_con_server_kill(svr); +} + +///////////////////////////////////////////////////////////////////////////////////// +void +ecore_con_socks_shutdown(void) +{ + Ecore_Con_Socks *ecs; + EINA_LIST_FREE(ecore_con_socks_proxies, ecs) + _ecore_con_socks_free(ecs); + _ecore_con_proxy_once = NULL; + _ecore_con_proxy_global = NULL; +} + +void +ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num) +{ + ECORE_CON_SOCKS_VERSION_CHECK(svr->ecs); + ECORE_CON_SOCKS_CAST(svr->ecs); + + if (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) return; + + if (v4) _ecore_con_socks_read_v4(svr, v4, buf, (unsigned int)num); + else _ecore_con_socks_read_v5(svr, v5, buf, (unsigned int)num); +} + +Eina_Bool +ecore_con_socks_svr_init(Ecore_Con_Server *svr) +{ + ECORE_CON_SOCKS_VERSION_CHECK_RETURN(svr->ecs, EINA_FALSE); + ECORE_CON_SOCKS_CAST(svr->ecs); + + if (!svr->ip) return EINA_FALSE; + if (svr->ecs_buf) return EINA_FALSE; + if (svr->ecs_state != ECORE_CON_PROXY_STATE_INIT) return EINA_FALSE; + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); + if (v4) return _ecore_con_socks_svr_init_v4(svr, v4); + return _ecore_con_socks_svr_init_v5(svr, v5); +} + +void +ecore_con_socks_dns_cb(const char *canonname EINA_UNUSED, const char *ip, struct sockaddr *addr, int addrlen EINA_UNUSED, Ecore_Con_Server *svr) +{ + svr->ip = eina_stringshare_add(ip); + svr->ecs_state++; + if (addr->sa_family == AF_INET) + { + memcpy(svr->ecs_addr, &((struct sockaddr_in *)addr)->sin_addr.s_addr, 4); + svr->ecs_addrlen = 4; + } +#ifdef HAVE_IPV6 + else + { + memcpy(svr->ecs_addr, &((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, 16); + svr->ecs_addrlen = 16; + } +#endif + ecore_con_socks_svr_init(svr); +} + +void +ecore_con_socks_init(void) +{ + const char *socks; + char *h, *p, *l, *u = NULL; + char buf[512]; + int port, lookup = 0; + Eina_Bool v5 = EINA_FALSE; + Ecore_Con_Socks *ecs; + unsigned char addr[sizeof(struct in_addr)]; +#ifdef HAVE_IPV6 + unsigned char addr6[sizeof(struct in6_addr)]; +#endif + + /* ECORE_CON_SOCKS_V4=[user@]host-port:[1|0] */ + socks = getenv("ECORE_CON_SOCKS_V4"); + if (!socks) + { + /* ECORE_CON_SOCKS_V5=[user@]host-port:[1|0] */ + socks = getenv("ECORE_CON_SOCKS_V5"); + v5 = EINA_TRUE; + } + if ((!socks) || (!socks[0]) || (strlen(socks) > 512)) return; + strncpy(buf, socks, sizeof(buf)); + h = strchr(buf, '@'); + /* username */ + if (h && (h - buf > 0)) *h++ = 0, u = buf; + else h = buf; + + /* host ip; I ain't resolvin shit here */ + p = strchr(h, '-'); + if (!p) return; + *p++ = 0; + if (!inet_pton(AF_INET, h, addr)) +#ifdef HAVE_IPV6 + { + if (!v5) return; + if (!inet_pton(AF_INET6, h, addr6)) + return; + } +#else + return; +#endif + + errno = 0; + port = strtol(p, &l, 10); + if (errno || (port < 0) || (port > 65535)) return; + if (l && (l[0] == ':')) + lookup = (l[1] == '1'); + if (v5) + ecs = ecore_con_socks5_remote_add(h, port, u, NULL); + else + ecs = ecore_con_socks4_remote_add(h, port, u); + if (!ecs) return; + ecore_con_socks_lookup_set(ecs, lookup); + ecore_con_socks_apply_always(ecs); + INF("Added global proxy server %s%s%s:%d - DNS lookup %s", + u ?: "", u ? "@" : "", h, port, lookup ? "ENABLED" : "DISABLED"); +} + +///////////////////////////////////////////////////////////////////////////////////// + +/** + * @defgroup Ecore_Con_Socks_Group Ecore Connection SOCKS functions + * @{ + */ + +/** + * Add a SOCKS v4 proxy to the proxy list + * + * Use this to create (or return, if previously added) a SOCKS proxy + * object which can be used by any ecore_con servers. + * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) + * @param port The port to connect to on the proxy + * @param username The username to use for the proxy (OPTIONAL) + * @return An allocated proxy object, or NULL on failure + * @note This object NEVER needs to be explicitly freed. + * @since 1.2 + */ +EAPI Ecore_Con_Socks * +ecore_con_socks4_remote_add(const char *ip, int port, const char *username) +{ + Ecore_Con_Socks *ecs; + size_t ulen = 0; + + if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL; + + if (username) + { + ulen = strlen(username); + /* max length for protocol */ + if ((!ulen) || (ulen > 255)) return NULL; + } + ecs = _ecore_con_socks_find(4, ip, port, username, ulen, NULL, 0); + if (ecs) return ecs; + + ecs = calloc(1, sizeof(Ecore_Con_Socks_v4)); + if (!ecs) return NULL; + + ecs->version = 4; + ecs->ip = eina_stringshare_add(ip); + ecs->port = port; + ecs->username = eina_stringshare_add(username); + ecs->ulen = ulen; + ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs); + return ecs; +} + +/** + * Find a SOCKS v4 proxy in the proxy list + * + * Use this to determine if a SOCKS proxy was previously added by checking + * the proxy list against the parameters given. + * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) + * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip + * @param username The username used for the proxy (OPTIONAL) + * @return true only if a proxy exists matching the given params + * @note This function matches slightly more loosely than ecore_con_socks4_remote_add(), and + * ecore_con_socks4_remote_add() should be used to return the actual object. + * @since 1.2 + */ +EAPI Eina_Bool +ecore_con_socks4_remote_exists(const char *ip, int port, const char *username) +{ + if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0]))) + return EINA_FALSE; + return !!_ecore_con_socks_find(4, ip, port, username, username ? strlen(username) : 0, NULL, 0); +} + +/** + * Remove a SOCKS v4 proxy from the proxy list and delete it + * + * Use this to remove a SOCKS proxy from the proxy list by checking + * the list against the parameters given. The proxy will then be deleted. + * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) + * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip + * @param username The username used for the proxy (OPTIONAL) + * @note This function matches in the same way as ecore_con_socks4_remote_exists(). + * @warning Be aware that deleting a proxy which is being used WILL ruin your life. + * @since 1.2 + */ +EAPI void +ecore_con_socks4_remote_del(const char *ip, int port, const char *username) +{ + Ecore_Con_Socks_v4 *v4; + + if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0]))) return; + if (!ecore_con_socks_proxies) return; + + v4 = (Ecore_Con_Socks_v4*)_ecore_con_socks_find(4, ip, port, username, username ? strlen(username) : 0, NULL, 0); + if (!v4) return; + ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v4); + _ecore_con_socks_free((Ecore_Con_Socks*)v4); +} +/** + * Add a SOCKS v5 proxy to the proxy list + * + * Use this to create (or return, if previously added) a SOCKS proxy + * object which can be used by any ecore_con servers. + * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) + * @param port The port to connect to on the proxy + * @param username The username to use for the proxy (OPTIONAL) + * @param password The password to use for the proxy (OPTIONAL) + * @return An allocated proxy object, or NULL on failure + * @note This object NEVER needs to be explicitly freed. + * @since 1.2 + */ +EAPI Ecore_Con_Socks * +ecore_con_socks5_remote_add(const char *ip, int port, const char *username, const char *password) +{ + Ecore_Con_Socks_v5 *ecs5; + size_t ulen = 0, plen = 0; + + if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL; + + if (username) + { + ulen = strlen(username); + /* max length for protocol */ + if ((!ulen) || (ulen > 255)) return NULL; + } + if (password) + { + plen = strlen(password); + /* max length for protocol */ + if ((!plen) || (plen > 255)) return NULL; + } + ecs5 = (Ecore_Con_Socks_v5*)_ecore_con_socks_find(5, ip, port, username, ulen, password, plen); + if (ecs5) return (Ecore_Con_Socks*)ecs5; + + ecs5 = calloc(1, sizeof(Ecore_Con_Socks_v5)); + if (!ecs5) return NULL; + + ecs5->version = 5; + ecs5->ip = eina_stringshare_add(ip); + ecs5->port = port; + ecs5->username = eina_stringshare_add(username); + ecs5->ulen = ulen; + ecs5->password = eina_stringshare_add(password); + ecs5->plen = plen; + ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs5); + return (Ecore_Con_Socks*)ecs5; +} + +/** + * Find a SOCKS v5 proxy in the proxy list + * + * Use this to determine if a SOCKS proxy was previously added by checking + * the proxy list against the parameters given. + * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) + * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip + * @param username The username used for the proxy (OPTIONAL) + * @param password The password used for the proxy (OPTIONAL) + * @return true only if a proxy exists matching the given params + * @note This function matches slightly more loosely than ecore_con_socks5_remote_add(), and + * ecore_con_socks5_remote_add() should be used to return the actual object. + * @since 1.2 + */ +EAPI Eina_Bool +ecore_con_socks5_remote_exists(const char *ip, int port, const char *username, const char *password) +{ + if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])) || (password && (!password[0]))) + return EINA_FALSE; + return !!_ecore_con_socks_find(5, ip, port, username, username ? strlen(username) : 0, password, password ? strlen(password) : 0); +} + +/** + * Remove a SOCKS v5 proxy from the proxy list and delete it + * + * Use this to remove a SOCKS proxy from the proxy list by checking + * the list against the parameters given. The proxy will then be deleted. + * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) + * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip + * @param username The username used for the proxy (OPTIONAL) + * @param password The password used for the proxy (OPTIONAL) + * @note This function matches in the same way as ecore_con_socks4_remote_exists(). + * @warning Be aware that deleting a proxy which is being used WILL ruin your life. + * @since 1.2 + */ +EAPI void +ecore_con_socks5_remote_del(const char *ip, int port, const char *username, const char *password) +{ + Ecore_Con_Socks_v5 *v5; + + if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0])) || (password && (!password[0]))) + return; + if (!ecore_con_socks_proxies) return; + + v5 = (Ecore_Con_Socks_v5*)_ecore_con_socks_find(5, ip, port, username, username ? strlen(username) : 0, password, password ? strlen(password) : 0); + if (!v5) return; + ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v5); + _ecore_con_socks_free((Ecore_Con_Socks*)v5); +} + +/** + * Set DNS lookup mode on an existing SOCKS proxy + * + * According to RFC, SOCKS v4 does not require that a proxy perform + * its own DNS lookups for addresses. SOCKS v4a specifies the protocol + * for this. SOCKS v5 allows DNS lookups. + * If you want to enable remote DNS lookup and are sure that your + * proxy supports it, use this function. + * @param ecs The proxy object + * @param enable If true, the proxy will perform the dns lookup + * @note By default, this setting is DISABLED. + * @since 1.2 + */ +EAPI void +ecore_con_socks_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable) +{ + ECORE_CON_SOCKS_VERSION_CHECK(ecs); + ecs->lookup = !!enable; +} + +/** + * Get DNS lookup mode on an existing SOCKS proxy + * + * According to RFC, SOCKS v4 does not require that a proxy perform + * its own DNS lookups for addresses. SOCKS v4a specifies the protocol + * for this. SOCKS v5 allows DNS lookups. + * This function returns whether lookups are enabled on a proxy object. + * @param ecs The proxy object + * @return If true, the proxy will perform the dns lookup + * @note By default, this setting is DISABLED. + * @since 1.2 + */ +EAPI Eina_Bool +ecore_con_socks_lookup_get(Ecore_Con_Socks *ecs) +{ + ECORE_CON_SOCKS_VERSION_CHECK_RETURN(ecs, EINA_FALSE); + return ecs->lookup; +} + +/** + * Enable bind mode on a SOCKS proxy + * + * Use this function to enable binding a remote port for use with a remote server. + * For more information, see http://ufasoft.com/doc/socks4_protocol.htm + * @param ecs The proxy object + * @param is_bind If true, the connection established will be a port binding + * @warning Be aware that changing the operation mode of an active proxy may result in undefined behavior + * @since 1.2 + */ +EAPI void +ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind) +{ + EINA_SAFETY_ON_NULL_RETURN(ecs); + ECORE_CON_SOCKS_VERSION_CHECK(ecs); + ecs->bind = !!is_bind; +} + +/** + * Return bind mode of a SOCKS proxy + * + * Use this function to return bind mode of a proxy (binding a remote port for use with a remote server). + * For more information, see http://ufasoft.com/doc/socks4_protocol.htm + * @param ecs The proxy object + * @return If true, the connection established will be a port binding + * @since 1.2 + */ +EAPI Eina_Bool +ecore_con_socks_bind_get(Ecore_Con_Socks *ecs) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, EINA_FALSE); + ECORE_CON_SOCKS_VERSION_CHECK_RETURN(ecs, EINA_FALSE); + return ecs->bind; +} + +/** + * Return SOCKS version of a SOCKS proxy + * + * Use this function to return the SOCKS protocol version of a proxy + * @param ecs The proxy object + * @return 0 on error, else 4/5 + * @since 1.2 + */ +EAPI unsigned int +ecore_con_socks_version_get(Ecore_Con_Socks *ecs) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, 0); + ECORE_CON_SOCKS_VERSION_CHECK_RETURN(ecs, 0); + return ecs->version; +} + +/** + * Remove a SOCKS v4 proxy from the proxy list and delete it + * + * Use this to remove a SOCKS proxy from the proxy list by directly deleting the object given. + * @param ecs The proxy object to delete + * @warning Be aware that deleting a proxy which is being used WILL ruin your life. + * @since 1.2 + */ +EAPI void +ecore_con_socks_remote_del(Ecore_Con_Socks *ecs) +{ + EINA_SAFETY_ON_NULL_RETURN(ecs); + if (!ecore_con_socks_proxies) return; + + ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, ecs); + _ecore_con_socks_free(ecs); +} + +/** + * Set a proxy object to be used with the next server created with ecore_con_server_connect() + * + * This function sets a proxy for the next ecore_con connection. After the next server is created, + * the proxy will NEVER be applied again unless explicitly enabled. + * @param ecs The proxy object + * @see ecore_con_socks_apply_always() + * @since 1.2 + */ +EAPI void +ecore_con_socks_apply_once(Ecore_Con_Socks *ecs) +{ + _ecore_con_proxy_once = ecs; +} + +/** + * Set a proxy object to be used with all servers created with ecore_con_server_connect() + * + * This function sets a proxy for all ecore_con connections. It will always be used. + * @param ecs The proxy object + * @see ecore_con_socks_apply_once() + * @since 1.2 + * @note ecore-con supports setting this through environment variables like so: + * ECORE_CON_SOCKS_V4=[user@]server-port:lookup + * ECORE_CON_SOCKS_V5=[user@]server-port:lookup + * user is the OPTIONAL string that would be passed to the proxy as the username + * server is the IP_ADDRESS of the proxy server + * port is the port to connect to on the proxy server + * lookup is 1 if the proxy should perform all DNS lookups, otherwise 0 or omitted + */ +EAPI void +ecore_con_socks_apply_always(Ecore_Con_Socks *ecs) +{ + _ecore_con_proxy_global = ecs; +} +/** @} */ diff --git a/src/lib/ecore_con/ecore_con_ssl.c b/src/lib/ecore_con/ecore_con_ssl.c new file mode 100644 index 0000000000..609d29161a --- /dev/null +++ b/src/lib/ecore_con/ecore_con_ssl.c @@ -0,0 +1,2141 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#if USE_GNUTLS +# include +# include +# include +#elif USE_OPENSSL +# include +# include +# include +#endif + +#ifdef HAVE_WS2TCPIP_H +# include +#endif + +#include +#include "Ecore.h" +#include "ecore_con_private.h" + +EAPI int ECORE_CON_EVENT_CLIENT_UPGRADE = 0; +EAPI int ECORE_CON_EVENT_SERVER_UPGRADE = 0; + +static int _init_con_ssl_init_count = 0; + +#ifdef USE_GNUTLS +# ifdef EINA_HAVE_THREADS +GCRY_THREAD_OPTION_PTHREAD_IMPL; +# endif + +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 + +#if USE_GNUTLS +static void +_gnutls_print_errors(void *conn, int type, int ret) +{ + char buf[1024]; + + if (!ret) return; + + snprintf(buf, sizeof(buf), "GNUTLS error: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret)); + if (type == ECORE_CON_EVENT_CLIENT_ERROR) + ecore_con_event_client_error(conn, buf); + else + ecore_con_event_server_error(conn, buf); +} + +static void +_gnutls_print_session(const gnutls_datum_t *cert_list, unsigned int cert_list_size) +{ + char *c = NULL; + gnutls_x509_crt_t crt; + unsigned int x; + + if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return; + for (x = 0; x < cert_list_size; x++) + { + gnutls_x509_crt_init(&crt); + gnutls_x509_crt_import(crt, &cert_list[x], GNUTLS_X509_FMT_DER); + gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, (gnutls_datum_t*)&c); + INF("CERTIFICATE:\n%s", c); + gnutls_free(c); + gnutls_x509_crt_deinit(crt); + crt = NULL; + } +} + +#ifdef ISCOMFITOR +static void +_gnutls_log_func(int level, + const char *str) +{ + char buf[128]; + strncat(buf, str, strlen(str) - 1); + DBG("|<%d>| %s", level, buf); +} +#endif + +static const char * +SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status) +{ + switch (status) + { + case GNUTLS_HANDSHAKE_HELLO_REQUEST: + return "Hello request"; + + case GNUTLS_HANDSHAKE_CLIENT_HELLO: + return "Client hello"; + + case GNUTLS_HANDSHAKE_SERVER_HELLO: + return "Server hello"; + + case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: + return "New session ticket"; + + case GNUTLS_HANDSHAKE_CERTIFICATE_PKT: + return "Certificate packet"; + + case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE: + return "Server key exchange"; + + case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST: + return "Certificate request"; + + case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE: + return "Server hello done"; + + case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY: + return "Certificate verify"; + + case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE: + return "Client key exchange"; + + case GNUTLS_HANDSHAKE_FINISHED: + return "Finished"; + + case GNUTLS_HANDSHAKE_SUPPLEMENTAL: + return "Supplemental"; + } + return NULL; +} + +#elif USE_OPENSSL + +static void +_openssl_print_verify_error(int error) +{ + switch (error) + { +#define ERROR(X) \ + case (X): \ + ERR("%s", #X); \ + break +#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT + ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT); +#endif +#ifdef X509_V_ERR_UNABLE_TO_GET_CRL + ERROR(X509_V_ERR_UNABLE_TO_GET_CRL); +#endif +#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE + ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE); +#endif +#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE + ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE); +#endif +#ifdef X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY + ERROR(X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY); +#endif +#ifdef X509_V_ERR_CERT_SIGNATURE_FAILURE + ERROR(X509_V_ERR_CERT_SIGNATURE_FAILURE); +#endif +#ifdef X509_V_ERR_CRL_SIGNATURE_FAILURE + ERROR(X509_V_ERR_CRL_SIGNATURE_FAILURE); +#endif +#ifdef X509_V_ERR_CERT_NOT_YET_VALID + ERROR(X509_V_ERR_CERT_NOT_YET_VALID); +#endif +#ifdef X509_V_ERR_CERT_HAS_EXPIRED + ERROR(X509_V_ERR_CERT_HAS_EXPIRED); +#endif +#ifdef X509_V_ERR_CRL_NOT_YET_VALID + ERROR(X509_V_ERR_CRL_NOT_YET_VALID); +#endif +#ifdef X509_V_ERR_CRL_HAS_EXPIRED + ERROR(X509_V_ERR_CRL_HAS_EXPIRED); +#endif +#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD + ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD); +#endif +#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD + ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD); +#endif +#ifdef X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD + ERROR(X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD); +#endif +#ifdef X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD + ERROR(X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); +#endif +#ifdef X509_V_ERR_OUT_OF_MEM + ERROR(X509_V_ERR_OUT_OF_MEM); +#endif +#ifdef X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT + ERROR(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT); +#endif +#ifdef X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN + ERROR(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN); +#endif +#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY + ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY); +#endif +#ifdef X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE + ERROR(X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); +#endif +#ifdef X509_V_ERR_CERT_CHAIN_TOO_LONG + ERROR(X509_V_ERR_CERT_CHAIN_TOO_LONG); +#endif +#ifdef X509_V_ERR_CERT_REVOKED + ERROR(X509_V_ERR_CERT_REVOKED); +#endif +#ifdef X509_V_ERR_INVALID_CA + ERROR(X509_V_ERR_INVALID_CA); +#endif +#ifdef X509_V_ERR_PATH_LENGTH_EXCEEDED + ERROR(X509_V_ERR_PATH_LENGTH_EXCEEDED); +#endif +#ifdef X509_V_ERR_INVALID_PURPOSE + ERROR(X509_V_ERR_INVALID_PURPOSE); +#endif +#ifdef X509_V_ERR_CERT_UNTRUSTED + ERROR(X509_V_ERR_CERT_UNTRUSTED); +#endif +#ifdef X509_V_ERR_CERT_REJECTED + ERROR(X509_V_ERR_CERT_REJECTED); +#endif + /* These are 'informational' when looking for issuer cert */ +#ifdef X509_V_ERR_SUBJECT_ISSUER_MISMATCH + ERROR(X509_V_ERR_SUBJECT_ISSUER_MISMATCH); +#endif +#ifdef X509_V_ERR_AKID_SKID_MISMATCH + ERROR(X509_V_ERR_AKID_SKID_MISMATCH); +#endif +#ifdef X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH + ERROR(X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH); +#endif +#ifdef X509_V_ERR_KEYUSAGE_NO_CERTSIGN + ERROR(X509_V_ERR_KEYUSAGE_NO_CERTSIGN); +#endif + +#ifdef X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER + ERROR(X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER); +#endif +#ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION + ERROR(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION); +#endif +#ifdef X509_V_ERR_KEYUSAGE_NO_CRL_SIGN + ERROR(X509_V_ERR_KEYUSAGE_NO_CRL_SIGN); +#endif +#ifdef X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION + ERROR(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION); +#endif +#ifdef X509_V_ERR_INVALID_NON_CA + ERROR(X509_V_ERR_INVALID_NON_CA); +#endif +#ifdef X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED + ERROR(X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED); +#endif +#ifdef X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE + ERROR(X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE); +#endif +#ifdef X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED + ERROR(X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED); +#endif + +#ifdef X509_V_ERR_INVALID_EXTENSION + ERROR(X509_V_ERR_INVALID_EXTENSION); +#endif +#ifdef X509_V_ERR_INVALID_POLICY_EXTENSION + ERROR(X509_V_ERR_INVALID_POLICY_EXTENSION); +#endif +#ifdef X509_V_ERR_NO_EXPLICIT_POLICY + ERROR(X509_V_ERR_NO_EXPLICIT_POLICY); +#endif +#ifdef X509_V_ERR_DIFFERENT_CRL_SCOPE + ERROR(X509_V_ERR_DIFFERENT_CRL_SCOPE); +#endif +#ifdef X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE + ERROR(X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE); +#endif + +#ifdef X509_V_ERR_UNNESTED_RESOURCE + ERROR(X509_V_ERR_UNNESTED_RESOURCE); +#endif + +#ifdef X509_V_ERR_PERMITTED_VIOLATION + ERROR(X509_V_ERR_PERMITTED_VIOLATION); +#endif +#ifdef X509_V_ERR_EXCLUDED_VIOLATION + ERROR(X509_V_ERR_EXCLUDED_VIOLATION); +#endif +#ifdef X509_V_ERR_SUBTREE_MINMAX + ERROR(X509_V_ERR_SUBTREE_MINMAX); +#endif +#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE + ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE); +#endif +#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX + ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX); +#endif +#ifdef X509_V_ERR_UNSUPPORTED_NAME_SYNTAX + ERROR(X509_V_ERR_UNSUPPORTED_NAME_SYNTAX); +#endif +#ifdef X509_V_ERR_CRL_PATH_VALIDATION_ERROR + ERROR(X509_V_ERR_CRL_PATH_VALIDATION_ERROR); +#endif + + /* The application is not happy */ +#ifdef X509_V_ERR_APPLICATION_VERIFICATION + ERROR(X509_V_ERR_APPLICATION_VERIFICATION); +#endif + } +#undef ERROR +} + +static void +_openssl_print_errors(void *conn, int type) +{ + char buf[1024]; + do + { + unsigned long err; + + err = ERR_get_error(); + if (!err) break; + snprintf(buf, sizeof(buf), "OpenSSL error: %s", ERR_reason_error_string(err)); + if (type == ECORE_CON_EVENT_CLIENT_ERROR) + ecore_con_event_client_error(conn, buf); + else + ecore_con_event_server_error(conn, buf); + + } while (1); +} + +static Eina_Bool +_openssl_name_verify(const char *name, const char *svrname) +{ + if (name[0] == '*') + { + /* we allow *.domain.TLD with a wildcard, but nothing else */ + const char *p, *s; + + EINA_SAFETY_ON_TRUE_RETURN_VAL((name[1] != '.') || (!name[2]), EINA_FALSE); + p = strchr(name + 1, '*'); + EINA_SAFETY_ON_TRUE_RETURN_VAL(!!p, EINA_FALSE); + /* verify that we have a domain of at least *.X.TLD and not *.TLD */ + p = strchr(name + 2, '.'); + EINA_SAFETY_ON_TRUE_RETURN_VAL(!p, EINA_FALSE); + s = strchr(svrname, '.'); + EINA_SAFETY_ON_TRUE_RETURN_VAL(!s, EINA_FALSE); + /* same as above for the stored name */ + EINA_SAFETY_ON_TRUE_RETURN_VAL(!strchr(s + 1, '.'), EINA_FALSE); + if (strcasecmp(s, name + 1)) + { + ERR("%s != %s", s, name + 1); + return EINA_FALSE; + } + } + else + if (strcasecmp(name, svrname)) + { + ERR("%s != %s", name, svrname); + return EINA_FALSE; + } + return EINA_TRUE; +} + +static void +_openssl_print_session(SSL *ssl) +{ + /* print session info into DBG */ + SSL_SESSION *s; + STACK_OF(X509) *sk; + BIO *b; + char log[4096], *p; + int x; + + if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return; + + memset(log, 0, sizeof(log)); + b = BIO_new(BIO_s_mem()); + sk = SSL_get_peer_cert_chain(ssl); + if (sk) + { + DBG("CERTIFICATES:"); + for (x = 0; x < sk_X509_num(sk); x++) + { + p = X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, x)), log, sizeof(log)); + DBG("%2d s:%s", x, p); + p = X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, x)), log, sizeof(log)); + DBG(" i:%s", p); + PEM_write_X509(stderr, sk_X509_value(sk, x)); + } + } + s = SSL_get_session(ssl); + SSL_SESSION_print(b, s); + fprintf(stderr, "\n"); + while (BIO_read(b, log, sizeof(log)) > 0) + fprintf(stderr, "%s", log); + + BIO_free(b); +} + +#endif + +#define SSL_ERROR_CHECK_GOTO_ERROR(X) \ + do \ + { \ + if ((X)) \ + { \ + ERR("Error at %s:%s:%d!", __FILE__, __PRETTY_FUNCTION__, __LINE__); \ + goto error; \ + } \ + } \ + while (0) + +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 Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (Ecore_Con_Server * svr, const char *ca_file); +static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (Ecore_Con_Server * svr, const char *crl_file); +static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (Ecore_Con_Server * svr, const char *cert); +static Eina_Bool SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (Ecore_Con_Server * svr, const char *key_file); + +static Ecore_Con_Ssl_Error SSL_SUFFIX(_ecore_con_ssl_server_prepare) (Ecore_Con_Server * svr, int ssl_type); +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 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, const unsigned char *buf, int size); + +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, + const 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) (); +#if _ECORE_CON_SSL_AVAILABLE != 0 + ECORE_CON_EVENT_CLIENT_UPGRADE = ecore_event_type_new(); + ECORE_CON_EVENT_SERVER_UPGRADE = ecore_event_type_new(); +#endif + } + + 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; +} + +Ecore_Con_Ssl_Error +ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, + int ssl_type) +{ + if (!ssl_type) + return ECORE_CON_SSL_ERROR_NONE; + return SSL_SUFFIX(_ecore_con_ssl_server_prepare) (svr, ssl_type); +} + +Ecore_Con_Ssl_Error +ecore_con_ssl_server_init(Ecore_Con_Server *svr) +{ + if (!(svr->type & ECORE_CON_SSL)) + return ECORE_CON_SSL_ERROR_NONE; + return SSL_SUFFIX(_ecore_con_ssl_server_init) (svr); +} + +Ecore_Con_Ssl_Error +ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr) +{ + if (!(svr->type & ECORE_CON_SSL)) + return ECORE_CON_SSL_ERROR_NONE; + return SSL_SUFFIX(_ecore_con_ssl_server_shutdown) (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, + const 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) +{ + if (!(cl->host_server->type & ECORE_CON_SSL)) + return ECORE_CON_SSL_ERROR_NONE; + return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl); +} + +Ecore_Con_Ssl_Error +ecore_con_ssl_client_shutdown(Ecore_Con_Client *cl) +{ + if (!(cl->host_server->type & ECORE_CON_SSL)) + return ECORE_CON_SSL_ERROR_NONE; + 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, + const unsigned char *buf, + int size) +{ + return SSL_SUFFIX(_ecore_con_ssl_client_write) (cl, buf, size); +} + +/** + * Returns if SSL support is available + * @return 1 if SSL is available and provided by gnutls, 2 if provided by openssl, + * 0 if it is not available. + * @ingroup Ecore_Con_Client_Group + */ +EAPI int +ecore_con_ssl_available_get(void) +{ + return _ECORE_CON_SSL_AVAILABLE; +} + +/** + * @addtogroup Ecore_Con_SSL_Group Ecore Connection SSL Functions + * + * Functions that operate on Ecore connection objects pertaining to SSL. + * + * @{ + */ + +/** + * @brief Enable certificate verification on a server object + * + * Call this function on a server object before main loop has started + * to enable verification of certificates against loaded certificates. + * @param svr The server object + */ +EAPI void +ecore_con_ssl_server_verify(Ecore_Con_Server *svr) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_verify"); + return; + } + svr->verify = EINA_TRUE; +} + +/** + * @brief Enable hostname-based certificate verification on a server object + * + * Call this function on a server object before main loop has started + * to enable verification of certificates using ONLY their hostnames. + * @param svr The server object + * @note This function has no effect when used on a listening server created by + * ecore_con_server_add + * @since 1.1 + */ +EAPI void +ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); + return; + } + svr->verify_basic = EINA_TRUE; +} + +/** + * @brief Set the hostname to verify against in certificate verification + * + * Sometimes the certificate hostname will not match the hostname that you are + * connecting to, and will instead match a different name. An example of this is + * that if you connect to talk.google.com to use Google Talk, you receive Google's + * certificate for gmail.com. This certificate should be trusted, and so you must call + * this function with "gmail.com" as @p name. + * See RFC2818 for more details. + * @param svr The server object + * @param name The hostname to verify against + * @since 1.2 + */ +EAPI void +ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); + return; + } + eina_stringshare_replace(&svr->verify_name, name); +} + +/** + * @brief Get the hostname to verify against in certificate verification + * + * This function returns the name which will be used to validate the SSL certificate + * common name (CN) or alt name (subjectAltName). It will default to the @p name + * param in ecore_con_server_connect(), but can be changed with ecore_con_ssl_server_verify_name_set(). + * @param svr The server object + * @return The hostname which will be used + * @since 1.2 + */ +EAPI const char * +ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); + return NULL; + } + return svr->verify_name ?: svr->name; +} + +/** + * @brief Add an ssl certificate for use in ecore_con functions. + * + * Use this function to add a SSL PEM certificate. + * Simply specify the cert here to use it in the server object for connecting or listening. + * If there is an error loading the certificate, an error will automatically be logged. + * @param svr The server object + * @param cert The path to the certificate. + * @return @c EINA_FALSE if the file cannot be loaded, otherwise @c EINA_TRUE. + */ + +EAPI Eina_Bool +ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr, + const char *cert) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cert_add"); + return EINA_FALSE; + } + + if (!svr->ssl_prepared) + { + svr->use_cert = EINA_TRUE; + svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT; + if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL)) + return EINA_FALSE; + } + + return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (svr, cert); +} + +/** + * @brief Add an ssl CA file for use in ecore_con functions. + * + * Use this function to add a SSL PEM CA file. + * Simply specify the file here to use it in the server object for connecting or listening. + * If there is an error loading the CAs, an error will automatically be logged. + * @param svr The server object + * @param ca_file The path to the CA file. + * @return @c EINA_FALSE if the file cannot be loaded, otherwise @c EINA_TRUE. + * @note since 1.2, this function can load directores + */ + +EAPI Eina_Bool +ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, + const char *ca_file) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_cafile_add"); + return EINA_FALSE; + } + + if (!svr->ssl_prepared) + { + svr->use_cert = EINA_TRUE; + svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT; + if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL)) + return EINA_FALSE; + } + + return SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (svr, ca_file); +} + +/** + * @brief Add an ssl private key for use in ecore_con functions. + * + * Use this function to add a SSL PEM private key + * Simply specify the key file here to use it in the server object for connecting or listening. + * If there is an error loading the key, an error will automatically be logged. + * @param svr The server object + * @param key_file The path to the key file. + * @return @c EINA_FALSE if the file cannot be loaded, otherwise @c EINA_TRUE. + */ + +EAPI Eina_Bool +ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr, + const char *key_file) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_privkey_add"); + return EINA_FALSE; + } + + if (!svr->ssl_prepared) + { + svr->use_cert = EINA_TRUE; + svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT; + if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL)) + return EINA_FALSE; + } + + return SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (svr, key_file); +} + +/** + * @brief Add an ssl CRL for use in ecore_con functions. + * + * Use this function to add a SSL PEM CRL file + * Simply specify the CRL file here to use it in the server object for connecting or listening. + * If there is an error loading the CRL, an error will automatically be logged. + * @param svr The server object + * @param crl_file The path to the CRL file. + * @return @c EINA_FALSE if the file cannot be loaded, otherwise @c EINA_TRUE. + */ + +EAPI Eina_Bool +ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, + const char *crl_file) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_ssl_server_crl_add"); + return EINA_FALSE; + } + + if (!svr->ssl_prepared) + { + svr->use_cert = EINA_TRUE; + svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT; + if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL)) + return EINA_FALSE; + } + + return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file); +} + +/** + * @brief Upgrade a connection to a specified level of encryption + * + * Use this function to begin an SSL handshake on a connection (STARTTLS or similar). + * Once the upgrade has been completed, an ECORE_CON_EVENT_SERVER_UPGRADE event will be emitted. + * The connection should be treated as disconnected until the next event. + * @param svr The server object + * @param ssl_type The SSL connection type (ONLY). + * @return @c EINA_FALSE if the connection cannot be upgraded, otherwise @c EINA_TRUE. + * @note This function is NEVER to be used on a server object created with ecore_con_server_add + * @warning Setting a wrong value for @p compl_type WILL mess up your program. + * @since 1.1 + */ + +EAPI Eina_Bool +ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__); + return EINA_FALSE; + } +#if _ECORE_CON_SSL_AVAILABLE == 0 + return EINA_FALSE; +#endif + + if (!svr->ssl_prepared) + { + if (ecore_con_ssl_server_prepare(svr, ssl_type)) + return EINA_FALSE; + } + if (!svr->use_cert) + svr->type |= ssl_type; + svr->upgrade = EINA_TRUE; + svr->handshaking = EINA_TRUE; + svr->ssl_state = ECORE_CON_SSL_STATE_INIT; + return !SSL_SUFFIX(_ecore_con_ssl_server_init) (svr); +} + +/** + * @brief Upgrade a connection to a specified level of encryption + * + * Use this function to begin an SSL handshake on a connection (STARTTLS or similar). + * Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted. + * The connection should be treated as disconnected until the next event. + * @param cl The client object + * @param ssl_type The SSL connection type (ONLY). + * @return @c EINA_FALSE if the connection cannot be upgraded, otherwise @c EINA_TRUE. + * @warning Setting a wrong value for @p compl_type WILL mess up your program. + * @since 1.1 + */ + +EAPI Eina_Bool +ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type ssl_type) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, __func__); + return EINA_FALSE; + } +#if _ECORE_CON_SSL_AVAILABLE == 0 + return EINA_FALSE; +#endif + + if (!cl->host_server->ssl_prepared) + { + if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type)) + return EINA_FALSE; + } + if (!cl->host_server->use_cert) + cl->host_server->type |= ssl_type; + cl->upgrade = EINA_TRUE; + cl->host_server->upgrade = EINA_TRUE; + cl->handshaking = EINA_TRUE; + cl->ssl_state = ECORE_CON_SSL_STATE_INIT; + return SSL_SUFFIX(_ecore_con_ssl_client_init) (cl); +} + +/** + * @} + */ + +#if USE_GNUTLS + +/* + * GnuTLS + */ + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_init_gnutls(void) +{ +#ifdef EINA_HAVE_THREADS + if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)) + WRN("YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!"); +#endif + if (gnutls_global_init()) + return ECORE_CON_SSL_ERROR_INIT_FAILED; + +#ifdef ISCOMFITOR + if (eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) + { + gnutls_global_set_log_level(9); + gnutls_global_set_log_function(_gnutls_log_func); + } +#endif + 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 Ecore_Con_Ssl_Error +_ecore_con_ssl_server_prepare_gnutls(Ecore_Con_Server *svr, + int ssl_type) +{ + int ret; + + if (ssl_type & ECORE_CON_USE_SSL2) + return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; + + switch (ssl_type) + { + case ECORE_CON_USE_SSL3: + case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: + case ECORE_CON_USE_TLS: + case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: + case ECORE_CON_USE_MIXED: + case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: + break; + + default: + return ECORE_CON_SSL_ERROR_NONE; + } + + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_allocate_credentials(&svr->cert)); + + if (svr->use_cert) + { + if (svr->created) + { + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_init(&svr->dh_params)); + INF("Generating DH params"); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_dh_params_generate2(svr->dh_params, 1024)); + + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_server_credentials(&svr->anoncred_s)); + /* TODO: implement PSK */ + // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_server_credentials(&svr->pskcred_s)); + + gnutls_anon_set_server_dh_params(svr->anoncred_s, svr->dh_params); + gnutls_certificate_set_dh_params(svr->cert, svr->dh_params); + //gnutls_psk_set_server_dh_params(svr->pskcred_s, svr->dh_params); + INF("DH params successfully generated and applied!"); + } + else + { + //SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_psk_allocate_client_credentials(&svr->pskcred_c)); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_anon_allocate_client_credentials(&svr->anoncred_c)); + } + } + + svr->ssl_prepared = EINA_TRUE; + return ECORE_CON_SSL_ERROR_NONE; + +error: + _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret); + _ecore_con_ssl_server_shutdown_gnutls(svr); + return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; +} + + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr) +{ + const gnutls_datum_t *cert_list; + unsigned int iter, cert_list_size; + gnutls_x509_crt_t cert = NULL; + const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; + int ret = 0; + + switch (svr->ssl_state) + { + case ECORE_CON_SSL_STATE_DONE: + return ECORE_CON_SSL_ERROR_NONE; + + case ECORE_CON_SSL_STATE_INIT: + if (svr->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */ + return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; + + switch (svr->type & ECORE_CON_SSL) + { + case ECORE_CON_USE_SSL3: + case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: + priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1"; + break; + + case ECORE_CON_USE_TLS: + case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: + priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0"; + break; + + case ECORE_CON_USE_MIXED: + case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: + break; + + default: + return ECORE_CON_SSL_ERROR_NONE; + } + + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&svr->session, GNUTLS_CLIENT)); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_client(svr->session)); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_server_name_set(svr->session, GNUTLS_NAME_DNS, svr->name, strlen(svr->name))); + INF("Applying priority string: %s", priority); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(svr->session, priority, NULL)); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_CERTIFICATE, svr->cert)); + // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_PSK, svr->pskcred_c)); + if (!svr->use_cert) + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(svr->session, GNUTLS_CRD_ANON, svr->anoncred_c)); + + gnutls_dh_set_prime_bits(svr->session, 512); + gnutls_transport_set_ptr(svr->session, (gnutls_transport_ptr_t)((intptr_t)svr->fd)); + svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; + + case ECORE_CON_SSL_STATE_HANDSHAKING: + if (!svr->session) + { + DBG("Server was previously lost, going to error condition"); + goto error; + } + ret = gnutls_handshake(svr->session); + DBG("calling gnutls_handshake(): returned with '%s'", gnutls_strerror_name(ret)); + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret)); + if (!ret) + { + svr->handshaking = EINA_FALSE; + svr->ssl_state = ECORE_CON_SSL_STATE_DONE; + } + else + { + if (gnutls_record_get_direction(svr->session)) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); + else + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); + return ECORE_CON_SSL_ERROR_NONE; + } + + default: + break; + } + + if ((!svr->verify) && (!svr->verify_basic)) + /* not verifying certificates, so we're done! */ + return ECORE_CON_SSL_ERROR_NONE; + if (svr->verify) + { + /* use CRL/CA lists to verify */ + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(svr->session, &iter)); + if (iter & GNUTLS_CERT_INVALID) + ERR("The certificate is not trusted."); + else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND) + ERR("The certificate hasn't got a known issuer."); + else if (iter & GNUTLS_CERT_REVOKED) + ERR("The certificate has been revoked."); + else if (iter & GNUTLS_CERT_EXPIRED) + ERR("The certificate has expired"); + else if (iter & GNUTLS_CERT_NOT_ACTIVATED) + ERR("The certificate is not yet activated"); + + if (iter) + goto error; + } + if (gnutls_certificate_type_get(svr->session) != GNUTLS_CRT_X509) + { + ERR("Warning: PGP certificates are not yet supported!"); + goto error; + } + + SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(svr->session, &cert_list_size))); + SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size); + + _gnutls_print_session(cert_list, cert_list_size); + + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert)); + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); + + SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->verify_name ?: svr->name)); + gnutls_x509_crt_deinit(cert); + DBG("SSL certificate verification succeeded!"); + return ECORE_CON_SSL_ERROR_NONE; + +error: + _gnutls_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR, ret); + if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) + ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(svr->session))); + if (svr->session && (svr->ssl_state != ECORE_CON_SSL_STATE_DONE)) + { + ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(svr->session))); + ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(svr->session))); + } + if (cert) + gnutls_x509_crt_deinit(cert); + _ecore_con_ssl_server_shutdown_gnutls(svr); + return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; +} + +static Eina_Bool +_ecore_con_ssl_server_cafile_add_gnutls(Ecore_Con_Server *svr, + const char *ca_file) +{ + struct stat st; + Eina_Iterator *it; + const char *file; + Eina_Bool error = EINA_FALSE; + + if (stat(ca_file, &st)) return EINA_FALSE; + if (S_ISDIR(st.st_mode)) + { + it = eina_file_ls(ca_file); + SSL_ERROR_CHECK_GOTO_ERROR(!it); + EINA_ITERATOR_FOREACH(it, file) + { + if (!error) + { + if (gnutls_certificate_set_x509_trust_file(svr->cert, file, GNUTLS_X509_FMT_PEM) < 1) + error++; + } + eina_stringshare_del(file); + } + eina_iterator_free(it); + } + else + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_trust_file(svr->cert, ca_file, + GNUTLS_X509_FMT_PEM) < 1); + + return !error; +error: + ERR("Could not load CA file!"); + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_crl_add_gnutls(Ecore_Con_Server *svr, + const char *crl_file) +{ + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_crl_file(svr->cert, crl_file, + GNUTLS_X509_FMT_PEM) < 1); + + return EINA_TRUE; +error: + ERR("Could not load CRL file!"); + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_privkey_add_gnutls(Ecore_Con_Server *svr, + const char *key_file) +{ + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_key_file(svr->cert, svr->cert_file, key_file, + GNUTLS_X509_FMT_PEM)); + + return EINA_TRUE; +error: + ERR("Could not load certificate/key file!"); + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_cert_add_gnutls(Ecore_Con_Server *svr, + const char *cert_file) +{ + if (!(svr->cert_file = strdup(cert_file))) + return EINA_FALSE; + + return EINA_TRUE; +} + +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); + } + + free(svr->cert_file); + svr->cert_file = NULL; + if (svr->cert) + gnutls_certificate_free_credentials(svr->cert); + svr->cert = NULL; + + if ((svr->type & ECORE_CON_SSL) && svr->created) + { + if (svr->dh_params) + { + gnutls_dh_params_deinit(svr->dh_params); + svr->dh_params = NULL; + } + if (svr->anoncred_s) + gnutls_anon_free_server_credentials(svr->anoncred_s); + // if (svr->pskcred_s) + // gnutls_psk_free_server_credentials(svr->pskcred_s); + + svr->anoncred_s = NULL; + svr->pskcred_s = NULL; + } + else if (svr->type & ECORE_CON_SSL) + { + if (svr->anoncred_c) + gnutls_anon_free_client_credentials(svr->anoncred_c); + // if (svr->pskcred_c) + // gnutls_psk_free_client_credentials(svr->pskcred_c); + + svr->anoncred_c = NULL; + svr->pskcred_c = NULL; + } + + svr->session = NULL; + + return ECORE_CON_SSL_ERROR_NONE; +} + +static int +_ecore_con_ssl_server_read_gnutls(Ecore_Con_Server *svr, + unsigned char *buf, + int size) +{ + int num; + + if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) + { + DBG("Continuing gnutls handshake"); + if (!_ecore_con_ssl_server_init_gnutls(svr)) + return 0; + return -1; + } + + num = gnutls_record_recv(svr->session, buf, size); + if (num > 0) + return num; + + if (num == GNUTLS_E_REHANDSHAKE) + { + WRN("Rehandshake request ignored"); + return 0; + + svr->handshaking = EINA_TRUE; + svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; + if (!_ecore_con_ssl_server_init_gnutls(svr)) + return 0; + } + else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS)) + return 0; + + return -1; +} + +static int +_ecore_con_ssl_server_write_gnutls(Ecore_Con_Server *svr, + const unsigned char *buf, + int size) +{ + int num; + + if (svr->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) + { + DBG("Continuing gnutls handshake"); + if (!_ecore_con_ssl_server_init_gnutls(svr)) + return 0; + return -1; + } + + num = gnutls_record_send(svr->session, buf, size); + if (num > 0) + return num; + + if (num == GNUTLS_E_REHANDSHAKE) + { + WRN("Rehandshake request ignored"); + return 0; +/* this is only partly functional I think? */ + svr->handshaking = EINA_TRUE; + svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; + if (!_ecore_con_ssl_server_init_gnutls(svr)) + return 0; + } + else if (!gnutls_error_is_fatal(num)) + return 0; + + return -1; +} + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl) +{ + const gnutls_datum_t *cert_list; + unsigned int iter, cert_list_size; + const char *priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+VERS-SSL3.0"; + int ret = 0; + + switch (cl->ssl_state) + { + case ECORE_CON_SSL_STATE_DONE: + return ECORE_CON_SSL_ERROR_NONE; + + case ECORE_CON_SSL_STATE_INIT: + if (cl->host_server->type & ECORE_CON_USE_SSL2) /* not supported because of security issues */ + return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; + + switch (cl->host_server->type & ECORE_CON_SSL) + { + case ECORE_CON_USE_SSL3: + case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: + priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-TLS1.0:!VERS-TLS1.1"; + break; + + case ECORE_CON_USE_TLS: + case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: + priority = "NONE:%VERIFY_ALLOW_X509_V1_CA_CRT:+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+COMP-DEFLATE:+COMP-NULL:+CTYPE-X509:+SHA1:+SHA256:+SHA384:+SHA512:+AES-256-CBC:+AES-128-CBC:+3DES-CBC:!VERS-SSL3.0"; + break; + + case ECORE_CON_USE_MIXED: + case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: + break; + + default: + return ECORE_CON_SSL_ERROR_NONE; + } + + _client_connected++; + + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_init(&cl->session, GNUTLS_SERVER)); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_key_generate(&cl->session_ticket)); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_session_ticket_enable_server(cl->session, &cl->session_ticket)); + INF("Applying priority string: %s", priority); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_priority_set_direct(cl->session, priority, NULL)); + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_CERTIFICATE, cl->host_server->cert)); + // SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_PSK, cl->host_server->pskcred_s)); + if (!cl->host_server->use_cert) + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_credentials_set(cl->session, GNUTLS_CRD_ANON, cl->host_server->anoncred_s)); + + gnutls_certificate_server_set_request(cl->session, GNUTLS_CERT_REQUEST); + + gnutls_dh_set_prime_bits(cl->session, 2048); + gnutls_transport_set_ptr(cl->session, (gnutls_transport_ptr_t)((intptr_t)cl->fd)); + cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; + + case ECORE_CON_SSL_STATE_HANDSHAKING: + if (!cl->session) + { + DBG("Client was previously lost, going to error condition"); + goto error; + } + DBG("calling gnutls_handshake()"); + ret = gnutls_handshake(cl->session); + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_error_is_fatal(ret)); + + if (!ret) + { + cl->handshaking = EINA_FALSE; + cl->ssl_state = ECORE_CON_SSL_STATE_DONE; + } + else + { + if (gnutls_record_get_direction(cl->session)) + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); + else + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); + return ECORE_CON_SSL_ERROR_NONE; + } + + default: + break; + } + + if (!cl->host_server->verify) + /* not verifying certificates, so we're done! */ + return ECORE_CON_SSL_ERROR_NONE; + /* use CRL/CA lists to verify */ + SSL_ERROR_CHECK_GOTO_ERROR(ret = gnutls_certificate_verify_peers2(cl->session, &iter)); + if (iter & GNUTLS_CERT_INVALID) + ERR("The certificate is not trusted."); + else if (iter & GNUTLS_CERT_SIGNER_NOT_FOUND) + ERR("The certificate hasn't got a known issuer."); + else if (iter & GNUTLS_CERT_REVOKED) + ERR("The certificate has been revoked."); + else if (iter & GNUTLS_CERT_EXPIRED) + ERR("The certificate has expired"); + else if (iter & GNUTLS_CERT_NOT_ACTIVATED) + ERR("The certificate is not yet activated"); + + if (iter) + goto error; + if (gnutls_certificate_type_get(cl->session) != GNUTLS_CRT_X509) + { + ERR("Warning: PGP certificates are not yet supported!"); + goto error; + } + + SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size))); + SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size); + + _gnutls_print_session(cert_list, cert_list_size); +/* + gnutls_x509_crt_t cert = NULL; + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert)); + SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); + + SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, cl->host_server->name)); + gnutls_x509_crt_deinit(cert); +*/ + DBG("SSL certificate verification succeeded!"); + return ECORE_CON_SSL_ERROR_NONE; + +error: + _gnutls_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR, ret); + if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) + ERR("Also received alert: %s", gnutls_alert_get_name(gnutls_alert_get(cl->session))); + if (cl->session && (cl->ssl_state != ECORE_CON_SSL_STATE_DONE)) + { + ERR("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_out(cl->session))); + ERR("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_get_last_in(cl->session))); + } +/* + if (cert) + gnutls_x509_crt_deinit(cert); +*/ + _ecore_con_ssl_client_shutdown_gnutls(cl); + return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; +} + +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); + gnutls_free(cl->session_ticket.data); + cl->session_ticket.data = NULL; + } + + cl->session = NULL; + + 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; + + if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) + { + if (!_ecore_con_ssl_client_init_gnutls(cl)) + return 0; + return -1; + } + + num = gnutls_record_recv(cl->session, buf, size); + if (num > 0) + return num; + + if (num == GNUTLS_E_REHANDSHAKE) + { + WRN("Rehandshake request ignored"); + return 0; + cl->handshaking = EINA_TRUE; + cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; + if (!_ecore_con_ssl_client_init_gnutls(cl)) + return 0; + WRN("Rehandshake request ignored"); + return 0; + } + else if ((!gnutls_error_is_fatal(num)) && (num != GNUTLS_E_SUCCESS)) + return 0; + + return -1; +} + +static int +_ecore_con_ssl_client_write_gnutls(Ecore_Con_Client *cl, + const unsigned char *buf, + int size) +{ + int num; + + if (cl->ssl_state == ECORE_CON_SSL_STATE_HANDSHAKING) + { + if (!_ecore_con_ssl_client_init_gnutls(cl)) + return 0; + return -1; + } + + num = gnutls_record_send(cl->session, buf, size); + if (num > 0) + return num; + + if (num == GNUTLS_E_REHANDSHAKE) + { + WRN("Rehandshake request ignored"); + return 0; + cl->handshaking = EINA_TRUE; + cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; + if (!_ecore_con_ssl_client_init_gnutls(cl)) + return 0; + } + else if (!gnutls_error_is_fatal(num)) + return 0; + + return -1; +} + +#elif USE_OPENSSL && !USE_GNUTLS + +/* + * OpenSSL + */ + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_init_openssl(void) +{ + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + + return ECORE_CON_SSL_ERROR_NONE; +} + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_shutdown_openssl(void) +{ + ERR_free_strings(); + EVP_cleanup(); + return ECORE_CON_SSL_ERROR_NONE; +} + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr, + int ssl_type) +{ + long options; + int dh = 0; + + if (ssl_type & ECORE_CON_USE_SSL2) + return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED; + + switch (ssl_type) + { + case ECORE_CON_USE_SSL3: + case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT: + if (!svr->created) + SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method()))); + else + SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_server_method()))); + break; + + case ECORE_CON_USE_TLS: + case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT: + if (!svr->created) + SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method()))); + else + SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_server_method()))); + break; + + case ECORE_CON_USE_MIXED: + case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT: + if (!svr->created) + SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method()))); + else + SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))); + options = SSL_CTX_get_options(svr->ssl_ctx); + SSL_CTX_set_options(svr->ssl_ctx, options | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE); + break; + + default: + svr->ssl_prepared = EINA_TRUE; + return ECORE_CON_SSL_ERROR_NONE; + } + + if ((!svr->use_cert) && svr->created) + { + DH *dh_params; + INF("Generating DH params"); + SSL_ERROR_CHECK_GOTO_ERROR(!(dh_params = DH_new())); + SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_parameters_ex(dh_params, 1024, DH_GENERATOR_5, NULL)); + SSL_ERROR_CHECK_GOTO_ERROR(!DH_check(dh_params, &dh)); + SSL_ERROR_CHECK_GOTO_ERROR((dh & DH_CHECK_P_NOT_PRIME) || (dh & DH_CHECK_P_NOT_SAFE_PRIME)); + SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_key(dh_params)); + SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_tmp_dh(svr->ssl_ctx, dh_params)); + DH_free(dh_params); + INF("DH params successfully generated and applied!"); + SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:@STRENGTH")); + } + else if (!svr->use_cert) + SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:!ECDH:RSA:AES:!PSK:@STRENGTH")); + + svr->ssl_prepared = EINA_TRUE; + return ECORE_CON_SSL_ERROR_NONE; + +error: + if (dh) + { + if (dh & DH_CHECK_P_NOT_PRIME) + ERR("openssl error: dh_params could not generate a prime!"); + else + ERR("openssl error: dh_params could not generate a safe prime!"); + } + else + _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); + _ecore_con_ssl_server_shutdown_openssl(svr); + return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; +} + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr) +{ + int ret = -1; + + switch (svr->ssl_state) + { + case ECORE_CON_SSL_STATE_DONE: + return ECORE_CON_SSL_ERROR_NONE; + + case ECORE_CON_SSL_STATE_INIT: + SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl = SSL_new(svr->ssl_ctx))); + + SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(svr->ssl, svr->fd)); + SSL_set_connect_state(svr->ssl); + svr->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; + + case ECORE_CON_SSL_STATE_HANDSHAKING: + if (!svr->ssl) + { + DBG("Server was previously lost, going to error condition"); + goto error; + } + ret = SSL_do_handshake(svr->ssl); + svr->ssl_err = SSL_get_error(svr->ssl, ret); + SSL_ERROR_CHECK_GOTO_ERROR((svr->ssl_err == SSL_ERROR_SYSCALL) || (svr->ssl_err == SSL_ERROR_SSL)); + + if (ret == 1) + { + svr->handshaking = EINA_FALSE; + svr->ssl_state = ECORE_CON_SSL_STATE_DONE; + } + else + { + if (svr->ssl_err == SSL_ERROR_WANT_READ) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); + else if (svr->ssl_err == SSL_ERROR_WANT_WRITE) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); + return ECORE_CON_SSL_ERROR_NONE; + } + + default: + break; + } + + _openssl_print_session(svr->ssl); + if ((!svr->verify) && (!svr->verify_basic)) + /* not verifying certificates, so we're done! */ + return ECORE_CON_SSL_ERROR_NONE; + + { + X509 *cert; + SSL_set_verify(svr->ssl, SSL_VERIFY_PEER, NULL); + /* use CRL/CA lists to verify */ + cert = SSL_get_peer_certificate(svr->ssl); + if (cert) + { + char *c; + int clen; + int name = 0; + + if (svr->verify) + { + int err; + + err = SSL_get_verify_result(svr->ssl); + _openssl_print_verify_error(err); + SSL_ERROR_CHECK_GOTO_ERROR(err); + } + clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, NULL, 0); + if (clen > 0) + name = NID_subject_alt_name; + else + clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, NULL, 0); + SSL_ERROR_CHECK_GOTO_ERROR(clen < 1); + if (!name) name = NID_commonName; + c = alloca(++clen); + X509_NAME_get_text_by_NID(X509_get_subject_name(cert), name, c, clen); + INF("CERT NAME: %s\n", c); + SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(c, svr->verify_name ?: svr->name)); + } + } + + DBG("SSL certificate verification succeeded!"); + + return ECORE_CON_SSL_ERROR_NONE; + +error: + _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); + _ecore_con_ssl_server_shutdown_openssl(svr); + return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; +} + +static Eina_Bool +_ecore_con_ssl_server_cafile_add_openssl(Ecore_Con_Server *svr, + const char *ca_file) +{ + struct stat st; + + if (stat(ca_file, &st)) return EINA_FALSE; + if (S_ISDIR(st.st_mode)) + SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, NULL, ca_file)); + else + SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, ca_file, NULL)); + return EINA_TRUE; + +error: + _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_crl_add_openssl(Ecore_Con_Server *svr, + const char *crl_file) +{ + X509_STORE *st; + X509_LOOKUP *lu; + static Eina_Bool flag = EINA_FALSE; + + SSL_ERROR_CHECK_GOTO_ERROR(!(st = SSL_CTX_get_cert_store(svr->ssl_ctx))); + SSL_ERROR_CHECK_GOTO_ERROR(!(lu = X509_STORE_add_lookup(st, X509_LOOKUP_file()))); + SSL_ERROR_CHECK_GOTO_ERROR(X509_load_crl_file(lu, crl_file, X509_FILETYPE_PEM) < 1); + if (!flag) + { + X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); + flag = EINA_TRUE; + } + + return EINA_TRUE; + +error: + _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_privkey_add_openssl(Ecore_Con_Server *svr, + const char *key_file) +{ + FILE *fp = NULL; + EVP_PKEY *privkey = NULL; + + if (!(fp = fopen(key_file, "r"))) + goto error; + + SSL_ERROR_CHECK_GOTO_ERROR(!(privkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL))); + + fclose(fp); + fp = NULL; + SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_PrivateKey(svr->ssl_ctx, privkey) < 1); + SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_check_private_key(svr->ssl_ctx) < 1); + + return EINA_TRUE; + +error: + if (fp) + fclose(fp); + _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_cert_add_openssl(Ecore_Con_Server *svr, + const char *cert_file) +{ + FILE *fp = NULL; + X509 *cert = NULL; + + if (!(fp = fopen(cert_file, "r"))) + goto error; + + SSL_ERROR_CHECK_GOTO_ERROR(!(cert = PEM_read_X509(fp, NULL, NULL, NULL))); + + fclose(fp); + fp = NULL; + SSL_ERROR_CHECK_GOTO_ERROR(SSL_CTX_use_certificate(svr->ssl_ctx, cert) < 1); + + return EINA_TRUE; + +error: + if (fp) + fclose(fp); + _openssl_print_errors(svr, ECORE_CON_EVENT_SERVER_ERROR); + return EINA_FALSE; +} + +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); + + svr->ssl = NULL; + svr->ssl_ctx = NULL; + svr->ssl_err = SSL_ERROR_NONE; + + return ECORE_CON_SSL_ERROR_NONE; +} + +static int +_ecore_con_ssl_server_read_openssl(Ecore_Con_Server *svr, + unsigned char *buf, + int size) +{ + int num; + + if (!svr->ssl) return -1; + 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, + const 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 Ecore_Con_Ssl_Error +_ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl) +{ + int ret = -1; + switch (cl->ssl_state) + { + case ECORE_CON_SSL_STATE_DONE: + return ECORE_CON_SSL_ERROR_NONE; + + case ECORE_CON_SSL_STATE_INIT: + SSL_ERROR_CHECK_GOTO_ERROR(!(cl->ssl = SSL_new(cl->host_server->ssl_ctx))); + + SSL_ERROR_CHECK_GOTO_ERROR(!SSL_set_fd(cl->ssl, cl->fd)); + SSL_set_accept_state(cl->ssl); + cl->ssl_state = ECORE_CON_SSL_STATE_HANDSHAKING; + + case ECORE_CON_SSL_STATE_HANDSHAKING: + if (!cl->ssl) + { + DBG("Client was previously lost, going to error condition"); + goto error; + } + ret = SSL_do_handshake(cl->ssl); + cl->ssl_err = SSL_get_error(cl->ssl, ret); + SSL_ERROR_CHECK_GOTO_ERROR((cl->ssl_err == SSL_ERROR_SYSCALL) || (cl->ssl_err == SSL_ERROR_SSL)); + if (ret == 1) + { + cl->handshaking = EINA_FALSE; + cl->ssl_state = ECORE_CON_SSL_STATE_DONE; + } + else + { + if (cl->ssl_err == SSL_ERROR_WANT_READ) + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); + else if (cl->ssl_err == SSL_ERROR_WANT_WRITE) + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_WRITE); + return ECORE_CON_SSL_ERROR_NONE; + } + + default: + break; + } + + _openssl_print_session(cl->ssl); + if (!cl->host_server->verify) + /* not verifying certificates, so we're done! */ + return ECORE_CON_SSL_ERROR_NONE; + SSL_set_verify(cl->ssl, SSL_VERIFY_PEER, NULL); + /* use CRL/CA lists to verify */ + if (SSL_get_peer_certificate(cl->ssl)) + { + int err; + + err = SSL_get_verify_result(cl->ssl); + _openssl_print_verify_error(err); + SSL_ERROR_CHECK_GOTO_ERROR(err); + } + + return ECORE_CON_SSL_ERROR_NONE; + +error: + _openssl_print_errors(cl, ECORE_CON_EVENT_CLIENT_ERROR); + _ecore_con_ssl_client_shutdown_openssl(cl); + return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED; +} + +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); + } + + cl->ssl = NULL; + cl->ssl_err = SSL_ERROR_NONE; + + 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; + + if (!cl->ssl) return -1; + 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, + const 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 Ecore_Con_Ssl_Error +_ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr EINA_UNUSED, + int ssl_type EINA_UNUSED) +{ + return ECORE_CON_SSL_ERROR_NONE; +} + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr EINA_UNUSED) +{ + return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; +} + +static Eina_Bool +_ecore_con_ssl_server_cafile_add_none(Ecore_Con_Server *svr EINA_UNUSED, + const char *ca_file EINA_UNUSED) +{ + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_cert_add_none(Ecore_Con_Server *svr EINA_UNUSED, + const char *cert_file EINA_UNUSED) +{ + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_privkey_add_none(Ecore_Con_Server *svr EINA_UNUSED, + const char *key_file EINA_UNUSED) +{ + return EINA_FALSE; +} + +static Eina_Bool +_ecore_con_ssl_server_crl_add_none(Ecore_Con_Server *svr EINA_UNUSED, + const char *crl_file EINA_UNUSED) +{ + return EINA_FALSE; +} + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_server_shutdown_none(Ecore_Con_Server *svr EINA_UNUSED) +{ + return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; +} + +static int +_ecore_con_ssl_server_read_none(Ecore_Con_Server *svr EINA_UNUSED, + unsigned char *buf EINA_UNUSED, + int size EINA_UNUSED) +{ + return -1; +} + +static int +_ecore_con_ssl_server_write_none(Ecore_Con_Server *svr EINA_UNUSED, + const unsigned char *buf EINA_UNUSED, + int size EINA_UNUSED) +{ + return -1; +} + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl EINA_UNUSED) +{ + return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; +} + +static Ecore_Con_Ssl_Error +_ecore_con_ssl_client_shutdown_none(Ecore_Con_Client *cl EINA_UNUSED) +{ + return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; +} + +static int +_ecore_con_ssl_client_read_none(Ecore_Con_Client *cl EINA_UNUSED, + unsigned char *buf EINA_UNUSED, + int size EINA_UNUSED) +{ + return -1; +} + +static int +_ecore_con_ssl_client_write_none(Ecore_Con_Client *cl EINA_UNUSED, + const unsigned char *buf EINA_UNUSED, + int size EINA_UNUSED) +{ + return -1; +} + +#endif diff --git a/src/lib/ecore_con/ecore_con_url.c b/src/lib/ecore_con/ecore_con_url.c new file mode 100644 index 0000000000..467f3f113b --- /dev/null +++ b/src/lib/ecore_con/ecore_con_url.c @@ -0,0 +1,1683 @@ +/* + * For info on how to use libcurl, see: + * http://curl.haxx.se/libcurl/c/libcurl-tutorial.html + */ + +/* + * FIXME: Support more CURL features... + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifdef HAVE_WS2TCPIP_H +# include +#endif + +#ifdef HAVE_ESCAPE +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Con.h" +#include "ecore_con_private.h" + +#define CURL_MIN_TIMEOUT 100 + +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 void _ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg); +static void _ecore_con_url_multi_remove(Ecore_Con_Url *url_con); +static Eina_Bool _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(Ecore_Con_Url *url_con, void *ev); +static Eina_Bool _ecore_con_url_timer(void *data); +static Eina_Bool _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); +static Eina_Bool _ecore_con_url_timeout_cb(void *data); +static void _ecore_con_url_status_get(Ecore_Con_Url *url_con); + +static Eina_List *_url_con_list = NULL; +static Eina_List *_fd_hd_list = NULL; +static CURLM *_curlm = NULL; +static int _init_count = 0; +static Ecore_Timer *_curl_timer = NULL; +static Eina_Bool pipelining = EINA_FALSE; +static Ecore_Idler *_curl_idler = NULL; +#endif + +/** + * @addtogroup Ecore_Con_Url_Group Ecore URL Connection Functions + * + * @{ + */ + +EAPI int +ecore_con_url_init(void) +{ +#ifdef HAVE_CURL + long ms; + if (++_init_count > 1) return _init_count; + + 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(); + + // curl_global_init() is not thread safe! + if (curl_global_init(CURL_GLOBAL_ALL)) return --_init_count; + + _curlm = curl_multi_init(); + if (!_curlm) + { + curl_global_cleanup(); + return --_init_count; + } + + curl_multi_timeout(_curlm, &ms); + if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; + + _curl_timer = ecore_timer_add((double)ms / 1000.0, + _ecore_con_url_timer, NULL); + ecore_timer_freeze(_curl_timer); + + return _init_count; +#else + return 0; +#endif +} + +EAPI int +ecore_con_url_shutdown(void) +{ +#ifdef HAVE_CURL + Ecore_Con_Url *url_con; + Ecore_Fd_Handler *fd_handler; + if (_init_count == 0) return 0; + --_init_count; + if (_init_count) return _init_count; + + if (_curl_timer) + { + ecore_timer_del(_curl_timer); + _curl_timer = NULL; + } + + if (_curl_idler) + { + ecore_idler_del(_curl_idler); + _curl_idler = NULL; + } + + EINA_LIST_FREE(_url_con_list, url_con) + ecore_con_url_free(url_con); + EINA_LIST_FREE(_fd_hd_list, fd_handler) + ecore_main_fd_handler_del(fd_handler); + + if (_curlm) + { + curl_multi_cleanup(_curlm); + _curlm = NULL; + } + curl_global_cleanup(); + return 0; +#endif + return 1; +} + +EAPI void +ecore_con_url_pipeline_set(Eina_Bool enable) +{ +#ifdef HAVE_CURL + if (enable == pipelining) return; + curl_multi_setopt(_curlm, CURLMOPT_PIPELINING, !!enable); + pipelining = enable; +#else + return; + (void)enable; +#endif +} + +EAPI Eina_Bool +ecore_con_url_pipeline_get(void) +{ +#ifdef HAVE_CURL + return pipelining; +#endif + return EINA_FALSE; +} + +extern Ecore_Con_Socks *_ecore_con_proxy_global; + +EAPI Ecore_Con_Url * +ecore_con_url_new(const char *url) +{ +#ifdef HAVE_CURL + Ecore_Con_Url *url_con; + CURLcode ret; + + if (!_init_count) + return NULL; + + url_con = calloc(1, sizeof(Ecore_Con_Url)); + if (!url_con) + return NULL; + + url_con->write_fd = -1; + + 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); + + if (!ecore_con_url_url_set(url_con, url)) + { + ecore_con_url_free(url_con); + return NULL; + } + + // Read socks proxy + url_con->proxy_type = -1; + if (_ecore_con_proxy_global && _ecore_con_proxy_global->ip && + (_ecore_con_proxy_global->version == 4 || + _ecore_con_proxy_global->version == 5)) + { + char proxy[256]; + char host[256]; + + if (_ecore_con_proxy_global->version == 5) + { + if (_ecore_con_proxy_global->lookup) + snprintf(host, sizeof(host), "socks5h://%s", + _ecore_con_proxy_global->ip); + else snprintf(host, sizeof(host), "socks5://%s", + _ecore_con_proxy_global->ip); + } + else if (_ecore_con_proxy_global->version == 4) + { + if (_ecore_con_proxy_global->lookup) + snprintf(host, sizeof(host), "socks4a://%s", + _ecore_con_proxy_global->ip); + else snprintf(host, sizeof(host), "socks4://%s", + _ecore_con_proxy_global->ip); + } + + if (_ecore_con_proxy_global->port > 0 && + _ecore_con_proxy_global->port <= 65535) + snprintf(proxy, sizeof(proxy), "%s:%d", host, + _ecore_con_proxy_global->port); + else snprintf(proxy, sizeof(proxy), "%s", host); + + ecore_con_url_proxy_set(url_con, proxy); + ecore_con_url_proxy_username_set(url_con, + _ecore_con_proxy_global->username); + } + + ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate"); + if (ret != CURLE_OK) + { + ERR("Could not set CURLOPT_ENCODING to \"gzip,deflate\": %s", + curl_easy_strerror(ret)); + ecore_con_url_free(url_con); + return NULL; + } + + 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_FOLLOWLOCATION, 1); + + return url_con; +#else + return NULL; + url = NULL; +#endif +} + +EAPI Ecore_Con_Url * +ecore_con_url_custom_new(const char *url, + const char *custom_request) +{ +#ifdef HAVE_CURL + Ecore_Con_Url *url_con; + CURLcode ret; + + if (!url) + return NULL; + + if (!custom_request) + return NULL; + + url_con = ecore_con_url_new(url); + + if (!url_con) + return NULL; + + ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_CUSTOMREQUEST, custom_request); + if (ret != CURLE_OK) + { + ERR("Could not set a custom request string: %s", + curl_easy_strerror(ret)); + ecore_con_url_free(url_con); + return NULL; + } + + return url_con; +#else + return NULL; + url = NULL; + custom_request = NULL; +#endif +} + +EAPI void +ecore_con_url_free(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_free"); + return; + } + + if (url_con->curl_easy) + { + // FIXME : How can we delete curl_easy's fds ?? (Curl do not give this info.) + // This cause "Failed to delete epoll fd xx!" error messages + curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL); + curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE); + + if (url_con->multi) + { + _ecore_con_url_multi_remove(url_con); + _url_con_list = eina_list_remove(_url_con_list, url_con); + } + + curl_easy_cleanup(url_con->curl_easy); + } + if (url_con->timer) ecore_timer_del(url_con->timer); + + url_con->curl_easy = NULL; + url_con->timer = NULL; + url_con->dead = EINA_TRUE; + if (url_con->event_count) return; + ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE); + + 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); + eina_stringshare_del(url_con->url); + if (url_con->post_data) free(url_con->post_data); + free(url_con); +#else + return; + (void)url_con; +#endif +} + +EAPI const char * +ecore_con_url_url_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, __func__); + return NULL; + } + return url_con->url; +#else + return NULL; + (void)url_con; +#endif +} + +EAPI int +ecore_con_url_status_code_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, __func__); + return 0; + } + + if (url_con->status) return url_con->status; + _ecore_con_url_status_get(url_con); + return url_con->status; +#else + return -1; + (void)url_con; +#endif +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + + if (url_con->dead) return EINA_FALSE; + eina_stringshare_replace(&url_con->url, 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 EINA_TRUE; +#else + return EINA_FALSE; + (void)url; + (void)url_con; +#endif +} + +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 +} + +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 (url_con->dead) return; + 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; + } + + if (url_con->dead) 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 +} + +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 +} + +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 +} + +EAPI void +ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, double timestamp) +{ +#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; + } + + if (url_con->dead) return; + url_con->time_condition = condition; + url_con->timestamp = timestamp; +#else + return; + (void)url_con; + (void)condition; + (void)timestamp; +#endif +} + +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; + } + + if (url_con->dead) return; + url_con->write_fd = fd; +#else + return; + (void)url_con; + (void)fd; +#endif +} + +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; + (void)url_con; +#endif +} + +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; + (void)url_con; +#endif +} + +EAPI Eina_Bool +ecore_con_url_httpauth_set(Ecore_Con_Url *url_con, const char *username, const char *password, Eina_Bool safe) +{ +#ifdef HAVE_CURL + CURLcode ret; + + 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 EINA_FALSE; + } + + if (url_con->dead) return EINA_FALSE; +# if LIBCURL_VERSION_NUM >= 0x071301 + if ((username) && (password)) + { + 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); + + ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username); + if (ret != CURLE_OK) + { + ERR("Could not set username for HTTP authentication: %s", + curl_easy_strerror(ret)); + return EINA_FALSE; + } + + ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password); + if (ret != CURLE_OK) + { + ERR("Could not set password for HTTP authentication: %s", + curl_easy_strerror(ret)); + return EINA_FALSE; + } + + return EINA_TRUE; + } +# endif +#else + return EINA_FALSE; + (void)url_con; + (void)username; + (void)password; + (void)safe; +#endif + + return EINA_FALSE; +} + +#define MODE_AUTO 0 +#define MODE_GET 1 +#define MODE_POST 2 + +static Eina_Bool +_ecore_con_url_send(Ecore_Con_Url *url_con, int mode, const void *data, long length, const char *content_type) +{ +#ifdef HAVE_CURL + Eina_List *l; + const char *s; + char tmp[512]; + + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_send"); + return EINA_FALSE; + } + + if (!url_con->url) return EINA_FALSE; + if (url_con->dead) return EINA_FALSE; + + /* Free response headers from previous send() calls */ + EINA_LIST_FREE(url_con->response_headers, s) + free((char *)s); + url_con->response_headers = NULL; + url_con->status = 0; + + curl_slist_free_all(url_con->headers); + url_con->headers = NULL; + + if ((mode == MODE_POST) || (mode == MODE_AUTO)) + { + if (url_con->post_data) free(url_con->post_data); + url_con->post_data = NULL; + if ((data) && (length > 0)) + { + url_con->post_data = malloc(length); + if (url_con->post_data) + { + memcpy(url_con->post_data, data, length); + if ((content_type) && (strlen(content_type) < 450)) + { + snprintf(tmp, sizeof(tmp), "Content-Type: %s", content_type); + url_con->headers = curl_slist_append(url_con->headers, tmp); + } + curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, url_con->post_data); + curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length); + } + else + return EINA_FALSE; + } + else curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, 0); + if (mode == MODE_POST) + curl_easy_setopt(url_con->curl_easy, CURLOPT_POST, 1); + } + + switch (url_con->time_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, + (long)url_con->timestamp); + 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, + (long)url_con->timestamp); + 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; + + return _ecore_con_url_perform(url_con); +#else + return EINA_FALSE; + (void)url_con; + (void)mode; + (void)data; + (void)length; + (void)content_type; +#endif +} + +EAPI Eina_Bool +ecore_con_url_get(Ecore_Con_Url *url_con) +{ + return _ecore_con_url_send(url_con, MODE_GET, NULL, 0, NULL); +} + +EAPI Eina_Bool +ecore_con_url_post(Ecore_Con_Url *url_con, const void *data, long length, const char *content_type) +{ + return _ecore_con_url_send(url_con, MODE_POST, data, length, content_type); +} + +EAPI Eina_Bool +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; + CURLcode ret; + + 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 EINA_FALSE; + } + + if (url_con->dead) return EINA_FALSE; + if (!url_con->url) return EINA_FALSE; + if ((!filename) || (!filename[0])) return EINA_FALSE; + + if (stat(filename, &file_info)) + return EINA_FALSE; + + snprintf(userpwd, sizeof(userpwd), "%s:%s", user, pass); + ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERPWD, userpwd); + if (ret != CURLE_OK) + { + ERR("Could not set username and password for FTP upload: %s", + curl_easy_strerror(ret)); + return EINA_FALSE; + } + + char tmp[PATH_MAX]; + snprintf(tmp, PATH_MAX, "%s", filename); + + 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)); + + if (!ecore_con_url_url_set(url_con, url)) + return EINA_FALSE; + + 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_UPLOAD, 1); + curl_easy_setopt(url_con->curl_easy, CURLOPT_READFUNCTION, + _ecore_con_url_read_cb); + + fd = fopen(filename, "rb"); + if (!fd) + { + ERR("Could not open \"%s\" for FTP upload", filename); + return EINA_FALSE; + } + curl_easy_setopt(url_con->curl_easy, CURLOPT_READDATA, fd); + + return _ecore_con_url_perform(url_con); +#else + return EINA_FALSE; + (void)url_con; + (void)filename; + (void)user; + (void)pass; + (void)upload_dir; +#endif +} + +EAPI void +ecore_con_url_cookies_init(Ecore_Con_Url *url_con) +{ +#ifdef HAVE_CURL + 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_cookies_init"); + return; + } + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, ""); +#else + return; + (void)url_con; +#endif +} + +EAPI void +ecore_con_url_cookies_ignore_old_session_set(Ecore_Con_Url *url_con, Eina_Bool ignore) +{ +#ifdef HAVE_CURL + 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_cookies_ignore_old_session_set"); + return; + } + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIESESSION, ignore); +#else + return; + (void)url_con; + (void)ignore; +#endif +} + +EAPI void +ecore_con_url_cookies_clear(Ecore_Con_Url *url_con) +{ +#ifdef HAVE_CURL + 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_cookies_clear"); + return; + } + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "ALL"); +#else + return; + (void)url_con; +#endif +} + +EAPI void +ecore_con_url_cookies_session_clear(Ecore_Con_Url *url_con) +{ +#ifdef HAVE_CURL + 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_cookies_session_clear"); + return; + } + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "SESS"); +#else + return; + (void)url_con; +#endif +} + +EAPI void +ecore_con_url_cookies_file_add(Ecore_Con_Url *url_con, const char *const file_name) +{ +#ifdef HAVE_CURL + 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_cookies_file_add"); + return; + } + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEFILE, file_name); +#else + return; + (void)url_con; + (void)file_name; +#endif +} + +EAPI Eina_Bool +ecore_con_url_cookies_jar_file_set(Ecore_Con_Url *url_con, const char *const cookiejar_file) +{ +#ifdef HAVE_CURL + CURLcode ret; + + if (!url_con) + return EINA_FALSE; + + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, + "ecore_con_url_cookies_jar_file_set"); + return EINA_FALSE; + } + + if (url_con->dead) return EINA_FALSE; + ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIEJAR, + cookiejar_file); + if (ret != CURLE_OK) + { + ERR("Setting the cookie-jar name failed: %s", + curl_easy_strerror(ret)); + return EINA_FALSE; + } + + return EINA_TRUE; +#else + return EINA_FALSE; + (void)url_con; + (void)cookiejar_file; +#endif +} + +EAPI void +ecore_con_url_cookies_jar_write(Ecore_Con_Url *url_con) +{ +#ifdef HAVE_CURL + 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_cookies_jar_write"); + return; + } + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_COOKIELIST, "FLUSH"); +#else + return; + (void)url_con; +#endif +} + +EAPI void +ecore_con_url_verbose_set(Ecore_Con_Url *url_con, Eina_Bool 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->url) + return; + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_VERBOSE, (int)verbose); +#else + return; + (void)url_con; + (void)verbose; +#endif +} + +EAPI void +ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con, Eina_Bool 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->url) + return; + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_FTP_USE_EPSV, (int)use_epsv); +#else + return; + (void)url_con; + (void)use_epsv; +#endif +} + +/** + * Toggle libcurl's verify peer's certificate option. + * + * If @p verify is @c EINA_TRUE, libcurl will verify + * the authenticity of the peer's certificate, otherwise + * it will not. Default behavior of libcurl is to check + * peer's certificate. + * + * @param url_con Ecore_Con_Url instance which will be acted upon. + * @param verify Whether or not libcurl will check peer's certificate. + * @since 1.1.0 + */ +EAPI void +ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con, Eina_Bool verify) +{ +#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_ssl_verify_peer_set"); + return; + } + + if (!url_con->url) + return; + + if (url_con->dead) return; + curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, (int)verify); +#else + return; + (void)url_con; + (void)verify; +#endif +} + +/** + * Set a custom CA to trust for SSL/TLS connections. + * + * Specify the path of a file (in PEM format) containing one or more + * CA certificate(s) to use for the validation of the server certificate. + * + * This function can also disable CA validation if @p ca_path is @c NULL. + * However, the server certificate still needs to be valid for the connection + * to succeed (i.e., the certificate must concern the server the + * connection is made to). + * + * @param url_con Connection object that will use the custom CA. + * @param ca_path Path to a CA certificate(s) file or @c NULL to disable + * CA validation. + * + * @return @c 0 on success. When cURL is used, non-zero return values + * are equal to cURL error codes. + */ +EAPI int +ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path) +{ + int res = -1; + +#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_ssl_ca_set"); + return -1; + } + + if (!url_con->url) return -1; + if (url_con->dead) return -1; + if (ca_path == NULL) + res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0); + else + { + res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 1); + if (!res) + res = curl_easy_setopt(url_con->curl_easy, CURLOPT_CAINFO, ca_path); + } +#else + return -1; + (void)url_con; + (void)ca_path; +#endif + + return res; +} + +EAPI Eina_Bool +ecore_con_url_http_version_set(Ecore_Con_Url *url_con, Ecore_Con_Url_Http_Version version) +{ +#ifdef HAVE_CURL + int res = -1; + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_http_version_set"); + return EINA_FALSE; + } + if (url_con->dead) return EINA_FALSE; + switch (version) + { + case ECORE_CON_URL_HTTP_VERSION_1_0: + res = curl_easy_setopt(url_con->curl_easy, + CURLOPT_HTTP_VERSION, + CURL_HTTP_VERSION_1_0); + break; + + case ECORE_CON_URL_HTTP_VERSION_1_1: + res = curl_easy_setopt(url_con->curl_easy, + CURLOPT_HTTP_VERSION, + CURL_HTTP_VERSION_1_1); + break; + + default: + break; + } + if (res != CURLE_OK) + { + ERR("curl http version setting failed: %s", curl_easy_strerror(res)); + return EINA_FALSE; + } + return EINA_TRUE; +#else + (void)url_con; + (void)version; + return EINA_FALSE; +#endif +} + +EAPI Eina_Bool +ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy) +{ +#ifdef HAVE_CURL + int res = -1; + curl_version_info_data *vers = NULL; + + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_set"); + return EINA_FALSE; + } + + if (!url_con->url) return EINA_FALSE; + if (url_con->dead) return EINA_FALSE; + + if (!proxy) res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, ""); + else + { + // before curl version 7.21.7, socks protocol:// prefix is not supported + // (e.g. socks4://, socks4a://, socks5:// or socks5h://, etc.) + vers = curl_version_info(CURLVERSION_NOW); + if (vers->version_num < 0x71507) + { + url_con->proxy_type = CURLPROXY_HTTP; + if (strstr(proxy, "socks4a")) + url_con->proxy_type = CURLPROXY_SOCKS4A; + else if (strstr(proxy, "socks4")) + url_con->proxy_type = CURLPROXY_SOCKS4; + else if (strstr(proxy, "socks5h")) + url_con->proxy_type = CURLPROXY_SOCKS5_HOSTNAME; + else if (strstr(proxy, "socks5")) + url_con->proxy_type = CURLPROXY_SOCKS5; + res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXYTYPE, + url_con->proxy_type); + if (res != CURLE_OK) + { + ERR("curl proxy type setting failed: %s", + curl_easy_strerror(res)); + url_con->proxy_type = -1; + return EINA_FALSE; + } + } + res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, proxy); + } + if (res != CURLE_OK) + { + ERR("curl proxy setting failed: %s", curl_easy_strerror(res)); + url_con->proxy_type = -1; + return EINA_FALSE; + } + return EINA_TRUE; +#else + return EINA_FALSE; + (void)url_con; + (void)proxy; +#endif +} + +EAPI void +ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout) +{ +#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_timeout_set"); + return; + } + + if (url_con->dead) return; + if (!url_con->url || timeout < 0) return; + if (url_con->timer) ecore_timer_del(url_con->timer); + url_con->timer = ecore_timer_add(timeout, _ecore_con_url_timeout_cb, url_con); +#else + return; + (void)url_con; + (void)timeout; +#endif +} + +EAPI Eina_Bool +ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username) +{ +#ifdef HAVE_CURL + int res = -1; + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_username_set"); + return EINA_FALSE; + } + + if (url_con->dead) return EINA_FALSE; + if (!url_con->url) return EINA_FALSE; + if ((!username) || (!username[0])) return EINA_FALSE; + if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A) + { + ERR("Proxy type should be socks5 and above"); + return EINA_FALSE; + } + + res = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username); + if (res != CURLE_OK) + { + ERR("curl_easy_setopt() failed: %s", curl_easy_strerror(res)); + return EINA_FALSE; + } + return EINA_TRUE; +#else + return EINA_FALSE; + (void)url_con; + (void)username; +#endif +} + +EAPI Eina_Bool +ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password) +{ +#ifdef HAVE_CURL + int res = -1; + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_password_set"); + return EINA_FALSE; + } + if (!url_con->url) return EINA_FALSE; + if (url_con->dead) return EINA_FALSE; + if (!password) return EINA_FALSE; + if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A) + { + ERR("Proxy type should be socks5 and above"); + return EINA_FALSE; + } + + res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password); + if (res != CURLE_OK) + { + ERR("curl_easy_setopt() failed: %s", curl_easy_strerror(res)); + return EINA_FALSE; + } + return EINA_TRUE; +#else + return EINA_FALSE; + (void)url_con; + (void)password; +#endif +} + +/** + * @} + */ + +#ifdef HAVE_CURL +static void +_ecore_con_url_status_get(Ecore_Con_Url *url_con) +{ + long status = 0; + + if (!url_con->curl_easy) return; + if (!curl_easy_getinfo(url_con->curl_easy, CURLINFO_RESPONSE_CODE, &status)) + url_con->status = status; + else + url_con->status = 0; +} + +static void +_ecore_con_url_event_url_complete(Ecore_Con_Url *url_con, CURLMsg *curlmsg) +{ + Ecore_Con_Event_Url_Complete *e; + int status = url_con->status; + + e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete)); + if (!e) return; + + if (!curlmsg) + { + ERR("Event completed without CURL message handle. Shouldn't happen"); + } + else if ((curlmsg->msg == CURLMSG_DONE) && + (curlmsg->data.result == CURLE_OPERATION_TIMEDOUT) && + (!curlmsg->easy_handle)) + { + /* easy_handle is set to NULL on timeout messages */ + status = 408; /* Request Timeout */ + } + else if (curlmsg->data.result == CURLE_OK) + { + if (!status) + { + _ecore_con_url_status_get(url_con); + status = url_con->status; + } + } + else + { + ERR("Curl message have errors: %d (%s)", + curlmsg->data.result, curl_easy_strerror(curlmsg->data.result)); + } + + e->status = status; + e->url_con = url_con; + + url_con->event_count++; + ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con); +} + +static void +_ecore_con_url_multi_remove(Ecore_Con_Url *url_con) +{ + CURLMcode ret; + + ret = curl_multi_remove_handle(_curlm, url_con->curl_easy); + url_con->multi = EINA_FALSE; + if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret)); +} + +static Eina_Bool +_ecore_con_url_timeout_cb(void *data) +{ + Ecore_Con_Url *url_con = data; + CURLMsg timeout_msg; + + if (!url_con) return ECORE_CALLBACK_CANCEL; + if (!url_con->curl_easy) return ECORE_CALLBACK_CANCEL; + + _ecore_con_url_multi_remove(url_con); + _url_con_list = eina_list_remove(_url_con_list, url_con); + + curl_slist_free_all(url_con->headers); + url_con->headers = NULL; + + url_con->timer = NULL; + + timeout_msg.msg = CURLMSG_DONE; + timeout_msg.easy_handle = NULL; + timeout_msg.data.result = CURLE_OPERATION_TIMEDOUT; + + _ecore_con_url_event_url_complete(url_con, &timeout_msg); + return ECORE_CALLBACK_CANCEL; +} + +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; + + INF("reading from %s", url_con->url); + 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); + url_con->event_count++; + ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con); + } + } + 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; +} + +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; + url_con->event_count++; + ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, (Ecore_End_Cb)_ecore_con_event_url_free, url_con); + } + + 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) + { + fclose((FILE *)stream); + return 0; + } + +#ifdef _WIN32 + INF("*** We read %Iu bytes from file", retcode); +#else + INF("*** We read %zu bytes from file", retcode); +#endif + return retcode; +} + +static void +_ecore_con_url_info_read(void) +{ + CURLMsg *curlmsg; + int n_remaining; + + while ((curlmsg = curl_multi_info_read(_curlm, &n_remaining))) + { + Eina_List *l, *ll; + Ecore_Con_Url *url_con = NULL; + DBG("Curl message: %d", curlmsg->msg); + + if (curlmsg->msg == CURLMSG_DONE) + { + EINA_LIST_FOREACH_SAFE(_url_con_list, l, ll, url_con) + { + if (curlmsg->easy_handle == url_con->curl_easy) + _ecore_con_url_event_url_complete(url_con, curlmsg); + } + } + } +} + +static void +_ecore_con_url_curl_clear(void) +{ + Ecore_Fd_Handler *fdh; + Ecore_Con_Url *url_con; + + EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh); + EINA_LIST_FREE(_url_con_list, url_con) _ecore_con_url_multi_remove(url_con); +} + +static Eina_Bool +_ecore_con_url_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + Ecore_Fd_Handler *fdh; + long ms; + + EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh); + + curl_multi_timeout(_curlm, &ms); + if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; + ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0); + + if (!_curl_idler) + _curl_idler = ecore_idler_add(_ecore_con_url_timer, NULL); + + return ECORE_CALLBACK_CANCEL; +} + +static void +_ecore_con_url_fdset(void) +{ + CURLMcode ret; + fd_set read_set, write_set, exc_set; + int fd, fd_max; + + FD_ZERO(&read_set); + FD_ZERO(&write_set); + FD_ZERO(&exc_set); + + ret = curl_multi_fdset(_curlm, &read_set, &write_set, &exc_set, &fd_max); + if (ret != CURLM_OK) + { + ERR("curl_multi_fdset failed: %s", curl_multi_strerror(ret)); + return; + } + + for (fd = 0; fd <= fd_max; fd++) + { + int 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) + { + // FIXME: Who is owner (easy_handle) of this fd?? (Curl do not give this info.) + // This cause "Failed to delete epoll fd xx!" error messages + Ecore_Fd_Handler *fd_handler; + fd_handler = ecore_main_fd_handler_add(fd, flags, + _ecore_con_url_fd_handler, + NULL, NULL, NULL); + if (fd_handler) + _fd_hd_list = eina_list_append(_fd_hd_list, fd_handler); + } + } +} + +static Eina_Bool +_ecore_con_url_timer(void *data EINA_UNUSED) +{ + Ecore_Fd_Handler *fdh; + int still_running; + CURLMcode ret; + + EINA_LIST_FREE(_fd_hd_list, fdh) ecore_main_fd_handler_del(fdh); + _ecore_con_url_info_read(); + + ret = curl_multi_perform(_curlm, &still_running); + if (ret == CURLM_CALL_MULTI_PERFORM) + { + DBG("curl_multi_perform() again immediately"); + return ECORE_CALLBACK_RENEW; + } + else if (ret != CURLM_OK) + { + ERR("curl_multi_perform() failed: %s", curl_multi_strerror(ret)); + _ecore_con_url_curl_clear(); + ecore_timer_freeze(_curl_timer); + if (_curl_idler) + { + ecore_idler_del(_curl_idler); + _curl_idler = NULL; + } + } + + if (still_running) + { + long ms; + _ecore_con_url_fdset(); + curl_multi_timeout(_curlm, &ms); + DBG("multiperform is still running: %d, timeout: %ld", still_running, ms); + if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; + ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0); + } + else + { + DBG("multiperform ended"); + _ecore_con_url_info_read(); + _ecore_con_url_curl_clear(); + ecore_timer_freeze(_curl_timer); + if (_curl_idler) + { + ecore_idler_del(_curl_idler); + _curl_idler = NULL; + } + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_ecore_con_url_perform(Ecore_Con_Url *url_con) +{ + CURLMcode ret; + + ret = curl_multi_add_handle(_curlm, url_con->curl_easy); + if (ret != CURLM_OK) + { + ERR("curl_multi_add_handle() failed: %s", curl_multi_strerror(ret)); + return EINA_FALSE; + } + + url_con->multi = EINA_TRUE; + _url_con_list = eina_list_append(_url_con_list, url_con); + ecore_timer_thaw(_curl_timer); + + return EINA_TRUE; +} + +static void +_ecore_con_event_url_free(Ecore_Con_Url *url_con, void *ev) +{ + free(ev); + url_con->event_count--; + if (url_con->dead && (!url_con->event_count)) + ecore_con_url_free(url_con); +} + +#endif diff --git a/src/lib/ecore_directfb/Ecore_DirectFB.h b/src/lib/ecore_directfb/Ecore_DirectFB.h new file mode 100644 index 0000000000..3b94816d96 --- /dev/null +++ b/src/lib/ecore_directfb/Ecore_DirectFB.h @@ -0,0 +1,181 @@ +#ifndef _ECORE_DIRECTFB_H +#define _ECORE_DIRECTFB_H + +#include + +#include + +#ifdef EAPI +# undef EAPI +#endif /* ifdef EAPI */ + +#ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else /* if __GNUC__ >= 4 */ +# define EAPI +# endif /* if __GNUC__ >= 4 */ +#else /* ifdef __GNUC__ */ +# define EAPI +#endif /* ifdef __GNUC__ */ + +#ifdef __cplusplus +extern "C" { +#endif /* ifdef __cplusplus */ + +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 /* ifndef _ECORE_DIRECTFB_WINDOW_PREDEF */ +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; + int double_click : 1; + int triple_click : 1; +}; +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, Eina_Bool set); +EAPI void ecore_directfb_window_fullscreen_set(Ecore_DirectFB_Window *window, Eina_Bool 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, Eina_Bool show); + +#ifdef __cplusplus +} +#endif /* ifdef __cplusplus */ + +#endif /* ifndef _ECORE_DIRECTFB_H */ diff --git a/src/lib/ecore_directfb/ecore_directfb.c b/src/lib/ecore_directfb/ecore_directfb.c new file mode 100644 index 0000000000..008fa1d6f9 --- /dev/null +++ b/src/lib/ecore_directfb/ecore_directfb.c @@ -0,0 +1,758 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include +#include +#include + +#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; // useful for DFBCHECK + +/*******************/ +/* local functions */ +/*******************/ + +/* free ecore directfb events functions */ +/****************************************/ + +static void +_ecore_directfb_event_free_key_down(void *data EINA_UNUSED, void *ev) +{ + Ecore_DirectFB_Event_Key_Down *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 EINA_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("Symbol %0X of class DFEC_INPUT not found.", 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("Symbol %0X of class DFEC_WINDOW not found.", 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("Symbol %0X of class DFEC_INPUT not found.", 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("Symbol %0X of class DFEC_WINDOW not found.", 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 Eina_Bool +_ecore_directfb_input_event_fd_handler(void *data EINA_UNUSED,Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + DFBEvent evt; + int v = 0; + + v = read(_input_event_fd, &evt, sizeof(DFBEvent)); + if (v < 0) + return EINA_TRUE; + + if (v < 1) + return EINA_TRUE; + + /* 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 EINA_TRUE; +} + +static Eina_Bool +_ecore_directfb_window_event_fd_handler(void *data EINA_UNUSED,Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + DFBEvent evt; + int v = 0; + + v = read(_window_event_fd, &evt, sizeof(DFBEvent)); + if (v < 0) + return EINA_TRUE; + + if (v < 1) + return EINA_TRUE; + + 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 EINA_TRUE; +} + +/* 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, Eina_Bool 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, Eina_Bool 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, Eina_Bool 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 + { + ecore_main_fd_handler_del(_input_event_fd_handler_handle); + DFBCHECK(_input_event->Release(_input_event)); + DFBCHECK(_layer->SetCooperativeLevel(_layer,DLSCL_SHARED)); + DFBCHECK(ecore_window->window->GetSurface(ecore_window->window, &ecore_window->surface)); + _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 EINA_UNUSED) +{ + int i = 0; + + if (++_ecore_directfb_init_count != 1) + return _ecore_directfb_init_count; + + _ecore_directfb_log_dom = eina_log_domain_register + ("ecore_directfb", 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; +} + diff --git a/src/lib/ecore_directfb/ecore_directfb_keys.h b/src/lib/ecore_directfb/ecore_directfb_keys.h new file mode 100644 index 0000000000..19cca46e57 --- /dev/null +++ b/src/lib/ecore_directfb/ecore_directfb_keys.h @@ -0,0 +1,184 @@ +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); diff --git a/src/lib/ecore_directfb/ecore_directfb_private.h b/src/lib/ecore_directfb/ecore_directfb_private.h new file mode 100644 index 0000000000..ed34587ab5 --- /dev/null +++ b/src/lib/ecore_directfb/ecore_directfb_private.h @@ -0,0 +1,52 @@ +#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 /* ifdef ECORE_DIRECTFB_DEFAULT_LOG_COLOR */ +#define ECORE_DIRECTFB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE + +#ifdef ERR +# undef ERR +#endif /* ifdef ERR */ +#define ERR(...) EINA_LOG_DOM_ERR(_ecore_directfb_log_dom, __VA_ARGS__) + +#ifdef DBG +# undef DBG +#endif /* ifdef DBG */ +#define DBG(...) EINA_LOG_DOM_DBG(_ecore_directfb_log_dom, __VA_ARGS__) + +#ifdef INF +# undef INF +#endif /* ifdef INF */ +#define INF(...) EINA_LOG_DOM_INFO(_ecore_directfb_log_dom, __VA_ARGS__) + +#ifdef WRN +# undef WRN +#endif /* ifdef WRN */ +#define WRN(...) EINA_LOG_DOM_WARN(_ecore_directfb_log_dom, __VA_ARGS__) + +#ifdef CRIT +# undef CRIT +#endif /* ifdef CRIT */ +#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 /* ifndef _ECORE_DIRECTFB_PRIVATE_H */ diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h new file mode 100644 index 0000000000..3c59c80c84 --- /dev/null +++ b/src/lib/ecore_evas/Ecore_Evas.h @@ -0,0 +1,2256 @@ +#ifndef _ECORE_EVAS_H +#define _ECORE_EVAS_H + +#include +#include +#include + +#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 + * + * The following is a list of example that partially exemplify Ecore_Evas's API: + * @li @ref ecore_evas_callbacks_example_c + * @li @ref ecore_evas_object_example_c + * @li @ref ecore_evas_basics_example_c + * @li @ref Ecore_Evas_Window_Sizes_Example_c + * @li @ref Ecore_Evas_Buffer_Example_01_c + * @li @ref Ecore_Evas_Buffer_Example_02_c + */ + +/* 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 + +/** + * @defgroup Ecore_Evas_Group Ecore_Evas wrapper/helper set of functions + * + * Ecore evas is a set of functions that makes it easy to tie together ecore's + * main loop and input handling to evas. As such it's a natural base for EFL + * applications. While this combination makes it easy to create the basic + * aspects all applications need, for normal applications(ones with buttons, + * checkboxes and layouts) one should consider using Elementary. + * + * Ecore evas is extremely well suited for applications that are not based on + * widgets. It has a main loop that delivers events, does basic window handling + * and leaves all of the drawing up to the user. This works very well if used + * in conjunction with Edje or if doing custom drawing as, for example, is done + * in games. + * + * This is a list of examples of these functions: + * @li @ref ecore_evas_basics_example_c + * @li @ref ecore_evas_object_example_c + * @li @ref ecore_evas_callbacks_example_c + * @li @ref Ecore_Evas_Window_Sizes_Example_c + * @li @ref Ecore_Evas_Buffer_Example_01_c + * @li @ref Ecore_Evas_Buffer_Example_02_c + * + * @{ + */ + +/* 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 +#define HAVE_ECORE_EVAS_EWS 1 +#define HAVE_ECORE_EVAS_PSL1GHT 1 +#define HAVE_ECORE_EVAS_WAYLAND_SHM 1 +#define HAVE_ECORE_EVAS_WAYLAND_EGL 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_OPENGL_COCOA, + ECORE_EVAS_ENGINE_SOFTWARE_SDL, + ECORE_EVAS_ENGINE_DIRECTFB, + ECORE_EVAS_ENGINE_SOFTWARE_FB, + ECORE_EVAS_ENGINE_SOFTWARE_8_X11, + 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_EWS, + ECORE_EVAS_ENGINE_PSL1GHT, + ECORE_EVAS_ENGINE_WAYLAND_SHM, + ECORE_EVAS_ENGINE_WAYLAND_EGL +} 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 struct _Ecore_WinCE_Window Ecore_WinCE_Window; +#endif + +#ifndef __ECORE_COCOA_H__ +typedef struct _Ecore_Cocoa_Window Ecore_Cocoa_Window; +#endif + +#ifndef _ECORE_EVAS_PRIVATE_H +/* basic data types */ +typedef struct _Ecore_Evas Ecore_Evas; +typedef void (*Ecore_Evas_Event_Cb) (Ecore_Evas *ee); /**< Callback used for several ecore evas events @since 1.2 */ +#endif + +#ifndef _ECORE_WAYLAND_H_ +#define _ECORE_WAYLAND_WINDOW_PREDEF +typedef struct _Ecore_Wl_Window Ecore_Wl_Window; +#endif + +/* module setup/shutdown calls */ + +EAPI int ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine); + +/** + * @brief Init the Ecore_Evas system. + * + * @return How many times the lib has been initialized, 0 indicates failure. + * + * Set up the Evas wrapper system. Init Evas and Ecore libraries. + * + * @see ecore_evas_shutdown() + */ +EAPI int ecore_evas_init(void); +/** + * @brief Shut down the Ecore_Evas system. + * + * @return 0 if ecore evas is fully shut down, or > 0 if it still being used. + * + * This closes the Evas wrapper system down. Shut down Evas and Ecore libraries. + * + * @see ecore_evas_init() + */ +EAPI int ecore_evas_shutdown(void); + +EAPI void ecore_evas_app_comp_sync_set(Eina_Bool do_sync); +EAPI Eina_Bool ecore_evas_app_comp_sync_get(void); + +/** + * @brief 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 or modify them, to free the list use ecore_evas_engines_free(). + */ +EAPI Eina_List *ecore_evas_engines_get(void); +/** + * @brief Free list returned by ecore_evas_engines_get() + * + * @param engines list with engines names + */ +EAPI void ecore_evas_engines_free(Eina_List *engines); +/** + * @brief 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 @c 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 @c 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); +/** + * @brief Set whether an Ecore_Evas has an alpha channel or not. + * + * @param ee The Ecore_Evas to shape + * @param alpha @c EINA_TRUE to enable the alpha channel, @c EINA_FALSE 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 transparency, as opposed to + * the 1 bit transparency of a shaped window (a pixel is either opaque, or + * it's transparent). + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_alpha_set(Ecore_Evas *ee, Eina_Bool alpha); +/** + * @brief Query whether an Ecore_Evas has an alpha channel. + * @param ee The Ecore_Evas to query. + * @return @c EINA_TRUE if ee has an alpha channel, @c EINA_FALSE if it does + * not. + * + * This function returns @c EINA_TRUE if @p ee has an alpha channel, and + * @c EINA_FALSE if it does not. + * + * @see ecore_evas_alpha_set() + */ +EAPI Eina_Bool ecore_evas_alpha_get(const Ecore_Evas *ee); +/** + * @brief Set whether an Ecore_Evas has an transparent window or not. + * + * @param ee The Ecore_Evas to shape + * @param transparent @c EINA_TRUE to enable the transparent window, + * @c EINA_FALSE to disable it + * + * This function sets some translucency options, for more complete support see + * ecore_evas_alpha_set(). + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_alpha_set() + */ +EAPI void ecore_evas_transparent_set(Ecore_Evas *ee, Eina_Bool transparent); +/** + * @brief Query whether an Ecore_Evas is transparent. + * + * @param ee The Ecore_Evas to query. + * @return @c EINA_TRUE if ee is transparent, @c EINA_FALSE if it isn't. + * + * @see ecore_evas_transparent_set() + */ +EAPI Eina_Bool ecore_evas_transparent_get(const Ecore_Evas *ee); +/** + * @brief 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. If any of the parameters is not desired you + * may pass @c NULL on them. + * + * @code + * int x, y, w, h; + * ecore_evas_geometry_get(ee, &x, &y, &w, &h); + * @endcode + * + * @see ecore_evas_new() + * @see ecore_evas_resize() + * @see ecore_evas_move() + * @see ecore_evas_move_resize() + */ +EAPI void ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); +/** + * @brief Get the geometry which an Ecore_Evas was latest recently requested. + * + * @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 which @p ee was latest recently requested . If any of the + * parameters is not desired you may pass @c NULL on them. + * This function can represent recently requested geometry. + * ecore_evas_geometry_get function returns the value is updated after engine + * finished request. By comparison, ecore_evas_request_geometry_get returns + * recently requested value. + * + * @code + * int x, y, w, h; + * ecore_evas_request_geometry_get(ee, &x, &y, &w, &h); + * @endcode + * + * @since 1.1 + */ +EAPI void ecore_evas_request_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); +/** + * @brief Set the focus of an Ecore_Evas' window. + * + * @param ee The Ecore_Evas + * @param on @c EINA_TRUE for focus, @c EINA_FALSE to defocus. + * + * This function focuses @p ee if @p on is @c EINA_TRUE, or unfocuses @p ee if + * @p on is @c EINA_FALSE. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool on); +/** + * @brief Query whether an Ecore_Evas' window is focused or not. + * + * @param ee The Ecore_Evas to set + * @return @c EINA_TRUE if @p ee if focused, @c EINA_FALSE if not. + * + * @see ecore_evas_focus_set() + */ +EAPI Eina_Bool ecore_evas_focus_get(const Ecore_Evas *ee); +/** + * @brief Iconify or uniconify an Ecore_Evas' window. + * + * @param ee The Ecore_Evas + * @param on @c EINA_TRUE to iconify, @c EINA_FALSE to uniconify. + * + * This function iconifies @p ee if @p on is @c EINA_TRUE, or uniconifies @p ee + * if @p on is @c EINA_FALSE. + * + * @note Iconify and minimize are synonyms. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_iconified_set(Ecore_Evas *ee, Eina_Bool on); +/** + * @brief Query whether an Ecore_Evas' window is iconified or not. + * + * @param ee The Ecore_Evas to set + * @return @c EINA_TRUE if @p ee is iconified, @c EINA_FALSE if not. + * + * @note Iconify and minimize are synonyms. + * + * @see ecore_evas_iconified_set() + */ +EAPI Eina_Bool ecore_evas_iconified_get(const Ecore_Evas *ee); +/** + * @brief Set whether an Ecore_Evas' window is borderless or not. + * + * @param ee The Ecore_Evas + * @param on @c EINA_TRUE for borderless, @c EINA_FALSE for bordered. + * + * This function makes @p ee borderless if @p on is @c EINA_TRUE, or bordered + * if @p on is @c EINA_FALSE. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_borderless_set(Ecore_Evas *ee, Eina_Bool on); +/** + * @brief Query whether an Ecore_Evas' window is borderless or not. + * + * @param ee The Ecore_Evas to set + * @return @c EINA_TRUE if @p ee is borderless, @c EINA_FALSE if not. + * + * @see ecore_evas_borderless_set() + */ +EAPI Eina_Bool ecore_evas_borderless_get(const Ecore_Evas *ee); +/** + * @brief Set whether or not an Ecore_Evas' window is fullscreen. + * + * @param ee The Ecore_Evas + * @param on @c EINA_TRUE fullscreen, @c EINA_FALSE not. + * + * This function causes @p ee to be fullscreen if @p on is @c EINA_TRUE, or + * not if @p on is @c EINA_FALSE. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on); +/** + * @brief Query whether an Ecore_Evas' window is fullscreen or not. + * + * @param ee The Ecore_Evas to set + * @return @c EINA_TRUE if @p ee is fullscreen, @c EINA_FALSE if not. + * + * @see ecore_evas_fullscreen_set() + */ +EAPI Eina_Bool ecore_evas_fullscreen_get(const Ecore_Evas *ee); +/** + * @brief Set another window that this window is a group member of + * + * @param ee The Ecore_Evas + * @param ee_group The other group member + * + * If @p ee_group is @c NULL, @p ee is removed from the group, otherwise it is + * added. Note that if you free the @p ee_group canvas before @p ee, then + * getting the group canvas with ecore_evas_window_group_get() will return + * an invalid handle. + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.2 + */ +EAPI void ecore_evas_window_group_set(Ecore_Evas *ee, const Ecore_Evas *ee_group); +/** + * @brief Get the canvas group set. + * + * This returns the handle set by ecore_evas_window_group_set(). + * + * @param ee The Ecore_Evas to set + * @return The Canvas group handle + * + * @see ecore_evas_window_group_set() + * @since 1.2 + */ +EAPI const Ecore_Evas *ecore_evas_window_group_get(const Ecore_Evas *ee); +/** + * @brief Set the aspect ratio of a canvas window + * + * @param ee The Ecore_Evas + * @param aspect The aspect ratio (width divided by height), or 0 to disable + * + * This sets the desired aspect ratio of a canvas window + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.2 + */ +EAPI void ecore_evas_aspect_set(Ecore_Evas *ee, double aspect); +/** + * @brief Get the aspect ratio of a canvas window + * + * This returns the value set by ecore_evas_aspect_set(). + * + * @param ee The Ecore_Evas to set + * @return The aspect ratio + * + * @see ecore_evas_aspect_set() + * @since 1.2 + */ +EAPI double ecore_evas_aspect_get(const Ecore_Evas *ee); +/** + * @brief Set The urgent hint flag + * + * @param ee The Ecore_Evas + * @param urgent The urgent state flag + * + * This sets the "urgent" state hint on a window so the desktop environment + * can highlight it somehow. + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.2 + */ +EAPI void ecore_evas_urgent_set(Ecore_Evas *ee, Eina_Bool urgent); +/** + * @brief Get the urgent state on the cavas window + * + * This returns the value set by ecore_evas_urgent_set() + * + * @param ee The Ecore_Evas to set + * @return The urgent state set + * + * @see ecore_evas_urgent_set() + * @since 1.2 + */ +EAPI Eina_Bool ecore_evas_urgent_get(const Ecore_Evas *ee); +/** + * @brief Set the modal state flag on the canvas window + * + * @param ee The Ecore_Evas + * @param modal The modal hint flag + * + * This hints if the window should be modal (eg if it is also transient + * for another window, the other window will maybe be denied focus by + * the desktop window manager). + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.2 + */ +EAPI void ecore_evas_modal_set(Ecore_Evas *ee, Eina_Bool modal); +/** + * @brief Get The modal flag + * + * This returns the value set by ecore_evas_modal_set(). + * + * @param ee The Ecore_Evas to set + * @return The modal flag + * + * @see ecore_evas_modal_set() + * @since 1.2 + */ +EAPI Eina_Bool ecore_evas_modal_get(const Ecore_Evas *ee); +/** + * @brief Set the "i demand attention" flag on a canvas window + * + * @param ee The Ecore_Evas + * @param demand The flag state to set + * + * A window may demand attention now (eg you must enter a password before + * continuing), and so it may flag a window with this. + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.2 + */ +EAPI void ecore_evas_demand_attention_set(Ecore_Evas *ee, Eina_Bool demand); +/** + * @brief Get the "i demand attention" flag + * + * This returns the value set by ecore_evas_demand_attention_set(). + * + * @param ee The Ecore_Evas to set + * @return The "i demand attention" flag. + * + * @see ecore_evas_demand_attention_set() + * @since 1.2 + */ +EAPI Eina_Bool ecore_evas_demand_attention_get(const Ecore_Evas *ee); +/** + * @brief Set the "focus skip" flag + * + * @param ee The Ecore_Evas + * @param skip The "focus skip" state to set. + * + * A window may not want to accept focus, be in the taskbar, pager etc. + * sometimes (example for a small notification window that hovers around + * a taskbar or panel, or hovers around a window until some activity + * dismisses it). + * + * @warning Support for this depends on the underlying windowing system. + * @since 1.2 + */ +EAPI void ecore_evas_focus_skip_set(Ecore_Evas *ee, Eina_Bool skip); +/** + * @brief Get the "focus skip" flag + * + * This returns the value set by ecore_evas_focus_skip_set(). + * + * @param ee The Ecore_Evas to set + * @return The "focus skip" flag. + * + * @see ecore_evas_focus_skip_set() + * @since 1.2 + */ +EAPI Eina_Bool ecore_evas_focus_skip_get(const Ecore_Evas *ee); + +/** + * @brief Set if this evas should ignore @b all events. + * + * @param ee The Ecore_Evas whose window's to ignore events. + * @param ignore The Ecore_Evas new ignore state. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_ignore_events_set(Ecore_Evas *ee, Eina_Bool ignore); +/** + * @brief 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. + * + * @see ecore_evas_ignore_events_set() + */ +EAPI Eina_Bool ecore_evas_ignore_events_get(const Ecore_Evas *ee); +/** + * @brief 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. + * + * @see ecore_evas_show() + * @see ecore_evas_hide() + */ +EAPI int ecore_evas_visibility_get(const Ecore_Evas *ee); +/** + * @brief 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. + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_lower() + * @see ecore_evas_raise() + */ +EAPI void ecore_evas_layer_set(Ecore_Evas *ee, int layer); +/** + * @brief Get the layer of an Ecore_Evas' window. + * + * @param ee The Ecore_Evas to set + * @return the layer @p ee's window is on. + * + * @see ecore_evas_layer_set() + * @see ecore_evas_lower() + * @see ecore_evas_raise() + */ +EAPI int ecore_evas_layer_get(const Ecore_Evas *ee); +/** + * @brief Maximize (or unmaximize) an Ecore_Evas' window. + * + * @param ee The Ecore_Evas + * @param on @c EINA_TRUE to maximize, @c EINA_FALSE to unmaximize. + * + * This function maximizes @p ee if @p on is @c EINA_TRUE, or unmaximizes @p ee + * if @p on is @c EINA_FALSE. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_maximized_set(Ecore_Evas *ee, Eina_Bool on); +/** + * @brief Query whether an Ecore_Evas' window is maximized or not. + * + * @param ee The Ecore_Evas to set + * @return @c EINA_TRUE if @p ee is maximized, @c EINA_FALSE if not. + * + * @see ecore_evas_maximized_set() + */ +EAPI Eina_Bool ecore_evas_maximized_get(const Ecore_Evas *ee); +/** + * @brief 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) + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_new() + * @see ecore_evas_resize() + * @see ecore_evas_move_resize() + */ +EAPI void ecore_evas_move(Ecore_Evas *ee, int x, int y); +/** + * @brief 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. + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_new() + * @see ecore_evas_move() + * @see ecore_evas_move_resize() + */ +EAPI void ecore_evas_resize(Ecore_Evas *ee, int w, int h); +/** + * @brief Move and resize an Ecore_Evas + * + * @param ee The Ecore_Evas to move and resize + * @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. + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_new() + * @see ecore_evas_move() + * @see ecore_evas_resize() + */ +EAPI void ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); +/** + * @brief 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. + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_rotation_with_resize_set() + */ +EAPI void ecore_evas_rotation_set(Ecore_Evas *ee, int rot); +/** + * @brief Set the rotation of an Ecore_Evas' window + * + * @param ee The Ecore_Evas + * @param rot the angle (in degrees) of rotation. + * + * Like ecore_evas_rotation_set(), but it also resizes the window's contents so + * that they fit inside the current window geometry. + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_rotation_set() + */ +EAPI void ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot); +/** + * @brief Get the rotation of an Ecore_Evas' window + * + * @param ee The Ecore_Evas + * @return the angle (in degrees) of rotation. + * + * @see ecore_evas_rotation_set() + * @see ecore_evas_rotation_with_resize_set() + */ +EAPI int ecore_evas_rotation_get(const Ecore_Evas *ee); +/** + * @brief Raise an Ecore_Evas' window. + * + * @param ee The Ecore_Evas to raise. + * + * This functions raises the Ecore_Evas to the front. + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_lower() + * @see ecore_evas_layer_set() + */ +EAPI void ecore_evas_raise(Ecore_Evas *ee); +/** + * @brief Lower an Ecore_Evas' window. + * + * @param ee The Ecore_Evas to raise. + * + * This functions lowers the Ecore_Evas to the back. + * + * @warning Support for this depends on the underlying windowing system. + * + * @see ecore_evas_raise() + * @see ecore_evas_layer_set() + */ +EAPI void ecore_evas_lower(Ecore_Evas *ee); +/** + * @brief 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. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_title_set(Ecore_Evas *ee, const char *t); +/** + * @brief 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. + * + * @see ecore_evas_title_set() + */ +EAPI const char *ecore_evas_title_get(const Ecore_Evas *ee); +/** + * @brief 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. The + * meaning of @p name and @p class depends on the underlying windowing system. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI void ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c); +/** + * @brief Get the name and class of an Ecore_Evas' window + * + * This function gets the name of @p ee into @p n, and its class into + * @p c. + * + * @param ee The Ecore_Evas to query. + * @param n A pointer to a string to place the name in. + * @param c A pointer to a string to place the class in. + * @see ecore_evas_name_class_set() + */ +EAPI void ecore_evas_name_class_get(const Ecore_Evas *ee, const char **n, const char **c); +/** + * @brief Returns a pointer to the underlying window. + * + * @param ee The Ecore_Evas whose window is desired. + * @return A pointer to the underlying window. + * + * @warning Support for this depends on the underlying windowing system. + */ +EAPI Ecore_Window ecore_evas_window_get(const Ecore_Evas *ee); + + +/* 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, Eina_Bool on); +EAPI Eina_Bool 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_VSYNC 2 +#define ECORE_EVAS_GL_X11_OPT_SWAP_MODE 3 +#define ECORE_EVAS_GL_X11_OPT_LAST 4 + +#define ECORE_EVAS_GL_X11_SWAP_MODE_AUTO 0 +#define ECORE_EVAS_GL_X11_SWAP_MODE_FULL 1 +#define ECORE_EVAS_GL_X11_SWAP_MODE_COPY 2 +#define ECORE_EVAS_GL_X11_SWAP_MODE_DOUBLE 3 +#define ECORE_EVAS_GL_X11_SWAP_MODE_TRIPLE 4 + +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, Eina_Bool on); +EAPI Eina_Bool 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, Eina_Bool on); +EAPI Eina_Bool 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_8_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_8_window_get(const Ecore_Evas *ee); +EAPI Ecore_X_Window ecore_evas_software_x11_8_subwindow_get(const Ecore_Evas *ee); +EAPI void ecore_evas_software_x11_8_direct_resize_set(Ecore_Evas *ee, Eina_Bool on); +EAPI Eina_Bool ecore_evas_software_x11_8_direct_resize_get(const Ecore_Evas *ee); +EAPI void ecore_evas_software_x11_8_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, Eina_Bool on); +EAPI Eina_Bool 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_wayland_shm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame); +EAPI Ecore_Evas *ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame); +EAPI void ecore_evas_wayland_resize(Ecore_Evas *ee, int location); +EAPI void ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y); + +EAPI void ecore_evas_wayland_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y); +EAPI void ecore_evas_wayland_type_set(Ecore_Evas *ee, int type); +EAPI Ecore_Wl_Window *ecore_evas_wayland_window_get(const Ecore_Evas *ee); + +/** + * @brief Create a new @c Ecore_Evas canvas bound to the Evas + * @b buffer engine + * + * @param w The width of the canvas, in pixels + * @param h The height of the canvas, in pixels + * @return A new @c Ecore_Evas instance or @c NULL, on failure + * + * This creates a new buffer canvas wrapper, with image data array + * @b bound to the ARGB format, 8 bits per pixel. + * + * This function will allocate the needed pixels array with canonical + * @c malloc(). If you wish a custom function to allocate it, consider + * using ecore_evas_buffer_allocfunc_new(), instead. + * + * @note This function actually is a wrapper on + * ecore_evas_buffer_allocfunc_new(), using the same @a w and @a h + * arguments and canonical @c malloc() and @c free() to the memory + * allocation and freeing functions. See that function's documentation + * for more details. + */ +EAPI Ecore_Evas *ecore_evas_buffer_new(int w, int h); + +/** + * @brief Create a new @c Ecore_Evas canvas bound to the Evas + * @b buffer engine, giving custom allocation and freeing functions for + * the canvas memory region + * + * @param w The width of the canvas, in canvas units + * @param h The height of the canvas, in canvas units + * @param alloc_func Function to be called to allocate the memory + * needed for the new buffer canvas. @a data will be passed the same + * value as the @p data of this function, while @a size will be passed + * @p w times @p h times @c sizeof(int). + * @param free_func Function to be called to free the memory used by + * the new buffer canvas. @a data will be passed the same value as the + * @p data of this function, while @a pix will be passed the canvas + * memory pointer. + * @param data Custom data to be passed to the allocation and freeing + * functions + * @return A new @c Ecore_Evas instance or @c NULL, on failure + * + * This creates a new buffer canvas wrapper, with image data array + * @b bound to the ARGB format, 8 bits per pixel. + * + * This function is useful when one wants an @c Ecore_Evas buffer + * canvas with a custom allocation function, like one getting memory + * chunks from a memory pool, for example. + * + * On any resizing of this @c Ecore_Evas buffer canvas, its image data + * will be @b freed, to be allocated again with the new size. + * + * @note @p w and @p h sizes have to greater or equal to 1. Otherwise, + * they'll be interpreted as 1, exactly. + * + * @see ecore_evas_buffer_new() + */ +EAPI Ecore_Evas *ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data); + +/** + * @brief Grab a pointer to the actual pixels array of a given + * @c Ecore_Evas @b buffer canvas/window. + * + * @param ee An @c Ecore_Evas handle + * @return A pointer to the internal pixels array of @p ee + * + * Besides returning a pointer to the actual pixel array of the given + * canvas, this call will force a rendering update on @p ee, + * first. + * + * A common use case for this call is to create an image object, from + * @b another canvas, to have as data @p ee's contents, thus + * snapshoting the canvas. For that case, one can also use the + * ecore_evas_object_image_new() helper function. + */ +EAPI const void *ecore_evas_buffer_pixels_get(Ecore_Evas *ee); + +/** + * @brief Create a new @c Ecore_Evas canvas bound to the Evas + * @b ews (Ecore + Evas Single Process Windowing System) engine + * + * EWS is a simple single process windowing system. The backing store + * is also an @c Ecore_Evas that can be setup with + * ecore_evas_ews_setup() and retrieved with + * ecore_evas_ews_ecore_evas_get(). It will allow window management + * using events prefixed with @c ECORE_EVAS_EVENT_EWS_. + * + * The EWS windows (returned by this function or + * ecore_evas_new("ews"...)) will all be software buffer windows + * automatic rendered to the backing store. + * + * @param x horizontal position of window, in pixels + * @param y vertical position of window, in pixels + * @param w The width of the canvas, in pixels + * @param h The height of the canvas, in pixels + * @return A new @c Ecore_Evas instance or @c NULL, on failure + * + * @see ecore_evas_ews_setup() + * @see ecore_evas_ews_ecore_evas_get() + * + * @since 1.1 + */ +EAPI Ecore_Evas *ecore_evas_ews_new(int x, int y, int w, int h); + + +/** + * Returns the backing store image object that represents the given + * window in EWS. + * @return The evas object of EWS backing store. + * + * @note This should not be modified anyhow, but may be helpful to + * determine stacking and geometry of it for window managers + * that decorate windows. + * + * @param ee The Ecore_Evas from which to get the backing store. + * @see ecore_evas_ews_manager_set() + * @see ecore_evas_ews_evas_get() + * @since 1.1 + */ +EAPI Evas_Object *ecore_evas_ews_backing_store_get(const Ecore_Evas *ee); + +/** + * Calls the window to be deleted (freed), but can let user decide to + * forbid it by using ecore_evas_callback_delete_request_set() + * + * @param ee The Ecore_Evas for which window will be deleted. + * @since 1.1 + */ +EAPI void ecore_evas_ews_delete_request(Ecore_Evas *ee); + +/** + * @brief Create an Evas image object with image data bound to an + * own, internal @c Ecore_Evas canvas wrapper + * + * @param ee_target @c Ecore_Evas to have the canvas receiving the new + * image object + * @return A handle to the new image object + * + * This will create a @b special Evas image object. The image's pixel + * array will get bound to the same image data array of an @b internal + * @b buffer @c Ecore_Evas canvas. The user of this function is, then, + * supposed to grab that @c Ecore_Evas handle, with + * ecore_evas_object_ecore_evas_get(), and use its canvas to render + * whichever contents he/she wants, @b independently of the contents + * of the canvas owned by @p ee_target. Those contents will reflect on + * the canvas of @p ee, though, being exactly the image data of the + * object returned by this function. + * + * This is a helper function for the scenario of one wanting to grab a + * buffer canvas' contents (with ecore_evas_buffer_pixels_get()) to be + * used on another canvas, for whichever reason. The most common goal + * of this setup is to @b save an image file with a whole canvas as + * contents, which could not be achieved by using an image file within + * the target canvas. + * + * @warning Always resize the returned image and its underlying + * @c Ecore_Evas handle accordingly. They must be kept with same sizes + * for things to work as expected. Also, you @b must issue + * @c evas_object_image_size_set() on the image with that same size. If + * the image is to be shown in a canvas bound to an engine different + * than the buffer one, then you must also set this image's @b fill + * properties accordingly. + * + * @note The image returned will always be bound to the + * @c EVAS_COLORSPACE_ARGB8888 colorspace, always. + * + * @note Use ecore_evas_object_evas_get() to grab the image's internal + * own canvas directly. + * + * @note If snapshoting this image's internal canvas, remember to + * flush its internal @c Ecore_Evas firstly, with + * ecore_evas_manual_render(). + */ +EAPI Evas_Object *ecore_evas_object_image_new(Ecore_Evas *ee_target); + +/** + * @brief Retrieve the internal @c Ecore_Evas handle of an image + * object created via ecore_evas_object_image_new() + * + * @param obj A handle to an image object created via + * ecore_evas_object_image_new() + * @return The underlying @c Ecore_Evas handle in @p obj + */ +EAPI Ecore_Evas *ecore_evas_object_ecore_evas_get(Evas_Object *obj); + +/** + * @brief Retrieve the canvas bound to the internal @c Ecore_Evas + * handle of an image object created via ecore_evas_object_image_new() + * + * @param obj A handle to an image object created via + * ecore_evas_object_image_new() + * @return A handle to @p obj's underlying @c Ecore_Evas's canvas + */ +EAPI Evas *ecore_evas_object_evas_get(Evas_Object *obj); + +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(Ecore_Cocoa_Window *parent, + int x, + int y, + int w, + int h); + +EAPI Ecore_Evas *ecore_evas_psl1ght_new(const char* name, int w, int h); + + +/* generic manipulation calls */ +/** + * @brief Get the engine name used by this Ecore_Evas(window). + * + * @param ee Ecore_Evas whose engine's name is desired. + * @return A string that can(usually) be used in ecore_evas_new() + * + * @see ecore_evas_free() + */ +EAPI const char *ecore_evas_engine_name_get(const Ecore_Evas *ee); +/** + * @brief 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, or @c NULL if not held by one. + * + * @warning Only use on Evas' created with ecore evas! + */ +EAPI Ecore_Evas *ecore_evas_ecore_evas_get(const Evas *e); +/** + * @brief 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); +/** + * @brief 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 @c 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); +/** + * @brief 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_callback_pre_free_set() + * @see ecore_evas_free() + * @see ecore_evas_data_get() + */ +EAPI void ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data); +/** + * 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_show_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_hide_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_sticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_unsticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); +/** + * Set a callback for Ecore_Evas 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_pre_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_post_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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. + * + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_pre_free_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); +/** + * Set a callback for Ecore_Evas state changes. + * @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 changes state. + * + * @since 1.2 + * @warning If and when this function is called depends on the underlying + * windowing system. + */ +EAPI void ecore_evas_callback_state_change_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb 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); + +/** + * 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); + +/** + * Set whether an Ecore_Evas is shaped or not. + * + * @param ee The Ecore_Evas to shape. + * @param shaped @c EINA_TRUE to shape, @c EINA_FALSE to not. + * + * This function allows one to make an Ecore_Evas shaped to the contents of the + * evas. If @p shaped is @c EINA_TRUE, @p ee will be transparent in parts of + * the evas that contain no objects. If @p shaped is @c EINA_FALSE, then @p ee + * will be rectangular, and parts with no data will show random framebuffer + * artifacting. For non-shaped Ecore_Evases, it is recommended to cover the + * entire evas with a background object. + */ +EAPI void ecore_evas_shaped_set(Ecore_Evas *ee, Eina_Bool shaped); + +/** + * Query whether an Ecore_Evas is shaped or not. + * + * @param ee The Ecore_Evas to query. + * @return @c EINA_TRUE if shaped, @c EINA_FALSE if not. + * + * This function returns @c EINA_TRUE if @p ee is shaped, and @c EINA_FALSE if not. + */ +EAPI Eina_Bool ecore_evas_shaped_get(const Ecore_Evas *ee); +/** + * @brief 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); +/** + * @brief Hide an Ecore_Evas' window + * + * @param ee The Ecore_Evas to hide. + * + * This function makes @p ee hidden(not visible). + */ +EAPI void ecore_evas_hide(Ecore_Evas *ee); + +/** + * 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); + + +/** + * Set the minimum size of a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas window's handle + * @param w The minimum width + * @param h The minimum height + * + * This function sets the minimum size of @p ee to be @p w x @p h. + * One won't be able to resize that window to dimensions smaller than + * the ones set. + * + * @note When base sizes are set, via ecore_evas_size_base_set(), + * they'll be used to calculate a window's minimum size, instead of + * those set by this function. + * + * @see ecore_evas_size_min_get() + */ +EAPI void ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h); + +/** + * Get the minimum size set for a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas window's handle + * @param w A pointer to an int to place the minimum width in. + * @param h A pointer to an int to place the minimum height in. + * + * @note Use @c NULL pointers on the size components you're not + * interested in: they'll be ignored by the function. + * + * @see ecore_evas_size_min_set() for more details + */ +EAPI void ecore_evas_size_min_get(const Ecore_Evas *ee, int *w, int *h); + +/** + * Set the maximum size of a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas window's handle + * @param w The maximum width + * @param h The maximum height + * + * This function sets the maximum size of @p ee to be @p w x @p h. + * One won't be able to resize that window to dimensions bigger than + * the ones set. + * + * @see ecore_evas_size_max_get() + */ +EAPI void ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h); + +/** + * Get the maximum size set for a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas window's handle + * @param w A pointer to an int to place the maximum width in. + * @param h A pointer to an int to place the maximum height in. + * + * @note Use @c NULL pointers on the size components you're not + * interested in: they'll be ignored by the function. + * + * @see ecore_evas_size_max_set() for more details + */ +EAPI void ecore_evas_size_max_get(const Ecore_Evas *ee, int *w, int *h); + +/** + * Set the base size for a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas window's handle + * @param w The base width + * @param h The base height + * + * This function sets the @b base size of @p ee to be @p w x @p h. + * When base sizes are set, they'll be used to calculate a window's + * @b minimum size, instead of those set by ecore_evas_size_min_get(). + * + * @see ecore_evas_size_base_get() + */ +EAPI void ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h); + +/** + * Get the base size set for a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas window's handle + * @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. + * + * @note Use @c NULL pointers on the size components you're not + * interested in: they'll be ignored by the function. + * + * @see ecore_evas_size_base_set() for more details + */ +EAPI void ecore_evas_size_base_get(const Ecore_Evas *ee, int *w, int *h); + +/** + * Set the "size step" for a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas window's handle + * @param w The step width + * @param h The step height + * + * This function sets the size steps of @p ee to be @p w x @p h. This + * limits the size of this @c Ecore_Evas window to be @b always an + * integer multiple of the step size, for each axis. + */ +EAPI void ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h); + +/** + * Get the "size step" set for a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas window's handle + * @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. + * + * @note Use @c NULL pointers on the size components you're not + * interested in: they'll be ignored by the function. + * + * @see ecore_evas_size_base_set() for more details + */ +EAPI void ecore_evas_size_step_get(const Ecore_Evas *ee, int *w, int *h); + +/** + * @brief 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 The layer in which the cursor will appear. + * @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. + * + * @note This function creates an object from the image and uses + * ecore_evas_object_cursor_set(). + * + * @see ecore_evas_object_cursor_set() + */ +EAPI void ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y); +/** + * @brief 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. + * + * @see ecore_evas_cursor_set() + * @see ecore_evas_object_cursor_set() + */ +EAPI void ecore_evas_cursor_get(const Ecore_Evas *ee, Evas_Object **obj, int *layer, int *hot_x, int *hot_y); +/** + * @brief Set the cursor of an Ecore_Evas + * + * @param ee The Ecore_Evas + * + * @param obj The Evas_Object which will be the cursor. + * @param layer The layer in which the cursor will appear. + * @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 object specified by + * @p obj. The actual point within the object 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 object. + * + * @see ecore_evas_cursor_set() + */ +EAPI void ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y); + +/** + * Tell the WM whether or not to ignore an Ecore_Evas' window + * + * @param ee The Ecore_Evas. + * @param on @c EINA_TRUE to ignore, @c EINA_FALSE to not. + * + * This function causes the window manager to ignore @p ee if @p on is + * @c EINA_TRUE, or not ignore @p ee if @p on is @c EINA_FALSE. + */ +EAPI void ecore_evas_override_set(Ecore_Evas *ee, Eina_Bool on); + +/** + * Query whether an Ecore_Evas' window is overridden or not + * + * @param ee The Ecore_Evas to set. + * @return @c EINA_TRUE if @p ee is overridden, @c EINA_FALSE if not. + */ +EAPI Eina_Bool ecore_evas_override_get(const Ecore_Evas *ee); + +/** + * Set whether or not an Ecore_Evas' window should avoid damage + * + * @param ee The Ecore_Evas + * @param on The type of the damage management + * + * This option causes updates of the Ecore_Evas to be done on a pixmap, and + * then copied to the window, or the pixmap used directly on the window, + * depending on the setting. Possible options are: + * + * @li @ref ECORE_EVAS_AVOID_DAMAGE_NONE - every expose event triggers a new + * damage and consequently render of the affected area. The rendering of things + * happens directly on the window; + * + * @li @ref ECORE_EVAS_AVOID_DAMAGE_EXPOSE - there's a pixmap where everything + * is rendered into, and then copied to the window. On expose events, there's + * no need to render things again, just to copy the exposed region to the + * window; + * + * @li @ref ECORE_EVAS_AVOID_DAMAGE_BUILT_IN - there's the same pixmap as the + * previous one, but it is set as a "background pixmap" of the window. The + * rendered things appear directly on the window, with no need to copy + * anything, but would stay stored on the pixmap, so there's no need to render + * things again on expose events. This option can be faster than the previous + * one, but may lead to artifacts during resize of the window. + */ +EAPI void ecore_evas_avoid_damage_set(Ecore_Evas *ee, Ecore_Evas_Avoid_Damage_Type on); + +/** + * Query whether an Ecore_Evas' window avoids damage or not + * @param ee The Ecore_Evas to set + * @return The type of the damage management + * + */ +EAPI Ecore_Evas_Avoid_Damage_Type ecore_evas_avoid_damage_get(const Ecore_Evas *ee); + +/** + * 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, Eina_Bool withdrawn); + +/** + * 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 Eina_Bool ecore_evas_withdrawn_get(const Ecore_Evas *ee); + +/** + * 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, Eina_Bool sticky); + +/** + * 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 Eina_Bool ecore_evas_sticky_get(const Ecore_Evas *ee); +EAPI void ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool manual_render); +EAPI Eina_Bool ecore_evas_manual_render_get(const Ecore_Evas *ee); + +/** + * @brief Registers an @c Ecore_Evas to receive events through ecore_input_evas. + * + * @param ee The @c Ecore_Evas handle. + * + * This function calls ecore_event_window_register() with the @p ee as its @c + * id argument, @c window argument, and uses its @c Evas too. It is useful when + * no @c window information is available on a given @c Ecore_Evas backend. + * + * @see ecore_evas_input_event_unregister() + * @since 1.1 + */ +EAPI void ecore_evas_input_event_register(Ecore_Evas *ee); +/** + * @brief Unregisters an @c Ecore_Evas receiving events through ecore_input_evas. + * + * @param ee The @c Ecore_Evas handle. + * + * @see ecore_evas_input_event_register() + * @since 1.1 + */ +EAPI void ecore_evas_input_event_unregister(Ecore_Evas *ee); + +/** + * @brief Force immediate rendering on a given @c Ecore_Evas window + * + * @param ee An @c Ecore_Evas handle + * + * Use this call to forcefully flush the @p ee's canvas rendering + * pipeline, thus bring its window to an up to date state. + */ +EAPI void ecore_evas_manual_render(Ecore_Evas *ee); +EAPI void ecore_evas_comp_sync_set(Ecore_Evas *ee, Eina_Bool do_sync); +EAPI Eina_Bool ecore_evas_comp_sync_get(const Ecore_Evas *ee); + +/** + * @brief Get geometry of screen associated with this Ecore_Evas. + * + * @param ee The Ecore_Evas whose window's to query container screen geometry. + * @param x where to return the horizontal offset value. May be @c NULL. + * @param y where to return the vertical offset value. May be @c NULL. + * @param w where to return the width value. May be @c NULL. + * @param h where to return the height value. May be @c NULL. + * + * @since 1.1 + */ +EAPI void ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); + +/** + * @brief Get the dpi of the screen the Ecore_Evas is primarily on. + * + * @param ee The Ecore_Evas whose window's to query. + * @param xdpi Pointer to integer to store horizontal DPI. May be @c NULL. + * @param ydpi Pointer to integer to store vertical DPI. May be @c NULL. + * + * @since 1.7 + */ +EAPI void ecore_evas_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi); + +EAPI void ecore_evas_draw_frame_set(Ecore_Evas *ee, Eina_Bool draw_frame); +EAPI Eina_Bool ecore_evas_draw_frame_get(const Ecore_Evas *ee); + +/** + * @brief Associate the given object to this ecore evas. + * + * @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 @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * 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: + * @li ECORE_EVAS_OBJECT_ASSOCIATE_BASE (or 0): to listen to basic events + * like delete, resize and move, but no stacking or layer are used. + * @li 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. + * @li 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(). + * @li 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. + */ +EAPI Eina_Bool ecore_evas_object_associate(Ecore_Evas *ee, Evas_Object *obj, Ecore_Evas_Object_Associate_Flags flags); +/** + * @brief 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 @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ecore_evas_object_dissociate(Ecore_Evas *ee, Evas_Object *obj); +/** + * @brief Get the object associated with @p ee + * + * @param ee The Ecore_Evas to get the object from. + * @return The associated object, or @c NULL if there is no associated object. + */ +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); + +/** + * @brief Get a list of all the ecore_evases. + * + * @return A list of ecore_evases. + * + * The returned list of ecore evases is only valid until the canvases are + * destroyed (and should not be cached for instance). The list can be freed by + * just deleting the list. + */ +EAPI Eina_List *ecore_evas_ecore_evas_list_get(void); + +/* specific calls to an x11 environment ecore_evas */ +EAPI void ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win); +EAPI Ecore_X_Window ecore_evas_x11_leader_get(Ecore_Evas *ee); +EAPI void ecore_evas_x11_leader_default_set(Ecore_Evas *ee); +EAPI void ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h); +EAPI void ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas *ee, int x, int y, int w, int h); +EAPI void ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas *ee, int x, int y, int w, int h); +EAPI void ecore_evas_x11_shape_input_empty(Ecore_Evas *ee); +EAPI void ecore_evas_x11_shape_input_reset(Ecore_Evas *ee); +EAPI void ecore_evas_x11_shape_input_apply(Ecore_Evas *ee); + +/** + * @defgroup Ecore_Evas_Ews Ecore_Evas Single Process Windowing System. + * + * These are global scope functions to manage the EWS to be used by + * ecore_evas_ews_new(). + * + * @since 1.1 + * @{ + */ + +/** + * Sets the engine to be used by the backing store engine. + * + * @param engine The engine to be set. + * @param options The options of the engine to be set. + * @return @c EINA_TRUE on success, @c EINA_FALSE if ews is already in use. + * @since 1.1 + */ +EAPI Eina_Bool ecore_evas_ews_engine_set(const char *engine, const char *options); + +/** + * Reconfigure the backing store used. + * + * @param x The X coordinate to be used. + * @param y The Y coordinate to be used. + * @param w The width of the Ecore_Evas to setup. + * @param h The height of the Ecore_Evas to setup. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * @since 1.1 + */ +EAPI Eina_Bool ecore_evas_ews_setup(int x, int y, int w, int h); + +/** + * Return the internal backing store in use. + * + * @return The internal backing store in use. + * @note this will forced it to be created, making future calls to + * ecore_evas_ews_engine_set() void. + * + * @see ecore_evas_ews_evas_get() + * @since 1.1 + */ +EAPI Ecore_Evas *ecore_evas_ews_ecore_evas_get(void); + +/** + * Return the internal backing store in use. + * + * @return The internal backing store in use. + * @note this will forced it to be created, making future calls to + * ecore_evas_ews_engine_set() void. + * + * @see ecore_evas_ews_ecore_evas_get() + * @since 1.1 + */ +EAPI Evas *ecore_evas_ews_evas_get(void); + +/** + * Get the current background. + */ +EAPI Evas_Object *ecore_evas_ews_background_get(void); + +/** + * Set the current background, must be created at evas ecore_evas_ews_evas_get() + * + * It will be kept at lowest layer (EVAS_LAYER_MIN) and below + * everything else. You can set any object, default is a black + * rectangle. + * + * @note previous object will be deleted! + * @param o The Evas_Object for which to set the background. + */ +EAPI void ecore_evas_ews_background_set(Evas_Object *o); + +/** + * Return all Ecore_Evas* created by EWS. + * + * @return An eina list of Ecore_evases. + e @note Do not change the returned list or its contents. + * @since 1.1 + */ +EAPI const Eina_List *ecore_evas_ews_children_get(void); + +/** + * Set the identifier of the manager taking care of internal windows. + * + * The ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE event is issued. Consider + * handling it to know if you should stop handling events yourself + * (ie: another manager took over) + * + * @param manager any unique identifier address. + * + * @see ecore_evas_ews_manager_get() + * @since 1.1 + */ +EAPI void ecore_evas_ews_manager_set(const void *manager); + +/** + * Get the identifier of the manager taking care of internal windows. + * + * @return the value set by ecore_evas_ews_manager_set() + * @since 1.1 + */ +EAPI const void *ecore_evas_ews_manager_get(void); + +EAPI extern int ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE; /**< manager was changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_ADD; /**< window was created @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_DEL; /**< window was deleted, pointer is already invalid but may be used as reference for further cleanup work. @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_RESIZE; /**< window was resized @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_MOVE; /**< window was moved @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_SHOW; /**< window become visible @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_HIDE; /**< window become hidden @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_FOCUS; /**< window was focused @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_UNFOCUS; /**< window lost focus @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_RAISE; /**< window was raised @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_LOWER; /**< window was lowered @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_ACTIVATE; /**< window was activated @since 1.1 */ + +EAPI extern int ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE; /**< window minimized/iconified changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE; /**< window maximized changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_LAYER_CHANGE; /**< window layer changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE; /**< window fullscreen changed @since 1.1 */ +EAPI extern int ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE; /**< some other window property changed (title, name, class, alpha, transparent, shaped...) @since 1.1 */ + +/** + * @} + */ + +/** + * @defgroup Ecore_Evas_Extn External plug/socket infrastructure to remote canvases + * + * These functions allow 1 process to create a "socket" was pluged into which another + * process can create a "plug" remotely to plug into. + * Socket can provides content for several plugs. + * This is best for small sized objects (about the size range + * of a small icon up to a few large icons). Sine the plug is actually an + * image object, you can fetch the pixel data + * + * @since 1.2 + * @{ + */ + +EAPI extern int ECORE_EVAS_EXTN_CLIENT_ADD; /**< this event is received when a plug has connected to an extn socket @since 1.2 */ +EAPI extern int ECORE_EVAS_EXTN_CLIENT_DEL; /**< this event is received when a plug has disconnected from an extn socket @since 1.2 */ + +/** + * @brief Create a new Ecore_Evas canvas for the new external ecore evas socket + * + * @param w The width of the canvas, in pixels + * @param h The height of the canvas, in pixels + * @return A new @c Ecore_Evas instance or @c NULL, on failure + * + * This creates a new extn_socket canvas wrapper, with image data array + * @b bound to the ARGB format, 8 bits per pixel. + * + * If creation is successful, an Ecore_Evas handle is returned or @c NULL if + * creation fails. Also focus, show, hide etc. callbacks will also be called + * if the plug object is shown, or already visible on connect, or if it is + * hidden later, focused or unfocused. + * + * This function has to be flowed by ecore_evas_extn_socket_listen(), + * for starting ecore ipc service. + * + * @code + * Eina_Bool res = EINA_FALSE; + * Ecore_Evas *ee = ecore_evas_extn_socket_new(1, 1); + * + * res = ecore_evas_extn_socket_listen("svcname", 1, EINA_FALSE); + * if (!res) return; + * ecore_evas_resize(ee, 240, 400); + * @endcode + * + * or + * + * @code + * Eina_Bool res = EINA_FALSE; + * Ecore_Evas *ee = ecore_evas_extn_socket_new(240, 400); + * + * res = ecore_evas_extn_socket_listen("svcname", 1, EINA_FALSE); + * if (!res) return; + * @endcode + * + * When a client(plug) connects, you will get the ECORE_EVAS_EXTN_CLIENT_ADD event + * in the ecore event queue, with event_info being the image object pointer + * passed as a void pointer. When a client disconnects you will get the + * ECORE_EVAS_EXTN_CLIENT_DEL event. + * + * You can set up event handles for these events as follows: + * + * @code + * static void client_add_cb(void *data, int event, void *event_info) + * { + * Evas_Object *obj = event_info; + * printf("client added to image object %p\n", obj); + * evas_object_show(obj); + * } + * + * static void client_del_cb(void *data, int event, void *event_info) + * { + * Evas_Object *obj = event_info; + * printf("client deleted from image object %p\n", obj); + * evas_object_hide(obj); + * } + * + * void setup(void) + * { + * ecore_event_handler_add(ECORE_EVAS_EXTN_CLIENT_ADD, + * client_add_cb, NULL); + * ecore_event_handler_add(ECORE_EVAS_EXTN_CLIENT_DEL, + * client_del_cb, NULL); + * } + * @endcode + * + * Note that events come in later after the event happened. You may want to be + * careful as data structures you had associated with the image object + * may have been freed after deleting, but the object may still be around + * awating cleanup and thus still be valid.You can change the size with something like: + * + * @see ecore_evas_extn_socket_listen() + * @see ecore_evas_extn_plug_new() + * @see ecore_evas_extn_plug_object_data_lock() + * @see ecore_evas_extn_plug_object_data_unlock() + * + * @since 1.2 + */ +EAPI Ecore_Evas *ecore_evas_extn_socket_new(int w, int h); + +/** + * @brief Create a socket to provide the service for external ecore evas + * socket. + * + * @param ee The Ecore_Evas. + * @param svcname The name of the service to be advertised. ensure that it is + * unique (when combined with @p svcnum) otherwise creation may fail. + * @param svcnum A number (any value, @c 0 being the common default) to + * differentiate multiple instances of services with the same name. + * @param svcsys A boolean that if true, specifies to create a system-wide + * service all users can connect to, otherwise the service is private to the + * user ide that created the service. + * @return @c EINA_TRUE if creation is successful, @c EINA_FALSE if it does + * not. + * + * This creates socket specified by @p svcname, @p svcnum and @p svcsys. If + * creation is successful, @c EINA_TRUE is returned or @c EINA_FALSE if + * creation fails. + * + * @see ecore_evas_extn_socket_new() + * @see ecore_evas_extn_plug_new() + * @see ecore_evas_extn_plug_object_data_lock() + * @see ecore_evas_extn_plug_object_data_unlock() + * + * @since 1.2 + */ +EAPI Eina_Bool ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys); + +/** + * @brief Lock the pixel data so the socket cannot change it + * + * @param obj The image object returned by ecore_evas_extn_plug_new() to lock + * + * You may need to get the image pixel data with evas_object_image_data_get() + * from the image object, but need to ensure that it does not change while + * you are using the data. This function lets you set an advisory lock on the + * image data so the external plug process will not render to it or alter it. + * + * You should only hold the lock for just as long as you need to read out the + * image data or otherwise deal with it, and then unlock it with + * ecore_evas_extn_plug_object_data_unlock(). Keeping a lock over more than + * 1 iteration of the main ecore loop will be problematic, so avoid it. Also + * forgetting to unlock may cause the socket process to freeze and thus create + * odd behavior. + * + * @see ecore_evas_extn_plug_new() + * @see ecore_evas_extn_plug_object_data_unlock() + * + * @since 1.2 + */ +EAPI void ecore_evas_extn_plug_object_data_lock(Evas_Object *obj); + +/** + * @brief Unlock the pixel data so the socket can change it again. + * + * @param obj The image object returned by ecore_evas_extn_plug_new() to unlock + * + * This unlocks after an advisor lock has been taken by + * ecore_evas_extn_plug_object_data_lock(). + * + * @see ecore_evas_extn_plug_new() + * @see ecore_evas_extn_plug_object_data_lock() + * + * @since 1.2 + */ +EAPI void ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj); + +/** + * @brief Create a new external ecore evas plug + * + * @param ee_target The Ecore_Evas containing the canvas in which the new image object will live. + * @return An evas image object that will contain the image output of a socket. + * + * This creates an image object that will contain the output of another + * processes socket canvas when it connects. All input will be sent back to + * this process as well, effectively swallowing or placing the socket process + * in the canvas of the plug process in place of the image object. The image + * object by default is created to be filled (equivalent of + * evas_object_image_filled_add() on creation) so image content will scale + * to fill the image unless otherwise reconfigured. The Ecore_Evas size + * of the plug is the master size and determines size in pixels of the + * plug canvas. You can change the size with something like: + * + * @code + * Eina_Bool res = EINA_FALSE; + * Evas_Object *obj = ecore_evas_extn_plug_new(ee); + * + * res = ecore_evas_extn_plug_connect("svcname", 1, EINA_FALSE); + * if (!res) return; + * ecore_evas_resize(ee, 240, 400); + * @endcode + * + * @see ecore_evas_extn_socket_new() + * @see ecore_evas_extn_plug_connect() + * @since 1.2 + */ +EAPI Evas_Object *ecore_evas_extn_plug_new(Ecore_Evas *ee_target); + +/** + * @brief Connect an external ecore evas plug to service provided by external + * ecore evas socket. + * + * @param obj The Ecore_Evas containing the canvas in which the new image + * object will live. + * @param svcname The service name to connect to set up by the socket. + * @param svcnum The service number to connect to (set up by socket). + * @param svcsys Boolean to set if the service is a system one or not (set up + * by socket). + * @return @c EINA_TRUE if creation is successful, @c EINA_FALSE if it does + * not. + * + * @see ecore_evas_extn_plug_new() + * + * @since 1.2 + */ +EAPI Eina_Bool ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c new file mode 100644 index 0000000000..3d841e7db6 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas.c @@ -0,0 +1,2781 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef _MSC_VER +# include +#endif + +#ifdef HAVE_SYS_MMAN_H +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Input.h" + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +Eina_Bool _ecore_evas_app_comp_sync = 1; +int _ecore_evas_log_dom = -1; +static int _ecore_evas_init_count = 0; +static Ecore_Fd_Handler *_ecore_evas_async_events_fd = NULL; +static Eina_Bool _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 Eina_Bool +_ecore_evas_idle_enter(void *data EINA_UNUSED) +{ + Ecore_Evas *ee; + double t1 = 0.0; + double t2 = 0.0; + int rend = 0; + + if (!ecore_evases) return ECORE_CALLBACK_RENEW; + 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 ECORE_CALLBACK_RENEW; +} + +/** + * Query if a particular rendering engine target has support + * @param engine The engine to check support for + * @return 1 if the particular 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 EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_SOFTWARE_XLIB: +#ifdef BUILD_ECORE_EVAS_SOFTWARE_XLIB + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_XRENDER_X11: + return EINA_FALSE; + case ECORE_EVAS_ENGINE_OPENGL_X11: +#ifdef BUILD_ECORE_EVAS_OPENGL_X11 + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_SOFTWARE_XCB: +#ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_XRENDER_XCB: + return EINA_FALSE; + case ECORE_EVAS_ENGINE_SOFTWARE_GDI: +#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_SOFTWARE_DDRAW: +#ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_DIRECT3D: +#ifdef BUILD_ECORE_EVAS_DIRECT3D + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_OPENGL_GLEW: +#ifdef BUILD_ECORE_EVAS_OPENGL_GLEW + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_SOFTWARE_SDL: +#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_OPENGL_SDL: +#ifdef BUILD_ECORE_EVAS_OPENGL_SDL + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_DIRECTFB: +#ifdef BUILD_ECORE_EVAS_DIRECTFB + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_SOFTWARE_FB: +#ifdef BUILD_ECORE_EVAS_FB + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + + case ECORE_EVAS_ENGINE_SOFTWARE_8_X11: +#ifdef BUILD_ECORE_EVAS_SOFTWARE_8_X11 + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + + case ECORE_EVAS_ENGINE_SOFTWARE_16_X11: + return EINA_FALSE; + case ECORE_EVAS_ENGINE_SOFTWARE_16_DDRAW: + return EINA_FALSE; + case ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE: + return EINA_FALSE; + + case ECORE_EVAS_ENGINE_OPENGL_COCOA: +#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_EWS: +#ifdef BUILD_ECORE_EVAS_EWS + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_PSL1GHT: +#ifdef BUILD_ECORE_EVAS_PSL1GHT + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_WAYLAND_SHM: +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + case ECORE_EVAS_ENGINE_WAYLAND_EGL: +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL + return EINA_TRUE; +#else + return EINA_FALSE; +#endif + default: + return EINA_FALSE; + }; +} + +static void +_ecore_evas_fork_cb(void *data EINA_UNUSED) +{ + int fd; + + if (_ecore_evas_async_events_fd) + ecore_main_fd_handler_del(_ecore_evas_async_events_fd); + 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); +} + +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; + } + + ecore_fork_reset_callback_add(_ecore_evas_fork_cb, NULL); + 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(); + +#ifdef BUILD_ECORE_EVAS_EWS + _ecore_evas_ews_events_init(); +#endif + + _ecore_evas_extn_init(); + + if (getenv("ECORE_EVAS_COMP_NOSYNC")) + _ecore_evas_app_comp_sync = 0; + return _ecore_evas_init_count; + + shutdown_ecore: + ecore_shutdown(); + shutdown_evas: + evas_shutdown(); + + return --_ecore_evas_init_count; +} + +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); + + _ecore_evas_extn_shutdown(); + + 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_EWS + while (_ecore_evas_ews_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 + + if (_ecore_evas_async_events_fd) + ecore_main_fd_handler_del(_ecore_evas_async_events_fd); + + ecore_fork_reset_callback_del(_ecore_evas_fork_cb, NULL); + + eina_log_domain_unregister(_ecore_evas_log_dom); + _ecore_evas_log_dom = -1; + ecore_shutdown(); + evas_shutdown(); + + return _ecore_evas_init_count; +} + +EAPI void +ecore_evas_app_comp_sync_set(Eina_Bool do_sync) +{ + _ecore_evas_app_comp_sync = do_sync; +} + +EAPI Eina_Bool +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_OPENGL_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(NULL, x, y, w, h); + free(name); + + if (ee) ecore_evas_move(ee, x, y); + 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_8_X11 +static Ecore_Evas * +_ecore_evas_constructor_software_8_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_8_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 EINA_UNUSED, int y EINA_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, "noframe=", &noframe); + _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; +} +#endif + +#ifdef BUILD_ECORE_EVAS_OPENGL_SDL +static Ecore_Evas * +_ecore_evas_constructor_opengl_sdl(int x EINA_UNUSED, int y EINA_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 EINA_UNUSED, int y EINA_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_PSL1GHT +static Ecore_Evas * +_ecore_evas_constructor_psl1ght(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options) +{ + Ecore_Evas *ee; + char *name = NULL; + + _ecore_evas_parse_extra_options_str(extra_options, "name=", &name); + ee = ecore_evas_psl1ght_new(name, w, h); + free(name); + + if (ee) ecore_evas_move(ee, x, y); + return ee; +} +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +static Ecore_Evas * +_ecore_evas_constructor_wayland_shm(int x, int y, int w, int h, const char *extra_options) +{ + char *disp_name = NULL; + unsigned int frame = 1, parent = 0; + Ecore_Evas *ee; + + _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name); + _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame); + _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent); + ee = ecore_evas_wayland_shm_new(disp_name, parent, x, y, w, h, frame); + free(disp_name); + + return ee; +} +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +static Ecore_Evas * +_ecore_evas_constructor_wayland_egl(int x, int y, int w, int h, const char *extra_options) +{ + char *disp_name = NULL; + unsigned int frame = 1, parent = 0; + Ecore_Evas *ee; + + _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name); + _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame); + _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent); + ee = ecore_evas_wayland_egl_new(disp_name, parent, x, y, w, h, frame); + 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_BUFFER +static Ecore_Evas * +_ecore_evas_constructor_buffer(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options EINA_UNUSED) +{ + return ecore_evas_buffer_new(w, h); +} +#endif + +#ifdef BUILD_ECORE_EVAS_EWS +static Ecore_Evas * +_ecore_evas_constructor_ews(int x, int y, int w, int h, const char *extra_options EINA_UNUSED) +{ + return ecore_evas_ews_new(x, y, 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_OPENGL_X11 + {"opengl_x11", _ecore_evas_constructor_opengl_x11}, +#endif +#ifdef BUILD_ECORE_EVAS_SOFTWARE_8_X11 + {"software_8_x11", _ecore_evas_constructor_software_8_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 + + /* Apple */ +#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA + {"opengl_cocoa", _ecore_evas_constructor_cocoa}, +#endif + + /* PS3 support */ +#ifdef BUILD_ECORE_EVAS_PSL1GHT + {"psl1ght", _ecore_evas_constructor_psl1ght}, +#endif + + /* Wayland */ +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM + {"wayland_shm", _ecore_evas_constructor_wayland_shm}, +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL + {"wayland_egl", _ecore_evas_constructor_wayland_egl}, +#endif + + /* Last chance to have a window */ +#ifdef BUILD_ECORE_EVAS_OPENGL_SDL + {"opengl_sdl", _ecore_evas_constructor_opengl_sdl}, +#endif + +#ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL + {"sdl", _ecore_evas_constructor_sdl}, +#endif + + /* independent */ +#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER + {"buffer", _ecore_evas_constructor_buffer}, +#endif + +#ifdef BUILD_ECORE_EVAS_EWS + {"ews", _ecore_evas_constructor_ews}, +#endif + {NULL, NULL} +}; + +EAPI Eina_List * +ecore_evas_engines_get(void) +{ + const struct ecore_evas_engine *itr; + Eina_List *lst = NULL; + + for (itr = _engines; itr->name; itr++) + lst = eina_list_append(lst, itr->name); + + return lst; +} + +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; 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; +} + +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; 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; +} + +EAPI const char * +ecore_evas_engine_name_get(const Ecore_Evas *ee) +{ + if (!ee) + return NULL; + return ee->driver; +} + +EAPI Ecore_Evas * +ecore_evas_ecore_evas_get(const Evas *e) +{ + Ecore_Evas *ee = evas_data_attach_get(e); + if (!ee) return NULL; + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_ecore_evas_get"); + return NULL; + } + return ee; +} + +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; +} + +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); +} + +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;} + +EAPI void +ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_show_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_hide_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_sticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_unsticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_pre_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_post_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_pre_free_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + 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; +} + +EAPI void +ecore_evas_callback_state_change_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_state_change_set"); + return; + } + ee->func.fn_state_change = func; +} + +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; +} + +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; +} + +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; +} + +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; + } +} + +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; + } +} + +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; + } +} + +EAPI void +ecore_evas_request_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_request_geometry_get"); + return; + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + if (x) *x = ee->req.x; + if (y) *y = ee->req.y; + if (w) *w = ee->req.h; + if (h) *h = ee->req.w; + } + else + { + if (x) *x = ee->req.x; + if (y) *y = ee->req.y; + if (w) *w = ee->req.w; + if (h) *h = ee->req.h; + } +} + +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; +} + +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; +} + +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; +} + +EAPI void +ecore_evas_shaped_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->shaped ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_alpha_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->alpha ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_transparent_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->transparent ? EINA_TRUE : 0; +} + +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; +} + +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; +} + + 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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; + } +} + +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; + } +} + +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; + } +} + +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; + } +} + +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; + } +} + +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; + } +} + +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; + } +} + +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; + } +} + +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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +EAPI void +ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->prop.focused ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_iconified_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->prop.iconified ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_borderless_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->prop.borderless ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_override_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->prop.override ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_maximized_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->prop.maximized ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->prop.fullscreen ? EINA_TRUE : EINA_FALSE; +} + +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; +} + +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 ECORE_EVAS_AVOID_DAMAGE_NONE; + } + return ee->prop.avoid_damage; +} + +EAPI void +ecore_evas_withdrawn_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->prop.withdrawn ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_sticky_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->prop.sticky ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_window_group_set(Ecore_Evas *ee, const Ecore_Evas *ee_group) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return; + } + + IFC(ee, fn_window_group_set) (ee, ee_group); + IFE; +} + +EAPI const Ecore_Evas * +ecore_evas_window_group_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return EINA_FALSE; + } + return ee->prop.group_ee; +} + +EAPI void +ecore_evas_aspect_set(Ecore_Evas *ee, double aspect) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return; + } + + IFC(ee, fn_aspect_set) (ee, aspect); + IFE; +} + +EAPI double +ecore_evas_aspect_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return EINA_FALSE; + } + return ee->prop.aspect; +} + +EAPI void +ecore_evas_urgent_set(Ecore_Evas *ee, Eina_Bool urgent) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return; + } + + IFC(ee, fn_urgent_set) (ee, urgent); + IFE; +} + +EAPI Eina_Bool +ecore_evas_urgent_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return EINA_FALSE; + } + return ee->prop.urgent ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_modal_set(Ecore_Evas *ee, Eina_Bool modal) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return; + } + + IFC(ee, fn_modal_set) (ee, modal); + IFE; +} + +EAPI Eina_Bool +ecore_evas_modal_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return EINA_FALSE; + } + return ee->prop.modal ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_demand_attention_set(Ecore_Evas *ee, Eina_Bool demand) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return; + } + + IFC(ee, fn_demands_attention_set) (ee, demand); + IFE; +} + +EAPI Eina_Bool +ecore_evas_demand_attention_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return EINA_FALSE; + } + return ee->prop.demand_attention ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_focus_skip_set(Ecore_Evas *ee, Eina_Bool skip) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return; + } + + IFC(ee, fn_focus_skip_set) (ee, skip); + IFE; +} + +EAPI Eina_Bool +ecore_evas_focus_skip_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "XXX"); + return EINA_FALSE; + } + return ee->prop.focus_skip ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_ignore_events_set(Ecore_Evas *ee, Eina_Bool 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + return ee->ignore_events ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool 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 Eina_Bool +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 EINA_FALSE; + } + return ee->manual_render ? EINA_TRUE : EINA_FALSE; +} + +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, Eina_Bool 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 Eina_Bool +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 EINA_FALSE; + } + 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; +} + +EAPI void +ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h) +{ + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_screen_geometry_get"); + return; + } + + IFC(ee, fn_screen_geometry_get) (ee, x, y, w, h); + IFE; +} + +EAPI void +ecore_evas_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi) +{ + if (xdpi) *xdpi = 0; + if (ydpi) *ydpi = 0; + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_screen_geometry_get"); + return; + } + + IFC(ee, fn_screen_dpi_get) (ee, xdpi, ydpi); + IFE; +} + +EAPI void +ecore_evas_draw_frame_set(Ecore_Evas *ee, Eina_Bool draw_frame) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_draw_frame_set"); + return; + } + ee->prop.draw_frame = draw_frame; +} + +EAPI Eina_Bool +ecore_evas_draw_frame_get(const Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_draw_frame_get"); + return EINA_FALSE; + } + return ee->prop.draw_frame; +} + +/* 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]; + const char *tmp; + + _ecore_evas_fps_debug_init_count++; + if (_ecore_evas_fps_debug_init_count > 1) return; + +#ifndef HAVE_EVIL + tmp = "/tmp"; +#else + tmp = evil_tmpdir_get (); +#endif /* HAVE_EVIL */ + snprintf(buf, sizeof(buf), "%s/.ecore_evas_fps_debug-%i", tmp, (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 *buf2 = (char *)&zero; + ssize_t todo = sizeof(unsigned int); + + while (todo > 0) + { + ssize_t r = write(_ecore_evas_fps_debug_fd, buf2, todo); + if (r > 0) + { + todo -= r; + buf2 += 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_ref(Ecore_Evas *ee) +{ + ee->refcount++; +} + +void +_ecore_evas_unref(Ecore_Evas *ee) +{ + ee->refcount--; + if (ee->refcount == 0) + { + if (ee->deleted) _ecore_evas_free(ee); + } + else if (ee->refcount < -1) + ERR("Ecore_Evas %p->refcount=%d < 0", ee, ee->refcount); +} + +void +_ecore_evas_free(Ecore_Evas *ee) +{ + ee->deleted = EINA_TRUE; + if (ee->refcount > 0) return; + + if (ee->func.fn_pre_free) ee->func.fn_pre_free(ee); + while (ee->sub_ecore_evas) + { + _ecore_evas_free(ee->sub_ecore_evas->data); + } + if (ee->data) eina_hash_free(ee->data); + ee->data = NULL; + if (ee->name) free(ee->name); + ee->name = NULL; + if (ee->prop.title) free(ee->prop.title); + ee->prop.title = NULL; + if (ee->prop.name) free(ee->prop.name); + ee->prop.name = NULL; + if (ee->prop.clas) free(ee->prop.clas); + ee->prop.clas = NULL; + if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); + ee->prop.cursor.object = NULL; + if (ee->evas) evas_free(ee->evas); + ee->evas = NULL; + ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE); + ee->driver = 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 Eina_Bool +_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 ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_ecore_evas_async_events_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + evas_async_events_process(); + + return ECORE_CALLBACK_RENEW; +} + +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) + { + int fx, fy; + evas_output_framespace_get(ee->evas, &fx, &fy, NULL, NULL); + evas_object_show(ee->prop.cursor.object); + if (ee->rotation == 0) + evas_object_move(ee->prop.cursor.object, + x - fx - ee->prop.cursor.hot.x, + y - fy - ee->prop.cursor.hot.y); + else if (ee->rotation == 90) + evas_object_move(ee->prop.cursor.object, + ee->h - y - fx - 1 - ee->prop.cursor.hot.x, + x - fy - ee->prop.cursor.hot.y); + else if (ee->rotation == 180) + evas_object_move(ee->prop.cursor.object, + ee->w - x - fx - 1 - ee->prop.cursor.hot.x, + ee->h - y - fy - 1 - ee->prop.cursor.hot.y); + else if (ee->rotation == 270) + evas_object_move(ee->prop.cursor.object, + y - fx - ee->prop.cursor.hot.x, + ee->w - x - fy - 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); +} + +void +_ecore_evas_mouse_multi_move_process(Ecore_Evas *ee, int device, + int x, int y, + double radius, + double radius_x, double radius_y, + double pressure, + double angle, + double mx, double my, + unsigned int timestamp) +{ + if (ee->rotation == 0) + evas_event_feed_multi_move(ee->evas, device, + x, y, + radius, + radius_x, radius_y, + pressure, + angle - ee->rotation, + mx, my, + timestamp, NULL); + else if (ee->rotation == 90) + evas_event_feed_multi_move(ee->evas, device, + ee->h - y - 1, x, + radius, + radius_y, radius_x, + pressure, + angle - ee->rotation, + ee->h - my - 1, mx, + timestamp, NULL); + else if (ee->rotation == 180) + evas_event_feed_multi_move(ee->evas, device, + ee->w - x - 1, ee->h - y - 1, + radius, + radius_x, radius_y, + pressure, + angle - ee->rotation, + ee->w - mx - 1, ee->h - my - 1, + timestamp, NULL); + else if (ee->rotation == 270) + evas_event_feed_multi_move(ee->evas, device, + y, ee->w - x - 1, + radius, + radius_y, radius_x, + pressure, + angle - ee->rotation, + my, ee->w - mx - 1, + timestamp, NULL); +} + +void +_ecore_evas_mouse_multi_down_process(Ecore_Evas *ee, int device, + int x, int y, + double radius, + double radius_x, double radius_y, + double pressure, + double angle, + double mx, double my, + Evas_Button_Flags flags, + unsigned int timestamp) +{ + if (ee->rotation == 0) + evas_event_feed_multi_down(ee->evas, device, + x, y, + radius, + radius_x, radius_y, + pressure, + angle - ee->rotation, + mx, my, + flags, timestamp, NULL); + else if (ee->rotation == 90) + evas_event_feed_multi_down(ee->evas, device, + ee->h - y - 1, x, + radius, + radius_y, radius_x, + pressure, + angle - ee->rotation, + ee->h - my - 1, mx, + flags, timestamp, NULL); + else if (ee->rotation == 180) + evas_event_feed_multi_down(ee->evas, device, + ee->w - x - 1, ee->h - y - 1, + radius, + radius_x, radius_y, + pressure, + angle - ee->rotation, + ee->w - mx - 1, ee->h - my - 1, + flags, timestamp, NULL); + else if (ee->rotation == 270) + evas_event_feed_multi_down(ee->evas, device, + y, ee->w - x - 1, + radius, + radius_y, radius_x, + pressure, + angle - ee->rotation, + my, ee->w - mx - 1, + flags, timestamp, NULL); +} + +void +_ecore_evas_mouse_multi_up_process(Ecore_Evas *ee, int device, + int x, int y, + double radius, + double radius_x, double radius_y, + double pressure, + double angle, + double mx, double my, + Evas_Button_Flags flags, + unsigned int timestamp) +{ + if (ee->rotation == 0) + evas_event_feed_multi_up(ee->evas, device, + x, y, + radius, + radius_x, radius_y, + pressure, + angle - ee->rotation, + mx, my, + flags, timestamp, NULL); + else if (ee->rotation == 90) + evas_event_feed_multi_up(ee->evas, device, + ee->h - y - 1, x, + radius, + radius_y, radius_x, + pressure, + angle - ee->rotation, + ee->h - my - 1, mx, + flags, timestamp, NULL); + else if (ee->rotation == 180) + evas_event_feed_multi_up(ee->evas, device, + ee->w - x - 1, ee->h - y - 1, + radius, + radius_x, radius_y, + pressure, + angle - ee->rotation, + ee->w - mx - 1, ee->h - my - 1, + flags, timestamp, NULL); + else if (ee->rotation == 270) + evas_event_feed_multi_up(ee->evas, device, + y, ee->w - x - 1, + radius, + radius_y, radius_x, + pressure, + angle - ee->rotation, + my, ee->w - mx - 1, + flags, timestamp, NULL); +} + +EAPI Eina_List * +ecore_evas_ecore_evas_list_get(void) +{ + Ecore_Evas *ee; + Eina_List *l = NULL; + + EINA_INLIST_FOREACH(ecore_evases, ee) + { + l = eina_list_append(l, ee); + } + + return l; +} + +EAPI void +ecore_evas_input_event_register(Ecore_Evas *ee) +{ + ecore_event_window_register((Ecore_Window)ee, ee, ee->evas, + (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); +} + +EAPI void +ecore_evas_input_event_unregister(Ecore_Evas *ee) +{ + ecore_event_window_unregister((Ecore_Window)ee); +} + +#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined (BUILD_ECORE_EVAS_WAYLAND_EGL) +EAPI void +ecore_evas_wayland_resize(Ecore_Evas *ee, int location) +{ + if (!ee) return; + if (!strcmp(ee->driver, "wayland_shm")) + { +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM + _ecore_evas_wayland_shm_resize(ee, location); +#endif + } + else if (!strcmp(ee->driver, "wayland_egl")) + { +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL + _ecore_evas_wayland_egl_resize(ee, location); +#endif + } +} + +EAPI void +ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y) +{ + if (!ee) return; + if (!strncmp(ee->driver, "wayland", 7)) + { + if (ee->engine.wl.win) + { + ee->engine.wl.win->moving = EINA_TRUE; + ecore_wl_window_move(ee->engine.wl.win, x, y); + } + } +} + +EAPI void +ecore_evas_wayland_type_set(Ecore_Evas *ee, int type) +{ + if (!ee) return; + ecore_wl_window_type_set(ee->engine.wl.win, type); +} + +EAPI Ecore_Wl_Window * +ecore_evas_wayland_window_get(const Ecore_Evas *ee) +{ + if (!(!strncmp(ee->driver, "wayland", 7))) + return NULL; + + return ee->engine.wl.win; +} + +EAPI void +ecore_evas_wayland_pointer_set(Ecore_Evas *ee EINA_UNUSED, int hot_x EINA_UNUSED, int hot_y EINA_UNUSED) +{ + +} + +#else +EAPI void +ecore_evas_wayland_resize(Ecore_Evas *ee EINA_UNUSED, int location EINA_UNUSED) +{ + +} + +EAPI void +ecore_evas_wayland_move(Ecore_Evas *ee EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED) +{ + +} + +EAPI void +ecore_evas_wayland_type_set(Ecore_Evas *ee EINA_UNUSED, int type EINA_UNUSED) +{ + +} + +EAPI Ecore_Wl_Window * +ecore_evas_wayland_window_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return NULL; +} + +EAPI void +ecore_evas_wayland_pointer_set(Ecore_Evas *ee EINA_UNUSED, int hot_x EINA_UNUSED, int hot_y EINA_UNUSED) +{ + +} + +#endif diff --git a/src/lib/ecore_evas/ecore_evas_buffer.c b/src/lib/ecore_evas/ecore_evas_buffer.c new file mode 100644 index 0000000000..26f48ce336 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_buffer.c @@ -0,0 +1,836 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! +#include + +#include +#include "ecore_private.h" +#include + +#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++; + 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 + { + ee->engine.buffer.free_func(ee->engine.buffer.data, + 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; + int stride = 0; + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->req.w = w; + ee->req.h = 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->engine.buffer.image) + { + ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1); + stride = evas_object_image_stride_get(ee->engine.buffer.image); + } + else + { + if (ee->engine.buffer.pixels) + ee->engine.buffer.free_func(ee->engine.buffer.data, + ee->engine.buffer.pixels); + ee->engine.buffer.pixels = + ee->engine.buffer.alloc_func(ee->engine.buffer.data, + ee->w * ee->h * sizeof(int)); + stride = ee->w * sizeof(int); + } + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; + einfo->info.dest_buffer_row_bytes = stride; + 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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + } + if (ee->engine.buffer.image) + evas_object_image_data_set(ee->engine.buffer.image, ee->engine.buffer.pixels); + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h) +{ + _ecore_evas_resize(ee, w, h); +} + +int +_ecore_evas_buffer_shutdown(void) +{ + _ecore_evas_init_count--; + if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; + return _ecore_evas_init_count; +} + +static void +_ecore_evas_show(Ecore_Evas *ee) +{ + if (ee->engine.buffer.image) return; + if (ee->prop.focused) return; + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); +} + +int +_ecore_evas_buffer_render(Ecore_Evas *ee) +{ + Eina_List *updates = NULL, *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); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_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); + ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1); + } + if (ee->engine.buffer.pixels) + { + updates = evas_render_updates(ee->evas); + } + if (ee->engine.buffer.image) + { + Eina_Rectangle *r; + + evas_object_image_data_set(ee->engine.buffer.image, ee->engine.buffer.pixels); + EINA_LIST_FOREACH(updates, l, r) + 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; +} + +// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! +static void +_ecore_evas_buffer_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y) +{ + Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh; + + evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, &ww, &hh); + evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh); + + if (fw < 1) fw = 1; + if (fh < 1) fh = 1; + + if (evas_object_map_get(ee->engine.buffer.image) && + evas_object_map_enable_get(ee->engine.buffer.image)) + { + fx = 0; fy = 0; + fw = ee->w; fh = ee->h; + ww = ee->w; hh = ee->h; + } + + if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh)) + { + *x = (ee->w * (*x - xx)) / fw; + *y = (ee->h * (*y - yy)) / fh; + } + else + { + xx = (*x - xx) - fx; + while (xx < 0) xx += fw; + while (xx > fw) xx -= fw; + *x = (ee->w * xx) / fw; + + yy = (*y - yy) - fy; + while (yy < 0) yy += fh; + while (yy > fh) yy -= fh; + *y = (ee->h * yy) / fh; + } +} + +static void +_ecore_evas_buffer_transfer_modifiers_locks(Evas *e, Evas *e2) +{ + const char *mods[] = + { "Shift", "Control", "Alt", "Meta", "Hyper", "Super", NULL }; + const char *locks[] = + { "Scroll_Lock", "Num_Lock", "Caps_Lock", NULL }; + int i; + + for (i = 0; mods[i]; i++) + { + if (evas_key_modifier_is_set(evas_key_modifier_get(e), mods[i])) + evas_key_modifier_on(e2, mods[i]); + else + evas_key_modifier_off(e2, mods[i]); + } + for (i = 0; locks[i]; i++) + { + if (evas_key_lock_is_set(evas_key_lock_get(e), locks[i])) + evas_key_lock_on(e2, locks[i]); + else + evas_key_lock_off(e2, locks[i]); + } +} + +static void +_ecore_evas_buffer_cb_mouse_in(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_In *ev; + + ee = data; + ev = event_info; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_mouse_out(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Out *ev; + + ee = data; + ev = event_info; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_mouse_down(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Down *ev; + + ee = data; + ev = event_info; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + 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, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Up *ev; + + ee = data; + ev = event_info; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + 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, Evas_Object *obj EINA_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_buffer_transfer_modifiers_locks(e, ee->evas); + _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); +} + +static void +_ecore_evas_buffer_cb_mouse_wheel(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Wheel *ev; + + ee = data; + ev = event_info; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + 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, Evas_Object *obj EINA_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; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + 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, Evas_Object *obj EINA_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; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + 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, Evas_Object *obj EINA_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; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + 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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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 EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Key_Down *ev; + + ee = data; + ev = event_info; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + 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 EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Key_Up *ev; + + ee = data; + ev = event_info; + _ecore_evas_buffer_transfer_modifiers_locks(e, ee->evas); + 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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + + ee = data; + ee->visible = 0; + if (ee->func.fn_hide) ee->func.fn_hide(ee); +} + +static void +_ecore_evas_buffer_alpha_set(Ecore_Evas *ee, int alpha) +{ + if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha))) return; + ee->alpha = alpha; + if (ee->engine.buffer.image) + evas_object_image_alpha_set(ee->engine.buffer.image, ee->alpha); + else + { + Evas_Engine_Info_Buffer *einfo; + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + } +} + +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, + _ecore_evas_move_resize, + NULL, + NULL, + _ecore_evas_show, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_buffer_alpha_set, + NULL, //transparent + NULL, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + _ecore_evas_buffer_render, + NULL, // screen_geometry_get + NULL // screen_dpi_get +}; +#endif + +static void * +_ecore_evas_buffer_pix_alloc(void *data EINA_UNUSED, int size) +{ + return malloc(size); +} + +static void +_ecore_evas_buffer_pix_free(void *data EINA_UNUSED, void *pix) +{ + free(pix); +} + +EAPI Ecore_Evas * +ecore_evas_buffer_new(int w, int h) +{ + return ecore_evas_buffer_allocfunc_new + (w, h, _ecore_evas_buffer_pix_alloc, _ecore_evas_buffer_pix_free, NULL); +} + +EAPI Ecore_Evas * +ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data) +{ +// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! +#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER + Evas_Engine_Info_Buffer *einfo; + Ecore_Evas *ee; + int rmethod; + + if ((!alloc_func) || (!free_func)) return NULL; + 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->engine.buffer.alloc_func = alloc_func; + ee->engine.buffer.free_func = free_func; + ee->engine.buffer.data = (void *)data; + + 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->req.w = ee->w; + ee->req.h = ee->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 = + ee->engine.buffer.alloc_func + (ee->engine.buffer.data, 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_RGB32; + 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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + 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); + + _ecore_evas_register(ee); + + evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + + return ee; +#else + return NULL; +#endif +} + +EAPI const void * +ecore_evas_buffer_pixels_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER + if (!ee) + { + CRIT("Ecore_Evas is missing"); + return NULL; + } + _ecore_evas_buffer_render(ee); + return ee->engine.buffer.pixels; +#else + return NULL; +#endif +} + +EAPI Evas * +ecore_evas_object_evas_get(Evas_Object *obj) +{ + Ecore_Evas *ee; + + ee = evas_object_data_get(obj, "Ecore_Evas"); + if (!ee) return NULL; + + return ecore_evas_get(ee); +} + +EAPI Ecore_Evas * +ecore_evas_object_ecore_evas_get(Evas_Object *obj) +{ + return evas_object_data_get(obj, "Ecore_Evas"); +} + +EAPI Evas_Object * +ecore_evas_object_image_new(Ecore_Evas *ee_target) +{ +// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar! +#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER + Evas_Object *o; + Evas_Engine_Info_Buffer *einfo; + Ecore_Evas *ee; + int rmethod; + int w = 1, h = 1; + + if (!ee_target) return NULL; + + 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); + evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); + evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(o, 0); + evas_object_image_size_set(o, w, h); + + 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"; + + ee->rotation = 0; + ee->visible = 0; + ee->w = w; + ee->h = h; + ee->req.w = ee->w; + ee->req.h = ee->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_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) + { + ee->engine.buffer.pixels = evas_object_image_data_get(o, 1); + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; + einfo->info.dest_buffer_row_bytes = evas_object_image_stride_get(o); + 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_object_image_data_set(o, ee->engine.buffer.pixels); + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + 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); + + return o; +#else + return NULL; +#endif +} diff --git a/src/lib/ecore_evas/ecore_evas_cocoa.c b/src/lib/ecore_evas/ecore_evas_cocoa.c new file mode 100644 index 0000000000..bf88e5e33f --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_cocoa.c @@ -0,0 +1,584 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Input.h" +#include "Ecore_Input_Evas.h" + +#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA +#include +#include +#endif + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + + +#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA + +// 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"; + + +static int +_ecore_evas_cocoa_render(Ecore_Evas *ee) +{ + int rend = 0; + Eina_List *updates = NULL; + Eina_List *ll; + Ecore_Evas *ee2; + + DBG("Render"); + + EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) + { + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + updates = evas_render_updates(ee->evas); + 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); + + 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 Ecore_Evas * +_ecore_evas_cocoa_match(void) +{ + DBG("Match"); + return ecore_evases; +} + +static int +_ecore_evas_cocoa_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + + DBG("Got Focus"); + + ee = _ecore_evas_cocoa_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + + return ECORE_CALLBACK_PASS_ON; +} + +static int +_ecore_evas_cocoa_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + + DBG("Lost Focus"); + + ee = _ecore_evas_cocoa_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + evas_focus_out(ee->evas); + ee->prop.focused = 0; + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + + return ECORE_CALLBACK_PASS_ON; +} + +static int +_ecore_evas_cocoa_event_video_resize(void *data EINA_UNUSED, int type EINA_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;*/ + + DBG("Video Resize"); + return ECORE_CALLBACK_PASS_ON; +} + +static int +_ecore_evas_cocoa_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee; + int w; + int h; + + DBG("Video Expose"); + + ee = _ecore_evas_cocoa_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + evas_output_size_get(ee->evas, &w, &h); + evas_damage_rectangle_add(ee->evas, 0, 0, w, h); + + return ECORE_CALLBACK_PASS_ON; +} + +static int +_ecore_evas_idle_enter(void *data EINA_UNUSED) +{ + Ecore_Evas *ee; + double t1 = 0.; + double t2 = 0.; + + DBG("Idle enter"); + + EINA_INLIST_FOREACH(ecore_evases, ee) + { + if (ee->visible) + evas_render(ee->evas); + else + evas_norender(ee->evas); + } + + return EINA_TRUE; +} + +static int +_ecore_evas_cocoa_event(void *data) +{ + // ecore_cocoa_feed_events(); + + DBG("Cocoa Event"); + + return 1; +} + +static int +_ecore_evas_cocoa_init(void) +{ + DBG("Cocoa Init"); + _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_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); + + ecore_event_evas_init(); + return _ecore_evas_init_count; +} + +static int +_ecore_evas_cocoa_shutdown(void) +{ + DBG("Cocoa SHutodwn"); + _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) +{ + DBG("Cocoa Free"); + 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) +{ + DBG("Resize"); + if ((w == ee->w) && (h == ee->h)) return; + ee->w = w; + ee->h = h; + + printf("Ecore_Evas Resize %d %d\n", w, h); + + ecore_cocoa_window_resize(ee->prop.window, w, 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, int y, int w, int h) +{ + DBG("Move Resize"); + if ((w == ee->w) && (h == ee->h)) return; + ee->w = w; + ee->h = h; + + ecore_cocoa_window_move_resize(ee->prop.window, x, y, w, 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_show(Ecore_Evas *ee, int x, int y, int w, int h) +{ + DBG("Show"); + ee->should_be_visible = 1; + if (ee->prop.avoid_damage) + _ecore_evas_cocoa_render(ee); + + ecore_cocoa_window_show(ee->prop.window); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); +} + + +static void +_ecore_evas_hide(Ecore_Evas *ee, int x, int y, int w, int h) +{ + DBG("Hide"); + + ecore_cocoa_window_hide(ee->prop.window); + ee->should_be_visible = 0; +} + +static void +_ecore_evas_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_cocoa_window_title_set(ee->prop.window, + ee->prop.title); +} + +static void +_ecore_evas_object_cursor_del(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Ecore_Evas *ee; + + DBG("Cursor DEL"); + + 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; + DBG("Cursor Set"); + 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 int +_ecore_evas_engine_cocoa_init(Ecore_Evas *ee) +{ + Evas_Engine_Info_GL_Cocoa *einfo; + const char *driver; + int rmethod; + + DBG("Cocoa Init"); + + driver = "gl_cocoa"; + + 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_Cocoa *)evas_engine_info_get(ee->evas); + if (einfo) + { + /* FIXME: REDRAW_DEBUG missing for now */ + einfo->window = ee->prop.window; + //einfo->info.depth = ecore_win32_screen_depth_get(); + //einfo->info.rotation = 0; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + return 0; + } + ecore_cocoa_window_view_set(einfo->window, einfo->view); + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + return 0; + } + + return 1; +} + +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, //move + NULL, + _ecore_evas_resize, + _ecore_evas_move_resize, + NULL, //rotation + NULL, //shaped + _ecore_evas_show, + _ecore_evas_hide, + NULL, //raise + NULL, //lower + NULL, //activate + _ecore_evas_title_set, + 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, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, // render + NULL, + NULL // screen_dpi_get + }; +#endif + +EAPI Ecore_Evas * +ecore_evas_cocoa_new(Ecore_Cocoa_Window *parent, int x, int y, int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_OPENGL_COCOA + Evas_Engine_Info_GL_Cocoa *einfo; + Ecore_Evas *ee; + int rmethod; + + DBG("Cocoa new"); + + if (!ecore_cocoa_init()) + 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(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_cocoa_engine_func; + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->visible = 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->semi_sync = 1; + + + ee->prop.max.w = 32767; + ee->prop.max.h = 32767; + ee->prop.layer = 4; + ee->prop.request_pos = 0; + ee->prop.sticky = 0; + ee->prop.window = 0; + + printf("Create New Evas\n"); + + ee->evas = evas_new(); + + if (!ee->evas) + goto free_name; + + 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); + + printf("Create New Cocoa Window\n"); + ee->prop.window = (Ecore_Cocoa_Window*)ecore_cocoa_window_new(x, y, w, h); + printf("Window Created %p\n", ee->prop.window); + if (!ee->prop.window) + { + _ecore_evas_cocoa_shutdown(); + free(ee); + return NULL; + } + + printf("Init Evas engine cocoa\n"); + if (!_ecore_evas_engine_cocoa_init(ee)) + { + _ecore_evas_cocoa_shutdown(); + free(ee); + return NULL; + } + + + ee->engine.func->fn_render = _ecore_evas_cocoa_render; + _ecore_evas_register(ee); + ecore_event_window_register(0, ee, ee->evas, NULL, NULL, NULL, NULL); + + evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + printf("Ecore Evas returned : %p\n", ee); + 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("Cocoa support in ecore-evas not enabled"); + return NULL; + (void) parent; + (void) x; (void) y; (void) w; (void) h; +#endif +} diff --git a/src/lib/ecore_evas/ecore_evas_directfb.c b/src/lib/ecore_evas/ecore_evas_directfb.c new file mode 100644 index 0000000000..f3567341b1 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_directfb.c @@ -0,0 +1,606 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include "ecore_private.h" +#ifdef BUILD_ECORE_EVAS_DIRECTFB +#include +#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; + + EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) + { + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + 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 Eina_Bool +_ecore_evas_directfb_event_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Key_Down *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* pass on event */ + evas_event_feed_key_down(ee->evas, e->name, e->name, e->string, + e->key_compose, e->time, NULL); + return EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Key_Up *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* pass on event */ + evas_event_feed_key_up(ee->evas, e->name, e->name, e->string, + e->key_compose, e->time, NULL); + return EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_motion(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Motion *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* pass on event */ + _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time); + return EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_button_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Button_Down *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* 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 EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_button_up(void *data EINA_UNUSED, int type EINA_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 EINA_TRUE; /* 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 EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_enter(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Enter *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* 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 EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_leave(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Leave *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* 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 EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Wheel *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* pass on event */ + evas_event_feed_mouse_wheel(ee->evas, e->direction, e->z, e->time, NULL); + return EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Got_Focus *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* pass on event */ + ee->prop.focused = 1; + return EINA_TRUE; +} + +static Eina_Bool +_ecore_evas_directfb_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_DirectFB_Event_Lost_Focus *e; + + e = event; + ee = _ecore_evas_directfb_match(e->win); + + if (!ee) return EINA_TRUE; /* pass on event */ + ee->prop.focused = 0; + return EINA_TRUE; +} + +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) +{ + ee->req.w = w; + ee->req.h = 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 EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) + { + 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; + 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); + } + } + einfo = (Evas_Engine_Info_DirectFB *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.surface = ee->engine.directfb.window->surface; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + } + 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, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, // render + NULL, // screen_geometry_get + NULL // screen_dpi_get +}; +#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->req.x = ee->x; + ee->req.y = ee->y; + ee->req.w = ee->w; + ee->req.h = ee->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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + + 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 EINA_UNUSED, int windowed EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + return NULL; +} +#endif + +#ifdef BUILD_ECORE_EVAS_DIRECTFB +EAPI Ecore_DirectFB_Window * +ecore_evas_directfb_window_get(const Ecore_Evas *ee) +{ + if (!(!strcmp(ee->driver, "directfb"))) return 0; + return (Ecore_DirectFB_Window *) _ecore_evas_directfb_window_get(ee); +} +#else +EAPI Ecore_DirectFB_Window * +ecore_evas_directfb_window_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return NULL; +} +#endif diff --git a/src/lib/ecore_evas/ecore_evas_ews.c b/src/lib/ecore_evas/ecore_evas_ews.c new file mode 100644 index 0000000000..ceffd663e6 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_ews.c @@ -0,0 +1,1469 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include +#include +#include "ecore_private.h" +#include + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +EAPI int ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_ADD = 0; +EAPI int ECORE_EVAS_EWS_EVENT_DEL = 0; +EAPI int ECORE_EVAS_EWS_EVENT_RESIZE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_MOVE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_SHOW = 0; +EAPI int ECORE_EVAS_EWS_EVENT_HIDE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_FOCUS = 0; +EAPI int ECORE_EVAS_EWS_EVENT_UNFOCUS = 0; +EAPI int ECORE_EVAS_EWS_EVENT_RAISE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_LOWER = 0; +EAPI int ECORE_EVAS_EWS_EVENT_ACTIVATE = 0; + +EAPI int ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_LAYER_CHANGE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE = 0; +EAPI int ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE = 0; + +#ifdef BUILD_ECORE_EVAS_EWS +static int _ecore_evas_init_count = 0; + +static Ecore_Evas *_ews_ee = NULL; +static Evas_Object *_ews_bg = NULL; +static Eina_List *_ews_children = NULL; +static const void *_ews_manager = NULL; +static char *_ews_engine = NULL; +static char *_ews_options = NULL; +static int _ews_x = 0; +static int _ews_y = 0; +static int _ews_w = 1024; +static int _ews_h = 768; +static Eina_Bool _ews_defaults_engine = EINA_TRUE; +static Eina_Bool _ews_defaults_geo = EINA_TRUE; + +static const char EWS_ENGINE_NAME[] = "ews"; + +static void +_ecore_evas_ews_pre_free(Ecore_Evas *ee EINA_UNUSED) +{ + DBG("EWS backing store free'd"); + _ews_children = eina_list_free(_ews_children); + _ews_ee = NULL; + _ews_bg = NULL; +} + +static void +_ecore_evas_ews_del_request(Ecore_Evas *ee EINA_UNUSED) +{ + INF("EWS backing store deletion is forbidden!"); +} + +static Ecore_Evas * +_ecore_evas_ews_ee_new(void) +{ + Ecore_Evas *ee = ecore_evas_new(_ews_engine, _ews_x, _ews_y, _ews_w, _ews_h, + _ews_options); + if (!ee) + ERR("Failed: ecore_evas_new(%s, %d, %d, %d, %d, %s)", + _ews_engine, _ews_x, _ews_y, _ews_w, _ews_h, _ews_options); + else + { + ecore_evas_size_min_set(ee, _ews_w, _ews_h); + ecore_evas_size_max_set(ee, _ews_w, _ews_h); + ecore_evas_callback_pre_free_set(ee, _ecore_evas_ews_pre_free); + ecore_evas_callback_delete_request_set(ee, _ecore_evas_ews_del_request); + ecore_evas_name_class_set(ee, "ecore_evas_ews", "ews"); + ecore_evas_title_set + (ee, "EWS: Ecore + Evas Single Process Windowing System"); + ecore_evas_show(ee); + } + + return ee; +} + +static void +_ecore_evas_ews_env_setup(void) +{ + const char *env = getenv("ECORE_EVAS_EWS"); + char *p, *n, *tmp; + + if (_ews_defaults_engine) + { + free(_ews_engine); + _ews_engine = NULL; + free(_ews_options); + _ews_options = NULL; + } + if (_ews_defaults_geo) + { + _ews_x = 0; + _ews_y = 0; + _ews_w = 1024; + _ews_h = 768; + } + + if ((!env) || (!*env)) return; + + p = tmp = strdup(env); + if (!tmp) return; + + n = strchr(p, ':'); + if (n) *n = '\0'; + if (_ews_defaults_engine) _ews_engine = strdup(p); + if (!n) goto end; + + p = n + 1; + n = strchr(p, ':'); + if (!n) goto end; + *n = '\0'; + if (_ews_defaults_geo) _ews_x = atoi(p); + + p = n + 1; + n = strchr(p, ':'); + if (!n) goto end; + *n = '\0'; + if (_ews_defaults_geo) _ews_y = atoi(p); + + p = n + 1; + n = strchr(p, ':'); + if (!n) goto end; + *n = '\0'; + if (_ews_defaults_geo) _ews_w = atoi(p); + + p = n + 1; + n = strchr(p, ':'); + if (n) *n = '\0'; + if (_ews_defaults_geo) _ews_h = atoi(p); + if (!n) goto end; + + p = n + 1; + if (_ews_defaults_engine) _ews_options = strdup(p); + + end: + free(tmp); +} + +static void +_ecore_evas_ews_event_free(void *data EINA_UNUSED, void *ev) +{ + Ecore_Evas *ee = ev; + _ecore_evas_unref(ee); +} + +static void +_ecore_evas_ews_event(Ecore_Evas *ee, int event) +{ + _ecore_evas_ref(ee); + ecore_event_add(event, ee, _ecore_evas_ews_event_free, NULL); +} + +static void +_ecore_evas_ews_event_free_del(void *data EINA_UNUSED, void *ev EINA_UNUSED) +{ + _ecore_evas_ews_shutdown(); +} + +static void +_ecore_evas_ews_free(Ecore_Evas *ee) +{ + evas_object_del(ee->engine.ews.image); + _ews_ee->sub_ecore_evas = eina_list_remove(_ews_ee->sub_ecore_evas, ee); + + ecore_event_add(ECORE_EVAS_EWS_EVENT_DEL, ee, _ecore_evas_ews_event_free_del, NULL); +} + +static void +_ecore_evas_ews_move(Ecore_Evas *ee, int x, int y) +{ + ee->req.x = x; + ee->req.y = y; + + if ((x == ee->x) && (y == ee->y)) return; + ee->x = x; + ee->y = y; + evas_object_move(ee->engine.ews.image, x, y); + if (ee->func.fn_move) ee->func.fn_move(ee); + + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MOVE); +} + +static void +_ecore_evas_ews_managed_move(Ecore_Evas *ee, int x, int y) +{ + ee->req.x = x; + ee->req.y = y; + + if ((x == ee->x) && (y == ee->y)) return; + ee->x = x; + ee->y = y; + if (ee->func.fn_move) ee->func.fn_move(ee); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MOVE); +} + +static void +_ecore_evas_ews_resize_internal(Ecore_Evas *ee, int w, int h) +{ + Evas_Engine_Info_Buffer *einfo; + void *pixels; + int stride; + + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + evas_damage_rectangle_add(ee->evas, 0, 0, w, h); + + evas_object_image_size_set(ee->engine.ews.image, w, h); + evas_object_image_fill_set(ee->engine.ews.image, 0, 0, w, h); + evas_object_resize(ee->engine.ews.image, w, h); + + pixels = evas_object_image_data_get(ee->engine.ews.image, 1); + evas_object_image_data_set(ee->engine.ews.image, pixels); // refcount + stride = evas_object_image_stride_get(ee->engine.ews.image); + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + EINA_SAFETY_ON_NULL_RETURN(einfo); + + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + einfo->info.dest_buffer = pixels; + einfo->info.dest_buffer_row_bytes = stride; + 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_object_image_data_set(ee->engine.ews.image, pixels); + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } +} + +static void +_ecore_evas_ews_resize(Ecore_Evas *ee, int w, int h) +{ + if (w < 1) w = 1; + if (h < 1) h = 1; + + ee->req.w = w; + ee->req.h = h; + + if ((w == ee->w) && (h == ee->h)) return; + ee->w = w; + ee->h = h; + _ecore_evas_ews_resize_internal(ee, w, h); + if (ee->func.fn_resize) ee->func.fn_resize(ee); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_RESIZE); +} + +static void +_ecore_evas_ews_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) +{ + _ecore_evas_ews_move(ee, x, y); + _ecore_evas_ews_resize(ee, w, h); +} + +static void +_ecore_evas_ews_rotation_set(Ecore_Evas *ee, int rot, int resize EINA_UNUSED) +{ + if (ee->rotation == rot) return; + ee->rotation = rot; + + ERR("TODO: rot=%d, resize=%d", rot, resize); + + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_shaped_set(Ecore_Evas *ee, int val) +{ + if (ee->shaped == val) return; + ee->shaped = val; + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_show(Ecore_Evas *ee) +{ + ee->should_be_visible = EINA_TRUE; + evas_object_show(ee->engine.ews.image); + if (ee->prop.fullscreen) + evas_object_focus_set(ee->engine.ews.image, EINA_TRUE); + + if (ee->func.fn_show) ee->func.fn_show(ee); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_SHOW); +} + +static void +_ecore_evas_ews_hide(Ecore_Evas *ee) +{ + ee->should_be_visible = EINA_FALSE; + evas_object_hide(ee->engine.ews.image); + + if (ee->func.fn_hide) ee->func.fn_hide(ee); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_HIDE); +} + +static void +_ecore_evas_ews_raise(Ecore_Evas *ee) +{ + evas_object_raise(ee->engine.ews.image); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_RAISE); +} + +static void +_ecore_evas_ews_lower(Ecore_Evas *ee) +{ + evas_object_lower(ee->engine.ews.image); + evas_object_lower(_ews_bg); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_LOWER); +} + +static void +_ecore_evas_ews_activate(Ecore_Evas *ee) +{ + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ACTIVATE); +} + +static void +_ecore_evas_ews_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_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_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_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_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; + evas_object_size_hint_min_set(ee->engine.ews.image, w, h); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_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; + evas_object_size_hint_max_set(ee->engine.ews.image, w, h); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_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; + evas_object_size_hint_request_set(ee->engine.ews.image, w, h); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_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_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + ee->prop.cursor.object = NULL; +} + +static void +_ecore_evas_ews_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) + { + 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_ews_object_cursor_del, ee); + + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_layer_set(Ecore_Evas *ee, int layer) +{ + if (layer < EVAS_LAYER_MIN + 1) + layer = EVAS_LAYER_MIN + 1; + else if (layer > EVAS_LAYER_MAX) + layer = EVAS_LAYER_MAX; + + if (ee->prop.layer == layer) return; + ee->prop.layer = layer; + evas_object_layer_set(ee->engine.ews.image, layer); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_LAYER_CHANGE); +} + +static void +_ecore_evas_ews_focus_set(Ecore_Evas *ee, int val) +{ + evas_object_focus_set(ee->engine.ews.image, val); + ee->prop.focused = val; + if (val) + { + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_FOCUS); + } + else + { + evas_focus_out(ee->evas); + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_UNFOCUS); + } +} + +static void +_ecore_evas_ews_iconified_set(Ecore_Evas *ee, int val) +{ + if (ee->prop.iconified == val) return; + ee->prop.iconified = val; + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE); +} + +static void +_ecore_evas_ews_borderless_set(Ecore_Evas *ee, int val) +{ + if (ee->prop.borderless == val) return; + ee->prop.borderless = val; + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_override_set(Ecore_Evas *ee, int val) +{ + if (ee->prop.override == val) return; + if (ee->visible) evas_object_show(ee->engine.ews.image); + if (ee->prop.focused) evas_object_focus_set(ee->engine.ews.image, EINA_TRUE); + ee->prop.override = val; + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_maximized_set(Ecore_Evas *ee, int val) +{ + if (ee->prop.maximized == val) return; + ee->prop.maximized = val; + if (val) evas_object_show(ee->engine.ews.image); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE); +} + +static void +_ecore_evas_ews_fullscreen_set(Ecore_Evas *ee, int val) +{ + if (ee->prop.fullscreen == val) return; + ee->prop.fullscreen = val; + + if (!val) + { + evas_object_move(ee->engine.ews.image, ee->x, ee->y); + evas_object_resize(ee->engine.ews.image, ee->w, ee->h); + } + else + { + Evas_Coord w, h; + ecore_evas_geometry_get(_ews_ee, NULL, NULL, &w, &h); + evas_object_move(ee->engine.ews.image, 0, 0); + evas_object_resize(ee->engine.ews.image, w, h); + evas_object_focus_set(ee->engine.ews.image, EINA_TRUE); + } + + if (ee->should_be_visible) + evas_object_show(ee->engine.ews.image); + else + evas_object_hide(ee->engine.ews.image); + + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE); +} + +static void +_ecore_evas_ews_avoid_damage_set(Ecore_Evas *ee, int val) +{ + if (ee->prop.avoid_damage == val) return; + ee->prop.avoid_damage = val; + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_withdrawn_set(Ecore_Evas *ee, int val) +{ + if (ee->prop.withdrawn == val) return; + ee->prop.withdrawn = val; + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_sticky_set(Ecore_Evas *ee, int val) +{ + if (ee->prop.sticky == val) return; + ee->prop.sticky = val; + if ((val) && (ee->func.fn_sticky)) ee->func.fn_sticky(ee); + else if ((!val) && (ee->func.fn_unsticky)) ee->func.fn_unsticky(ee); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_ignore_events_set(Ecore_Evas *ee, int val) +{ + if (ee->ignore_events == val) return; + ee->ignore_events = val; + evas_object_pass_events_set(ee->engine.ews.image, val); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_alpha_set(Ecore_Evas *ee, int val) +{ + if (ee->alpha == val) return; + ee->alpha = val; + evas_object_image_alpha_set(ee->engine.ews.image, val); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static void +_ecore_evas_ews_transparent_set(Ecore_Evas *ee, int val) +{ + if (ee->transparent == val) return; + ee->transparent = val; + evas_object_image_alpha_set(ee->engine.ews.image, val); + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE); +} + +static int +_ecore_evas_ews_render(Ecore_Evas *ee) +{ + Eina_List *updates = NULL, *l, *ll; + Ecore_Evas *ee2; + Eina_Rectangle *r; + int w, h, rend = 0; + void *pixels; + + EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) + { + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + rend |= _ecore_evas_ews_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + evas_object_image_size_get(ee->engine.ews.image, &w, &h); + if ((w != ee->w) || (h != ee->h)) + ecore_evas_resize(ee, w, h); + + pixels = evas_object_image_data_get(ee->engine.ews.image, 1); + if (pixels) + { + updates = evas_render_updates(ee->evas); + } + evas_object_image_data_set(ee->engine.ews.image, pixels); + + EINA_LIST_FOREACH(updates, l, r) + evas_object_image_data_update_add(ee->engine.ews.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_ews_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) +{ + ecore_evas_geometry_get(_ews_ee, x, y, w, h); +} + +static const Ecore_Evas_Engine_Func _ecore_ews_engine_func = +{ + _ecore_evas_ews_free, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_ews_move, + _ecore_evas_ews_managed_move, + _ecore_evas_ews_resize, + _ecore_evas_ews_move_resize, + _ecore_evas_ews_rotation_set, + _ecore_evas_ews_shaped_set, + _ecore_evas_ews_show, + _ecore_evas_ews_hide, + _ecore_evas_ews_raise, + _ecore_evas_ews_lower, + _ecore_evas_ews_activate, + _ecore_evas_ews_title_set, + _ecore_evas_ews_name_class_set, + _ecore_evas_ews_size_min_set, + _ecore_evas_ews_size_max_set, + _ecore_evas_ews_size_base_set, + _ecore_evas_ews_size_step_set, + _ecore_evas_ews_object_cursor_set, + _ecore_evas_ews_layer_set, + _ecore_evas_ews_focus_set, + _ecore_evas_ews_iconified_set, + _ecore_evas_ews_borderless_set, + _ecore_evas_ews_override_set, + _ecore_evas_ews_maximized_set, + _ecore_evas_ews_fullscreen_set, + _ecore_evas_ews_avoid_damage_set, + _ecore_evas_ews_withdrawn_set, + _ecore_evas_ews_sticky_set, + _ecore_evas_ews_ignore_events_set, + _ecore_evas_ews_alpha_set, + _ecore_evas_ews_transparent_set, + NULL, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + _ecore_evas_ews_render, + _ecore_evas_ews_screen_geometry_get, + NULL // screen_dpi_get +}; + +void +_ecore_evas_ews_events_init(void) +{ + if (ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE != 0) return; + ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_ADD = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_DEL = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_RESIZE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_MOVE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_SHOW = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_HIDE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_FOCUS = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_UNFOCUS = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_RAISE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_LOWER = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_ACTIVATE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_LAYER_CHANGE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE = ecore_event_type_new(); + ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE = ecore_event_type_new(); +} + +static int +_ecore_evas_ews_init(void) +{ + _ecore_evas_init_count++; + if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; + + _ecore_evas_ews_env_setup(); + + return _ecore_evas_init_count; +} + +int +_ecore_evas_ews_shutdown(void) +{ + _ecore_evas_init_count--; + if (_ecore_evas_init_count == 0) + { + if (_ews_ee) + { + ecore_evas_free(_ews_ee); + _ews_ee = NULL; + } + if (_ews_children) + { + eina_list_free(_ews_children); + _ews_children = NULL; + } + + free(_ews_engine); + _ews_engine = NULL; + free(_ews_options); + _ews_options = NULL; + _ews_defaults_engine = EINA_TRUE; + _ews_defaults_geo = EINA_TRUE; + + } + if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; + return _ecore_evas_init_count; +} + +static void +_ecore_evas_ews_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y) +{ + Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh; + + evas_object_geometry_get(ee->engine.ews.image, &xx, &yy, &ww, &hh); + evas_object_image_fill_get(ee->engine.ews.image, &fx, &fy, &fw, &fh); + + if (fw < 1) fw = 1; + if (fh < 1) fh = 1; + + if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh)) + { + *x = (ee->w * (*x - xx)) / fw; + *y = (ee->h * (*y - yy)) / fh; + } + else + { + xx = (*x - xx) - fx; + while (xx < 0) xx += fw; + while (xx > fw) xx -= fw; + *x = (ee->w * xx) / fw; + + yy = (*y - yy) - fy; + while (yy < 0) yy += fh; + while (yy > fh) yy -= fh; + *y = (ee->h * yy) / fh; + } +} + +static void +_ecore_evas_ews_modifiers_apply(Ecore_Evas *ee, const Evas_Modifier *modifier) +{ + Evas *e = ee->evas; + + if (evas_key_modifier_is_set(modifier, "Shift")) + evas_key_modifier_on(e, "Shift"); + else evas_key_modifier_off(e, "Shift"); + + if (evas_key_modifier_is_set(modifier, "Control")) + evas_key_modifier_on(e, "Control"); + else evas_key_modifier_off(e, "Control"); + + if (evas_key_modifier_is_set(modifier, "Alt")) + evas_key_modifier_on(e, "Alt"); + else evas_key_modifier_off(e, "Alt"); + + if (evas_key_modifier_is_set(modifier, "Super")) + evas_key_modifier_on(e, "Super"); + else evas_key_modifier_off(e, "Super"); + + if (evas_key_modifier_is_set(modifier, "Hyper")) + evas_key_modifier_on(e, "Hyper"); + else evas_key_modifier_off(e, "Hyper"); + + if (evas_key_modifier_is_set(modifier, "Scroll_Lock")) + evas_key_lock_on(e, "Scroll_Lock"); + else evas_key_lock_off(e, "Scroll_Lock"); + + if (evas_key_modifier_is_set(modifier, "Num_Lock")) + evas_key_lock_on(e, "Num_Lock"); + else evas_key_lock_off(e, "Num_Lock"); + + if (evas_key_modifier_is_set(modifier, "Caps_Lock")) + evas_key_lock_on(e, "Caps_Lock"); + else evas_key_lock_off(e, "Caps_Lock"); + + if (evas_key_modifier_is_set(modifier, "Shift_Lock")) + evas_key_lock_on(e, "Shift_Lock"); + else evas_key_lock_off(e, "Shift_Lock"); +} + +static void +_ecore_evas_ews_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_In *ev = event_info; + Evas_Coord x = ev->canvas.x; + Evas_Coord y = ev->canvas.y; + _ecore_evas_ews_coord_translate(ee, &x, &y); + if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); + _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); +} + +static void +_ecore_evas_ews_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Out *ev = event_info; + Evas_Coord x = ev->canvas.x; + Evas_Coord y = ev->canvas.y; + // TODO: consider grab mode in EWS + _ecore_evas_ews_coord_translate(ee, &x, &y); + if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); + if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); + _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); +} + +static void +_ecore_evas_ews_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Down *ev = event_info; + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + evas_event_feed_mouse_down(ee->evas, ev->button, ev->flags, ev->timestamp, NULL); +} + +static void +_ecore_evas_ews_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Up *ev = event_info; + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + evas_event_feed_mouse_up(ee->evas, ev->button, ev->flags, ev->timestamp, NULL); +} + +static void +_ecore_evas_ews_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Move *ev = event_info; + Evas_Coord x = ev->cur.canvas.x; + Evas_Coord y = ev->cur.canvas.y; + _ecore_evas_ews_coord_translate(ee, &x, &y); + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); +} + +static void +_ecore_evas_ews_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Wheel *ev = event_info; + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, ev->timestamp, NULL); +} + +static void +_ecore_evas_ews_cb_multi_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Multi_Down *ev = event_info; + Evas_Coord x, y, xx, yy; + double xf, yf; + + x = ev->canvas.x; + y = ev->canvas.y; + xx = x; + yy = y; + _ecore_evas_ews_coord_translate(ee, &x, &y); + xf = (ev->canvas.xsub - (double)xx) + (double)x; + yf = (ev->canvas.ysub - (double)yy) + (double)y; + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + 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_ews_cb_multi_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Multi_Up *ev = event_info; + Evas_Coord x, y, xx, yy; + double xf, yf; + + x = ev->canvas.x; + y = ev->canvas.y; + xx = x; + yy = y; + _ecore_evas_ews_coord_translate(ee, &x, &y); + xf = (ev->canvas.xsub - (double)xx) + (double)x; + yf = (ev->canvas.ysub - (double)yy) + (double)y; + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + 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_ews_cb_multi_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Multi_Move *ev = event_info; + Evas_Coord x, y, xx, yy; + double xf, yf; + + x = ev->cur.canvas.x; + y = ev->cur.canvas.y; + xx = x; + yy = y; + _ecore_evas_ews_coord_translate(ee, &x, &y); + xf = (ev->cur.canvas.xsub - (double)xx) + (double)x; + yf = (ev->cur.canvas.ysub - (double)yy) + (double)y; + _ecore_evas_ews_modifiers_apply(ee, ev->modifiers); + 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_ews_cb_free(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + if (ee->driver) _ecore_evas_free(ee); +} + +static void +_ecore_evas_ews_cb_key_down(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Key_Down *ev = event_info; + + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift")) + evas_key_modifier_on(ee->evas, "Shift"); + else + evas_key_modifier_off(ee->evas, "Shift"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control")) + evas_key_modifier_on(ee->evas, "Control"); + else + evas_key_modifier_off(ee->evas, "Control"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt")) + evas_key_modifier_on(ee->evas, "Alt"); + else + evas_key_modifier_off(ee->evas, "Alt"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta")) + evas_key_modifier_on(ee->evas, "Meta"); + else + evas_key_modifier_off(ee->evas, "Meta"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper")) + evas_key_modifier_on(ee->evas, "Hyper"); + else + evas_key_modifier_off(ee->evas, "Hyper"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super")) + evas_key_modifier_on(ee->evas, "Super"); + else + evas_key_modifier_off(ee->evas, "Super"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock")) + evas_key_lock_on(ee->evas, "Scroll_Lock"); + else + evas_key_lock_off(ee->evas, "Scroll_Lock"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock")) + evas_key_lock_on(ee->evas, "Num_Lock"); + else + evas_key_lock_off(ee->evas, "Num_Lock"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock")) + evas_key_lock_on(ee->evas, "Caps_Lock"); + else + evas_key_lock_off(ee->evas, "Caps_Lock"); + evas_event_feed_key_down(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL); +} + +static void +_ecore_evas_ews_cb_key_up(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Key_Up *ev = event_info; + + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift")) + evas_key_modifier_on(ee->evas, "Shift"); + else + evas_key_modifier_off(ee->evas, "Shift"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control")) + evas_key_modifier_on(ee->evas, "Control"); + else + evas_key_modifier_off(ee->evas, "Control"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt")) + evas_key_modifier_on(ee->evas, "Alt"); + else + evas_key_modifier_off(ee->evas, "Alt"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta")) + evas_key_modifier_on(ee->evas, "Meta"); + else + evas_key_modifier_off(ee->evas, "Meta"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper")) + evas_key_modifier_on(ee->evas, "Hyper"); + else + evas_key_modifier_off(ee->evas, "Hyper"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super")) + evas_key_modifier_on(ee->evas, "Super"); + else + evas_key_modifier_off(ee->evas, "Super"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock")) + evas_key_lock_on(ee->evas, "Scroll_Lock"); + else + evas_key_lock_off(ee->evas, "Scroll_Lock"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock")) + evas_key_lock_on(ee->evas, "Num_Lock"); + else + evas_key_lock_off(ee->evas, "Num_Lock"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock")) + evas_key_lock_on(ee->evas, "Caps_Lock"); + else + evas_key_lock_off(ee->evas, "Caps_Lock"); + evas_event_feed_key_up(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL); +} + +static void +_ecore_evas_ews_cb_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + ecore_evas_focus_set(ee, EINA_TRUE); +} + +static void +_ecore_evas_ews_cb_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + if (ee->deleted) return; + ecore_evas_focus_set(ee, EINA_FALSE); +} + +static void +_ecore_evas_ews_cb_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + ecore_evas_show(ee); +} + +static void +_ecore_evas_ews_cb_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + if (ee->deleted) return; + ecore_evas_hide(ee); +} +#endif + +EAPI Ecore_Evas * +ecore_evas_ews_new(int x, int y, int w, int h) +{ +// basically a copy of ecore_evas_buffer_new() keep in sync... +#ifdef BUILD_ECORE_EVAS_EWS + Evas_Object *o; + Evas_Engine_Info_Buffer *einfo; + Ecore_Evas *ee; + int rmethod; + + if (_ecore_evas_ews_init() < 1) return NULL; + + if (!_ews_ee) _ews_ee = _ecore_evas_ews_ee_new(); + if (!_ews_ee) + { + ERR("Could not create EWS backing store"); + _ecore_evas_ews_shutdown(); + return NULL; + } + + rmethod = evas_render_method_lookup("buffer"); + if (!rmethod) return NULL; + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + if (w < 1) w = 1; + if (h < 1) h = 1; + + o = evas_object_image_add(_ews_ee->evas); + evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); + evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888); + evas_object_image_size_set(o, w, h); + evas_object_image_alpha_set(o, 1); + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_ews_engine_func; + + ee->driver = EWS_ENGINE_NAME; + + ee->x = 0; + ee->y = 0; + 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; + + /* 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); + + evas_object_move(o, x, y); + evas_object_resize(o, w, h); + evas_object_image_fill_set(o, 0, 0, w, h); + + ee->engine.ews.image = o; + evas_object_data_set(ee->engine.ews.image, "Ecore_Evas", ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MOUSE_IN, + _ecore_evas_ews_cb_mouse_in, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MOUSE_OUT, + _ecore_evas_ews_cb_mouse_out, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MOUSE_DOWN, + _ecore_evas_ews_cb_mouse_down, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MOUSE_UP, + _ecore_evas_ews_cb_mouse_up, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MOUSE_MOVE, + _ecore_evas_ews_cb_mouse_move, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MOUSE_WHEEL, + _ecore_evas_ews_cb_mouse_wheel, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MULTI_DOWN, + _ecore_evas_ews_cb_multi_down, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MULTI_UP, + _ecore_evas_ews_cb_multi_up, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_MULTI_MOVE, + _ecore_evas_ews_cb_multi_move, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_FREE, + _ecore_evas_ews_cb_free, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_KEY_DOWN, + _ecore_evas_ews_cb_key_down, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_KEY_UP, + _ecore_evas_ews_cb_key_up, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_FOCUS_IN, + _ecore_evas_ews_cb_focus_in, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_FOCUS_OUT, + _ecore_evas_ews_cb_focus_out, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_SHOW, + _ecore_evas_ews_cb_show, ee); + evas_object_event_callback_add(ee->engine.ews.image, + EVAS_CALLBACK_HIDE, + _ecore_evas_ews_cb_hide, ee); + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + void *pixels = evas_object_image_data_get(o, 1); + evas_object_image_data_set(o, pixels); // refcount + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + einfo->info.dest_buffer = pixels; + einfo->info.dest_buffer_row_bytes = evas_object_image_stride_get(o); + 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_object_image_data_set(o, pixels); + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + 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"); + + _ews_ee->sub_ecore_evas = eina_list_append(_ews_ee->sub_ecore_evas, ee); + _ews_children = eina_list_append(_ews_children, ee); + + _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ADD); + + return ee; +#else + return NULL; + (void)x; + (void)y; + (void)w; + (void)h; +#endif +} + +EAPI Evas_Object * +ecore_evas_ews_backing_store_get(const Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_EWS + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_ews_backing_store_get"); + return NULL; + } + return ee->engine.ews.image; +#else + return NULL; + (void)ee; +#endif +} + +EAPI void +ecore_evas_ews_delete_request(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_EWS + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_ews_delete_request"); + return; + } + if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee); + else ecore_evas_free(ee); +#else + (void)ee; +#endif +} + + +EAPI Eina_Bool +ecore_evas_ews_engine_set(const char *engine, const char *options) +{ +#ifdef BUILD_ECORE_EVAS_EWS + if (_ews_ee) return EINA_FALSE; + + free(_ews_engine); + free(_ews_options); + + _ews_engine = engine ? strdup(engine) : NULL; + _ews_options = options ? strdup(options) : NULL; + + if ((engine) && (!_ews_engine)) return EINA_FALSE; + if ((options) && (!_ews_options)) return EINA_FALSE; + + _ews_defaults_engine = EINA_FALSE; + return EINA_TRUE; +#else + return EINA_FALSE; + (void)engine; + (void)options; +#endif +} + +EAPI Eina_Bool +ecore_evas_ews_setup(int x, int y, int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_EWS + Eina_Bool ret = EINA_TRUE; + + _ews_defaults_geo = EINA_FALSE; + _ews_x = x; + _ews_y = y; + _ews_w = w; + _ews_h = h; + + if (!_ews_ee) return EINA_TRUE; + + /* move-resize is not as implemented as move + resize */ + ecore_evas_move(_ews_ee, x, y); + ecore_evas_size_min_set(_ews_ee, w, h); + ecore_evas_size_max_set(_ews_ee, w, h); + ecore_evas_resize(_ews_ee, w, h); + + ecore_evas_geometry_get(_ews_ee, &x, &y, &w, &h); + +#define TST(n) if ((n != _ews_##n)) \ + { \ + WRN("Asked %d, got %d for "#n, _ews_##n, n); \ + ret = EINA_FALSE; \ + } + TST(x); + TST(y); + TST(w); + TST(h); +#undef TST + return ret; +#else + return EINA_FALSE; + (void)x; + (void)y; + (void)w; + (void)h; +#endif +} + +EAPI Ecore_Evas * +ecore_evas_ews_ecore_evas_get(void) +{ +#ifdef BUILD_ECORE_EVAS_EWS + if (!_ews_ee) _ews_ee = _ecore_evas_ews_ee_new(); + return _ews_ee; +#else + return NULL; +#endif +} + +EAPI Evas * +ecore_evas_ews_evas_get(void) +{ +#ifdef BUILD_ECORE_EVAS_EWS + return ecore_evas_get(ecore_evas_ews_ecore_evas_get()); +#else + return NULL; +#endif +} + +EAPI Evas_Object * +ecore_evas_ews_background_get(void) +{ +#ifdef BUILD_ECORE_EVAS_EWS + return _ews_bg; +#else + return NULL; +#endif +} + +#ifdef BUILD_ECORE_EVAS_EWS +static void +_ecore_evas_ews_background_free(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info EINA_UNUSED) +{ + _ews_bg = NULL; + ecore_evas_ews_background_set(NULL); +} +#endif + +EAPI void +ecore_evas_ews_background_set(Evas_Object *o) +{ +#ifdef BUILD_ECORE_EVAS_EWS + if ((o) && (o == _ews_bg)) return; + + if (_ews_bg) + { + evas_object_del(_ews_bg); + _ews_bg = NULL; + } + + if ((!o) && (_ews_ee)) + { + o = evas_object_rectangle_add(ecore_evas_get(_ews_ee)); + evas_object_color_set(o, 0, 0, 0, 255); + } + + if (_ews_ee) + { + Evas_Coord w, h; + Evas *e = ecore_evas_get(_ews_ee); + + if (e != evas_object_evas_get(o)) + { + ERR("background not in ecore_evas_ews_evas_get() canvas!"); + return; + } + + evas_output_viewport_get(e, NULL, NULL, &w, &h); + evas_object_move(o, 0, 0); + evas_object_resize(o, w, h); + evas_object_layer_set(o, EVAS_LAYER_MIN); + evas_object_lower(o); + evas_object_show(o); + + evas_object_event_callback_add + (o, EVAS_CALLBACK_FREE, _ecore_evas_ews_background_free, NULL); + } + + _ews_bg = o; +#else + return; + (void)o; +#endif +} + + +EAPI const Eina_List * +ecore_evas_ews_children_get(void) +{ +#ifdef BUILD_ECORE_EVAS_EWS + return _ews_children; +#else + return NULL; +#endif +} + +EAPI void +ecore_evas_ews_manager_set(const void *manager) +{ +#ifdef BUILD_ECORE_EVAS_EWS + if (_ews_manager == manager) return; + _ews_manager = manager; + ecore_event_add(ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE, NULL, NULL, NULL); +#else + (void)manager; +#endif +} + +EAPI const void * +ecore_evas_ews_manager_get(void) +{ +#ifdef BUILD_ECORE_EVAS_EWS + return _ews_manager; +#else + return NULL; +#endif +} diff --git a/src/lib/ecore_evas/ecore_evas_extn.c b/src/lib/ecore_evas/ecore_evas_extn.c new file mode 100644 index 0000000000..2e1dac5cf8 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_extn.c @@ -0,0 +1,2266 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_MMAN_H +# include +#endif +#include +#include +#include +#include +#include + +#include +#include "ecore_private.h" +#include + +#ifdef BUILD_ECORE_EVAS_EXTN + +#include + +#endif + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + + +#ifdef BUILD_ECORE_EVAS_EXTN + + +typedef struct _Shmfile Shmfile; + +struct _Shmfile +{ + int fd; + int size; + void *addr; + const char *file; +}; + +static int blank = 0x00000000; + +static Shmfile * +shmfile_new(const char *base, int id, int size, Eina_Bool sys) +{ + Shmfile *sf; + char file[PATH_MAX]; + + sf = calloc(1, sizeof(Shmfile)); + do + { + mode_t mode; + + snprintf(file, sizeof(file), "/%s-%i-%i.%i.%i", + base, id, (int)time(NULL), (int)getpid(), (int)rand()); + mode = S_IRUSR | S_IWUSR; + if (sys) mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + sf->fd = shm_open(file, O_RDWR | O_CREAT | O_EXCL, mode); + } + while (sf->fd < 0); + + sf->file = eina_stringshare_add(file); + if (!sf->file) + { + close(sf->fd); + shm_unlink(sf->file); + eina_stringshare_del(sf->file); + free(sf); + return NULL; + } + sf->size = size; + if (ftruncate(sf->fd, size) < 0) + { + close(sf->fd); + shm_unlink(sf->file); + eina_stringshare_del(sf->file); + free(sf); + return NULL; + } + sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0); + if (sf->addr == MAP_FAILED) + { + close(sf->fd); + shm_unlink(sf->file); + eina_stringshare_del(sf->file); + free(sf); + return NULL; + } + return sf; +} + +void +shmfile_free(Shmfile *sf) +{ + munmap(sf->addr, sf->size); + close(sf->fd); + shm_unlink(sf->file); + eina_stringshare_del(sf->file); + free(sf); +} + +static Shmfile * +shmfile_open(const char *ref, int size, Eina_Bool sys) +{ + Shmfile *sf; + mode_t mode; + + sf = calloc(1, sizeof(Shmfile)); + mode = S_IRUSR | S_IWUSR; + if (sys) mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + sf->fd = shm_open(ref, O_RDWR, mode); + if (sf->fd < 0) + { + free(sf); + return NULL; + } + sf->file = eina_stringshare_add(ref); + if (!sf->file) + { + close(sf->fd); + eina_stringshare_del(sf->file); + free(sf); + return NULL; + } + sf->size = size; + sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0); + if (sf->addr == MAP_FAILED) + { + close(sf->fd); + eina_stringshare_del(sf->file); + free(sf); + return NULL; + } + return sf; +} + +void +shmfile_close(Shmfile *sf) +{ + munmap(sf->addr, sf->size); + close(sf->fd); + eina_stringshare_del(sf->file); + free(sf); +} + +// procotol version - change this as needed +#define MAJOR 0x1011 + +enum // opcodes +{ + OP_RESIZE, + OP_SHOW, + OP_HIDE, + OP_FOCUS, + OP_UNFOCUS, + OP_UPDATE, + OP_UPDATE_DONE, + OP_LOCK_FILE, + OP_SHM_REF, + OP_EV_MOUSE_IN, + OP_EV_MOUSE_OUT, + OP_EV_MOUSE_UP, + OP_EV_MOUSE_DOWN, + OP_EV_MOUSE_MOVE, + OP_EV_MOUSE_WHEEL, + OP_EV_MULTI_UP, + OP_EV_MULTI_DOWN, + OP_EV_MULTI_MOVE, + OP_EV_KEY_UP, + OP_EV_KEY_DOWN, + OP_EV_HOLD +}; + +enum +{ + MOD_SHIFT = (1 << 0), + MOD_CTRL = (1 << 1), + MOD_ALT = (1 << 2), + MOD_META = (1 << 3), + MOD_HYPER = (1 << 4), + MOD_SUPER = (1 << 5), + MOD_CAPS = (1 << 6), + MOD_NUM = (1 << 7), + MOD_SCROLL = (1 << 8), +}; + +typedef struct _Ipc_Data_Resize Ipc_Data_Resize; +typedef struct _Ipc_Data_Update Ipc_Data_Update; +typedef struct _Ipc_Data_Ev_Mouse_In Ipc_Data_Ev_Mouse_In; +typedef struct _Ipc_Data_Ev_Mouse_Out Ipc_Data_Ev_Mouse_Out; +typedef struct _Ipc_Data_Ev_Mouse_Up Ipc_Data_Ev_Mouse_Up; +typedef struct _Ipc_Data_Ev_Mouse_Down Ipc_Data_Ev_Mouse_Down; +typedef struct _Ipc_Data_Ev_Mouse_Move Ipc_Data_Ev_Mouse_Move; +typedef struct _Ipc_Data_Ev_Mouse_Wheel Ipc_Data_Ev_Mouse_Wheel; +typedef struct _Ipc_Data_Ev_Hold Ipc_Data_Ev_Hold; +typedef struct _Ipc_Data_Ev_Multi_Up Ipc_Data_Ev_Multi_Up; +typedef struct _Ipc_Data_Ev_Multi_Down Ipc_Data_Ev_Multi_Down; +typedef struct _Ipc_Data_Ev_Multi_Move Ipc_Data_Ev_Multi_Move; +typedef struct _Ipc_Data_Ev_Key_Up Ipc_Data_Ev_Key_Up; +typedef struct _Ipc_Data_Ev_Key_Down Ipc_Data_Ev_Key_Down; + +struct _Ipc_Data_Resize +{ + int w, h; +}; + +struct _Ipc_Data_Update +{ + int x, w, y, h; +}; + +struct _Ipc_Data_Ev_Mouse_In +{ + unsigned int timestamp; + int mask; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Mouse_Out +{ + unsigned int timestamp; + int mask; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Mouse_Up +{ + int b; + Evas_Button_Flags flags; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Mouse_Down +{ + int b; + Evas_Button_Flags flags; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Mouse_Move +{ + int x, y; + Evas_Button_Flags flags; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Mouse_Wheel +{ + int direction, z; + Evas_Button_Flags flags; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Hold +{ + int hold; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Multi_Up +{ + Evas_Button_Flags flags; + int d, x, y; + double rad, radx, rady, pres, ang, fx, fy; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Multi_Down +{ + Evas_Button_Flags flags; + int d, x, y; + double rad, radx, rady, pres, ang, fx, fy; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Multi_Move +{ + int d, x, y; + double rad, radx, rady, pres, ang, fx, fy; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Key_Up +{ + const char *keyname, *key, *string, *compose; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +struct _Ipc_Data_Ev_Key_Down +{ + const char *keyname, *key, *string, *compose; + int mask; + unsigned int timestamp; + Evas_Event_Flags event_flags; +}; + +typedef struct _Extn Extn; + +struct _Extn +{ + struct { + Ecore_Ipc_Server *server; + Eina_List *clients; + Eina_List *handlers; + Eina_Bool am_server : 1; + } ipc; + struct { + const char *name; + int num; + Eina_Bool sys : 1; + } svc; + struct { + const char *lock; + int lockfd; + const char *shm; + int w, h; + Shmfile *shmfile; + Eina_List *updates; + Eina_Bool have_lock : 1; + Eina_Bool have_real_lock : 1; + } file; +}; + +static Eina_List *extn_ee_list = NULL; + +EAPI int ECORE_EVAS_EXTN_CLIENT_ADD = 0; +EAPI int ECORE_EVAS_EXTN_CLIENT_DEL = 0; + +void +_ecore_evas_extn_init(void) +{ + if (ECORE_EVAS_EXTN_CLIENT_ADD) return; + ECORE_EVAS_EXTN_CLIENT_ADD = ecore_event_type_new(); + ECORE_EVAS_EXTN_CLIENT_DEL = ecore_event_type_new(); +} + +void +_ecore_evas_extn_shutdown(void) +{ +} + +static void +_ecore_evas_extn_event_free(void *data, void *ev EINA_UNUSED) +{ + Ecore_Evas *ee = data; + if (ee->engine.buffer.image) + evas_object_unref(ee->engine.buffer.image); + _ecore_evas_unref(ee); +} + +static void +_ecore_evas_extn_event(Ecore_Evas *ee, int event) +{ + _ecore_evas_ref(ee); + if (ee->engine.buffer.image) + evas_object_ref(ee->engine.buffer.image); + ecore_event_add(event, ee->engine.buffer.image, + _ecore_evas_extn_event_free, ee); +} + +static Eina_Bool +_ecore_evas_lock_other_have(Ecore_Evas *ee) +{ + Eina_List *l; + Ecore_Evas *ee2; + Extn *extn, *extn2; + + extn = ee->engine.buffer.data; + if (!extn) return EINA_FALSE; + // brute force - i know. i expect extn_ee_list to be fairly short. could + // be improved with a hash of lockfiles + EINA_LIST_FOREACH(extn_ee_list, l, ee2) + { + if (ee == ee2) continue; + extn2 = ee2->engine.buffer.data; + if (!extn2) continue; + if ((extn->file.lock) && (extn2->file.lock) && + (!strcmp(extn->file.lock, extn2->file.lock)) && + (extn2->file.have_real_lock)) + return EINA_TRUE; + } + return EINA_FALSE; +} + +static void +_ecore_evas_socket_lock(Ecore_Evas *ee) +{ + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->file.lockfd < 0) return; + if (extn->file.have_lock) return; + extn->file.have_lock = EINA_TRUE; + if (_ecore_evas_lock_other_have(ee)) return; + flock(extn->file.lockfd, LOCK_EX); + extn->file.have_real_lock = EINA_TRUE; +} + +static void +_ecore_evas_socket_unlock(Ecore_Evas *ee) +{ + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->file.lockfd < 0) return; + if (!extn->file.have_lock) return; + extn->file.have_lock = EINA_FALSE; + if (!extn->file.have_real_lock) return; + flock(extn->file.lockfd, LOCK_UN); +} + +static void +_ecore_evas_extn_plug_targer_render_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + if (ee) _ecore_evas_socket_lock(ee); +} + +static void +_ecore_evas_extn_plug_targer_render_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + if (ee) _ecore_evas_socket_unlock(ee); +} + +static void +_ecore_evas_extn_plug_image_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + if (ee) ecore_evas_free(ee); +} + +static void +_ecore_evas_extn_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y) +{ + Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh; + + evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, &ww, &hh); + evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh); + + if (fw < 1) fw = 1; + if (fh < 1) fh = 1; + + if (evas_object_map_get(ee->engine.buffer.image) && + evas_object_map_enable_get(ee->engine.buffer.image)) + { + fx = 0; fy = 0; + fw = ee->w; fh = ee->h; + ww = ee->w; hh = ee->h; + } + + if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh)) + { + *x = (ee->w * (*x - xx)) / fw; + *y = (ee->h * (*y - yy)) / fh; + } + else + { + xx = (*x - xx) - fx; + while (xx < 0) xx += fw; + while (xx > fw) xx -= fw; + *x = (ee->w * xx) / fw; + + yy = (*y - yy) - fy; + while (yy < 0) yy += fh; + while (yy > fh) yy -= fh; + *y = (ee->h * yy) / fh; + } +} + +static void +_ecore_evas_extn_free(Ecore_Evas *ee) +{ + Extn *extn; + Ecore_Ipc_Client *client; + + extn = ee->engine.buffer.data; + if (extn) + { + Ecore_Event_Handler *hdl; + + if (extn->file.have_lock) + _ecore_evas_socket_unlock(ee); + if (extn->file.lockfd) + { + close(extn->file.lockfd); + if (extn->ipc.am_server) + { + if (extn->file.lock) unlink(extn->file.lock); + } + } + if (extn->svc.name) eina_stringshare_del(extn->svc.name); + if (extn->ipc.clients) + { + EINA_LIST_FREE(extn->ipc.clients, client) + ecore_ipc_client_del(client); + } + if (extn->ipc.server) ecore_ipc_server_del(extn->ipc.server); + if (extn->file.lock) eina_stringshare_del(extn->file.lock); + if (extn->file.shm) eina_stringshare_del(extn->file.shm); + if (extn->file.shmfile) + { + if (extn->ipc.am_server) + shmfile_free(extn->file.shmfile); + else + shmfile_close(extn->file.shmfile); + } + + EINA_LIST_FREE(extn->ipc.handlers, hdl) + ecore_event_handler_del(hdl); + free(extn); + ecore_ipc_shutdown(); + ee->engine.buffer.data = NULL; + } + if (ee->engine.buffer.image) + { + Ecore_Evas *ee2; + + evas_object_event_callback_del_full(ee->engine.buffer.image, + EVAS_CALLBACK_DEL, + _ecore_evas_extn_plug_image_obj_del, + ee); + evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image), + EVAS_CALLBACK_RENDER_PRE, + _ecore_evas_extn_plug_targer_render_pre, + ee); + evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image), + EVAS_CALLBACK_RENDER_POST, + _ecore_evas_extn_plug_targer_render_post, + ee); + evas_object_del(ee->engine.buffer.image); + ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent"); + if (ee2) + { + ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee); + } + } + extn_ee_list = eina_list_remove(extn_ee_list, ee); +} + +static void +_ecore_evas_resize(Ecore_Evas *ee, int w, int h) +{ + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->req.w = w; + ee->req.h = h; + if ((w == ee->w) && (h == ee->h)) return; + ee->w = w; + ee->h = h; + + /* + * No need for it if not used later. + Extn *extn; + + extn = ee->engine.buffer.data; + */ + if (ee->engine.buffer.image) + evas_object_image_size_set(ee->engine.buffer.image, ee->w, ee->h); + /* Server can have many plugs, so I block resize comand from client to server * + if ((extn) && (extn->ipc.server)) + { + Ipc_Data_Resize ipc; + + ipc.w = ee->w; + ipc.h = ee->h; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_RESIZE, 0, 0, 0, &ipc, sizeof(ipc)); + }*/ + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h) +{ + _ecore_evas_resize(ee, w, h); +} + +static int +_ecore_evas_modifiers_locks_mask_get(Evas *e) +{ + int mask = 0; + + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift")) + mask |= MOD_SHIFT; + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control")) + mask |= MOD_CTRL; + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt")) + mask |= MOD_ALT; + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta")) + mask |= MOD_META; + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper")) + mask |= MOD_HYPER; + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super")) + mask |= MOD_SUPER; + if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock")) + mask |= MOD_SCROLL; + if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock")) + mask |= MOD_NUM; + if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock")) + mask |= MOD_CAPS; + return mask; +} + +static void +_ecore_evas_modifiers_locks_mask_set(Evas *e, int mask) +{ + if (mask & MOD_SHIFT) evas_key_modifier_on (e, "Shift"); + else evas_key_modifier_off(e, "Shift"); + if (mask & MOD_CTRL) evas_key_modifier_on (e, "Control"); + else evas_key_modifier_off(e, "Control"); + if (mask & MOD_ALT) evas_key_modifier_on (e, "Alt"); + else evas_key_modifier_off(e, "Alt"); + if (mask & MOD_META) evas_key_modifier_on (e, "Meta"); + else evas_key_modifier_off(e, "Meta"); + if (mask & MOD_HYPER) evas_key_modifier_on (e, "Hyper"); + else evas_key_modifier_off(e, "Hyper"); + if (mask & MOD_SUPER) evas_key_modifier_on (e, "Super"); + else evas_key_modifier_off(e, "Super"); + if (mask & MOD_SCROLL) evas_key_lock_on (e, "Scroll_Lock"); + else evas_key_lock_off(e, "Scroll_Lock"); + if (mask & MOD_NUM) evas_key_lock_on (e, "Num_Lock"); + else evas_key_lock_off(e, "Num_Lock"); + if (mask & MOD_CAPS) evas_key_lock_on (e, "Caps_Lock"); + else evas_key_lock_off(e, "Caps_Lock"); +} + +static void +_ecore_evas_extn_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_In *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Mouse_In ipc; + memset(&ipc, 0, sizeof(ipc)); + + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_IN, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + +static void +_ecore_evas_extn_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Out *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Mouse_Out ipc; + memset(&ipc, 0, sizeof(ipc)); + + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_OUT, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + +static void +_ecore_evas_extn_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Down *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + /* We have send mouse move event before mouse down event */ + { + Ipc_Data_Ev_Mouse_Move ipc_move; + memset(&ipc_move, 0, sizeof(ipc_move)); + Evas_Coord x, y; + + x = ev->canvas.x; + y = ev->canvas.y; + _ecore_evas_extn_coord_translate(ee, &x, &y); + ipc_move.x = x; + ipc_move.y = y; + ipc_move.timestamp = ev->timestamp; + ipc_move.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc_move.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc_move, sizeof(ipc_move)); + } + { + Ipc_Data_Ev_Mouse_Down ipc; + memset(&ipc, 0, sizeof(ipc)); + ipc.b = ev->button; + ipc.flags = ev->flags; + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_DOWN, 0, 0, 0, &ipc, sizeof(ipc)); + } + } +} + +static void +_ecore_evas_extn_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Up *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Mouse_Up ipc; + memset(&ipc, 0, sizeof(ipc)); + + ipc.b = ev->button; + ipc.flags = ev->flags; + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_UP, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + +static void +_ecore_evas_extn_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Move *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Mouse_Move ipc; + memset(&ipc, 0, sizeof(ipc)); + Evas_Coord x, y; + + x = ev->cur.canvas.x; + y = ev->cur.canvas.y; + _ecore_evas_extn_coord_translate(ee, &x, &y); + ipc.x = x; + ipc.y = y; + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_MOVE, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + +static void +_ecore_evas_extn_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Mouse_Wheel *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Mouse_Wheel ipc; + memset(&ipc, 0, sizeof(ipc)); + + ipc.direction = ev->direction; + ipc.z = ev->z; + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MOUSE_WHEEL, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + +static void +_ecore_evas_extn_cb_multi_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Multi_Down *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Multi_Down ipc; + memset(&ipc, 0, sizeof(ipc)); + Evas_Coord x, y; + + ipc.d = ev->device; + x = ev->canvas.x; + y = ev->canvas.y; + _ecore_evas_extn_coord_translate(ee, &x, &y); + ipc.x = x; + ipc.y = y; + ipc.rad = ev->radius; + ipc.radx = ev->radius_x; + ipc.rady = ev->radius_y; + ipc.pres = ev->pressure; + ipc.ang = ev->angle; + ipc.fx = ev->canvas.xsub; + ipc.fy = ev->canvas.ysub; + ipc.flags = ev->flags; + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_DOWN, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + + +static void +_ecore_evas_extn_cb_multi_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Multi_Up *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Multi_Up ipc; + memset(&ipc, 0, sizeof(ipc)); + Evas_Coord x, y; + + ipc.d = ev->device; + x = ev->canvas.x; + y = ev->canvas.y; + _ecore_evas_extn_coord_translate(ee, &x, &y); + ipc.x = x; + ipc.y = y; + ipc.rad = ev->radius; + ipc.radx = ev->radius_x; + ipc.rady = ev->radius_y; + ipc.pres = ev->pressure; + ipc.ang = ev->angle; + ipc.fx = ev->canvas.xsub; + ipc.fy = ev->canvas.ysub; + ipc.flags = ev->flags; + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_UP, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + +static void +_ecore_evas_extn_cb_multi_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Multi_Move *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Multi_Move ipc; + memset(&ipc, 0, sizeof(ipc)); + Evas_Coord x, y; + + ipc.d = ev->device; + x = ev->cur.canvas.x; + y = ev->cur.canvas.y; + _ecore_evas_extn_coord_translate(ee, &x, &y); + ipc.x = x; + ipc.y = y; + ipc.rad = ev->radius; + ipc.radx = ev->radius_x; + ipc.rady = ev->radius_y; + ipc.pres = ev->pressure; + ipc.ang = ev->angle; + ipc.fx = ev->cur.canvas.xsub; + ipc.fy = ev->cur.canvas.ysub; + ipc.timestamp = ev->timestamp; + ipc.mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_MULTI_MOVE, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + +static void +_ecore_evas_extn_cb_free(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + + ee = data; + if (ee->driver) _ecore_evas_free(ee); +} + +static void +_ecore_evas_extn_cb_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Key_Down *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Key_Down *ipc; + char *st, *p; + int len = 0; + + len = sizeof(Ipc_Data_Ev_Key_Down); + if (ev->key) len += strlen(ev->key) + 1; + if (ev->keyname) len += strlen(ev->keyname) + 1; + if (ev->string) len += strlen(ev->string) + 1; + if (ev->compose) len += strlen(ev->compose) + 1; + len += 1; + st = alloca(len); + ipc = (Ipc_Data_Ev_Key_Down *)st; + memset(st, 0, len); + p = st + sizeof(Ipc_Data_Ev_Key_Down); + if (ev->key) + { + strcpy(p, ev->key); + ipc->key = p - (long)st; + p += strlen(p) + 1; + } + if (ev->keyname) + { + strcpy(p, ev->keyname); + ipc->keyname = p - (long)st; + p += strlen(p) + 1; + } + if (ev->string) + { + strcpy(p, ev->string); + ipc->string = p - (long)st; + p += strlen(p) + 1; + } + if (ev->compose) + { + strcpy(p, ev->compose); + ipc->compose = p - (long)st; + p += strlen(p) + 1; + } + ipc->timestamp = ev->timestamp; + ipc->mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc->event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_KEY_DOWN, 0, 0, 0, ipc, len); + } +} + +static void +_ecore_evas_extn_cb_key_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Key_Up *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Key_Up *ipc; + char *st, *p; + int len = 0; + + len = sizeof(Ipc_Data_Ev_Key_Up); + if (ev->key) len += strlen(ev->key) + 1; + if (ev->keyname) len += strlen(ev->keyname) + 1; + if (ev->string) len += strlen(ev->string) + 1; + if (ev->compose) len += strlen(ev->compose) + 1; + len += 1; + st = alloca(len); + ipc = (Ipc_Data_Ev_Key_Up *)st; + memset(st, 0, len); + p = st + sizeof(Ipc_Data_Ev_Key_Down); + if (ev->key) + { + strcpy(p, ev->key); + ipc->key = p - (long)st; + p += strlen(p) + 1; + } + if (ev->keyname) + { + strcpy(p, ev->keyname); + ipc->keyname = p - (long)st; + p += strlen(p) + 1; + } + if (ev->string) + { + strcpy(p, ev->string); + ipc->string = p - (long)st; + p += strlen(p) + 1; + } + if (ev->compose) + { + strcpy(p, ev->compose); + ipc->compose = p - (long)st; + p += strlen(p) + 1; + } + ipc->timestamp = ev->timestamp; + ipc->mask = _ecore_evas_modifiers_locks_mask_get(ee->evas); + ipc->event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_KEY_UP, 0, 0, 0, ipc, len); + } +} + +static void +_ecore_evas_extn_cb_hold(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + Ecore_Evas *ee = data; + Evas_Event_Hold *ev = event_info; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return; + if (extn->ipc.server) + { + Ipc_Data_Ev_Hold ipc; + memset(&ipc, 0, sizeof(ipc)); + + ipc.hold = ev->hold; + ipc.timestamp = ev->timestamp; + ipc.event_flags = ev->event_flags; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_EV_HOLD, 0, 0, 0, &ipc, sizeof(ipc)); + } +} + +static void +_ecore_evas_extn_cb_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + Extn *extn; + + ee = data; + ee->prop.focused = 1; + extn = ee->engine.buffer.data; + if (!extn) return; + if (!extn->ipc.server) return; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_FOCUS, 0, 0, 0, NULL, 0); +} + +static void +_ecore_evas_extn_cb_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + Extn *extn; + + ee = data; + ee->prop.focused = 0; + extn = ee->engine.buffer.data; + if (!extn) return; + if (!extn->ipc.server) return; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_UNFOCUS, 0, 0, 0, NULL, 0); +} + +static void +_ecore_evas_extn_cb_show(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + Extn *extn; + + ee = data; + ee->visible = 1; + extn = ee->engine.buffer.data; + if (!extn) return; + if (!extn->ipc.server) return; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_SHOW, 0, 0, 0, NULL, 0); +} + +static void +_ecore_evas_extn_cb_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + Extn *extn; + + ee = data; + ee->visible = 0; + extn = ee->engine.buffer.data; + if (!extn) return; + if (!extn->ipc.server) return; + ecore_ipc_server_send(extn->ipc.server, MAJOR, OP_HIDE, 0, 0, 0, NULL, 0); +} + +static const Ecore_Evas_Engine_Func _ecore_extn_plug_engine_func = +{ + _ecore_evas_extn_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, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, //transparent + NULL, // profiles_set + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, // render + NULL, // screen_geometry_get + NULL // screen_dpi_get +}; + +static Eina_Bool +_ipc_server_add(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Ipc_Event_Server_Add *e = event; + Ecore_Evas *ee = data; + Extn *extn; + + if (ee != ecore_ipc_server_data_get(e->server)) + return ECORE_CALLBACK_PASS_ON; + if (!eina_list_data_find(extn_ee_list, ee)) + return ECORE_CALLBACK_PASS_ON; + extn = ee->engine.buffer.data; + if (!extn) return ECORE_CALLBACK_PASS_ON; + //FIXME: find a way to let app know server there + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ipc_server_del(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Ipc_Event_Server_Del *e = event; + Ecore_Evas *ee = data; + Extn *extn; + + extn = ee->engine.buffer.data; + if (!extn) return ECORE_CALLBACK_PASS_ON; + if (extn->ipc.server != e->server) return ECORE_CALLBACK_PASS_ON; + evas_object_image_data_set(ee->engine.buffer.image, NULL); + ee->engine.buffer.pixels = NULL; + if (extn->file.shmfile) + { + shmfile_close(extn->file.shmfile); + extn->file.shmfile = NULL; + } + if (extn->file.shm) + { + eina_stringshare_del(extn->file.shm); + extn->file.shm = NULL; + } + extn->ipc.server = NULL; + if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ipc_server_data(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Ipc_Event_Server_Data *e = event; + Ecore_Evas *ee = data; + Extn *extn; + + if (ee != ecore_ipc_server_data_get(e->server)) + return ECORE_CALLBACK_PASS_ON; + if (!eina_list_data_find(extn_ee_list, ee)) + return ECORE_CALLBACK_PASS_ON; + extn = ee->engine.buffer.data; + if (!extn) return ECORE_CALLBACK_PASS_ON; + if (e->major != MAJOR) + return ECORE_CALLBACK_PASS_ON; + switch (e->minor) + { + case OP_UPDATE: + // add rect to update list + if (e->size >= (int)sizeof(Ipc_Data_Update)) + { + Ipc_Data_Update *ipc = malloc(sizeof(Ipc_Data_Update)); + if (ipc) + { + memcpy(ipc, e->data, sizeof(Ipc_Data_Update)); + extn->file.updates = eina_list_append(extn->file.updates, ipc); + } + } + break; + case OP_UPDATE_DONE: + // updates finished being sent - done now. frame ready + { + Ipc_Data_Update *ipc; + + EINA_LIST_FREE(extn->file.updates, ipc) + { + if (ee->engine.buffer.image) + evas_object_image_data_update_add(ee->engine.buffer.image, + ipc->x, ipc->y, + ipc->w, ipc->h); + } + } + break; + case OP_LOCK_FILE: + if ((e->data) && (e->size > 0) && + (((unsigned char *)e->data)[e->size - 1] == 0)) + { + if (extn->file.have_lock) _ecore_evas_socket_unlock(ee); + if (extn->file.lockfd) close(extn->file.lockfd); + if (extn->file.lock) eina_stringshare_del(extn->file.lock); + extn->file.lock = eina_stringshare_add(e->data); + extn->file.lockfd = open(extn->file.lock, O_RDONLY); + } + break; + case OP_SHM_REF: + // e->ref == w + // e->ref_to == h + // e->response == alpha + // e->data = shm ref string + nul byte + if ((e->data) && ((unsigned char *)e->data)[e->size - 1] == 0) + { + ee->engine.buffer.pixels = NULL; + if (extn->file.shmfile) + { + shmfile_close(extn->file.shmfile); + extn->file.shmfile = NULL; + } + if (extn->file.shm) + { + eina_stringshare_del(extn->file.shm); + extn->file.shm = NULL; + } + if ((e->ref > 0) && (e->ref_to > 0)) + { + extn->file.w = e->ref; + extn->file.h = e->ref_to; + extn->file.shm = eina_stringshare_add(e->data); + extn->file.shmfile = shmfile_open(extn->file.shm, + extn->file.w * + extn->file.h * 4, + EINA_TRUE); + if (extn->file.shmfile) + { + ee->engine.buffer.pixels = extn->file.shmfile->addr; + if (ee->engine.buffer.image) + { + if (e->response) + evas_object_image_alpha_set(ee->engine.buffer.image, + EINA_TRUE); + else + evas_object_image_alpha_set(ee->engine.buffer.image, + EINA_FALSE); + evas_object_image_size_set(ee->engine.buffer.image, + extn->file.w, + extn->file.h); + evas_object_image_data_set(ee->engine.buffer.image, + ee->engine.buffer.pixels); + evas_object_image_data_update_add(ee->engine.buffer.image, + 0, 0, + extn->file.w, + extn->file.h); + _ecore_evas_resize(ee, + extn->file.w, + extn->file.h); + } + else + evas_object_image_data_set(ee->engine.buffer.image, NULL); + } + else + evas_object_image_data_set(ee->engine.buffer.image, NULL); + } + else + evas_object_image_data_set(ee->engine.buffer.image, NULL); + } + break; + case OP_RESIZE: + if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize))) + { + Ipc_Data_Resize *ipc = e->data; + _ecore_evas_resize(ee, ipc->w, ipc->h); + } + break; + default: + break; + } + return ECORE_CALLBACK_PASS_ON; +} +#else +void +_ecore_evas_extn_init(void) +{ +} + +void +_ecore_evas_extn_shutdown(void) +{ +} + +#endif /* BUILD_ECORE_EVAS_EXTN */ + +EAPI Evas_Object * +ecore_evas_extn_plug_new(Ecore_Evas *ee_target) +{ +#ifdef BUILD_ECORE_EVAS_EXTN + Evas_Object *o; + Ecore_Evas *ee; + int w = 1, h = 1; + + if (!ee_target) return NULL; + + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + o = evas_object_image_filled_add(ee_target->evas); + /* this make problem in gl engine, so I'll block this until solve problem + evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);*/ + evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888); + evas_object_image_alpha_set(o, 1); + evas_object_image_size_set(o, 1, 1); + evas_object_image_data_set(o, &blank); + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_plug_engine_func; + + ee->driver = "extn_plug"; + + ee->rotation = 0; + ee->visible = 0; + ee->w = w; + ee->h = h; + ee->req.w = ee->w; + ee->req.h = ee->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; + + 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_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_IN, + _ecore_evas_extn_cb_mouse_in, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_OUT, + _ecore_evas_extn_cb_mouse_out, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_DOWN, + _ecore_evas_extn_cb_mouse_down, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_UP, + _ecore_evas_extn_cb_mouse_up, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_MOVE, + _ecore_evas_extn_cb_mouse_move, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_WHEEL, + _ecore_evas_extn_cb_mouse_wheel, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MULTI_DOWN, + _ecore_evas_extn_cb_multi_down, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MULTI_UP, + _ecore_evas_extn_cb_multi_up, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MULTI_MOVE, + _ecore_evas_extn_cb_multi_move, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_FREE, + _ecore_evas_extn_cb_free, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_KEY_DOWN, + _ecore_evas_extn_cb_key_down, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_KEY_UP, + _ecore_evas_extn_cb_key_up, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_HOLD, + _ecore_evas_extn_cb_hold, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_FOCUS_IN, + _ecore_evas_extn_cb_focus_in, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_FOCUS_OUT, + _ecore_evas_extn_cb_focus_out, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_SHOW, + _ecore_evas_extn_cb_show, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_HIDE, + _ecore_evas_extn_cb_hide, ee); + + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_DEL, + _ecore_evas_extn_plug_image_obj_del, ee); + + + extn_ee_list = eina_list_append(extn_ee_list, ee); + ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee); + + evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_PRE, + _ecore_evas_extn_plug_targer_render_pre, ee); + evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_POST, + _ecore_evas_extn_plug_targer_render_post, ee); + return o; +#else + return NULL; +#endif +} + +EAPI Eina_Bool +ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys) +{ +#ifdef BUILD_ECORE_EVAS_EXTN + Extn *extn; + Ecore_Evas *ee = NULL; + + if (!obj) return EINA_FALSE; + + ee = evas_object_data_get(obj, "Ecore_Evas"); + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) return EINA_FALSE; + + if (!svcname) + { + ee->engine.buffer.data = NULL; + return EINA_FALSE; + } + + extn = calloc(1, sizeof(Extn)); + if (!extn) return EINA_FALSE; + + Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER; + + ecore_ipc_init(); + extn->svc.name = eina_stringshare_add(svcname); + extn->svc.num = svcnum; + extn->svc.sys = svcsys; + + if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM; + extn->ipc.server = ecore_ipc_server_connect(ipctype, (char *)extn->svc.name, + extn->svc.num, ee); + if (!extn->ipc.server) + { + ee->engine.buffer.data = NULL; + eina_stringshare_del(extn->svc.name); + free(extn); + ecore_ipc_shutdown(); + return EINA_FALSE; + } + ee->engine.buffer.data = extn; + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, + _ipc_server_add, ee)); + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, + _ipc_server_del, ee)); + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, + _ipc_server_data, ee)); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +EAPI void +ecore_evas_extn_plug_object_data_lock(Evas_Object *obj) +{ +#ifdef BUILD_ECORE_EVAS_EXTN + Ecore_Evas *ee; + + ee = ecore_evas_object_ecore_evas_get(obj); + if (!ee) return; + _ecore_evas_socket_lock(ee); +#endif +} + +EAPI void +ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj) +{ +#ifdef BUILD_ECORE_EVAS_EXTN + Ecore_Evas *ee; + + ee = ecore_evas_object_ecore_evas_get(obj); + if (!ee) return; + _ecore_evas_socket_unlock(ee); +#endif +} + +#ifdef BUILD_ECORE_EVAS_EXTN +static void +_ecore_evas_socket_resize(Ecore_Evas *ee, int w, int h) +{ + Extn *extn; + Evas_Engine_Info_Buffer *einfo; + int stride = 0; + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->req.w = w; + ee->req.h = 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); + extn = ee->engine.buffer.data; + if (extn) + { + if (extn->file.shmfile) + shmfile_free(extn->file.shmfile); + ee->engine.buffer.pixels = NULL; + extn->file.shmfile = shmfile_new(extn->svc.name, extn->svc.num, + ee->w * ee->h * 4, extn->svc.sys); + if (extn->file.shmfile) + ee->engine.buffer.pixels = extn->file.shmfile->addr; + + stride = ee->w * 4; + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; + einfo->info.dest_buffer_row_bytes = stride; + 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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + } + + if (extn->ipc.clients && extn->file.shmfile) + { + Ipc_Data_Resize ipc; + Eina_List *l; + Ecore_Ipc_Client *client; + + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_SHM_REF, + ee->w, ee->h, ee->alpha, + extn->file.shmfile->file, + strlen(extn->file.shmfile->file) + 1); + ipc.w = ee->w; + ipc.h = ee->h; + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_RESIZE, + 0, 0, 0, &ipc, sizeof(ipc)); + } + } + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_socket_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h) +{ + _ecore_evas_socket_resize(ee, w, h); +} + +int +_ecore_evas_extn_socket_render(Ecore_Evas *ee) +{ + Eina_List *updates = NULL, *l, *ll; + Ecore_Evas *ee2; + int rend = 0; + Eina_Rectangle *r; + Extn *extn; + Ecore_Ipc_Client *client; + + extn = ee->engine.buffer.data; + if (!extn) return rend; + EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) + { + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + + if (ee->engine.buffer.pixels) + { + _ecore_evas_socket_lock(ee); + updates = evas_render_updates(ee->evas); + _ecore_evas_socket_unlock(ee); + } + EINA_LIST_FOREACH(updates, l, r) + { + Ipc_Data_Update ipc; + + + ipc.x = r->x; + ipc.y = r->y; + ipc.w = r->w; + ipc.h = r->h; + EINA_LIST_FOREACH(extn->ipc.clients, ll, client) + ecore_ipc_client_send(client, MAJOR, OP_UPDATE, 0, 0, 0, &ipc, sizeof(ipc)); + } + if (updates) + { + evas_render_updates_free(updates); + _ecore_evas_idle_timeout_update(ee); + EINA_LIST_FOREACH(extn->ipc.clients, ll, client) + ecore_ipc_client_send(client, MAJOR, OP_UPDATE_DONE, 0, 0, 0, NULL, 0); + } + + if (ee->func.fn_post_render) ee->func.fn_post_render(ee); + return updates ? 1 : rend; +} + +static Eina_Bool +_ipc_client_add(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Ipc_Event_Client_Add *e = event; + Ecore_Evas *ee = data; + Extn *extn; + + if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client))) + return ECORE_CALLBACK_PASS_ON; + if (!eina_list_data_find(extn_ee_list, ee)) + return ECORE_CALLBACK_PASS_ON; + extn = ee->engine.buffer.data; + if (!extn) return ECORE_CALLBACK_PASS_ON; + + extn->ipc.clients = eina_list_append(extn->ipc.clients, e->client); + ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE, 0, 0, 0, extn->file.lock, strlen(extn->file.lock) + 1); + + if (extn->file.shmfile) + { + Ipc_Data_Resize ipc; + + ecore_ipc_client_send(e->client, MAJOR, OP_SHM_REF, + ee->w, ee->h, ee->alpha, + extn->file.shmfile->file, + strlen(extn->file.shmfile->file) + 1); + ipc.w = ee->w; + ipc.h = ee->h; + + ecore_ipc_client_send(e->client, MAJOR, OP_RESIZE, + 0, 0, 0, &ipc, sizeof(ipc)); + } + _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_ADD); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ipc_client_del(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Ipc_Event_Client_Del *e = event; + Ecore_Evas *ee = data; + Extn *extn; + extn = ee->engine.buffer.data; + if (!extn) return ECORE_CALLBACK_PASS_ON; + if (!eina_list_data_find(extn->ipc.clients, e->client)) return ECORE_CALLBACK_PASS_ON; + + extn->ipc.clients = eina_list_remove(extn->ipc.clients, e->client); + + _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_DEL); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ipc_client_data(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Ipc_Event_Client_Data *e = event; + Ecore_Evas *ee = data; + Extn *extn; + + if (ee != ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client))) + return ECORE_CALLBACK_PASS_ON; + if (!eina_list_data_find(extn_ee_list, ee)) + return ECORE_CALLBACK_PASS_ON; + extn = ee->engine.buffer.data; + if (!extn) return ECORE_CALLBACK_PASS_ON; + if (e->major != MAJOR) + return ECORE_CALLBACK_PASS_ON; + switch (e->minor) + { + case OP_RESIZE: + if ((e->data) && (e->size >= (int)sizeof(Ipc_Data_Resize))) + { + + Ipc_Data_Resize *ipc = e->data; + /* create callbacke data size changed */ + _ecore_evas_socket_resize(ee, ipc->w, ipc->h); + } + break; + case OP_SHOW: + if (!ee->visible) + { + ee->visible = 1; + if (ee->func.fn_show) ee->func.fn_show(ee); + } + break; + case OP_HIDE: + if (ee->visible) + { + ee->visible = 0; + if (ee->func.fn_hide) ee->func.fn_hide(ee); + } + break; + case OP_FOCUS: + if (!ee->prop.focused) + { + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + } + break; + case OP_UNFOCUS: + if (ee->prop.focused) + { + ee->prop.focused = 0; + evas_focus_out(ee->evas); + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + } + break; + case OP_EV_MOUSE_IN: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_In)) + { + Ipc_Data_Ev_Mouse_In *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_mouse_in(ee->evas, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + case OP_EV_MOUSE_OUT: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Out)) + { + Ipc_Data_Ev_Mouse_Out *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_mouse_out(ee->evas, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + case OP_EV_MOUSE_UP: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Up)) + { + Ipc_Data_Ev_Mouse_Up *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_mouse_up(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + case OP_EV_MOUSE_DOWN: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Down)) + { + Ipc_Data_Ev_Mouse_Up *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_mouse_down(ee->evas, ipc->b, ipc->flags, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + case OP_EV_MOUSE_MOVE: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Move)) + { + Ipc_Data_Ev_Mouse_Move *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_mouse_move(ee->evas, ipc->x, ipc->y, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + case OP_EV_MOUSE_WHEEL: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Mouse_Wheel)) + { + Ipc_Data_Ev_Mouse_Wheel *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_mouse_wheel(ee->evas, ipc->direction, ipc->z, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + case OP_EV_MULTI_UP: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Up)) + { + Ipc_Data_Ev_Multi_Up *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_multi_up(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->flags, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + case OP_EV_MULTI_DOWN: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Down)) + { + Ipc_Data_Ev_Multi_Down *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_multi_down(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->flags, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + case OP_EV_MULTI_MOVE: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Multi_Move)) + { + Ipc_Data_Ev_Multi_Move *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_multi_move(ee->evas, ipc->d, ipc->x, ipc->y, ipc->rad, ipc->radx, ipc->rady, ipc->pres, ipc->ang, ipc->fx, ipc->fy, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + +#define STRGET(val) \ + do { \ + if ((ipc->val) && (ipc->val < (char *)(long)(e->size - 1))) \ + ipc->val = ((char *)ipc) + (long)ipc->val; \ + else \ + ipc->val = NULL; \ + } while (0) + + case OP_EV_KEY_UP: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Up)) + { + if ((e->data) && (e->size > 0) && + (((unsigned char *)e->data)[e->size - 1] == 0)) + { + Ipc_Data_Ev_Key_Up *ipc = e->data; + Evas_Event_Flags flags; + + STRGET(keyname); + STRGET(key); + STRGET(string); + STRGET(compose); + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_key_up(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + } + break; + case OP_EV_KEY_DOWN: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Key_Down)) + { + if ((e->data) && (e->size > 0) && + (((unsigned char *)e->data)[e->size - 1] == 0)) + { + Ipc_Data_Ev_Key_Down *ipc = e->data; + Evas_Event_Flags flags; + + STRGET(keyname); + STRGET(key); + STRGET(string); + STRGET(compose); + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + _ecore_evas_modifiers_locks_mask_set(ee->evas, ipc->mask); + evas_event_feed_key_down(ee->evas, ipc->keyname, ipc->key, ipc->string, ipc->compose, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + } + break; + case OP_EV_HOLD: + if (e->size >= (int)sizeof(Ipc_Data_Ev_Hold)) + { + Ipc_Data_Ev_Hold *ipc = e->data; + Evas_Event_Flags flags; + + flags = evas_event_default_flags_get(ee->evas); + evas_event_default_flags_set(ee->evas, ipc->event_flags); + evas_event_feed_hold(ee->evas, ipc->hold, ipc->timestamp, NULL); + evas_event_default_flags_set(ee->evas, flags); + } + break; + default: + break; + } + return ECORE_CALLBACK_PASS_ON; +} + +static void +_ecore_evas_extn_socket_alpha_set(Ecore_Evas *ee, int alpha) +{ + Extn *extn; + Eina_List *l; + Ecore_Ipc_Client *client; + + if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha))) return; + ee->alpha = alpha; + + extn = ee->engine.buffer.data; + if (extn) + { + Evas_Engine_Info_Buffer *einfo; + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + EINA_LIST_FOREACH(extn->ipc.clients, l, client) + ecore_ipc_client_send(client, MAJOR, OP_SHM_REF, + ee->w, ee->h, ee->alpha, + extn->file.shmfile->file, + strlen(extn->file.shmfile->file) + 1); + } +} + +static const Ecore_Evas_Engine_Func _ecore_extn_socket_engine_func = +{ + _ecore_evas_extn_free, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_socket_resize, + _ecore_evas_socket_move_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, + _ecore_evas_extn_socket_alpha_set, + NULL, //transparent + NULL, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + _ecore_evas_extn_socket_render, // render + NULL, // screen_geometry_get + NULL, // screen_dpi_get +}; + +#endif + +EAPI Ecore_Evas * +ecore_evas_extn_socket_new(int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_EXTN + 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); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_extn_socket_engine_func; + + ee->driver = "extn_socket"; + + ee->rotation = 0; + ee->visible = 0; + ee->w = w; + ee->h = h; + ee->req.w = ee->w; + ee->req.h = ee->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); + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->alpha) + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + else + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.dest_buffer = NULL; + einfo->info.dest_buffer_row_bytes = 0; + 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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + 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"); + + extn_ee_list = eina_list_append(extn_ee_list, ee); + + _ecore_evas_register(ee); + + return ee; +#else + return NULL; +#endif +} + +EAPI Eina_Bool +ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys) +{ +#ifdef BUILD_ECORE_EVAS_EXTN + Extn *extn; + + extn = calloc(1, sizeof(Extn)); + if (!extn) + { + return EINA_FALSE; + } + else + { + Ecore_Ipc_Type ipctype = ECORE_IPC_LOCAL_USER; + char buf[PATH_MAX]; + + ecore_ipc_init(); + extn->svc.name = eina_stringshare_add(svcname); + extn->svc.num = svcnum; + extn->svc.sys = svcsys; + + snprintf(buf, sizeof(buf), "/tmp/ee-lock-XXXXXX"); + extn->file.lockfd = mkstemp(buf); + if (extn->file.lockfd >= 0) + extn->file.lock = eina_stringshare_add(buf); + if ((extn->file.lockfd < 0) || (!extn->file.lock)) + { + if (extn->file.lockfd) + { + close(extn->file.lockfd); + unlink(buf); + } + eina_stringshare_del(extn->svc.name); + if (extn->file.lock) eina_stringshare_del(extn->file.lock); + free(extn); + ecore_ipc_shutdown(); + return EINA_FALSE; + } + + if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM; + extn->ipc.am_server = EINA_TRUE; + extn->ipc.server = ecore_ipc_server_add(ipctype, + (char *)extn->svc.name, + extn->svc.num, ee); + if (!extn->ipc.server) + { + if (extn->file.lockfd) + { + close(extn->file.lockfd); + if (extn->file.lock) unlink(extn->file.lock); + } + eina_stringshare_del(extn->svc.name); + eina_stringshare_del(extn->file.lock); + free(extn); + ecore_ipc_shutdown(); + return EINA_FALSE; + } + ee->engine.buffer.data = extn; + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, + _ipc_client_add, ee)); + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, + _ipc_client_del, ee)); + extn->ipc.handlers = eina_list_append + (extn->ipc.handlers, + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, + _ipc_client_data, ee)); + } + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} diff --git a/src/lib/ecore_evas/ecore_evas_fb.c b/src/lib/ecore_evas/ecore_evas_fb.c new file mode 100644 index 0000000000..0f98e62d06 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_fb.c @@ -0,0 +1,678 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include +#include "ecore_private.h" +#ifdef BUILD_ECORE_EVAS_FB +#include +#include +#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[4] = {NULL, NULL, NULL, NULL}; + +static void +_ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y) +{ + 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); + } +} + +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 EINA_UNUSED) +{ + 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 EINA_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 Eina_Bool +_ecore_evas_event_mouse_button_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Event_Mouse_Button *e; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return ECORE_CALLBACK_PASS_ON; + _ecore_evas_mouse_move_process_fb(ee, e->x, e->y); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_event_mouse_button_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Event_Mouse_Button *e; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return ECORE_CALLBACK_PASS_ON; + _ecore_evas_mouse_move_process_fb(ee, e->x, e->y); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_event_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Event_Mouse_Move *e; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return ECORE_CALLBACK_PASS_ON; + _ecore_evas_mouse_move_process_fb(ee, e->x, e->y); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_event_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Event_Mouse_Wheel *e; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return ECORE_CALLBACK_PASS_ON; + _ecore_evas_mouse_move_process_fb(ee, e->x, e->y); + return ECORE_CALLBACK_PASS_ON; +} + +static int +_ecore_evas_fb_render(Ecore_Evas *ee) +{ + int rend = 0; + + if (ee->visible) + { + Eina_List *updates; + Eina_List *ll; + Ecore_Evas *ee2; + + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + + EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) + { + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + 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(Ecore_Evas *ee, int w, int h) +{ + Eina_File_Direct_Info *info; + Eina_Iterator *ls; + Ecore_Fb_Input_Device *device; + Ecore_Fb_Input_Device_Cap caps; + int mouse_handled = 0; + + _ecore_evas_init_count++; + if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; + + ecore_event_evas_init(); + + /* register all input devices */ + ls = eina_file_direct_ls("/dev/input/"); + + EINA_ITERATOR_FOREACH(ls, info) + { + if (strncmp(info->path + info->name_start, "event", 5) != 0) + continue; + + if (!(device = ecore_fb_input_device_open(info->path))) + continue; + ecore_fb_input_device_window_set(device, ee); + + 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[0] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL); + ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL); + ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL); + ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_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); + } + } + eina_iterator_free(ls); + + if (!mouse_handled) + { + if (ecore_fb_ts_init()) + { + ecore_fb_ts_event_window_set(ee); + ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL); + ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL); + ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_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) +{ + ecore_evas_input_event_unregister(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) +{ + ee->req.w = w; + ee->req.h = 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 EINA_UNUSED, int y EINA_UNUSED, int w, int h) +{ + ee->req.w = w; + ee->req.h = 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 EINA_UNUSED) +{ + 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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + if (!ee->prop.fullscreen) + { + int tmp; + + tmp = ee->w; + ee->w = ee->h; + ee->h = tmp; + ee->req.w = ee->w; + ee->req.h = ee->h; + } + 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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + 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); + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_show(Ecore_Evas *ee) +{ + if (ee->prop.focused) return; + 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_hide(Ecore_Evas *ee) +{ + if (ee->prop.focused) + { + 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_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) + { + 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; + ee->req.w = ee->w; + ee->req.h = ee->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; + ee->req.w = ee->w; + ee->req.h = ee->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 < 4; i++) + { + if (ecore_evas_event_handlers[i]) + ecore_event_handler_del(ecore_evas_event_handlers[i]); + } + ecore_fb_ts_shutdown(); + 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_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, + _ecore_evas_show, + _ecore_evas_hide, + 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, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, // render + NULL, // screen_geometry_get + NULL // screen_dpi_get +}; +#endif + +/** + * @brief Create Ecore_Evas using fb backend. + * @param disp_name The name of the display to be used. + * @param rotation The rotation to be used. + * @param w The width of the Ecore_Evas to be created. + * @param h The height of the Ecore_Evas to be created. + * @return The new Ecore_Evas. + */ +#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(ee, 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->req.w = ee->w; + ee->req.h = ee->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 = 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 && disp_name) + { + einfo->info.virtual_terminal = 0; + einfo->info.device_number = strtol(disp_name, NULL, 10); + einfo->info.refresh = 0; + einfo->info.rotation = ee->rotation; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + + ecore_evas_input_event_register(ee); + + ee->engine.func->fn_render = _ecore_evas_fb_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); + return ee; +} +#else +EAPI Ecore_Evas * +ecore_evas_fb_new(const char *disp_name EINA_UNUSED, int rotation EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + return NULL; +} +#endif diff --git a/src/lib/ecore_evas/ecore_evas_private.h b/src/lib/ecore_evas/ecore_evas_private.h new file mode 100644 index 0000000000..0c7b03043d --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_private.h @@ -0,0 +1,490 @@ +#ifndef _ECORE_EVAS_PRIVATE_H +#define _ECORE_EVAS_PRIVATE_H + +#include +#include +#include +#include +#include + +#define ECORE_MAGIC_EVAS 0x76543211 + +#ifdef BUILD_ECORE_EVAS_X11 +# include +# include +# ifdef HAVE_ECORE_X_XCB +# include +# endif +# ifdef HAVE_ECORE_X_XLIB +# include +# include +# endif +#endif + +#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 +# include +#endif + +#ifdef BUILD_ECORE_EVAS_OPENGL_X11 +# include +#endif + +#ifdef BUILD_ECORE_EVAS_FB +# include +#endif + +#ifdef BUILD_ECORE_EVAS_DIRECTFB +# include +# include "Ecore_DirectFB.h" +#endif + +#if defined(BUILD_ECORE_EVAS_SOFTWARE_BUFFER) || defined(BUILD_ECORE_EVAS_EWS) +# include +#endif + +#ifdef BUILD_ECORE_EVAS_WIN32 +# include "Ecore_Win32.h" +# ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI +# include +# endif +# ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW +# include +# endif +# ifdef BUILD_ECORE_EVAS_DIRECT3D +# include +# endif +# ifdef BUILD_ECORE_EVAS_OPENGL_GLEW +# include +# endif +#endif + +#ifdef BUILD_ECORE_EVAS_GL_COCOA +# include "Ecore_Cocoa.h" +# include +#endif + +#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) +# include "Ecore_Wayland.h" +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +# include +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +# include +#endif + +/** Log domain macros and variables **/ + +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; +typedef void (*Ecore_Evas_Event_Cb) (Ecore_Evas *ee); +#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, Ecore_Evas_Event_Cb func); + void (*fn_callback_move_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_show_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_hide_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_delete_request_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_destroy_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_focus_in_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_focus_out_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_mouse_in_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_mouse_out_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_sticky_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_unsticky_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_pre_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + void (*fn_callback_post_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); + 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); + void (*fn_profiles_set) (Ecore_Evas *ee, const char **profiles, int num_profiles); + + void (*fn_window_group_set) (Ecore_Evas *ee, const Ecore_Evas *ee_group); + void (*fn_aspect_set) (Ecore_Evas *ee, double aspect); + void (*fn_urgent_set) (Ecore_Evas *ee, int urgent); + void (*fn_modal_set) (Ecore_Evas *ee, int modal); + void (*fn_demands_attention_set) (Ecore_Evas *ee, int demand); + void (*fn_focus_skip_set) (Ecore_Evas *ee, int skip); + + int (*fn_render) (Ecore_Evas *ee); + void (*fn_screen_geometry_get) (const Ecore_Evas *ee, int *x, int *y, int *w, int *h); + void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi); +}; + +struct _Ecore_Evas_Engine +{ + Ecore_Evas_Engine_Func *func; + +/* TODO: UGLY! This should be an union or inheritance! */ +#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; + Ecore_X_Window leader; + Ecore_X_Sync_Counter netwm_sync_counter; + int netwm_sync_val_hi; + unsigned int netwm_sync_val_lo; + 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; + unsigned char netwm_sync_set : 1; + unsigned char configure_coming : 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; + Ecore_X_Window win_shaped_input; + } 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; + void (*free_func) (void *data, void *pix); + void *(*alloc_func) (void *data, int size); + void *data; + } 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 region : 1; + unsigned char fullscreen : 1; + } state; + } win32; +#endif +#ifdef BUILD_ECORE_EVAS_EWS + struct { + Evas_Object *image; + } ews; +#endif + +#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) + struct + { + Ecore_Wl_Window *parent, *win; + Evas_Object *frame; + +# if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) + struct wl_shm_pool *pool; + size_t pool_size; + void *pool_data; + struct wl_buffer *buffer; +# endif + + } wl; +#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_Bool in : 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; + char *profile; + 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; + Ecore_Evas *group_ee; + Ecore_Window group_ee_win; + double aspect; + 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; + char draw_frame : 1; + char hwsurface : 1; + char urgent : 1; + char modal : 1; + char demand_attention : 1; + char focus_skip : 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); + void (*fn_state_change) (Ecore_Evas *ee); + } func; + + Ecore_Evas_Engine engine; + Eina_List *sub_ecore_evas; + + int refcount; + + unsigned char ignore_events : 1; + unsigned char manual_render : 1; + unsigned char registered : 1; + unsigned char no_comp_sync : 1; + unsigned char semi_sync : 1; + unsigned char deleted : 1; + int gl_sync_draw_done; // added by gl77.lee +}; + +void _ecore_evas_ref(Ecore_Evas *ee); +void _ecore_evas_unref(Ecore_Evas *ee); + +#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_EWS +void _ecore_evas_ews_events_init(void); +int _ecore_evas_ews_shutdown(void); +#endif + +#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) +int _ecore_evas_wl_common_init(void); +int _ecore_evas_wl_common_shutdown(void); +void _ecore_evas_wl_common_pre_free(Ecore_Evas *ee); +void _ecore_evas_wl_common_free(Ecore_Evas *ee); +void _ecore_evas_wl_common_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +void _ecore_evas_wl_common_move(Ecore_Evas *ee, int x, int y); +void _ecore_evas_wl_common_raise(Ecore_Evas *ee); +void _ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title); +void _ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *c); +void _ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h); +void _ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h); +void _ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h); +void _ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h); +void _ecore_evas_wl_common_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y); +void _ecore_evas_wl_common_layer_set(Ecore_Evas *ee, int layer); +void _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, int iconify); +void _ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, int max); +void _ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, int full); +void _ecore_evas_wl_common_ignore_events_set(Ecore_Evas *ee, int ignore); +int _ecore_evas_wl_common_pre_render(Ecore_Evas *ee); +int _ecore_evas_wl_common_render_updates(Ecore_Evas *ee); +void _ecore_evas_wl_common_post_render(Ecore_Evas *ee); +int _ecore_evas_wl_common_render(Ecore_Evas *ee); +void _ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); +void _ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi); + +Evas_Object * _ecore_evas_wl_common_frame_add(Evas *evas); + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +void _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location); +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +void _ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location); +#endif +#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); +void _ecore_evas_mouse_multi_move_process(Ecore_Evas *ee, int device, + int x, int y, + double radius, + double radius_x, double radius_y, + double pressure, + double angle, + double mx, double my, + unsigned int timestamp); +void _ecore_evas_mouse_multi_down_process(Ecore_Evas *ee, int device, + int x, int y, + double radius, + double radius_x, double radius_y, + double pressure, + double angle, + double mx, double my, + Evas_Button_Flags flags, + unsigned int timestamp); +void _ecore_evas_mouse_multi_up_process(Ecore_Evas *ee, int device, + int x, int y, + double radius, + double radius_x, double radius_y, + double pressure, + double angle, + double mx, double my, + Evas_Button_Flags flags, + unsigned int timestamp); + +extern Eina_Bool _ecore_evas_app_comp_sync; + +void _ecore_evas_extn_init(void); +void _ecore_evas_extn_shutdown(void); + +#endif diff --git a/src/lib/ecore_evas/ecore_evas_psl1ght.c b/src/lib/ecore_evas/ecore_evas_psl1ght.c new file mode 100644 index 0000000000..35252a3703 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_psl1ght.c @@ -0,0 +1,515 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +#ifdef BUILD_ECORE_EVAS_PSL1GHT +#include +#include + +static int _ecore_evas_init_count = 0; + +static Ecore_Evas *psl1ght_ee = NULL; +static Ecore_Event_Handler *ecore_evas_event_handlers[5] = { + NULL, NULL, NULL, NULL +}; + +static const char *ecore_evas_psl1ght_default = "EFL PSL1GHT"; +static int _ecore_evas_fps_debug = 0; +static Ecore_Poller *ecore_evas_event; + +static unsigned int +_ecore_evas_time_get() +{ + return (unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff; +} + +static Ecore_Evas * +_ecore_evas_psl1ght_match(void) +{ + return psl1ght_ee; +} + +static Eina_Bool +_ecore_evas_psl1ght_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee; + + ee = _ecore_evas_psl1ght_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + /* pass on event */ + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_psl1ght_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee; + + ee = _ecore_evas_psl1ght_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + /* pass on event */ + evas_focus_out(ee->evas); + ee->prop.focused = 0; + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_psl1ght_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee; + int w; + int h; + + ee = _ecore_evas_psl1ght_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + evas_output_size_get(ee->evas, &w, &h); + evas_damage_rectangle_add(ee->evas, 0, 0, w, h); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_psl1ght_event_key_modifiers(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Psl1ght_Event_Key_Modifiers *e = event; + + ee = _ecore_evas_psl1ght_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + ecore_event_evas_modifier_lock_update(ee->evas, e->modifiers); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_psl1ght_event_quit (void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee; + + ee = _ecore_evas_psl1ght_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (ee->func.fn_delete_request) + ee->func.fn_delete_request(ee); + return ECORE_CALLBACK_PASS_ON; +} + +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_psl1ght_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 Eina_Bool +_ecore_evas_psl1ght_event(void *data EINA_UNUSED) +{ + ecore_psl1ght_poll_events(); + return ECORE_CALLBACK_RENEW; +} + +static int +_ecore_evas_psl1ght_init(int w EINA_UNUSED, int h EINA_UNUSED) +{ + _ecore_evas_init_count++; + if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; + + _ecore_evas_fps_debug = 1; + + // 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_psl1ght_event, NULL); + ecore_poller_poll_interval_set(ECORE_POLLER_CORE, 0.006); + + if (_ecore_evas_fps_debug) + _ecore_evas_fps_debug_init(); + + ecore_event_evas_init(); + + ecore_evas_event_handlers[0] = + ecore_event_handler_add(ECORE_PSL1GHT_EVENT_GOT_FOCUS, + _ecore_evas_psl1ght_event_got_focus, NULL); + ecore_evas_event_handlers[1] = + ecore_event_handler_add(ECORE_PSL1GHT_EVENT_LOST_FOCUS, + _ecore_evas_psl1ght_event_lost_focus, NULL); + ecore_evas_event_handlers[2] = + ecore_event_handler_add(ECORE_PSL1GHT_EVENT_EXPOSE, + _ecore_evas_psl1ght_event_video_expose, NULL); + ecore_evas_event_handlers[3] = + ecore_event_handler_add(ECORE_PSL1GHT_EVENT_KEY_MODIFIERS, + _ecore_evas_psl1ght_event_key_modifiers, NULL); + ecore_evas_event_handlers[4] = + ecore_event_handler_add(ECORE_PSL1GHT_EVENT_QUIT, + _ecore_evas_psl1ght_event_quit, NULL); + + return _ecore_evas_init_count; +} + +static int +_ecore_evas_psl1ght_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++) + ecore_event_handler_del(ecore_evas_event_handlers[i]); + ecore_event_evas_shutdown(); + ecore_poller_del(ecore_evas_event); + ecore_evas_event = NULL; + if (_ecore_evas_fps_debug) + _ecore_evas_fps_debug_shutdown(); + } + if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; + return _ecore_evas_init_count; +} + +static void +_ecore_evas_psl1ght_free(Ecore_Evas *ee) +{ + if (psl1ght_ee == ee) psl1ght_ee = NULL; + + ecore_event_window_unregister(0); + _ecore_evas_psl1ght_shutdown(); + ecore_psl1ght_shutdown(); +} + +static void +_ecore_evas_psl1ght_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) +{ + ee->func.fn_delete_request = func; +} + +static void +_ecore_evas_screen_resized(Ecore_Evas *ee) +{ + int w, h; + + /* Do not resize if the window is not fullscreen */ + if (ee->prop.fullscreen == 0) return; + + ecore_psl1ght_screen_resolution_get (&w, &h); + + if (w != ee->w || h != ee->h) + { + ee->req.w = ee->w = w; + ee->req.h = 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_psl1ght_resolution_set (w, h); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + + _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + _ecore_evas_time_get()); + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } +} + +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); + + ecore_psl1ght_resolution_set (w, h); + + if (ee->func.fn_resize) ee->func.fn_resize(ee); + + _ecore_evas_screen_resized (ee); +} + +static void +_ecore_evas_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h) +{ + _ecore_evas_resize (ee, w, h); +} + +static void +_ecore_evas_show(Ecore_Evas *ee) +{ + if (ee->prop.focused) return; + 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_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) +{ + if (x) *x = 0; + if (y) *y = 0; + ecore_psl1ght_screen_resolution_get (w, h); +} + +static void +_ecore_evas_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) + { + 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_psl1ght_engine_func = +{ + _ecore_evas_psl1ght_free, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_psl1ght_callback_delete_request_set, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_resize, + _ecore_evas_move_resize, + NULL, + NULL, + _ecore_evas_show, + 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, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, // render + _ecore_evas_screen_geometry_get, // screen_geometry_get + NULL // screen_dpi_get +}; + +EAPI Ecore_Evas * +ecore_evas_psl1ght_new(const char *name, int w, int h) +{ + void *einfo; + Ecore_Evas *ee; + + if (!name) + name = ecore_evas_psl1ght_default; + + 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_psl1ght_engine_func; + + ee->driver = "psl1ght"; + 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 = 0; + 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, evas_render_method_lookup("psl1ght")); + + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + einfo = evas_engine_info_get(ee->evas); + if (einfo) + { + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + + if (!ecore_psl1ght_init(name)) + { + evas_free(ee->evas); + if (ee->name) free(ee->name); + free(ee); + return NULL; + } + ecore_psl1ght_resolution_set (w, h); + + _ecore_evas_psl1ght_init(w, h); + + ecore_event_window_register(0, ee, ee->evas, + (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); + + ee->engine.func->fn_render = _ecore_evas_psl1ght_render; + _ecore_evas_register(ee); + + psl1ght_ee = ee; + + _ecore_evas_screen_resized (ee); + + if (getenv("ECORE_EVAS_PSL1GHT_CURSOR_PATH")) + ecore_evas_cursor_set(ee, getenv("ECORE_EVAS_PSL1GHT_CURSOR_PATH"), EVAS_LAYER_MAX, 0, 0); + + evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + + return ee; +} + +#else /* BUILD_ECORE_EVAS_PSL1GHT */ + +EAPI Ecore_Evas * +ecore_evas_psl1ght_new(const char *name EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + ERR("OUTCH !"); + return NULL; +} + +#endif /* BUILD_ECORE_EVAS_PSL1GHT */ diff --git a/src/lib/ecore_evas/ecore_evas_sdl.c b/src/lib/ecore_evas/ecore_evas_sdl.c new file mode 100644 index 0000000000..90b348ef2c --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_sdl.c @@ -0,0 +1,665 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#if defined(BUILD_ECORE_EVAS_SOFTWARE_SDL) || defined(BUILD_ECORE_EVAS_OPENGL_SDL) +# include +# ifdef BUILD_ECORE_EVAS_OPENGL_SDL +# include +# endif +#endif + +#include +#include + +#if defined(BUILD_ECORE_EVAS_SOFTWARE_SDL) || defined(BUILD_ECORE_EVAS_OPENGL_SDL) +#include +#endif + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +/* + * SDL only handle one window at a time. That's by definition, there is nothing wrong here. + * + */ +#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_evas_sdl_match(void) +{ + return sdl_ee; +} + +static void * +_ecore_evas_sdl_switch_buffer(void *data, void *dest EINA_UNUSED) +{ + SDL_Flip(data); + return ((SDL_Surface*)data)->pixels; +} + +static Eina_Bool +_ecore_evas_sdl_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee; + + ee = _ecore_evas_sdl_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + /* pass on event */ + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_sdl_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee; + + ee = _ecore_evas_sdl_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + /* pass on event */ + ee->prop.focused = 0; + evas_focus_out(ee->evas); + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_sdl_event_video_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Sdl_Event_Video_Resize *e; + Ecore_Evas *ee; + int rmethod; + + e = event; + ee = _ecore_evas_sdl_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + + rmethod = evas_output_method_get(ee->evas); + if (rmethod == evas_render_method_lookup("buffer")) + { + Evas_Engine_Info_Buffer *einfo; + + einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.switch_data = SDL_SetVideoMode(e->w, e->h, 32, + (ee->prop.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) + | (ee->prop.fullscreen ? SDL_FULLSCREEN : 0) + | (ee->alpha ? SDL_SRCALPHA : 0) + | SDL_DOUBLEBUF); + if (!einfo->info.switch_data) + { + return EINA_FALSE; + } + + SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); + SDL_FillRect(einfo->info.switch_data, NULL, 0); + + einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; + einfo->info.dest_buffer_row_bytes = e->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; + einfo->info.func.switch_buffer = _ecore_evas_sdl_switch_buffer; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *) einfo)) + { + return EINA_FALSE; + } + } + } + + ee->w = e->w; + ee->h = e->h; + ee->req.w = e->w; + ee->req.h = e->h; + + evas_output_size_set(ee->evas, e->w, e->h); + evas_output_viewport_set(ee->evas, 0, 0, e->w, e->h); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_sdl_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +{ + Ecore_Evas *ee; + int w; + int h; + + ee = _ecore_evas_sdl_match(); + + if (!ee) return ECORE_CALLBACK_PASS_ON; + evas_output_size_get(ee->evas, &w, &h); + evas_damage_rectangle_add(ee->evas, 0, 0, w, h); + + return ECORE_CALLBACK_PASS_ON; +} + +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; + 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); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + 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 Eina_Bool +_ecore_evas_sdl_event(void *data EINA_UNUSED) +{ + ecore_sdl_feed_events(); + return ECORE_CALLBACK_RENEW; +} + +static int +_ecore_evas_sdl_init(int w EINA_UNUSED, int h EINA_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) + { + unsigned 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) +{ + int rmethod; + + if ((w == ee->w) && (h == ee->h)) return; + ee->req.w = w; + ee->req.h = h; + ee->w = w; + ee->h = h; + + rmethod = evas_output_method_get(ee->evas); + if (rmethod == evas_render_method_lookup("buffer")) + { + Evas_Engine_Info_Buffer *einfo; + + einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.switch_data = SDL_SetVideoMode(w, h, 32, + (ee->prop.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) + | (ee->prop.fullscreen ? SDL_FULLSCREEN : 0) + | (ee->alpha ? SDL_SRCALPHA : 0) + | SDL_DOUBLEBUF); + if (!einfo->info.switch_data) + { + return ; + } + + SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); + SDL_FillRect(einfo->info.switch_data, NULL, 0); + + einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; + einfo->info.dest_buffer_row_bytes = 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; + einfo->info.func.switch_buffer = _ecore_evas_sdl_switch_buffer; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *) einfo)) + { + return ; + } + } + } + + 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 EINA_UNUSED, int y EINA_UNUSED, int w, int h) +{ + if ((w == ee->w) && (h == ee->h)) return; + ee->req.w = w; + ee->req.h = 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); + 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_show(Ecore_Evas *ee) +{ + if (ee->prop.focused) return; + ee->prop.focused = 1; + evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); +} + +static void +_ecore_evas_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) + { + 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, + _ecore_evas_show, + 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, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, // render + NULL, // screen_geometry_get + NULL // screen_dpi_get +}; + +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) +{ + Ecore_Evas *ee; + + if (!name) + name = ecore_evas_sdl_default; + + 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->req.w = w; + ee->req.h = h; + 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; + ee->alpha = alpha; + ee->prop.hwsurface = hwsurface; + + /* 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("buffer")) + { + Evas_Engine_Info_Buffer *einfo; + + einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); + if (einfo) + { + SDL_Init(SDL_INIT_NOPARACHUTE); + + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + { + ERR("SDL_Init failed with %s", SDL_GetError()); + SDL_Quit(); + return NULL; + } + + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; + einfo->info.switch_data = SDL_SetVideoMode(w, h, 32, + (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) + | (fullscreen ? SDL_FULLSCREEN : 0) + | (noframe ? SDL_NOFRAME : 0) + | (alpha ? SDL_SRCALPHA : 0) + | SDL_DOUBLEBUF); + if (!einfo->info.switch_data) + { + ERR("SDL_SetVideoMode failed !"); + ecore_evas_free(ee); + return NULL; + } + + SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); + SDL_FillRect(einfo->info.switch_data, NULL, 0); + + einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; + einfo->info.dest_buffer_row_bytes = 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; + einfo->info.func.switch_buffer = _ecore_evas_sdl_switch_buffer; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *) einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else if (rmethod == evas_render_method_lookup("gl_sdl")) + { +#ifdef BUILD_ECORE_EVAS_OPENGL_SDL + Evas_Engine_Info_GL_SDL *einfo; + + einfo = (Evas_Engine_Info_GL_SDL *) evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->flags.fullscreen = fullscreen; + einfo->flags.noframe = noframe; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } +#endif + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + + 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, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); + + SDL_ShowCursor(SDL_ENABLE); + + ee->engine.func->fn_render = _ecore_evas_sdl_render; + _ecore_evas_register(ee); + + sdl_ee = ee; + 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("buffer"); + if (!rmethod) return NULL; + + ee = _ecore_evas_internal_sdl_new(rmethod, name, w, h, fullscreen, hwsurface, noframe, alpha); + return ee; +} +#else +EAPI Ecore_Evas* +ecore_evas_sdl_new(const char* name EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, int fullscreen EINA_UNUSED, int hwsurface EINA_UNUSED, int noframe EINA_UNUSED, int alpha EINA_UNUSED) +{ + ERR("OUTCH !"); + return NULL; +} +#endif + +EAPI Ecore_Evas* +ecore_evas_sdl16_new(const char* name EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, int fullscreen EINA_UNUSED, int hwsurface EINA_UNUSED, int noframe EINA_UNUSED, int alpha EINA_UNUSED) +{ + ERR("OUTCH !"); + return NULL; +} + +#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); + if (ee) ee->driver = "gl_sdl"; + return ee; +} +#else +EAPI Ecore_Evas* +ecore_evas_gl_sdl_new(const char* name EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, int fullscreen EINA_UNUSED, int noframe EINA_UNUSED) +{ + ERR("OUTCH !"); + return NULL; +} +#endif + diff --git a/src/lib/ecore_evas/ecore_evas_util.c b/src/lib/ecore_evas/ecore_evas_util.c new file mode 100644 index 0000000000..85ff2bd37f --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_util.c @@ -0,0 +1,451 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#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, Evas_Coord x, Evas_Coord y) +{ + Ecore_Evas *ee = data; + // FIXME: account for frame + ecore_evas_move(ee, x, y); + if (ecore_evas_override_get(ee)) evas_object_move(obj, x, y); +} + +static void +_ecore_evas_obj_intercept_raise(void *data, Evas_Object *obj EINA_UNUSED) +{ + Ecore_Evas *ee = data; + ecore_evas_raise(ee); +} + +static void +_ecore_evas_obj_intercept_lower(void *data, Evas_Object *obj EINA_UNUSED) +{ + Ecore_Evas *ee = data; + ecore_evas_lower(ee); +} + +static void +_ecore_evas_obj_intercept_stack_above(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *above EINA_UNUSED) +{ + INF("TODO: %s", __FUNCTION__); +} + +static void +_ecore_evas_obj_intercept_stack_below(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *below EINA_UNUSED) +{ + INF("TODO: %s", __FUNCTION__); +} + +static void +_ecore_evas_obj_intercept_layer_set(void *data, Evas_Object *obj EINA_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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + ecore_evas_show(ee); +} + +static void +_ecore_evas_obj_callback_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + ecore_evas_hide(ee); +} + +static void +_ecore_evas_obj_callback_resize(void *data, Evas *e, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + Evas_Coord ow, oh, fw, fh; + + evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); + evas_output_framespace_get(e, NULL, NULL, &fw, &fh); + ow += fw; + oh += fh; + ecore_evas_resize(ee, ow, oh); +} + +static void +_ecore_evas_obj_callback_changed_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj, void *event_info EINA_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 EINA_UNUSED, Evas_Object *obj, void *event_info EINA_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 EINA_UNUSED, 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; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + + CHECK_PARAM_POINTER_RETURN("obj", obj, EINA_FALSE); + if (!_ecore_evas_object_evas_check(__FUNCTION__, ee, obj)) + return EINA_FALSE; + + 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 EINA_TRUE; +} + +EAPI Eina_Bool +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 EINA_FALSE; + } + + CHECK_PARAM_POINTER_RETURN("obj", obj, EINA_FALSE); + 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 EINA_FALSE; + } + + 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 EINA_FALSE; + } + + _ecore_evas_object_dissociate(ee, obj); + + return EINA_TRUE; +} + +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. + * @param parser This parameter isn't in use. + * @param desc This parameter isn't in use. + * @param str This parameter isn't in use. + * @param data The data to be used. + * @param storage The storage to be used. + * @return The function always return 1. + */ +unsigned char +ecore_getopt_callback_ecore_evas_list_engines(const Ecore_Getopt *parser EINA_UNUSED, const Ecore_Getopt_Desc *desc EINA_UNUSED, const char *str EINA_UNUSED, void *data, Ecore_Getopt_Value *storage) +{ + Eina_List *lst, *n; + const char *engine; + + if (!storage) + { + ERR("Storage is missing"); + return 0; + } + + 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; +} diff --git a/src/lib/ecore_evas/ecore_evas_wayland_common.c b/src/lib/ecore_evas/ecore_evas_wayland_common.c new file mode 100644 index 0000000000..f29e711166 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_wayland_common.c @@ -0,0 +1,785 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +//#define LOGFNS 1 + +#ifdef LOGFNS +# include +# define LOGFN(fl, ln, fn) \ + printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn); +#else +# define LOGFN(fl, ln, fn) +#endif + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +/* local structures */ +typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data; +struct _EE_Wl_Smart_Data +{ + Evas_Object *frame; + Evas_Object *text; + Evas_Coord x, y, w, h; +}; + +static Evas_Smart *_ecore_evas_wl_common_smart = NULL; + +/* local variables */ + +static int _ecore_evas_wl_init_count = 0; +static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[5]; + +static Eina_Bool +_ecore_evas_wl_common_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Mouse_In *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = event; + ee = ecore_event_window_match(ev->window); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (!ee->in) + { + if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); + ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); + evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); + ee->in = EINA_TRUE; + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Mouse_Out *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = event; + ee = ecore_event_window_match(ev->window); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (ee->in) + { + ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); + evas_event_feed_mouse_out(ee->evas, ev->timestamp, 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); + ee->in = EINA_FALSE; + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Focus_In *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = event; + ee = ecore_event_window_match(ev->win); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Focus_In *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = event; + ee = ecore_event_window_match(ev->win); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + evas_focus_out(ee->evas); + ee->prop.focused = 0; + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Window_Configure *ev; + int nw = 0, nh = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = event; + ee = ecore_event_window_match(ev->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; + if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + + if (ee->prop.fullscreen) + { + _ecore_evas_wl_common_move(ee, ev->x, ev->y); + ee->engine.func->fn_resize(ee, ev->w, ev->h); + + return ECORE_CALLBACK_PASS_ON; + } + + if ((ee->x != ev->x) || (ee->y != ev->y)) + { + ee->req.x = ee->x; + ee->req.y = ee->y; + if (ee->func.fn_move) ee->func.fn_move(ee); + } + + nw = ev->w; + nh = ev->h; + + if ((ee->prop.maximized) || (!ee->prop.fullscreen)) + { + int fw = 0, fh = 0; + + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + nw = ev->w - fw; + nh = ev->h - fh; + } + + if (ee->prop.min.w > nw) nw = ee->prop.min.w; + else if (nw > ee->prop.max.w) nw = ee->prop.max.w; + if (ee->prop.min.h > nh) nh = ee->prop.min.h; + else if (nh > ee->prop.max.h) nh = ee->prop.max.h; + + if ((ee->w != nw) || (ee->h != nh)) + { + ee->req.w = nw; + ee->req.h = nh; + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } + + return ECORE_CALLBACK_PASS_ON; +} + +int +_ecore_evas_wl_common_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (++_ecore_evas_wl_init_count != 1) + return _ecore_evas_wl_init_count; + + _ecore_evas_wl_event_hdls[0] = + ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, + _ecore_evas_wl_common_cb_mouse_in, NULL); + _ecore_evas_wl_event_hdls[1] = + ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, + _ecore_evas_wl_common_cb_mouse_out, NULL); + _ecore_evas_wl_event_hdls[2] = + ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, + _ecore_evas_wl_common_cb_focus_in, NULL); + _ecore_evas_wl_event_hdls[3] = + ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, + _ecore_evas_wl_common_cb_focus_out, NULL); + _ecore_evas_wl_event_hdls[4] = + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, + _ecore_evas_wl_common_cb_window_configure, NULL); + + ecore_event_evas_init(); + + return _ecore_evas_wl_init_count; +} + +int +_ecore_evas_wl_common_shutdown(void) +{ + unsigned int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (--_ecore_evas_wl_init_count != 0) + return _ecore_evas_wl_init_count; + + for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++) + { + if (_ecore_evas_wl_event_hdls[i]) + ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]); + } + + ecore_event_evas_shutdown(); + + return _ecore_evas_wl_init_count; +} + +void +_ecore_evas_wl_common_pre_free(Ecore_Evas *ee) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame); +} + +void +_ecore_evas_wl_common_free(Ecore_Evas *ee) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win); + ee->engine.wl.win = NULL; + + ecore_event_window_unregister(ee->prop.window); + ecore_evas_input_event_unregister(ee); + + _ecore_evas_wl_common_shutdown(); + ecore_wl_shutdown(); +} + +void +_ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (w < 1) w = 1; + if (h < 1) h = 1; + + ee->req.w = w; + ee->req.h = h; + + if (!ee->prop.fullscreen) + { + int fw = 0, fh = 0; + + if (ee->prop.min.w > w) w = ee->prop.min.w; + else if (w > ee->prop.max.w) w = ee->prop.max.w; + if (ee->prop.min.h > h) h = ee->prop.min.h; + else if (h > ee->prop.max.h) h = ee->prop.max.h; + + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + w += fw; + h += fh; + } + + if ((ee->w != w) || (ee->h != h)) + { + ee->w = w; + ee->h = h; + + if ((ee->rotation == 90) || (ee->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); + } + + if (ee->prop.avoid_damage) + { + int pdam = 0; + + pdam = ecore_evas_avoid_damage_get(ee); + ecore_evas_avoid_damage_set(ee, 0); + ecore_evas_avoid_damage_set(ee, pdam); + } + + if (ee->engine.wl.frame) + evas_object_resize(ee->engine.wl.frame, w, h); + } +} + +void +_ecore_evas_wl_common_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_resize = func; +} + +void +_ecore_evas_wl_common_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_move = func; +} + +void +_ecore_evas_wl_common_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_delete_request = func; +} + +void +_ecore_evas_wl_common_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_focus_in = func; +} + +void +_ecore_evas_wl_common_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_focus_out = func; +} + +void +_ecore_evas_wl_common_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_mouse_in = func; +} + +void +_ecore_evas_wl_common_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + if (!ee) return; + ee->func.fn_mouse_out = func; +} + +void +_ecore_evas_wl_common_move(Ecore_Evas *ee, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + + ee->req.x = x; + ee->req.y = y; + + if ((ee->x != x) || (ee->y != y)) + { + ee->x = x; + ee->y = y; + if (ee->engine.wl.win) + ecore_wl_window_update_location(ee->engine.wl.win, x, y); + if (ee->func.fn_move) ee->func.fn_move(ee); + } +} + +static void +_ecore_evas_wl_common_smart_add(Evas_Object *obj) +{ + EE_Wl_Smart_Data *sd; + Evas *evas; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return; + + evas = evas_object_evas_get(obj); + + sd->x = 0; + sd->y = 0; + sd->w = 1; + sd->h = 1; + + sd->frame = evas_object_rectangle_add(evas); + evas_object_color_set(sd->frame, 249, 249, 249, 255); + evas_object_smart_member_add(sd->frame, obj); + + sd->text = evas_object_text_add(evas); + evas_object_color_set(sd->text, 0, 0, 0, 255); + evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN); + evas_object_text_font_set(sd->text, "Sans", 10); + evas_object_text_text_set(sd->text, "Smart Test"); + evas_object_smart_member_add(sd->text, obj); + + evas_object_smart_data_set(obj, sd); +} + +static void +_ecore_evas_wl_common_smart_del(Evas_Object *obj) +{ + EE_Wl_Smart_Data *sd; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sd = evas_object_smart_data_get(obj))) return; + evas_object_del(sd->text); + evas_object_del(sd->frame); + free(sd); +} + +static void +_ecore_evas_wl_common_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) +{ + EE_Wl_Smart_Data *sd; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sd = evas_object_smart_data_get(obj))) return; + if ((sd->w == w) && (sd->h == h)) return; + sd->w = w; + sd->h = h; + evas_object_resize(sd->frame, w, h); +} + +static void +_ecore_evas_wl_common_smart_show(Evas_Object *obj) +{ + EE_Wl_Smart_Data *sd; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sd = evas_object_smart_data_get(obj))) return; + evas_object_show(sd->frame); + evas_object_show(sd->text); +} + +static void +_ecore_evas_wl_common_smart_hide(Evas_Object *obj) +{ + EE_Wl_Smart_Data *sd; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sd = evas_object_smart_data_get(obj))) return; + evas_object_hide(sd->text); + evas_object_hide(sd->frame); +} + +static void +_ecore_evas_wl_common_smart_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (_ecore_evas_wl_common_smart) return; + { + static const Evas_Smart_Class sc = + { + "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION, + _ecore_evas_wl_common_smart_add, + _ecore_evas_wl_common_smart_del, + NULL, + _ecore_evas_wl_common_smart_resize, + _ecore_evas_wl_common_smart_show, + _ecore_evas_wl_common_smart_hide, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + }; + _ecore_evas_wl_common_smart = evas_smart_class_new(&sc); + } +} + +Evas_Object * +_ecore_evas_wl_common_frame_add(Evas *evas) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_evas_wl_common_smart_init(); + return evas_object_smart_add(evas, _ecore_evas_wl_common_smart); +} + +void +_ecore_evas_wl_common_raise(Ecore_Evas *ee) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!ee) || (!ee->visible)) return; + ecore_wl_window_raise(ee->engine.wl.win); +} + +void +_ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->prop.title) free(ee->prop.title); + ee->prop.title = NULL; + if (title) ee->prop.title = strdup(title); + if ((ee->prop.draw_frame) && (ee->engine.wl.frame)) + { + EE_Wl_Smart_Data *sd; + + if ((sd = evas_object_smart_data_get(ee->engine.wl.frame))) + evas_object_text_text_set(sd->text, ee->prop.title); + } + + if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) + wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, + ee->prop.title); +} + +void +_ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *c) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + 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); + + if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) + wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, + ee->prop.clas); +} + +void +_ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + 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; +} + +void +_ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + 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; +} + +void +_ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + 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; +} + +void +_ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return; + ee->prop.step.w = w; + ee->prop.step.h = h; +} + +static void +_ecore_evas_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee; + + ee = data; + if (ee) ee->prop.cursor.object = NULL; +} + +void +_ecore_evas_wl_common_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y) +{ + int x, y, fx, fy; + + if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); + + if (!obj) + { + ee->prop.cursor.object = NULL; + ee->prop.cursor.layer = 0; + ee->prop.cursor.hot.x = 0; + ee->prop.cursor.hot.y = 0; + ecore_wl_window_cursor_default_restore(ee->engine.wl.win); + 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_wl_window_pointer_set(ee->engine.wl.win, NULL, 0, 0); + + evas_pointer_output_xy_get(ee->evas, &x, &y); + evas_output_framespace_get(ee->evas, &fx, &fy, NULL, NULL); + evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer); + evas_object_move(ee->prop.cursor.object, + x - fx - ee->prop.cursor.hot.x, + y - fy - 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); +} + +void +_ecore_evas_wl_common_layer_set(Ecore_Evas *ee, int layer) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->prop.layer == layer) return; + if (layer < 1) layer = 1; + else if (layer > 255) layer = 255; + ee->prop.layer = layer; +} + +void +_ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, int iconify) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->prop.iconified == iconify) return; + ee->prop.iconified = iconify; + /* FIXME: Implement this in Wayland someshow */ +} + +void +_ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, int max) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->prop.maximized == max) return; + ee->prop.maximized = max; + ecore_wl_window_maximized_set(ee->engine.wl.win, max); +} + +void +_ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, int full) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->prop.fullscreen == full) return; + ee->prop.fullscreen = full; + ecore_wl_window_fullscreen_set(ee->engine.wl.win, full); +} + +void +_ecore_evas_wl_common_ignore_events_set(Ecore_Evas *ee, int ignore) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + ee->ignore_events = ignore; + /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */ +} + +int +_ecore_evas_wl_common_pre_render(Ecore_Evas *ee) +{ + int rend = 0; + Eina_List *ll = NULL; + Ecore_Evas *ee2 = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + + EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) + { + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + return rend; +} + +int +_ecore_evas_wl_common_render_updates(Ecore_Evas *ee) +{ + int rend = 0; + Eina_List *updates = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((updates = evas_render_updates(ee->evas))) + { + Eina_List *l = NULL; + Eina_Rectangle *r; + + EINA_LIST_FOREACH(updates, l, r) + ecore_wl_window_damage(ee->engine.wl.win, + r->x, r->y, r->w, r->h); + + ecore_wl_flush(); + + evas_render_updates_free(updates); + rend = 1; + } + + return rend; +} + +void +_ecore_evas_wl_common_post_render(Ecore_Evas *ee) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_evas_idle_timeout_update(ee); + if (ee->func.fn_post_render) ee->func.fn_post_render(ee); +} + +int +_ecore_evas_wl_common_render(Ecore_Evas *ee) +{ + int rend = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return 0; + if (!ee->visible) + { + evas_norender(ee->evas); + return 0; + } + + rend = _ecore_evas_wl_common_pre_render(ee); + rend |= _ecore_evas_wl_common_render_updates(ee); + _ecore_evas_wl_common_post_render(ee); + + return rend; +} + +void +_ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (x) *x = 0; + if (y) *y = 0; + ecore_wl_screen_size_get(w, h); +} + +void +_ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee EINA_UNUSED, int *xdpi, int *ydpi) +{ + int dpi = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (xdpi) *xdpi = 0; + if (ydpi) *ydpi = 0; + /* FIXME: Ideally this needs to get the DPI from a specific screen */ + dpi = ecore_wl_dpi_get(); + if (xdpi) *xdpi = dpi; + if (ydpi) *ydpi = dpi; +} diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c b/src/lib/ecore_evas/ecore_evas_wayland_egl.c new file mode 100644 index 0000000000..ed176e8b6e --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_wayland_egl.c @@ -0,0 +1,434 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +//#define LOGFNS 1 + +#ifdef LOGFNS +# include +# define LOGFN(fl, ln, fn) \ + printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn); +#else +# define LOGFN(fl, ln, fn) +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +# include +# include +# include +# include +# include +#endif + +#include + +#include "Ecore_Evas.h" + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +# include "ecore_evas_private.h" +# include +# include + +/* local function prototypes */ +static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h); +static void _ecore_evas_wl_show(Ecore_Evas *ee); +static void _ecore_evas_wl_hide(Ecore_Evas *ee); +static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha); +static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent); + +static Ecore_Evas_Engine_Func _ecore_wl_engine_func = +{ + _ecore_evas_wl_common_free, + _ecore_evas_wl_common_callback_resize_set, + _ecore_evas_wl_common_callback_move_set, + NULL, + NULL, + _ecore_evas_wl_common_callback_delete_request_set, + NULL, + _ecore_evas_wl_common_callback_focus_in_set, + _ecore_evas_wl_common_callback_focus_out_set, + _ecore_evas_wl_common_callback_mouse_in_set, + _ecore_evas_wl_common_callback_mouse_out_set, + NULL, // sticky_set + NULL, // unsticky_set + NULL, // pre_render_set + NULL, // post_render_set + _ecore_evas_wl_common_move, + NULL, // managed_move + _ecore_evas_wl_resize, + NULL, // move_resize + NULL, // rotation_set + NULL, // shaped_set + _ecore_evas_wl_show, + _ecore_evas_wl_hide, + _ecore_evas_wl_common_raise, + NULL, // lower + NULL, // activate + _ecore_evas_wl_common_title_set, + _ecore_evas_wl_common_name_class_set, + _ecore_evas_wl_common_size_min_set, + _ecore_evas_wl_common_size_max_set, + _ecore_evas_wl_common_size_base_set, + _ecore_evas_wl_common_size_step_set, + _ecore_evas_wl_common_object_cursor_set, + _ecore_evas_wl_common_layer_set, + NULL, // focus set + _ecore_evas_wl_common_iconified_set, + NULL, // borderless set + NULL, // override set + _ecore_evas_wl_common_maximized_set, + _ecore_evas_wl_common_fullscreen_set, + NULL, // func avoid_damage set + NULL, // func withdrawn set + NULL, // func sticky set + _ecore_evas_wl_common_ignore_events_set, + _ecore_evas_wl_alpha_set, + _ecore_evas_wl_transparent_set, + NULL, // func profiles set + NULL, // window group set + NULL, // aspect set + NULL, // urgent set + NULL, // modal set + NULL, // demand attention set + NULL, // focus skip set + _ecore_evas_wl_common_render, + _ecore_evas_wl_common_screen_geometry_get, + _ecore_evas_wl_common_screen_dpi_get +}; + +/* external variables */ + +/* external functions */ +EAPI Ecore_Evas * +ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame) +{ + Ecore_Wl_Window *p = NULL; + Evas_Engine_Info_Wayland_Egl *einfo; + Ecore_Evas *ee; + int method = 0, count = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(method = evas_render_method_lookup("wayland_egl"))) + { + ERR("Render method lookup failed for Wayland_Egl"); + return NULL; + } + + count = ecore_wl_init(disp_name); + if (!count) + { + ERR("Failed to initialize Ecore_Wayland"); + return NULL; + } + else if (count == 1) + ecore_wl_display_iterate(); + + if (!(ee = calloc(1, sizeof(Ecore_Evas)))) + { + ERR("Failed to allocate Ecore_Evas"); + goto ee_err; + } + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_wl_common_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func; + + ee->driver = "wayland_egl"; + 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->rotation = 0; + ee->prop.max.w = 32767; + ee->prop.max.h = 32767; + ee->prop.layer = 4; + ee->prop.request_pos = 0; + ee->prop.sticky = 0; + ee->prop.draw_frame = frame; + ee->alpha = EINA_FALSE; + + ee->evas = evas_new(); + evas_data_attach_set(ee->evas, ee); + evas_output_method_set(ee->evas, method); + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + + /* FIXME: This needs to be set based on theme & scale */ + if (ee->prop.draw_frame) + evas_output_framespace_set(ee->evas, 4, 18, 8, 22); + + if (parent) + p = ecore_wl_window_find(parent); + + /* FIXME: Get if parent is alpha, and set */ + + ee->engine.wl.parent = p; + ee->engine.wl.win = + ecore_wl_window_new(p, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW); + ee->prop.window = ee->engine.wl.win->id; + + if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) + { + einfo->info.display = ecore_wl_display_get(); + einfo->info.destination_alpha = ee->alpha; + einfo->info.rotation = ee->rotation; + einfo->info.depth = 32; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("Failed to set Evas Engine Info for '%s'", ee->driver); + goto err; + } + } + else + { + ERR("Failed to get Evas Engine Info for '%s'", ee->driver); + goto err; + } + + ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free); + + if (ee->prop.draw_frame) + { + ee->engine.wl.frame = _ecore_evas_wl_common_frame_add(ee->evas); + evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE); + evas_object_move(ee->engine.wl.frame, 0, 0); + } + + _ecore_evas_register(ee); + ecore_evas_input_event_register(ee); + + ecore_event_window_register(ee->prop.window, ee, ee->evas, + (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); + + return ee; + + err: + ecore_evas_free(ee); + _ecore_evas_wl_common_shutdown(); + + ee_err: + ecore_wl_shutdown(); + return NULL; +} + +static void +_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (w < 1) w = 1; + if (h < 1) h = 1; + + ee->req.w = w; + ee->req.h = h; + + if (!ee->prop.fullscreen) + { + int fw = 0, fh = 0; + + if (ee->prop.min.w > w) w = ee->prop.min.w; + else if (w > ee->prop.max.w) w = ee->prop.max.w; + if (ee->prop.min.h > h) h = ee->prop.min.h; + else if (h > ee->prop.max.h) h = ee->prop.max.h; + + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + w += fw; + h += fh; + } + + if ((ee->w != w) || (ee->h != h)) + { + ee->w = w; + ee->h = h; + + if ((ee->rotation == 90) || (ee->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); + } + + if (ee->prop.avoid_damage) + { + int pdam = 0; + + pdam = ecore_evas_avoid_damage_get(ee); + ecore_evas_avoid_damage_set(ee, 0); + ecore_evas_avoid_damage_set(ee, pdam); + } + + if (ee->engine.wl.frame) + evas_object_resize(ee->engine.wl.frame, w, h); + + + if (ee->engine.wl.win) + { + ecore_wl_window_update_size(ee->engine.wl.win, w, h); + ecore_wl_window_buffer_attach(ee->engine.wl.win, NULL, 0, 0); + } + + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } +} + +static void +_ecore_evas_wl_show(Ecore_Evas *ee) +{ + Evas_Engine_Info_Wayland_Egl *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!ee) || (ee->visible)) return; + + if (ee->engine.wl.win) + { + ecore_wl_window_show(ee->engine.wl.win); + ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); + ecore_wl_window_buffer_attach(ee->engine.wl.win, NULL, 0, 0); + + if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) + wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, + ee->prop.clas); + if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) + wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, + ee->prop.title); + } + + if (ee->engine.wl.frame) + { + evas_object_show(ee->engine.wl.frame); + evas_object_resize(ee->engine.wl.frame, ee->w, ee->h); + } + + if (ee->engine.wl.win) + { + einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas); + if (!einfo) + { + ERR("Failed to get Evas Engine Info for '%s'", ee->driver); + return; + } + + einfo->info.surface = ecore_wl_window_surface_get(ee->engine.wl.win); + /* if (einfo->info.surface) */ + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + /* else */ + /* printf("Failed to get a Surface from Ecore_Wl\n"); */ + } + + ee->visible = 1; + if (ee->func.fn_show) ee->func.fn_show(ee); +} + +static void +_ecore_evas_wl_hide(Ecore_Evas *ee) +{ + Evas_Engine_Info_Wayland_Egl *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!ee) || (!ee->visible)) return; + + einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.surface = NULL; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + + if (ee->engine.wl.win) + ecore_wl_window_hide(ee->engine.wl.win); + + ee->visible = 0; + ee->should_be_visible = 0; + + if (ee->func.fn_hide) ee->func.fn_hide(ee); +} + +static void +_ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha) +{ + Evas_Engine_Info_Wayland_Egl *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if ((ee->alpha == alpha)) return; + ee->alpha = alpha; + if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) + { + einfo->info.destination_alpha = alpha; + 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); + } +} + +static void +_ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent) +{ + Evas_Engine_Info_Wayland_Egl *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if ((ee->transparent == transparent)) return; + ee->transparent = transparent; + if (!ee->visible) return; + if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) + { + 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); + } +} + +void +_ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->engine.wl.win) + { + Evas_Engine_Info_Wayland_Egl *einfo; + + if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) + { + einfo->info.edges = location; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + + ee->engine.wl.win->resizing = EINA_TRUE; + ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location); + } +} +#else +EAPI Ecore_Evas * +ecore_evas_wayland_egl_new(const char *disp_name EINA_UNUSED, unsigned int parent EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, Eina_Bool frame EINA_UNUSED) +{ + return NULL; +} +#endif diff --git a/src/lib/ecore_evas/ecore_evas_wayland_shm.c b/src/lib/ecore_evas/ecore_evas_wayland_shm.c new file mode 100644 index 0000000000..24e349534a --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_wayland_shm.c @@ -0,0 +1,656 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +//#define LOGFNS 1 + +#ifdef LOGFNS +# include +# define LOGFN(fl, ln, fn) \ + printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn); +#else +# define LOGFN(fl, ln, fn) +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +# include +# include +# include +# include +# include +#endif + +#include + +#include "Ecore_Evas.h" + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +# include "ecore_evas_private.h" +# include +# include + +/* local function prototypes */ +static void _ecore_evas_wl_free(Ecore_Evas *ee); +static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h); +static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); +static void _ecore_evas_wl_show(Ecore_Evas *ee); +static void _ecore_evas_wl_hide(Ecore_Evas *ee); +static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha); +static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent); +static int _ecore_evas_wl_render(Ecore_Evas *ee); + +/* SHM Only */ +static void _ecore_evas_wl_shm_pool_free(Ecore_Evas *ee); +static void _ecore_evas_wl_shm_pool_create(Ecore_Evas *ee, size_t size); +static void _ecore_evas_wl_buffer_free(Ecore_Evas *ee); +static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, int w, int h); + +/* Frame listener */ +static void _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t time); +static const struct wl_callback_listener frame_listener = +{ + _ecore_evas_wl_frame_complete, +}; + +static Ecore_Evas_Engine_Func _ecore_wl_engine_func = +{ + _ecore_evas_wl_free, + _ecore_evas_wl_common_callback_resize_set, + _ecore_evas_wl_common_callback_move_set, + NULL, + NULL, + _ecore_evas_wl_common_callback_delete_request_set, + NULL, + _ecore_evas_wl_common_callback_focus_in_set, + _ecore_evas_wl_common_callback_focus_out_set, + _ecore_evas_wl_common_callback_mouse_in_set, + _ecore_evas_wl_common_callback_mouse_out_set, + NULL, // sticky_set + NULL, // unsticky_set + NULL, // pre_render_set + NULL, // post_render_set + _ecore_evas_wl_common_move, + NULL, // managed_move + _ecore_evas_wl_resize, + _ecore_evas_wl_move_resize, + NULL, // rotation_set + NULL, // shaped_set + _ecore_evas_wl_show, + _ecore_evas_wl_hide, + _ecore_evas_wl_common_raise, + NULL, // lower + NULL, // activate + _ecore_evas_wl_common_title_set, + _ecore_evas_wl_common_name_class_set, + _ecore_evas_wl_common_size_min_set, + _ecore_evas_wl_common_size_max_set, + _ecore_evas_wl_common_size_base_set, + _ecore_evas_wl_common_size_step_set, + _ecore_evas_wl_common_object_cursor_set, + _ecore_evas_wl_common_layer_set, + NULL, // focus set + _ecore_evas_wl_common_iconified_set, + NULL, // borderless set + NULL, // override set + _ecore_evas_wl_common_maximized_set, + _ecore_evas_wl_common_fullscreen_set, + NULL, // func avoid_damage set + NULL, // func withdrawn set + NULL, // func sticky set + _ecore_evas_wl_common_ignore_events_set, + _ecore_evas_wl_alpha_set, + _ecore_evas_wl_transparent_set, + NULL, // func profiles set + NULL, // window group set + NULL, // aspect set + NULL, // urgent set + NULL, // modal set + NULL, // demand attention set + NULL, // focus skip set + _ecore_evas_wl_render, + _ecore_evas_wl_common_screen_geometry_get, + _ecore_evas_wl_common_screen_dpi_get +}; + +/* external variables */ + +/* external functions */ +EAPI Ecore_Evas * +ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame) +{ + Ecore_Wl_Window *p = NULL; + Evas_Engine_Info_Wayland_Shm *einfo; + Ecore_Evas *ee; + int method = 0, count = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(method = evas_render_method_lookup("wayland_shm"))) + { + ERR("Render method lookup failed for Wayland_Shm"); + return NULL; + } + + count = ecore_wl_init(disp_name); + if (!count) + { + ERR("Failed to initialize Ecore_Wayland"); + return NULL; + } + else if (count == 1) + ecore_wl_display_iterate(); + + if (!(ee = calloc(1, sizeof(Ecore_Evas)))) + { + ERR("Failed to allocate Ecore_Evas"); + goto ee_err; + } + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_wl_common_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func; + + ee->driver = "wayland_shm"; + 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->rotation = 0; + ee->prop.max.w = 32767; + ee->prop.max.h = 32767; + ee->prop.layer = 4; + ee->prop.request_pos = 0; + ee->prop.sticky = 0; + ee->prop.draw_frame = frame; + ee->alpha = EINA_FALSE; + + ee->evas = evas_new(); + evas_data_attach_set(ee->evas, ee); + evas_output_method_set(ee->evas, method); + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + + /* FIXME: This needs to be set based on theme & scale */ + if (ee->prop.draw_frame) + evas_output_framespace_set(ee->evas, 4, 18, 8, 22); + + if (parent) + p = ecore_wl_window_find(parent); + + /* FIXME: Get if parent is alpha, and set */ + + ee->engine.wl.parent = p; + ee->engine.wl.win = + ecore_wl_window_new(p, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_SHM); + ee->prop.window = ee->engine.wl.win->id; + + if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) + { + einfo->info.destination_alpha = ee->alpha; + einfo->info.rotation = ee->rotation; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("Failed to set Evas Engine Info for '%s'", ee->driver); + goto err; + } + } + else + { + ERR("Failed to get Evas Engine Info for '%s'", ee->driver); + goto err; + } + + ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free); + + if (ee->prop.draw_frame) + { + ee->engine.wl.frame = _ecore_evas_wl_common_frame_add(ee->evas); + evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE); + evas_object_move(ee->engine.wl.frame, 0, 0); + } + + _ecore_evas_register(ee); + ecore_evas_input_event_register(ee); + + ecore_event_window_register(ee->prop.window, ee, ee->evas, + (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); + + return ee; + + err: + ecore_evas_free(ee); + _ecore_evas_wl_common_shutdown(); + + ee_err: + ecore_wl_shutdown(); + return NULL; +} + +static void +_ecore_evas_wl_free(Ecore_Evas *ee) +{ + _ecore_evas_wl_buffer_free(ee); + _ecore_evas_wl_shm_pool_free(ee); + _ecore_evas_wl_common_free(ee); +} + +static void +_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (w < 1) w = 1; + if (h < 1) h = 1; + + ee->req.w = w; + ee->req.h = h; + + if (!ee->prop.fullscreen) + { + int fw = 0, fh = 0; + + if (ee->prop.min.w > w) w = ee->prop.min.w; + else if (w > ee->prop.max.w) w = ee->prop.max.w; + if (ee->prop.min.h > h) h = ee->prop.min.h; + else if (h > ee->prop.max.h) h = ee->prop.max.h; + + evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh); + w += fw; + h += fh; + } + + if ((ee->w != w) || (ee->h != h)) + { + ee->w = w; + ee->h = h; + + if ((ee->rotation == 90) || (ee->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); + } + + if (ee->prop.avoid_damage) + { + int pdam = 0; + + pdam = ecore_evas_avoid_damage_get(ee); + ecore_evas_avoid_damage_set(ee, 0); + ecore_evas_avoid_damage_set(ee, pdam); + } + + if (ee->engine.wl.frame) + evas_object_resize(ee->engine.wl.frame, w, h); + + _ecore_evas_wl_buffer_new(ee, w, h); + + einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); + if (!einfo) + { + ERR("Failed to get Evas Engine Info for '%s'", ee->driver); + return; + } + + einfo->info.dest = ee->engine.wl.pool_data; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + + if (ee->engine.wl.win) + { + ecore_wl_window_update_size(ee->engine.wl.win, w, h); + ecore_wl_window_buffer_attach(ee->engine.wl.win, + ee->engine.wl.buffer, 0, 0); + } + + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } +} + +static void +_ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if ((ee->x != x) || (ee->y != y)) + _ecore_evas_wl_common_move(ee, x, y); + if ((ee->w != w) || (ee->h != h)) + _ecore_evas_wl_resize(ee, w, h); +} + +static void +_ecore_evas_wl_show(Ecore_Evas *ee) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!ee) || (ee->visible)) return; + + _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); + + einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); + if (!einfo) + { + ERR("Failed to get Evas Engine Info for '%s'", ee->driver); + return; + } + + einfo->info.dest = ee->engine.wl.pool_data; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + + if (ee->engine.wl.win) + { + ecore_wl_window_show(ee->engine.wl.win); + ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); + ecore_wl_window_buffer_attach(ee->engine.wl.win, + ee->engine.wl.buffer, 0, 0); + + if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface)) + wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, + ee->prop.clas); + if ((ee->prop.title) && (ee->engine.wl.win->shell_surface)) + wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, + ee->prop.title); + } + + if (ee->engine.wl.frame) + { + evas_object_show(ee->engine.wl.frame); + evas_object_resize(ee->engine.wl.frame, ee->w, ee->h); + } + + ee->visible = 1; + if (ee->func.fn_show) ee->func.fn_show(ee); +} + +static void +_ecore_evas_wl_hide(Ecore_Evas *ee) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!ee) || (!ee->visible)) return; + + _ecore_evas_wl_buffer_free(ee); + + munmap(ee->engine.wl.pool_data, ee->engine.wl.pool_size); + + einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); + if ((einfo) && (einfo->info.dest)) + { + einfo->info.dest = NULL; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + + if (ee->engine.wl.win) + ecore_wl_window_hide(ee->engine.wl.win); + + ee->visible = 0; + ee->should_be_visible = 0; + + if (ee->func.fn_hide) ee->func.fn_hide(ee); +} + +static void +_ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + Ecore_Wl_Window *win = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if ((ee->alpha == alpha)) return; + ee->alpha = alpha; + + /* FIXME: NB: We should really add a ecore_wl_window_alpha_set function + * but we are in API freeze, so just hack it in for now and fix when + * freeze is over */ + if ((win = ee->engine.wl.win)) + win->alpha = alpha; + + /* if (ee->engine.wl.win) */ + /* ecore_wl_window_transparent_set(ee->engine.wl.win, alpha); */ + + _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); + + if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) + { + einfo->info.destination_alpha = alpha; + einfo->info.dest = ee->engine.wl.pool_data; + 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); + } + + if (win) + { + ecore_wl_window_update_size(win, ee->w, ee->h); + ecore_wl_window_buffer_attach(win, ee->engine.wl.buffer, 0, 0); + } +} + +static void +_ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if ((ee->transparent == transparent)) return; + ee->transparent = transparent; + + if (ee->engine.wl.win) + ecore_wl_window_transparent_set(ee->engine.wl.win, transparent); + + _ecore_evas_wl_buffer_new(ee, ee->w, ee->h); + + if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) + { + einfo->info.destination_alpha = transparent; + einfo->info.dest = ee->engine.wl.pool_data; + 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); + } + + if (ee->engine.wl.win) + { + ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h); + ecore_wl_window_buffer_attach(ee->engine.wl.win, + ee->engine.wl.buffer, 0, 0); + } +} + +static void +_ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t time EINA_UNUSED) +{ + Ecore_Evas *ee = data; + Ecore_Wl_Window *win = NULL; + + if (!ee) return; + if (!(win = ee->engine.wl.win)) return; + + win->frame_callback = NULL; + win->frame_pending = EINA_FALSE; + wl_callback_destroy(callback); + + if (win->surface) + { + win->frame_callback = wl_surface_frame(win->surface); + wl_callback_add_listener(win->frame_callback, &frame_listener, ee); + } +} + +static int +_ecore_evas_wl_render(Ecore_Evas *ee) +{ + int rend = 0; + Ecore_Wl_Window *win = NULL; + + if (!ee) return 0; + if (!ee->visible) + { + evas_norender(ee->evas); + return 0; + } + + if (!(win = ee->engine.wl.win)) return 0; + + rend = _ecore_evas_wl_common_pre_render(ee); + if (!(win->frame_pending)) + { + /* FIXME - ideally have an evas_changed_get to return the value + * of evas->changed to avoid creating this callback and + * destroying it again + */ + + if (!win->frame_callback) + { + win->frame_callback = wl_surface_frame(win->surface); + wl_callback_add_listener(win->frame_callback, &frame_listener, ee); + } + + rend |= _ecore_evas_wl_common_render_updates(ee); + if (rend) + win->frame_pending = EINA_TRUE; + } + _ecore_evas_wl_common_post_render(ee); + return rend; +} + +static void +_ecore_evas_wl_shm_pool_free(Ecore_Evas *ee) +{ + if (!ee->engine.wl.pool) return; + + wl_shm_pool_destroy(ee->engine.wl.pool); + ee->engine.wl.pool = NULL; + ee->engine.wl.pool_size = 0; + ee->engine.wl.pool_data = NULL; +} + +static void +_ecore_evas_wl_shm_pool_create(Ecore_Evas *ee, size_t size) +{ + struct wl_shm *shm; + void *data; + char tmp[PATH_MAX]; + int fd; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (size <= ee->engine.wl.pool_size) + return; + + size *= 1.5; + _ecore_evas_wl_shm_pool_free(ee); + + if (!(shm = ecore_wl_shm_get())) + { + ERR("ecore_wl_shm_get returned NULL"); + return; + } + + strcpy(tmp, "/tmp/ecore-evas-wayland_shm-XXXXXX"); + if ((fd = mkstemp(tmp)) < 0) + { + ERR("Could not create temporary file."); + return; + } + + if (ftruncate(fd, size) < 0) + { + ERR("Could not truncate temporary file."); + goto end; + } + + data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0); + unlink(tmp); + + if (data == MAP_FAILED) + { + ERR("mmap of temporary file failed."); + goto end; + } + + ee->engine.wl.pool_size = size; + ee->engine.wl.pool_data = data; + ee->engine.wl.pool = wl_shm_create_pool(shm, fd, size); + + end: + close(fd); +} + +static void +_ecore_evas_wl_buffer_free(Ecore_Evas *ee) +{ + if (!ee->engine.wl.buffer) return; + + wl_buffer_destroy(ee->engine.wl.buffer); + ee->engine.wl.buffer = NULL; +} + +static void +_ecore_evas_wl_buffer_new(Ecore_Evas *ee, int w, int h) +{ + unsigned int format; + int stride = 0; + + stride = (w * sizeof(int)); + + _ecore_evas_wl_shm_pool_create(ee, stride * h); + + if ((ee->alpha) || (ee->transparent)) + format = WL_SHM_FORMAT_ARGB8888; + else + format = WL_SHM_FORMAT_XRGB8888; + + _ecore_evas_wl_buffer_free(ee); + ee->engine.wl.buffer = + wl_shm_pool_create_buffer(ee->engine.wl.pool, 0, w, h, stride, format); +} + +void +_ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->engine.wl.win) + { + ee->engine.wl.win->resizing = EINA_TRUE; + ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location); + } +} +#else +EAPI Ecore_Evas * +ecore_evas_wayland_shm_new(const char *disp_name EINA_UNUSED, unsigned int parent EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, Eina_Bool frame EINA_UNUSED) +{ + return NULL; +} +#endif diff --git a/src/lib/ecore_evas/ecore_evas_win32.c b/src/lib/ecore_evas/ecore_evas_win32.c new file mode 100644 index 0000000000..32ecc46de4 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_win32.c @@ -0,0 +1,1524 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include /* for NULL */ + +#include +#include "ecore_private.h" +#ifdef BUILD_ECORE_EVAS_WIN32 +# define WIN32_LEAN_AND_MEAN +# include +# undef WIN32_LEAN_AND_MEAN +# include +# include +#endif /* BUILD_ECORE_EVAS_WIN32 */ + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +#ifdef BUILD_ECORE_EVAS_WIN32 + +#define ECORE_EVAS_EVENT_COUNT 10 + +static int _ecore_evas_init_count = 0; + +static Ecore_Event_Handler *ecore_evas_event_handlers[ECORE_EVAS_EVENT_COUNT]; + +static Eina_Bool _ecore_evas_win32_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_window_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_window_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_window_damage(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_window_destroy(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_window_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_window_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +static Eina_Bool _ecore_evas_win32_event_window_delete_request(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); + +/* Private functions */ + +static int +_ecore_evas_win32_render(Ecore_Evas *ee) +{ + int rend = 0; + Eina_List *updates = NULL; + 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); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + 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_FOCUS_IN, _ecore_evas_win32_event_window_focus_in, NULL); + ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT, _ecore_evas_win32_event_window_focus_out, NULL); + ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_DAMAGE, _ecore_evas_win32_event_window_damage, NULL); + ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_DESTROY, _ecore_evas_win32_event_window_destroy, NULL); + ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_SHOW, _ecore_evas_win32_event_window_show, NULL); + ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_HIDE, _ecore_evas_win32_event_window_hide, NULL); + ecore_evas_event_handlers[8] = ecore_event_handler_add(ECORE_WIN32_EVENT_WINDOW_CONFIGURE, _ecore_evas_win32_event_window_configure, NULL); + ecore_evas_event_handlers[9] = 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 Eina_Bool +_ecore_evas_win32_event_mouse_in(void *data EINA_UNUSED, int type EINA_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->timestamp, NULL); + evas_focus_in(ee->evas); + _ecore_evas_mouse_move_process(ee, e->x, e->y, e->timestamp); + + return 1; +} + +static Eina_Bool +_ecore_evas_win32_event_mouse_out(void *data EINA_UNUSED, int type EINA_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->timestamp); + + evas_event_feed_mouse_out(ee->evas, e->timestamp, 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 Eina_Bool +_ecore_evas_win32_event_window_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Win32_Event_Window_Focus_In *e; + + e = event; + ee = ecore_event_window_match((Ecore_Window)e->window); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if ((Ecore_Window)e->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_win32_event_window_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_Win32_Event_Window_Focus_Out *e; + + e = event; + ee = ecore_event_window_match((Ecore_Window)e->window); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; + if ((Ecore_Window)e->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + + evas_focus_out(ee->evas); + ee->prop.focused = 0; + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_win32_event_window_damage(void *data EINA_UNUSED, int type EINA_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 Eina_Bool +_ecore_evas_win32_event_window_destroy(void *data EINA_UNUSED, int type EINA_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 Eina_Bool +_ecore_evas_win32_event_window_show(void *data EINA_UNUSED, int type EINA_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 Eina_Bool +_ecore_evas_win32_event_window_hide(void *data EINA_UNUSED, int type EINA_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 Eina_Bool +_ecore_evas_win32_event_window_configure(void *data EINA_UNUSED, int type EINA_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->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->width) || (ee->h != e->height)) + { + ee->w = e->width; + ee->h = e->height; + 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) */ +/* _ecore_evas_win32_region_border_resize(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 Eina_Bool +_ecore_evas_win32_event_window_delete_request(void *data EINA_UNUSED, int type EINA_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, + Ecore_Evas_Event_Cb func) +{ + 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); + ee->req.x = x; + ee->req.y = 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); + ee->req.w = width; + ee->req.h = 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); + } + 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_win32_region_border_resize(ee); */ + 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); + ee->req.x = x; + ee->req.y = y; + ee->req.w = width; + ee->req.h = 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); + } + 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_win32_region_border_resize(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); + } + } +} + +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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + _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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + _ecore_evas_win32_rotation_set_internal(ee, rotation); + } +#endif /* BUILD_ECORE_EVAS_SOFTWARE_DDRAW */ +} + +static void +_ecore_evas_win32_shaped_set(Ecore_Evas *ee, int shaped) +{ + if (((ee->shaped) && (shaped)) || ((!ee->shaped) && (!shaped))) + return; + + if (!strcmp(ee->driver, "software_ddraw")) 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); + ee->shaped = shaped; + if (einfo) + { + ee->engine.win32.state.region = ee->shaped; + einfo->info.region = ee->engine.win32.state.region; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + if (ee->shaped) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } +#endif /* BUILD_ECORE_EVAS_SOFTWARE_GDI */ + } +} + +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((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 EINA_UNUSED) +{ + ecore_win32_window_focus((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); + +#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) + { + einfo->info.borderless = ee->prop.borderless; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + } + if (ee->prop.borderless) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + } +#endif /* BUILD_ECORE_EVAS_SOFTWARE_GDI */ +} + +static void +_ecore_evas_win32_override_set(Ecore_Evas *ee, int on) +{ + struct _Ecore_Win32_Window *window; + + INF("ecore evas override set"); + + window = (struct _Ecore_Win32_Window *)ee->prop.window; + + if (ee->prop.override == on) return; + if (ee->should_be_visible) ecore_win32_window_hide(window); + /* FIXME: use borderless_set for now */ + ecore_win32_window_borderless_set(window, on); + if (ee->should_be_visible) ecore_win32_window_show(window); + if (ee->prop.focused) ecore_win32_window_focus(window); + ee->prop.override = on; +} + +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_fullscreen_set(window, on); + } + else + { + ecore_win32_window_fullscreen_set(window, on); + } + + /* 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) + { + einfo->info.fullscreen = !!on; +/* einfo->info.layered = window->shape.layered; */ + 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_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) + { + einfo->info.fullscreen = !!on; + einfo->info.layered = window->shape.layered; + 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_DIRECT3D */ +} +static void +_ecore_evas_win32_alpha_set(Ecore_Evas *ee, int alpha) +{ + alpha = !!alpha; + if ((ee->alpha == alpha)) return; + + if (!strcmp(ee->driver, "software_gdi")) + { +#ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI + Evas_Engine_Info_Software_Gdi *einfo; + + einfo = (Evas_Engine_Info_Software_Gdi *)evas_engine_info_get(ee->evas); + if (!einfo) return; + + ee->shaped = 0; + ee->alpha = alpha; + /* ecore_win32_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_win32_window_override_new(ee->engine.win32.win_root, */ + /* ee->req.x, */ + /* ee->req.y, */ + /* ee->req.w, */ + /* ee->req.h); */ + /* else */ + /* ee->prop.window = ecore_win32_window_new(ee->engine.win32.win_root, */ + /* ee->req.x, */ + /* ee->req.y, */ + /* ee->req.w, */ + /* ee->req.h); */ + /* if (ee->engine.win32.mask) ecore_x_pixmap_free(ee->engine.x.mask); */ + /* ee->engine.win32.mask = 0; */ + /* ecore_win32_window_shape_input_mask_set(ee->prop.window, 0); */ + /* } */ + + /* einfo->info.destination_alpha = alpha; */ + einfo->info.region = alpha; + +// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask); +// ee->engine.x.mask = 0; + /* einfo->info.mask = ee->engine.win32.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_win32_window_shape_mask_set(ee->prop.window, 0); */ + /* ecore_event_window_register(ee->prop.window, ee, ee->evas, */ + /* (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, */ + /* (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, */ + /* (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, */ + /* (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); */ + if (ee->prop.borderless) + ecore_win32_window_borderless_set((struct _Ecore_Win32_Window *)ee->prop.window, ee->prop.borderless); + if (ee->visible) ecore_win32_window_show((struct _Ecore_Win32_Window *)ee->prop.window); + if (ee->prop.focused) ecore_win32_window_focus((struct _Ecore_Win32_Window *)ee->prop.window); + if (ee->prop.title) + { + ecore_win32_window_title_set((struct _Ecore_Win32_Window *)ee->prop.window, ee->prop.title); + /* ecore_win32_name_set(ee->prop.window, ee->prop.title); */ + } + ecore_win32_window_type_set((struct _Ecore_Win32_Window *)ee->prop.window, ECORE_WIN32_WINDOW_TYPE_NORMAL); +#endif /* BUILD_ECORE_EVAS_SOFTWARE_GDI */ + } +} + +static void +_ecore_evas_win32_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi) +{ + HDC dc; + + dc = GetDC(NULL); + if (!dc) + { + if (xdpi) *xdpi = 0; + if (ydpi) *ydpi = 0; + return; + } + + if (xdpi) *xdpi = GetDeviceCaps(dc, LOGPIXELSX); + if (ydpi) *ydpi = GetDeviceCaps(dc, LOGPIXELSY); + + /* + * Alternative (to test) + int width_mm; + int height_mm; + int width_px; + int height_px; + + width_mm = GetDeviceCaps(dc, HORZSIZE); + height_mm = GetDeviceCaps(dc, VERTSIZE); + width_px = GetDeviceCaps(dc, HORZRES); + height_px = GetDeviceCaps(dc, VERTRES); + + *xdpi = (width_px * 254) / (width_mm * 10); + *ydpi = (height_px * 254) / (height_mm * 10); + + code with LOGPIXELS gives 96x96 + code with the computation gives 101x77 + + */ + + ReleaseDC(NULL, dc); +} + +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, + _ecore_evas_win32_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, + _ecore_evas_win32_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 */ + _ecore_evas_win32_alpha_set, + NULL, //transparent + NULL, // profiles_set + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, // render + NULL, // screen_geometry_get + _ecore_evas_win32_screen_dpi_get +}; + +#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.depth = ecore_win32_screen_depth_get(); + einfo->info.rotation = 0; + einfo->info.borderless = 0; + einfo->info.fullscreen = 0; + einfo->info.region = 0; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + return 0; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + return 0; + } + + 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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + return 0; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + return 0; + } + + 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; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + return 0; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + return 0; + } + + 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(); + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + return 0; + } + } + else + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + return 0; + } + + return 1; +} +#endif /* BUILD_ECORE_EVAS_OPENGL_GLEW */ + +#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->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; + /* 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_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_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 EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_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 EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_UNUSED) +{ + return NULL; +} + +#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_DDRAW */ + + +EAPI Ecore_Evas * +ecore_evas_software_16_ddraw_new(Ecore_Win32_Window *parent EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_UNUSED) +{ + return NULL; +} + +#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 EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_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 EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_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 EINA_UNUSED) +{ + return NULL; +} + +#endif /* BUILD_ECORE_EVAS_WIN32 */ diff --git a/src/lib/ecore_evas/ecore_evas_wince.c b/src/lib/ecore_evas/ecore_evas_wince.c new file mode 100644 index 0000000000..142a85059c --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_wince.c @@ -0,0 +1,67 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include /* for NULL */ + +#include +#include "ecore_private.h" + +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +EAPI Ecore_Evas * +ecore_evas_software_wince_new(Ecore_WinCE_Window *parent EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_Evas * +ecore_evas_software_wince_fb_new(Ecore_WinCE_Window *parent EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_Evas * +ecore_evas_software_wince_gapi_new(Ecore_WinCE_Window *parent EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_Evas * +ecore_evas_software_wince_ddraw_new(Ecore_WinCE_Window *parent EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_Evas * +ecore_evas_software_wince_gdi_new(Ecore_WinCE_Window *parent EINA_UNUSED, + int x EINA_UNUSED, + int y EINA_UNUSED, + int width EINA_UNUSED, + int height EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_WinCE_Window * +ecore_evas_software_wince_window_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return NULL; +} diff --git a/src/lib/ecore_evas/ecore_evas_x.c b/src/lib/ecore_evas/ecore_evas_x.c new file mode 100644 index 0000000000..d94f055319 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_x.c @@ -0,0 +1,3663 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include + +#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 int leader_ref = 0; +static Ecore_X_Window leader_win = 0; + +static void +_ecore_evas_x_hints_update(Ecore_Evas *ee) +{ + ecore_x_icccm_hints_set + (ee->prop.window, + !ee->prop.focus_skip /* accepts_focus */, + ee->prop.iconified ? ECORE_X_WINDOW_STATE_HINT_ICONIC : + ee->prop.withdrawn ? ECORE_X_WINDOW_STATE_HINT_WITHDRAWN : + ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */, + 0 /* icon_pixmap */, + 0 /* icon_mask */, + 0 /* icon_window */, + ee->prop.group_ee_win /* window_group */, + ee->prop.urgent /* is_urgent */); +} + +static void +_ecore_evas_x_group_leader_set(Ecore_Evas *ee) +{ + leader_ref++; + if (leader_ref == 1) + { + char *id = NULL; + + leader_win = + ecore_x_window_override_new(ee->engine.x.win_root, 1234, 5678, 1, 2); + ecore_x_window_defaults_set(leader_win); + if ((id = getenv("DESKTOP_STARTUP_ID"))) + ecore_x_netwm_startup_id_set(leader_win,id); + ecore_x_icccm_client_leader_set(leader_win, leader_win); + } + ee->engine.x.leader = leader_win; + ecore_x_icccm_client_leader_set(ee->prop.window, leader_win); +} + +static void +_ecore_evas_x_group_leader_unset(Ecore_Evas *ee) +{ + ecore_x_window_prop_property_del(ee->prop.window, + ECORE_X_ATOM_WM_CLIENT_LEADER); + if (ee->engine.x.leader == leader_win) + { + leader_ref--; + if (leader_ref <= 0) + { + ecore_x_window_free(leader_win); + leader_win = 0; + } + ee->engine.x.leader = 0; + } +} + +static void +_ecore_evas_x_group_leader_update(Ecore_Evas *ee) +{ + if (ee->engine.x.leader) + ecore_x_icccm_client_leader_set(ee->prop.window, ee->engine.x.leader); +} + +static void +_ecore_evas_x_protocols_set(Ecore_Evas *ee) +{ + Ecore_X_Atom protos[3]; + unsigned int num = 0, tmp = 0; + + if (ee->func.fn_delete_request) + protos[num++] = ECORE_X_ATOM_WM_DELETE_WINDOW; + protos[num++] = ECORE_X_ATOM_NET_WM_PING; + protos[num++] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; + ecore_x_icccm_protocol_atoms_set(ee->prop.window, protos, num); + + if (!ee->engine.x.netwm_sync_counter) + ee->engine.x.netwm_sync_counter = ecore_x_sync_counter_new(0); + + tmp = ee->engine.x.netwm_sync_counter; + ecore_x_window_prop_card32_set(ee->prop.window, + ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, + &tmp, 1); +} + +static void +_ecore_evas_x_sync_set(Ecore_Evas *ee) +{ + Ecore_X_Sync_Counter sync_counter = ee->engine.x.sync_counter; + + if (((ee->should_be_visible) || (ee->visible)) && + ((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_val = 0; + } + ee->engine.x.sync_counter = 0; + } + if (sync_counter != ee->engine.x.sync_counter) + 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_val = 0; + ee->engine.x.sync_counter = 0; +} + +# ifdef BUILD_ECORE_EVAS_OPENGL_X11 +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) + { + 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]; + } + else if (opt[op] == ECORE_EVAS_GL_X11_OPT_VSYNC) + { + op++; + einfo->vsync = opt[op]; + } +#ifdef EVAS_ENGINE_GL_X11_SWAP_MODE_EXISTS + else if (opt[op] == ECORE_EVAS_GL_X11_OPT_SWAP_MODE) + { + op++; + if ((evas_version->major >= 1) && + (evas_version->minor >= 7) && + (evas_version->micro >= 99)) + einfo->swap_mode = opt[op]; + } +#endif + } + } + + /* FIXME: this is inefficient as its 1 or more round trips */ + screen = ecore_x_screen_index_get(ecore_x_default_screen_get()); + if (ecore_x_screen_count_get() > 1) + { + Ecore_X_Window *roots; + int num, i; + + num = 0; + roots = ecore_x_window_root_list(&num); + if (roots) + { + Ecore_X_Window root; + + root = ecore_x_window_root_get(parent); + for (i = 0; i < num; i++) + { + if (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); + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + return 0; + } + } + + if (argb) + { + if (override) + win = ecore_x_window_override_argb_new(parent, x, y, w, h); + else + win = ecore_x_window_argb_new(parent, x, y, w, h); + } + else + { + if (override) + win = ecore_x_window_override_new(parent, x, y, w, h); + else + win = ecore_x_window_new(parent, x, y, w, h); + } + + ecore_x_window_pixel_gravity_set(win, ECORE_X_GRAVITY_FORGET); + + /* 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)) + { + ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); + ecore_x_window_free(win); + return 0; + } + } + else + win = 0; + + return win; +} +#endif + +static int +_ecore_evas_x_render(Ecore_Evas *ee) +{ + int rend = 0; + Eina_List *updates = NULL; + 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); + if (ee2->engine.func->fn_render) + rend |= ee2->engine.func->fn_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + updates = evas_render_updates(ee->evas); + if (ee->prop.avoid_damage) + { + if (ee->engine.x.using_bg_pixmap) + { + if (updates) + { + Eina_List *l = NULL; + Eina_Rectangle *r; + + 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) + { + 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); + } + _ecore_evas_idle_timeout_update(ee); + rend = 1; + } + } + else + { + if (updates) + { + Eina_List *l = NULL; + Eina_Rectangle *r; + + 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 (ee->shaped) + { + + /* if we have a damage pixmap - we can avoid exposures by + * disabling them just for setting the mask */ + ecore_x_event_mask_unset(ee->prop.window, ECORE_X_EVENT_MASK_WINDOW_DAMAGE); + 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_WINDOW_DAMAGE); + } + ecore_x_xregion_set(ee->engine.x.damages, ee->engine.x.gc); + 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; + } + _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))) + { + 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); + } + _ecore_evas_idle_timeout_update(ee); + rend = 1; + } + } + else + evas_norender(ee->evas); + evas_render_updates_free(updates); + + 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 */ + } +} + +/* TODO: we need to make this work for all the states, not just sticky */ +static Eina_Bool +_ecore_evas_x_event_property_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Property *e; + int state_change = 0; + + e = event; + ee = ecore_event_window_match(e->win); + if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (e->atom == ECORE_X_ATOM_NET_WM_STATE) + { + unsigned int i, num; + Ecore_X_Window_State *state; + struct { + 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; + } x; + struct { + char modal : 1; + char maximized : 1; + char sticky : 1; + char fullscreen : 1; + char focus_skip : 1; + } prop; + } prev; + + prev.x.modal = ee->engine.x.state.modal; + prev.x.sticky = ee->engine.x.state.sticky; + prev.x.maximized_v = ee->engine.x.state.maximized_v; + prev.x.maximized_h = ee->engine.x.state.maximized_h; + prev.x.shaded = ee->engine.x.state.shaded; + prev.x.skip_taskbar = ee->engine.x.state.skip_taskbar; + prev.x.skip_pager = ee->engine.x.state.skip_pager; + prev.x.fullscreen = ee->engine.x.state.fullscreen; + prev.x.above = ee->engine.x.state.above; + prev.x.below = ee->engine.x.state.below; + + prev.prop.modal = ee->prop.modal; + prev.prop.maximized = ee->prop.maximized; + prev.prop.sticky = ee->prop.sticky; + prev.prop.fullscreen = ee->prop.fullscreen; + prev.prop.focus_skip = ee->prop.focus_skip; + + ee->engine.x.state.modal = 0; + ee->engine.x.state.sticky = 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->engine.x.state.fullscreen = 0; + ee->engine.x.state.above = 0; + ee->engine.x.state.below = 0; + + ee->prop.modal = 0; + ee->prop.maximized = 0; + ee->prop.sticky = 0; + ee->prop.fullscreen = 0; + ee->prop.focus_skip = 0; + + 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; + ee->prop.modal = 1; + break; + case ECORE_X_WINDOW_STATE_STICKY: + ee->prop.sticky = 1; + ee->engine.x.state.sticky = 1; + break; + case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT: + ee->engine.x.state.maximized_v = 1; + ee->prop.maximized = 1; + break; + case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ: + ee->engine.x.state.maximized_h = 1; + ee->prop.maximized = 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; + ee->prop.focus_skip = 1; + break; + case ECORE_X_WINDOW_STATE_SKIP_PAGER: + ee->engine.x.state.skip_pager = 1; + ee->prop.focus_skip = 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); + } + if ( +// (prev.x.modal != ee->engine.x.state.modal) || + (prev.x.sticky != ee->engine.x.state.sticky) || + (prev.x.maximized_v != ee->engine.x.state.maximized_v) || + (prev.x.maximized_h != ee->engine.x.state.maximized_h) || +// (prev.x.shaded != ee->engine.x.state.shaded) || +// (prev.x.skip_taskbar != ee->engine.x.state.skip_taskbar) || +// (prev.x.skip_pager != ee->engine.x.state.skip_pager) || + (prev.x.fullscreen != ee->engine.x.state.fullscreen) || +// (prev.x.above != ee->engine.x.state.above) || +// (prev.x.below != ee->engine.x.state.below) || +// (prev.prop.modal != ee->prop.modal) || + (prev.prop.maximized != ee->prop.maximized) || + (prev.prop.sticky != ee->prop.sticky) || + (prev.prop.fullscreen != ee->prop.fullscreen) || + (prev.prop.focus_skip != ee->prop.focus_skip)) + state_change = 1; + } + else if (e->atom == ECORE_X_ATOM_WM_STATE) + { + Ecore_X_Window_State_Hint state; + + // handle WM_STATE changes + state = ecore_x_icccm_state_get(e->win); + switch (state) + { + case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN: + if ((!ee->prop.withdrawn) || (ee->prop.iconified)) + { + state_change = 1; + ee->prop.withdrawn = 1; + ee->prop.iconified = 0; + } + break; + case ECORE_X_WINDOW_STATE_HINT_ICONIC: + if ((!ee->prop.iconified) || (ee->prop.withdrawn)) + { + state_change = 1; + ee->prop.iconified = 1; + ee->prop.withdrawn = 0; + } + break; + case ECORE_X_WINDOW_STATE_HINT_NORMAL: + if ((ee->prop.iconified) || (ee->prop.withdrawn)) + { + state_change = 1; + ee->prop.iconified = 0; + ee->prop.withdrawn = 0; + } + break; + default: + break; + } + } + else if (e->atom == ECORE_X_ATOM_E_PROFILE) + { + char *p = ecore_x_e_window_profile_get(e->win); + if ((p) && (ee->prop.profile)) + { + if (strcmp(p, ee->prop.profile) != 0) + { + free(ee->prop.profile); + ee->prop.profile = strdup(p); + state_change = 1; + } + } + else if ((!p) && (ee->prop.profile)) + { + free(ee->prop.profile); + ee->prop.profile = NULL; + state_change = 1; + } + else if ((p) && (!ee->prop.profile)) + { + ee->prop.profile = strdup(p); + state_change = 1; + } + + if (p) + free(p); + } + + if (state_change) + { + if (ee->func.fn_state_change) ee->func.fn_state_change(ee); + } + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_visibility_change(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; +// 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 ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_client_message(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Client_Message *e; + + e = event; + if (e->format != 32) return ECORE_CALLBACK_PASS_ON; + if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_BEGIN) + { + ee = ecore_event_window_match(e->data.l[0]); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->data.l[0] != (long)ee->prop.window) + return ECORE_CALLBACK_PASS_ON; + if (!ee->engine.x.sync_began) + { + // qeue a damage + draw. work around an event re-ordering thing. + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + 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 ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->data.l[0] != (long)ee->prop.window) + return ECORE_CALLBACK_PASS_ON; + 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 ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->data.l[0] != (long)ee->prop.window) + return ECORE_CALLBACK_PASS_ON; + ee->engine.x.sync_began = 0; + ee->engine.x.sync_cancel = 1; + } + else if ((e->message_type == ECORE_X_ATOM_WM_PROTOCOLS) && + (e->data.l[0] == (int)ECORE_X_ATOM_NET_WM_SYNC_REQUEST)) + { + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + ee->engine.x.netwm_sync_val_lo = (unsigned int)e->data.l[2]; + ee->engine.x.netwm_sync_val_hi = (int)e->data.l[3]; + ee->engine.x.netwm_sync_set = 1; + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_mouse_in(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; +/* { */ +/* 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 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; */ + if (!ee->in) + { + 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); + ee->in = EINA_TRUE; + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_mouse_out(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; + /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; +/* { */ +/* 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; */ +// printf("OUT: ee->in=%i, e->mode=%i, e->detail=%i, dount_count=%i\n", +// ee->in, e->mode, e->detail, evas_event_down_count_get(ee->evas)); + if (ee->in) + { + if ((evas_event_down_count_get(ee->evas) > 0) && + (!((e->mode == ECORE_X_EVENT_MODE_GRAB) && + (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))) + return ECORE_CALLBACK_PASS_ON; + 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); + ee->in = EINA_FALSE; + } + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_window_focus_in(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; +//xx// filtering with these doesnt help +//xx// if (e->mode == ECORE_X_EVENT_MODE_UNGRAB) return ECORE_CALLBACK_PASS_ON; + ee->prop.focused = 1; + evas_focus_in(ee->evas); + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_window_focus_out(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; +//xx// filtering with these doesnt help +//xx// if (e->mode == ECORE_X_EVENT_MODE_GRAB) return ECORE_CALLBACK_PASS_ON; + +// 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 ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_window_damage(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Damage *e; + + e = event; + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (ee->engine.x.using_bg_pixmap) return ECORE_CALLBACK_PASS_ON; +// 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 ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_window_destroy(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Destroy *e; + + e = event; + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (ee->func.fn_destroy) ee->func.fn_destroy(ee); + _ecore_evas_x_sync_clear(ee); + ecore_evas_free(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Configure *e; + + e = event; + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (ee->engine.x.direct_resize) return ECORE_CALLBACK_PASS_ON; + + ee->engine.x.configure_coming = 0; + 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 ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_window_delete_request(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_window_show(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Show *e; + static int first_map_bug = -1; + + e = event; + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + /* some GL drivers are doing buffer copy in a separate thread. + * we need to check whether GL driver sends SYNC_DRAW_DONE msg afger copying + * that are required in order to exactly render. - added by gl77.lee + */ + if (ee->gl_sync_draw_done < 0) + { + if (getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE")) + ee->gl_sync_draw_done = atoi(getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE")); + else + ee->gl_sync_draw_done = 0; + } + if (first_map_bug < 0) + { + char *bug = NULL; + + if ((bug = getenv("ECORE_EVAS_GL_FIRST_MAP_BUG"))) + first_map_bug = atoi(bug); + else + first_map_bug = 0; + } + if ((first_map_bug) && (!strcmp(ee->driver, "opengl_x11"))) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + if (ee->visible) return ECORE_CALLBACK_PASS_ON; +// if (ee->visible) return ECORE_CALLBACK_DONE; +// printf("SHOW EVENT %p\n", ee); + ee->visible = 1; + if (ee->func.fn_show) ee->func.fn_show(ee); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_x_event_window_hide(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Hide *e; + + e = event; + ee = ecore_event_window_match(e->win); + if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ + if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + if (ee->in) + { + 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); + ee->in = EINA_FALSE; + } + if (!ee->visible) return ECORE_CALLBACK_PASS_ON; +// if (!ee->visible) return ECORE_CALLBACK_DONE; +// printf("HIDE EVENT %p\n", ee); + ee->visible = 0; + if (ee->func.fn_hide) ee->func.fn_hide(ee); + return ECORE_CALLBACK_PASS_ON; +} + +/* FIXME, should be in idler */ +/* FIXME, round trip */ +static void +_ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee) +{ + 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 */, + ee->prop.aspect /* min_aspect */, + ee->prop.aspect /* max_aspect */); +} + +/* FIXME, should be in idler */ +static void +_ecore_evas_x_state_update(Ecore_Evas *ee) +{ + Ecore_X_Window_State state[10]; + int num = 0; + + if (ee->prop.modal) + state[num++] = ECORE_X_WINDOW_STATE_MODAL; + if (ee->prop.sticky) + state[num++] = ECORE_X_WINDOW_STATE_STICKY; + if (ee->prop.maximized) + state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_VERT; + if (ee->prop.maximized) + state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ; +// if (bd->client.netwm.state.shaded) +// state[num++] = ECORE_X_WINDOW_STATE_SHADED; + if (ee->prop.focus_skip) + state[num++] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR; + if (ee->prop.focus_skip) + 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; + if (ee->prop.demand_attention) + state[num++] = ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION; + + 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_group_leader_unset(ee); + _ecore_evas_x_sync_set(ee); + if (ee->engine.x.win_shaped_input) + ecore_x_window_free(ee->engine.x.win_shaped_input); + 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, Ecore_Evas_Event_Cb func) +{ + 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 + { + if (((ee->x != x) || (ee->y != y)) || + (ee->engine.x.configure_coming)) + { + ee->engine.x.configure_coming = 1; + if (!ee->engine.x.managed) + { + 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); + } + } +} + +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)) + { + ee->w = w; + ee->h = h; + ecore_x_window_resize(ee->prop.window, w, 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 if (((ee->w != w) || (ee->h != h)) || + (ee->engine.x.configure_coming)) + { + ee->engine.x.configure_coming = 1; + 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 if (((ee->w != w) || (ee->h != h) || (ee->x != x) || (ee->y != y)) || + (ee->engine.x.configure_coming)) + { + ee->engine.x.configure_coming = 1; + 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) + { + ee->engine.x.configure_coming = 1; + 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; + 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); + } + 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); + } +} + +#define _USE_WIN_ROT_EFFECT 1 + +#if _USE_WIN_ROT_EFFECT +static void _ecore_evas_x_flush_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED); + +typedef struct _Ecore_Evas_X_Rotation_Effect Ecore_Evas_X_Rotation_Effect; +struct _Ecore_Evas_X_Rotation_Effect +{ + Eina_Bool wait_for_comp_reply; +}; + +static Ecore_Evas_X_Rotation_Effect _rot_effect = +{ + EINA_FALSE +}; + +static void +_ecore_evas_x_rotation_effect_setup(void) +{ + _rot_effect.wait_for_comp_reply = EINA_TRUE; +} +#endif /* end of _USE_WIN_ROT_EFFECT */ + +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 _USE_WIN_ROT_EFFECT + int angles[2]; + angles[0] = rotation; + angles[1] = ee->rotation; +#endif /* end of _USE_WIN_ROT_EFFECT */ + + 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); +# if _USE_WIN_ROT_EFFECT + ecore_x_window_prop_property_set(ee->prop.window, + ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, + ECORE_X_ATOM_CARDINAL, 32, &angles, 2); +# else + ecore_x_window_prop_property_set(ee->prop.window, + ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, + ECORE_X_ATOM_CARDINAL, 32, &rotation, 1); +# endif +#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); +# if _USE_WIN_ROT_EFFECT + ecore_x_window_prop_property_set(ee->prop.window, + ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, + ECORE_X_ATOM_CARDINAL, 32, &angles, 2); +# else + ecore_x_window_prop_property_set(ee->prop.window, + ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, + ECORE_X_ATOM_CARDINAL, 32, &rotation, 1); +# endif +#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */ + } + +#if _USE_WIN_ROT_EFFECT + if ((ee->visible) && + ((ecore_x_e_comp_sync_supported_get(ee->engine.x.win_root)) && + (!ee->no_comp_sync) && (_ecore_evas_app_comp_sync)) && + (ee->engine.x.sync_counter) && + (ee->engine.x.sync_val > 0)) + { + _ecore_evas_x_rotation_effect_setup(); + _ecore_evas_x_flush_pre(ee, NULL, NULL); + } +#endif /* end of _USE_WIN_ROT_EFFECT */ +} + +static void +_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped) +{ + if ((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; + 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_SOFTWARE_X11 */ + } +} + +/* FIXME, round trip */ +static void +_ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha) +{ + Ecore_X_Window_Attributes att; + char *id = NULL; + + if ((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; + + ecore_x_window_attributes_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, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_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); + } + if (ee->prop.name) + ecore_x_icccm_name_class_set(ee->prop.window, + ee->prop.name, ee->prop.clas); + _ecore_evas_x_hints_update(ee); + _ecore_evas_x_group_leader_update(ee); + ecore_x_window_defaults_set(ee->prop.window); + _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_sync_set(ee); + _ecore_evas_x_size_pos_hints_update(ee); +#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */ + if ((id = getenv("DESKTOP_STARTUP_ID"))) + { + ecore_x_netwm_startup_id_set(ee->prop.window, 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); + } + */ + + ecore_x_window_attributes_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, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_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); + } + if (ee->prop.name) + ecore_x_icccm_name_class_set(ee->prop.window, + ee->prop.name, ee->prop.clas); + _ecore_evas_x_hints_update(ee); + _ecore_evas_x_group_leader_update(ee); + ecore_x_window_defaults_set(ee->prop.window); + _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_sync_set(ee); + _ecore_evas_x_size_pos_hints_update(ee); +#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */ + if ((id = getenv("DESKTOP_STARTUP_ID"))) + { + ecore_x_netwm_startup_id_set(ee->prop.window, 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)) 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 + } +} + +static void +_ecore_evas_x_window_group_set(Ecore_Evas *ee, const Ecore_Evas *group_ee) +{ + if (ee->prop.group_ee == group_ee) return; + + ee->prop.group_ee = (Ecore_Evas *)group_ee; + if (ee->prop.group_ee) + ee->prop.group_ee_win = group_ee->prop.window; + else + ee->prop.group_ee_win = 0; + _ecore_evas_x_hints_update(ee); +} + +static void +_ecore_evas_x_aspect_set(Ecore_Evas *ee, double aspect) +{ + if (ee->prop.aspect == aspect) return; + + ee->prop.aspect = aspect; + _ecore_evas_x_size_pos_hints_update(ee); +// netwm state +// 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_urgent_set(Ecore_Evas *ee, int urgent) +{ + if (ee->prop.urgent == urgent) return; + + ee->prop.urgent = urgent; + _ecore_evas_x_hints_update(ee); +} + +static void +_ecore_evas_x_modal_set(Ecore_Evas *ee, int modal) +{ + if (ee->prop.modal == modal) return; + + ee->prop.modal = modal; + if (ee->should_be_visible) + ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_MODAL, -1, modal); + else + _ecore_evas_x_state_update(ee); +} + +static void +_ecore_evas_x_demand_attention_set(Ecore_Evas *ee, int demand) +{ + if (ee->prop.demand_attention == demand) return; + + ee->prop.demand_attention = demand; + if (ee->should_be_visible) + ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION, -1, demand); + else + _ecore_evas_x_state_update(ee); +} + +static void +_ecore_evas_x_focus_skip_set(Ecore_Evas *ee, int skip) +{ + if (ee->prop.focus_skip == skip) return; + + ee->prop.focus_skip = skip; + if (ee->should_be_visible) + { + ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_SKIP_TASKBAR, -1, skip); + ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_SKIP_PAGER, -1, skip); + } + else + _ecore_evas_x_state_update(ee); + _ecore_evas_x_hints_update(ee); +} + +#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_evas_x_sync_set(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; + _ecore_evas_x_sync_set(ee); +} + +static void +_ecore_evas_x_raise(Ecore_Evas *ee) +{ + ecore_x_window_raise(ee->prop.window); +} + +static void +_ecore_evas_x_lower(Ecore_Evas *ee) +{ + 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 EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_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) + { + 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 EINA_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) return; + ee->prop.iconified = on; + _ecore_evas_x_hints_update(ee); + if (on) + ecore_x_icccm_iconic_request_send(ee->prop.window, ee->engine.x.win_root); + else + ecore_evas_show(ee); +} + +static void +_ecore_evas_x_borderless_set(Ecore_Evas *ee, int on) +{ + if (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) +{ + if (ee->prop.withdrawn == withdrawn) return; + ee->prop.withdrawn = withdrawn; + _ecore_evas_x_hints_update(ee); +} + +static void +_ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky) +{ + if (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) return; + + ee->ignore_events = ignore; + if (ee->prop.window) + ecore_x_window_ignore_set(ee->prop.window, ignore); +} + +/* +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, "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) return; + if (ee->should_be_visible) ecore_x_window_hide(ee->prop.window); + ecore_x_window_override_set(ee->prop.window, on); + if (ee->should_be_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_maximized_set(Ecore_Evas *ee, int on) +{ + if (ee->prop.maximized == on) return; + ee->engine.x.state.maximized_h = 1; + ee->engine.x.state.maximized_v = 1; + ee->prop.maximized = on; + if (ee->should_be_visible) + { + ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, -1, on); + ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, -1, on); + } + else + _ecore_evas_x_state_update(ee); +} + +static void +_ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on) +{ + if (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_profiles_set(Ecore_Evas *ee, const char **plist, int n) +{ + /* Ecore_Evas's profile will be updated when WM sets the E_PROFILE. */ + ecore_x_e_window_profile_list_set(ee->prop.window, plist, n); +} + +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, "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 */ + } +} + +static void +_ecore_evas_x_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) +{ + int outnum = 0; + int px = 0, py = 0, pw = 0, ph = 0; + Ecore_X_Window root; + Ecore_X_Randr_Output *out = NULL; + Ecore_X_Randr_Crtc crtc; + unsigned int val[4] = { 0 }; + + if (ecore_x_window_prop_card32_get + (ee->prop.window, ecore_x_atom_get("E_ZONE_GEOMETRY"), val, 4) == 4) + { + if (x) *x = (int)val[0]; + if (y) *y = (int)val[1]; + if (w) *w = (int)val[2]; + if (h) *h = (int)val[3]; + return; + } + + root = ecore_x_window_root_get(ee->prop.window); + out = ecore_x_randr_window_outputs_get(ee->prop.window, &outnum); + if (!out) + { +norandr: + if (out) free(out); + if (x) *x = 0; + if (y) *y = 0; + ecore_x_window_size_get(root, w, h); + return; + } + crtc = ecore_x_randr_output_crtc_get(root, out[0]); + if (!crtc) goto norandr; + ecore_x_randr_crtc_geometry_get(root, crtc, &px, &py, &pw, &ph); + if ((pw == 0) || (ph == 0)) goto norandr; + if (x) *x = px; + if (y) *y = py; + if (w) *w = pw; + if (h) *h = ph; + free(out); +} + +static void +_ecore_evas_x_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi) +{ + int scdpi, xmm = 0, ymm = 0, outnum = 0, w = 0, h = 0; + int px = 0, py = 0; + Ecore_X_Window root; + Ecore_X_Randr_Output *out = NULL; + Ecore_X_Randr_Crtc crtc; + + root = ecore_x_window_root_get(ee->prop.window); + out = ecore_x_randr_window_outputs_get(ee->prop.window, &outnum); + if (!out) + { +norandr: + if (out) free(out); + scdpi = ecore_x_dpi_get(); + if (xdpi) *xdpi = scdpi; + if (ydpi) *ydpi = scdpi; + return; + } + crtc = ecore_x_randr_output_crtc_get(root, out[0]); + if (!crtc) goto norandr; + ecore_x_randr_crtc_geometry_get(root, crtc, &px, &py, &w, &h); + if ((w == 0) || (h == 0)) goto norandr; + ecore_x_randr_output_size_mm_get(root, out[0], &xmm, &ymm); + if ((xmm == 0) || (ymm == 0)) goto norandr; + if (xdpi) *xdpi = (w * 254) / (xmm * 10); // 25.4mm / inch + if (ydpi) *ydpi = (h * 254) / (ymm * 10); // 25.4mm / inch + free(out); +} + +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, + _ecore_evas_x_maximized_set, + _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, + _ecore_evas_x_profiles_set, + + _ecore_evas_x_window_group_set, + _ecore_evas_x_aspect_set, + _ecore_evas_x_urgent_set, + _ecore_evas_x_modal_set, + _ecore_evas_x_demand_attention_set, + _ecore_evas_x_focus_skip_set, + + NULL, // render + _ecore_evas_x_screen_geometry_get, + _ecore_evas_x_screen_dpi_get +}; +#endif /* BUILD_ECORE_EVAS_X11 */ + +/* + * FIXME: there are some round trips. Especially, we can split + * ecore_x_init in 2 functions and suppress some round trips. + */ + +#if defined (BUILD_ECORE_EVAS_SOFTWARE_X11) || defined (BUILD_ECORE_EVAS_OPENGL_X11) +static void +_ecore_evas_x_flush_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_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) + { + if (!ee->semi_sync) + 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 EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Ecore_Evas *ee = data; + + if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) && + (!ee->gl_sync_draw_done)) // added by gl77.lee + { + if (ee->engine.x.sync_counter) + { + if (ee->engine.x.sync_began) + { + if (!ee->engine.x.sync_cancel) + { + ecore_x_e_comp_sync_draw_size_done_send + (ee->engine.x.win_root, ee->prop.window, ee->w, ee->h); + } + } + } + } + if (ee->engine.x.netwm_sync_set) + { + ecore_x_sync_counter_2_set(ee->engine.x.netwm_sync_counter, + ee->engine.x.netwm_sync_val_hi, + ee->engine.x.netwm_sync_val_lo); + ee->engine.x.netwm_sync_set = 0; + } +} +#endif + +/** + * @brief Create Ecore_Evas using software x11. + * @note If ecore is not compiled with support to x11 then nothing is done and NULL is returned. + * @param disp_name The name of the Ecore_Evas to be created. + * @param parent The parent of the Ecore_Evas to be created. + * @param x The X coordinate to be used. + * @param y The Y coordinate to be used. + * @param w The width of the Ecore_Evas to be created. + * @param h The height of the Ecore_Evas to be created. + * @return A handle to the created Ecore_Evas. + */ +#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, rmethod; + static int redraw_debug = -1; + char *id = NULL; + + 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 ((id = getenv("DESKTOP_STARTUP_ID"))) + { + ecore_x_netwm_startup_id_set(ee->prop.window, 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) + { + Ecore_X_Screen *screen; + + /* FIXME: this is inefficient as its 1 or more round trips */ + screen = ecore_x_default_screen_get(); + if (ecore_x_screen_count_get() > 1) + { + Ecore_X_Window *roots; + int num, i; + + num = 0; + roots = ecore_x_window_root_list(&num); + if (roots) + { + Ecore_X_Window root; + + root = ecore_x_window_root_get(parent); + for (i = 0; i < num; i++) + { + if (root == roots[i]) + { + screen = ecore_x_screen_get(i); + break; + } + } + free(roots); + } + } + + einfo->info.destination_alpha = argb; + + 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 + einfo->info.drawable = ee->prop.window; + + if (argb) + { + Ecore_X_Window_Attributes at; + + ecore_x_window_attributes_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; + } + else + { + einfo->info.visual = + ecore_x_default_visual_get(einfo->info.connection, screen); + einfo->info.colormap = + ecore_x_default_colormap_get(einfo->info.connection, screen); + einfo->info.depth = + ecore_x_default_depth_get(einfo->info.connection, screen); + 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)) + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + + _ecore_evas_x_hints_update(ee); + _ecore_evas_x_group_leader_set(ee); + ecore_x_window_defaults_set(ee->prop.window); + _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_sync_set(ee); + + 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, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); + return ee; +} +#else +EAPI Ecore_Evas * +ecore_evas_software_x11_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + return NULL; +} +#endif + +/** + * @brief Get the window from Ecore_Evas using software x11. + * @note If ecore is not compiled with support for x11 or if @p ee was not + * created with ecore_evas_software_x11_new() then nothing is done and + * 0 is returned. + * @param ee The Ecore_Evas from which to get the window. + * @return The window of type Ecore_X_Window. + */ +#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 +EAPI Ecore_X_Window +ecore_evas_software_x11_window_get(const Ecore_Evas *ee) +{ + if (!(!strcmp(ee->driver, "software_x11"))) return 0; + return (Ecore_X_Window) ecore_evas_window_get(ee); +} +#else +EAPI Ecore_X_Window +ecore_evas_software_x11_window_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} +#endif + +/** + * @brief Set the direct_resize of Ecore_Evas using software x11. + * @note If ecore is not compiled with support to x11 then nothing is done. + * @param ee The Ecore_Evas in which to set direct resize. + * @param on Enables the resize of Ecore_Evas if equals EINA_TRUE, disables if equals EINA_FALSE. + */ +#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 +EAPI void +ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool 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 EINA_UNUSED, Eina_Bool on EINA_UNUSED) +{ +} +#endif + +/** + * @brief Gets if the Ecore_Evas is being directly resized using software x11. + * @note If ecore is not compiled with support to x11 then nothing is done and EINA_FALSE is returned. + * @param ee The Ecore_Evas from which to get direct resize. + * @return EINA_TRUE if the resize was managed directly, otherwise return EINA_FALSE. + */ +#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11 +EAPI Eina_Bool +ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee) +{ + return ee->engine.x.direct_resize; +} +#else +EAPI Eina_Bool +ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} +#endif + +/** + * @brief Add extra window on Ecore_Evas using software x11. + * @note If ecore is not compiled with support to x11 then nothing is done. + * @param ee The Ecore_Evas on which to add the window. + * @param win The window to be added at the Ecore_Evas. + */ +#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, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); + } +} +#else +EAPI void +ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) +{ +} +#endif + +/** + * @brief Create Ecore_Evas using opengl x11. + * @note If ecore is not compiled with support to x11 then nothing is done and NULL is returned. + * @param disp_name The name of the display of the Ecore_Evas to be created. + * @param parent The parent of the Ecore_Evas to be created. + * @param x The X coordinate to be used. + * @param y The Y coordinate to be used. + * @param w The width of the Ecore_Evas to be created. + * @param h The height of the Ecore_Evas to be created. + * @return The new Ecore_Evas. + */ +#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) +{ + Ecore_Evas *ee; + int rmethod; + char *id = NULL; + + 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); + + ee->gl_sync_draw_done = -1; // added by gl77.lee + + _ecore_evas_x_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func; + + ee->driver = "opengl_x11"; +#if 1 + ee->semi_sync = 0; // gl engine doesn't need to sync - its whole swaps +#else + if (!getenv("ECORE_EVAS_COMP_NOSEMISYNC")) + ee->semi_sync = 1; // gl engine doesn't need to sync - its whole swaps +// ee->no_comp_sync = 1; // gl engine doesn't need to sync - its whole swaps +#endif + 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) + { + ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + if ((id = getenv("DESKTOP_STARTUP_ID"))) + { + ecore_x_netwm_startup_id_set(ee->prop.window, 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_evas_x_hints_update(ee); + _ecore_evas_x_group_leader_set(ee); + ecore_x_window_defaults_set(ee->prop.window); + _ecore_evas_x_protocols_set(ee); + _ecore_evas_x_sync_set(ee); + + 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, + (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, + (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, + (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); + + return ee; +} +#else +EAPI Ecore_Evas * +ecore_evas_gl_x11_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + return NULL; +} +EAPI Ecore_Evas * +ecore_evas_gl_x11_options_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, const int *opt EINA_UNUSED) +{ + return NULL; +} +#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ + +/** + * @brief Get the window from Ecore_Evas using opengl x11. + * @note If ecore is not compiled with support for x11 or if @p ee was not + * created with ecore_evas_gl_x11_new() then nothing is done and + * 0 is returned. + * @param ee The Ecore_Evas from which to get the window. + * @return The window of type Ecore_X_Window of Ecore_Evas. + */ +#ifdef BUILD_ECORE_EVAS_OPENGL_X11 +EAPI Ecore_X_Window +ecore_evas_gl_x11_window_get(const Ecore_Evas *ee) +{ + if (!(!strcmp(ee->driver, "opengl_x11"))) return 0; + return (Ecore_X_Window) ecore_evas_window_get(ee); +} +#else +EAPI Ecore_X_Window +ecore_evas_gl_x11_window_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} +#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ + +/** + * @brief Set direct_resize for Ecore_Evas using opengl x11. + * @note If ecore is not compiled with support to x11 then nothing is done. + * @param ee The Ecore_Evas in which to set direct resize. + * @param on Enables the resize of Ecore_Evas if equals EINA_TRUE, disables if equals EINA_FALSE. + */ +#ifdef BUILD_ECORE_EVAS_OPENGL_X11 +EAPI void +ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on) +{ + ee->engine.x.direct_resize = on; +} +#else +EAPI void +ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool on EINA_UNUSED) +{ +} +#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ + +/** + * @brief Gets if the Ecore_Evas is being directly resized using opengl x11. + * @note If ecore is not compiled with support to x11 then nothing is done and EINA_FALSE is returned. + * @param ee The Ecore_Evas from which to get direct resize. + * @return EINA_TRUE if the resize was managed directly, otherwise return EINA_FALSE. + */ +#ifdef BUILD_ECORE_EVAS_OPENGL_X11 +EAPI Eina_Bool +ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee) +{ + return ee->engine.x.direct_resize; +} +#else +EAPI Eina_Bool +ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} +#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ + +/** + * @brief Add extra window on Ecore_Evas using opengl x11. + * @note If ecore is not compiled with support to x11 then nothing is done. + * @param ee The Ecore_Evas for which to add the window. + * @param win The window to be added at the Ecore_Evas. + */ +#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 EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) +{ +} +#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ + +/** + * @brief Set the functions to be used before and after the swap callback. + * @note If ecore is not compiled with support to x11 then nothing is done and the function is returned. + * @param ee The Ecore_Evas for which to set the swap callback. + * @param data The data for which to set the swap callback. + * @param pre_cb The function to be called before the callback. + * @param post_cb The function to be called after the callback. + */ +#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.post_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 EINA_UNUSED, void *data EINA_UNUSED, void (*pre_cb) (void *data, Evas *e) EINA_UNUSED, void (*post_cb) (void *data, Evas *e) EINA_UNUSED) +{ + return; +} +#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */ + +EAPI Ecore_Evas * +ecore_evas_xrender_x11_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_X_Window +ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} + +EAPI void +ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool on EINA_UNUSED) +{ +} + +EAPI Eina_Bool +ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} + +EAPI void +ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) +{ +} + +EAPI Ecore_Evas * +ecore_evas_software_x11_16_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_X_Window +ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} + +EAPI void +ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool on EINA_UNUSED) +{ +} + +EAPI Eina_Bool +ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} + +EAPI void +ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) +{ +} + +EAPI Ecore_Evas * +ecore_evas_software_x11_8_new(const char *disp_name EINA_UNUSED, Ecore_X_Window parent EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_X_Window +ecore_evas_software_x11_8_window_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} + +EAPI Ecore_X_Window +ecore_evas_software_x11_8_subwindow_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} + +EAPI void +ecore_evas_software_x11_8_direct_resize_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool on EINA_UNUSED) +{ +} + +EAPI Eina_Bool +ecore_evas_software_x11_8_direct_resize_get(const Ecore_Evas *ee EINA_UNUSED) +{ + return 0; +} + +EAPI void +ecore_evas_software_x11_8_extra_event_window_add(Ecore_Evas *ee EINA_UNUSED, Ecore_X_Window win EINA_UNUSED) +{ + return; +} + +EAPI void +ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win) +{ +#ifdef BUILD_ECORE_EVAS_X11 + _ecore_evas_x_group_leader_unset(ee); + ee->engine.x.leader = win; + _ecore_evas_x_group_leader_update(ee); +#else + return; + ee = NULL; + win = 0; +#endif +} + +EAPI Ecore_X_Window +ecore_evas_x11_leader_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_X11 + return ee->engine.x.leader; +#else + return 0; + ee = NULL; +#endif +} + +EAPI void +ecore_evas_x11_leader_default_set(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_X11 + _ecore_evas_x_group_leader_unset(ee); + _ecore_evas_x_group_leader_set(ee); +#else + return; + ee = NULL; +#endif +} + +#ifdef BUILD_ECORE_EVAS_X11 +static Eina_Bool +_ecore_evas_x11_convert_rectangle_with_angle(Ecore_Evas *ee, Ecore_X_Rectangle *dst_rect, Ecore_X_Rectangle *src_rect) +{ + if ((!src_rect) || (!dst_rect)) return 0; + + if (ee->rotation == 0) + { + dst_rect->x = src_rect->x; + dst_rect->y = src_rect->y; + dst_rect->width = src_rect->width; + dst_rect->height = src_rect->height; + } + else if (ee->rotation == 90) + { + dst_rect->x = src_rect->y; + dst_rect->y = ee->req.h - src_rect->x - src_rect->width; + dst_rect->width = src_rect->height; + dst_rect->height = src_rect->width; + } + else if (ee->rotation == 180) + { + dst_rect->x = ee->req.w - src_rect->x - src_rect->width; + dst_rect->y = ee->req.h - src_rect->y - src_rect->height; + dst_rect->width = src_rect->width; + dst_rect->height = src_rect->height; + } + else if (ee->rotation == 270) + { + dst_rect->x = ee->req.w - src_rect->y - src_rect->height; + dst_rect->y = src_rect->x; + dst_rect->width = src_rect->height; + dst_rect->height = src_rect->width; + } + else + { + return 0; + } + + return 1; +} +#endif + +EAPI void +ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_X11 + Eina_Bool ret; + Ecore_X_Rectangle src_rect; + Ecore_X_Rectangle dst_rect; + + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_x11_shape_input_rectangle_set"); + return; + } + + src_rect.x = x; + src_rect.y = y; + src_rect.width = w; + src_rect.height = h; + + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = 0; + dst_rect.height = 0; + + ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect); + + if (!ee->engine.x.win_shaped_input) + ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, + 0, 0, 1, 1); + + if (ret) + ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, + dst_rect.x, dst_rect.y, + dst_rect.width, dst_rect.height); +#else + return; + ee = NULL; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas *ee, int x, int y, int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_X11 + Eina_Bool ret; + Ecore_X_Rectangle src_rect; + Ecore_X_Rectangle dst_rect; + + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_x11_shape_input_rectangle_add"); + return; + } + + src_rect.x = x; + src_rect.y = y; + src_rect.width = w; + src_rect.height = h; + + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = 0; + dst_rect.height = 0; + + ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect); + + if (!ee->engine.x.win_shaped_input) + ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, + 0, 0, 1, 1); + + if (ret) + ecore_x_window_shape_input_rectangle_add(ee->engine.x.win_shaped_input, + dst_rect.x, dst_rect.y, + dst_rect.width, dst_rect.height); +#else + return; + ee = NULL; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas *ee, int x, int y, int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_X11 + Eina_Bool ret; + Ecore_X_Rectangle src_rect; + Ecore_X_Rectangle dst_rect; + + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_x11_shape_input_rectangle_subtract"); + return; + } + + src_rect.x = x; + src_rect.y = y; + src_rect.width = w; + src_rect.height = h; + + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = 0; + dst_rect.height = 0; + + ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect); + + if (!ee->engine.x.win_shaped_input) + ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, + 0, 0, 1, 1); + + if (ret) + ecore_x_window_shape_input_rectangle_subtract(ee->engine.x.win_shaped_input, + dst_rect.x, dst_rect.y, + dst_rect.width, dst_rect.height); +#else + return; + ee = NULL; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_evas_x11_shape_input_empty(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_X11 + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_x11_shape_input_empty"); + return; + } + + if (!ee->engine.x.win_shaped_input) + ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1); + + ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, 0, 0, 0, 0); +#else + return; + ee = NULL; +#endif +} + +EAPI void +ecore_evas_x11_shape_input_reset(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_X11 + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_x11_shape_input_reset"); + return; + } + + if (!ee->engine.x.win_shaped_input) + ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1); + + ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, 0, 0, 65535, 65535); +#else + return; + ee = NULL; +#endif +} + +EAPI void +ecore_evas_x11_shape_input_apply(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_X11 + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_x11_shape_input_apply"); + return; + } + + if (!ee->engine.x.win_shaped_input) return; + + ecore_x_window_shape_input_window_set(ee->prop.window, ee->engine.x.win_shaped_input); +#else + return; + ee = NULL; +#endif +} diff --git a/src/lib/ecore_fb/Ecore_Fb.h b/src/lib/ecore_fb/Ecore_Fb.h new file mode 100644 index 0000000000..069cccdff9 --- /dev/null +++ b/src/lib/ecore_fb/Ecore_Fb.h @@ -0,0 +1,100 @@ +#ifndef _ECORE_FB_H +#define _ECORE_FB_H + +#include + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#else +# define EAPI +#endif + +/* FIXME: + * maybe a new module? + * - code to get battery info + * - code to get thermal info + * ecore evas fb isn't 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 + +/** + * @defgroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. + * + * Functions used to set up and shut down the Ecore_Framebuffer functions. + * + * @{ + */ + +/** + * @typedef Ecore_Fb_Input_Device + * Input device handler. + */ +typedef struct _Ecore_Fb_Input_Device Ecore_Fb_Input_Device; + +/** + * @enum _Ecore_Fb_Input_Device_Cap + * 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 Ecore_Fb_Input_Device_Cap + * Device capabilities. + */ +typedef enum _Ecore_Fb_Input_Device_Cap Ecore_Fb_Input_Device_Cap; + +/* 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, Eina_Bool 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); +EAPI void ecore_fb_input_device_window_set(Ecore_Fb_Input_Device *dev, void *window); + +/* 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 diff --git a/src/lib/ecore_fb/ecore_fb.c b/src/lib/ecore_fb/ecore_fb.c new file mode 100644 index 0000000000..ff96ac8a77 --- /dev/null +++ b/src/lib/ecore_fb/ecore_fb.c @@ -0,0 +1,129 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "Ecore_Fb.h" +#include "ecore_fb_private.h" + +static void _ecore_fb_size_get(int *w, int *h); + +static int _ecore_fb_init_count = 0; +static int _ecore_fb_console_w = 0; +static int _ecore_fb_console_h = 0; + +/** + * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. + * + * @{ + */ + +static sighandler_t oldhand = NULL; + +static void +nosigint(int val EINA_UNUSED) +{ +} + +/** + * @brief Initialize the Ecore_Fb library. + * + * @param name Device target name. + * @return 1 or greater on success, 0 on error. + * + * This function sets up all the Ecore_Fb library. It returns 0 on + * failure, otherwise it returns the number of times it has already + * been called. + * + * When Ecore_Fb is not used anymore, call ecore_fb_shutdown() to shut down + * the Ecore_Fb library. + */ +EAPI int +ecore_fb_init(const char *name EINA_UNUSED) +{ + if (++_ecore_fb_init_count != 1) + return _ecore_fb_init_count; + + if (!ecore_fb_vt_init()) + return --_ecore_fb_init_count; + + if (!oldhand) + { + oldhand = signal(SIGINT, nosigint); + } + + _ecore_fb_size_get(&_ecore_fb_console_w, &_ecore_fb_console_h); + + return _ecore_fb_init_count; +} + +/** + * @brief Shut down the Ecore_Fb library. + * + * @return 0 when the library is completely shut down, 1 or + * greater otherwise. + * + * This function shuts down the Ecore_Fb library. It returns 0 when it has + * been called the same number of times than ecore_fb_init(). + */ +EAPI int +ecore_fb_shutdown(void) +{ + if (--_ecore_fb_init_count != 0) + return _ecore_fb_init_count; + + if (oldhand) + { + signal(SIGINT, oldhand); + oldhand = NULL; + } + + ecore_fb_vt_shutdown(); + + return _ecore_fb_init_count; +} + + +/** + * @brief Retrieve 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. + * + * This function retrieves the size of the current frame buffer in + * pixels. @p w and @p h can be buffers that will be filled with the + * corresponding values. If one of them is @c NULL, nothing will be + * done for that parameter. + */ +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) + goto exit; + + if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) + goto err_ioctl; + + *w = fb_var.xres; + *h = fb_var.yres; + +err_ioctl: + close(fb); +exit: + return; +} + +/** + * @} + */ diff --git a/src/lib/ecore_fb/ecore_fb_kbd.c b/src/lib/ecore_fb/ecore_fb_kbd.c new file mode 100644 index 0000000000..fd111db04d --- /dev/null +++ b/src/lib/ecore_fb/ecore_fb_kbd.c @@ -0,0 +1,326 @@ +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 * 7] = +{ +#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 = -1; +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 Eina_Bool _ecore_fb_kbd_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); + +static void +_ecore_fb_event_free_key_down(void *data EINA_UNUSED, void *ev) +{ + Ecore_Fb_Event_Key_Down *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 EINA_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 Eina_Bool +_ecore_fb_kbd_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + int v = 0; + + do + { + unsigned char buf; + + v = read(_ecore_fb_kbd_fd, &buf, 1); + if (v < 0) return EINA_TRUE; + if (v < 1) return EINA_TRUE; + 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) * 7]); + e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + add]); + e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + 3 + add]); + } + else + e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]); + if (!e->keyname) + { + free(e); + goto retry; + } + e->window = 1; + e->event_window = e->window; + e->root_window = e->window; + e->same_screen = 1; + e->timestamp = ecore_loop_time_get() * 1000.0; + 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 ((_ecore_fb_kbd_fd == _ecore_fb_tty_fd) && + (_ecore_fb_ctrl)) + { + const char *ts = _ecore_fb_kbd_syms[(buf & 0x7f) + 3 + 3]; + + if (ts) + { + if (e->key_compose) free(e->key_compose); + e->key_compose = strdup(ts); + } + } + if ((vt_switch >= 0) && + (_ecore_fb_ctrl) && + (_ecore_fb_alt)) + _ecore_fb_vt_switch(vt_switch); + ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, e, _ecore_fb_event_free_key_down, NULL); + } + 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) * 7]); + e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + add]); + e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + 3 + add]); + } + else + e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]); + if (!e->keyname) + { + free(e); + goto retry; + } + e->window = 1; + e->event_window = e->window; + e->root_window = e->window; + e->same_screen = 1; + e->timestamp = ecore_loop_time_get() * 1000.0; + 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 EINA_TRUE; +} + +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_handler_handle) + ecore_main_fd_handler_del(_ecore_fb_kbd_fd_handler_handle); + if (_ecore_fb_kbd_fd >= 0) close(_ecore_fb_kbd_fd); + _ecore_fb_kbd_fd = -1; + _ecore_fb_kbd_fd_handler_handle = NULL; + _ecore_fb_ctrl = 0; + _ecore_fb_lock = 0; + _ecore_fb_shift = 0; + _ecore_fb_alt = 0; +} diff --git a/src/lib/ecore_fb/ecore_fb_keytable.h b/src/lib/ecore_fb/ecore_fb_keytable.h new file mode 100644 index 0000000000..70bf6b9689 --- /dev/null +++ b/src/lib/ecore_fb/ecore_fb_keytable.h @@ -0,0 +1,129 @@ +/* this table was taken from ecore_fb, is the default en layout */ + "0x00", "0x00", "0x00", /**/"", "", "", NULL,/***/ + "Escape", "Escape", "Escape", /**/"", "", "", "\x1b",/***/ + "1", "exclam", "1", /**/"1", "!", "1", NULL,/***/ + "2", "at", "2", /**/"2", "@", "2", "",/***/ + "3", "numbersign", "3", /**/"3", "#", "3", "\x1b",/***/ + "4", "dollar", "4", /**/"4", "$", "4", "\x1c",/***/ + "5", "percent", "5", /**/"5", "%", "5", "\x1d",/***/ + "6", "asciicircumm", "6", /**/"6", "^", "6", "\x1e",/***/ + "7", "ampersand", "7", /**/"7", "&", "7", "\x1f",/***/ + "8", "asterisk", "8", /**/"8", "*", "8", "\x7f",/***/ + "9", "parenleft", "9", /**/"9", "(", "9", NULL,/***/ + "0", "parenright", "0", /**/"0", ")", "0", NULL,/***/ + "minus", "underscore", "minus", /**/"-", "_", "-", NULL,/***/ + "equal", "plus", "equal", /**/"=", "+", "=", NULL,/***/ + "BackSpace", "BackSpace", "BackSpace", /**/"\010","\010","\010", NULL,/***/ + "Tab", "ISO_Left_Tab", "Tab", /**/"\011","", "\011", NULL,/***/ + "q", "Q", "Q", /**/"q", "Q", "Q", "\x11",/***/ + "w", "W", "W", /**/"w", "W", "W", "\x17",/***/ + "e", "E", "E", /**/"e", "E", "E", "\x05",/***/ + "r", "R", "R", /**/"r", "R", "R", "\x12",/***/ + "t", "T", "T", /**/"t", "T", "T", "\x14",/***/ + "y", "Y", "Y", /**/"y", "Y", "Y", "\x19",/***/ + "u", "U", "U", /**/"u", "U", "U", "\x15",/***/ + "i", "I", "I", /**/"i", "I", "I", "\x09",/***/ + "o", "O", "O", /**/"o", "O", "O", "\x0f",/***/ + "p", "P", "P", /**/"p", "P", "P", "\x10",/***/ + "bracketleft", "braceleft", "bracketleft", /**/"[", "{", "[", "\x1b",/***/ + "bracketright", "braceright", "bracketright", /**/"]", "}", "]", "\x1d",/***/ + "Return", "Return", "Return", /**/"\015","\015","\015", NULL,/***/ + "Control_L", "Control_L", "Control_L", /**/"", "", "", NULL,/***/ + "a", "A", "A", /**/"a", "A", "A", "\x01",/***/ + "s", "S", "S", /**/"s", "S", "S", "\x13",/***/ + "d", "D", "D", /**/"d", "D", "D", "\x04",/***/ + "f", "F", "F", /**/"f", "F", "F", "\x06",/***/ + "g", "G", "G", /**/"g", "G", "G", "\x07",/***/ + "h", "h", "H", /**/"h", "H", "H", "\x08",/***/ + "j", "J", "J", /**/"j", "J", "J", "\x0a",/***/ + "k", "K", "K", /**/"k", "K", "K", "\x0b",/***/ + "l", "L", "L", /**/"l", "L", "L", "\x0c",/***/ + "semicolon", "colon", "semicolon", /**/";", ":", ";", NULL,/***/ + "apostrophe", "quotedbl", "apostrophe", /**/"'", "\"", "'", NULL,/***/ + "grave", "asciitilde", "grave", /**/"`", "~", "`", "",/***/ + "Shift_L", "Shift_L", "Shift_L", /**/"", "", "", NULL,/***/ + "backslash", "bar", "backslash", /**/"\\", "|", "\\", "\x1c",/***/ + "z", "Z", "Z", /**/"z", "Z", "Z", "\x1a",/***/ + "x", "X", "X", /**/"x", "X", "X", "\x18",/***/ + "c", "C", "C", /**/"c", "C", "C", "\x03",/***/ + "v", "V", "V", /**/"v", "V", "V", "\x16",/***/ + "b", "B", "B", /**/"b", "B", "B", "\x02",/***/ + "n", "N", "N", /**/"n", "N", "N", "\x0e",/***/ + "m", "M", "M", /**/"m", "M", "M", "\x0d",/***/ + "comma", "less", "comma", /**/",", "<", ",", NULL,/***/ + "period", "greater", "period", /**/".", ">", ".", NULL,/***/ + "slash", "question", "slash", /**/"/", "?", "/", "",/***/ + "Shift_R", "Shift_R", "Shift_R", /**/"", "", "", NULL,/***/ + "KP_Multiply", "KP_Multiply", "KP_Multiply", /**/"", "*", "", NULL,/***/ + "Alt_L", "Alt_L", "Alt_L", /**/"", "", "", NULL,/***/ + "space", "space", "space", /**/" ", " ", " ", "",/***/ + "Caps_Lock", "Caps_Lock", "Caps_Lock", /**/"", "", "", NULL,/***/ + "F1", "F1", "F1", /**/"", "", "", NULL,/***/ + "F2", "F2", "F2", /**/"", "", "", NULL,/***/ + "F3", "F3", "F3", /**/"", "", "", NULL,/***/ + "F4", "F4", "F4", /**/"", "", "", NULL,/***/ + "F5", "F5", "F5", /**/"", "", "", NULL,/***/ + "F6", "F6", "F6", /**/"", "", "", NULL,/***/ + "F7", "F7", "F7", /**/"", "", "", NULL,/***/ + "F8", "F8", "F8", /**/"", "", "", NULL,/***/ + "F9", "F9", "F9", /**/"", "", "", NULL,/***/ + "F10", "F10", "F10", /**/"", "", "", NULL,/***/ + "Num_Lock", "Num_Lock", "Num_Lock", /**/"", "", "", NULL,/***/ + "Scroll_Lock", "Scroll_Lock", "Scroll_Lock", /**/"", "", "", NULL,/***/ + "KP_Home", "KP_7", "KP_Home", /**/"", "7", "", NULL,/***/ + "KP_Up", "KP_8", "KP_Up", /**/"", "8", "", NULL,/***/ + "KP_Prior", "KP_9", "KP_Prior", /**/"", "9", "", NULL,/***/ + "KP_Subtract", "KP_Subtract", "KP_Subtract", /**/"", "", "", NULL,/***/ + "KP_Left", "KP_4", "KP_Left", /**/"", "4", "", NULL,/***/ + "KP_Begin", "KP_5", "KP_Begin", /**/"", "5", "", NULL,/***/ + "KP_Right", "KP_6", "KP_Right", /**/"", "6", "", NULL,/***/ + "KP_Add", "KP_Add", "KP_Add", /**/"", "", "", NULL,/***/ + "KP_End", "KP_1", "KP_End", /**/"", "1", "", NULL,/***/ + "KP_Down", "KP_2", "KP_Down", /**/"", "2", "", NULL,/***/ + "KP_Next", "KP_3", "KP_Next", /**/"", "3", "", NULL,/***/ + "KP_Insert", "KP_0", "KP_Insert", /**/"", "0", "", NULL,/***/ + "KP_Delete", "KP_Decimal", "KP_Delete", /**/"", ".", "", NULL,/***/ + "0x54", "0x54", "0x54", /**/"", "", "", NULL,/***/ + "0x55", "0x55", "0x55", /**/"", "", "", NULL,/***/ + "0x56", "0x56", "0x56", /**/"", "", "", NULL,/***/ + "F11", "F11", "F11", /**/"", "", "", NULL,/***/ + "F12", "F12", "F12", /**/"", "", "", NULL,/***/ + "0x59", "0x59", "0x59", /**/"", "", "", NULL,/***/ + "0x5a", "0x5a", "0x5a", /**/"", "", "", NULL,/***/ + "0x5b", "0x5b", "0x5b", /**/"", "", "", NULL,/***/ + "0x5c", "0x5c", "0x5c", /**/"", "", "", NULL,/***/ + "0x5d", "0x5d", "0x5d", /**/"", "", "", NULL,/***/ + "0x5e", "0x5e", "0x5e", /**/"", "", "", NULL,/***/ + "0x5f", "0x5f", "0x5f", /**/"", "", "", NULL,/***/ + "KP_Enter", "KP_Enter", "KP_Enter", /**/"\015", "\015", "\015", NULL,/***/ + "Control_R", "Control_R", "Control_R", /**/"", "", "", NULL,/***/ + "KP_Divide", "KP_Divide", "KP_Divide", /**/"", "", "", NULL,/***/ + "Print", "Print", "Print", /**/"", "", "", NULL,/***/ + "Alt_R", "Alt_R", "Alt_R", /**/"", "", "", NULL,/***/ + "0x65", "0x65", "0x65", /**/"", "", "", NULL,/***/ + "Home", "Home", "Home", /**/"", "", "", NULL,/***/ + "Up", "Up", "Up", /**/"", "", "", NULL,/***/ + "Prior", "Prior", "Prior", /**/"", "", "", NULL,/***/ + "Left", "Left", "Left", /**/"", "", "", NULL,/***/ + "Right", "Right", "Right", /**/"", "", "", NULL,/***/ + "End", "End", "End", /**/"", "", "", NULL,/***/ + "Down", "Down", "Down", /**/"", "", "", NULL,/***/ + "Next", "Next", "Next", /**/"", "", "", NULL,/***/ + "Insert", "Insert", "Insert", /**/"", "", "", NULL,/***/ + "Delete", "Delete", "Delete", /**/"\177","\177","\177", NULL,/***/ + "0x70", "0x70", "0x70", /**/"", "", "", NULL,/***/ + "0x71", "0x71", "0x71", /**/"", "", "", NULL,/***/ + "0x72", "0x72", "0x72", /**/"", "", "", NULL,/***/ + "0x73", "0x73", "0x73", /**/"", "", "", NULL,/***/ + "0x74", "0x74", "0x74", /**/"", "", "", NULL,/***/ + "0x75", "0x75", "0x75", /**/"", "", "", NULL,/***/ + "0x76", "0x76", "0x76", /**/"", "", "", NULL,/***/ + "Pause", "Pause", "Pause", /**/"", "", "", NULL,/***/ + "0x78", "0x78", "0x78", /**/"", "", "", NULL,/***/ + "0x79", "0x79", "0x79", /**/"", "", "", NULL,/***/ + "0x7a", "0x7a", "0x7a", /**/"", "", "", NULL,/***/ + "0x7b", "0x7b", "0x7b", /**/"", "", "", NULL,/***/ + "0x7c", "0x7c", "0x7c", /**/"", "", "", NULL,/***/ + "Super_L", "Super_L", "Super_L", /**/"", "", "", NULL,/***/ + "Super_R", "Super_R", "Super_R", /**/"", "", "", NULL,/***/ + "0x7f", "0x7f", "0x7f", /**/"", "", "", NULL, /***/ diff --git a/src/lib/ecore_fb/ecore_fb_li.c b/src/lib/ecore_fb/ecore_fb_li.c new file mode 100644 index 0000000000..0ea0549f92 --- /dev/null +++ b/src/lib/ecore_fb/ecore_fb_li.c @@ -0,0 +1,721 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#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 * 7] = +{ +#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_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)) + { + int offset = 0; + const char *keyname = _ecore_fb_li_kbd_syms[iev->code * 7]; + + /* check the key table */ + if (iev->value) + { + /* its a repeated key, dont increment */ + if (iev->value != 2) + { + if (!strcmp(keyname, "Control_L")) + dev->keyboard.ctrl++; + else if (!strcmp(keyname, "Control_R")) + dev->keyboard.ctrl++; + else if (!strcmp(keyname, "Alt_L")) + dev->keyboard.alt++; + else if (!strcmp(keyname, "Alt_R")) + dev->keyboard.alt++; + else if (!strcmp(keyname, "Shift_L")) + dev->keyboard.shift++; + else if (!strcmp(keyname, "Shift_R")) + dev->keyboard.shift++; + else if (!strcmp(keyname, "Caps_Lock")) + dev->keyboard.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 + { + if (!strcmp(keyname, "Control_L")) + dev->keyboard.ctrl--; + else if (!strcmp(keyname, "Control_R")) + dev->keyboard.ctrl--; + else if (!strcmp(keyname, "Alt_L")) + dev->keyboard.alt--; + else if (!strcmp(keyname, "Alt_R")) + dev->keyboard.alt--; + else if (!strcmp(keyname, "Shift_L")) + dev->keyboard.shift--; + else if (!strcmp(keyname, "Shift_R")) + dev->keyboard.shift--; + 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; + } + + /* sending ecore_input_evas events */ + Ecore_Event_Key *e; + + if (dev->keyboard.shift) offset = 1; + else if (dev->keyboard.lock) offset = 2; + + const char *key = _ecore_fb_li_kbd_syms[(iev->code * 7) + offset]; + const char *compose = _ecore_fb_li_kbd_syms[(iev->code * 7) + 3 + offset]; + + if (dev->keyboard.ctrl) + { + const char *ts = _ecore_fb_li_kbd_syms[(iev->code * 7) + 3 + 3]; + + if (ts) compose = ts; + } + + e = calloc(1, sizeof(Ecore_Event_Key) + strlen(key) + + strlen(keyname) + (compose ? strlen(compose) : 0) + 3); + 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 = 0; + if (dev->keyboard.shift) + e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL; + if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS; + + e->timestamp = ecore_loop_time_get() * 1000.0; + e->window = (Ecore_Window)dev->window; + e->event_window = (Ecore_Window)dev->window; + e->root_window = (Ecore_Window)dev->window; + e->same_screen = 1; + + if (iev->value) + ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); + else + ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); + } + /* check for mouse button events */ + else if ((iev->code >= BTN_MOUSE) && (iev->code < BTN_JOYSTICK)) + { + int button; + Ecore_Event_Mouse_Button *e; + double current = ecore_loop_time_get(); + + button = ((iev->code & 0x00F) + 1); + // swap 2 and 3 to make middle and right butotn work right. + if (button == 3) button = 2; + else if (button == 2) button = 3; + if (iev->value) + { + dev->mouse.did_double = EINA_FALSE; + dev->mouse.did_triple = EINA_FALSE; + + if (((current - dev->mouse.prev) <= dev->mouse.threshold) && + (button == dev->mouse.prev_button)) + { + dev->mouse.did_double = EINA_TRUE; + if (((current - dev->mouse.last) <= (2 * dev->mouse.threshold)) && + (button == dev->mouse.last_button)) + { + dev->mouse.did_triple = EINA_TRUE; + /* reset */ + dev->mouse.prev = 0; + dev->mouse.last = 0; + current = 0; + } + } + dev->mouse.last = dev->mouse.prev; + dev->mouse.prev = current; + dev->mouse.last_button = dev->mouse.prev_button; + dev->mouse.prev_button = button; + } + + e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + if (!e) + return; + + e->timestamp = current * 1000.0; + e->window = (Ecore_Window)dev->window; + e->event_window = (Ecore_Window)dev->window; + e->root_window = (Ecore_Window)dev->window; + e->same_screen = 1; + + e->modifiers = 0; + if (dev->keyboard.shift) + e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL; + if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS; + + e->x = dev->mouse.x; + e->y = dev->mouse.y; + e->root.x = e->x; + e->root.y = e->y; + e->buttons = button; + + if (dev->mouse.did_double) + e->double_click = 1; + if (dev->mouse.did_triple) + e->triple_click = 1; + + if (iev->value) + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); + else + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, 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_Event_Mouse_Move *e; + 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; + } + + e = calloc(1, sizeof(Ecore_Event_Mouse_Move)); + if (!e) + return; + + e->window = (Ecore_Window)dev->window; + e->event_window = (Ecore_Window)dev->window; + e->root_window = (Ecore_Window)dev->window; + e->same_screen = 1; + + e->modifiers = 0; + if (dev->keyboard.shift) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL; + if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS; + + e->x = dev->mouse.x; + e->y = dev->mouse.y; + e->root.x = e->x; + e->root.y = e->y; + + e->timestamp = ecore_loop_time_get() * 1000.0; + + ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); + + break; + } + case REL_WHEEL: + case REL_HWHEEL: + { + Ecore_Event_Mouse_Wheel *e; + + e = calloc(1, sizeof(Ecore_Event_Mouse_Wheel)); + if (!e) + return; + + e->x = dev->mouse.x; + e->y = dev->mouse.y; + if (iev->code == REL_HWHEEL) e->direction = 1; + e->z = iev->value; + e->root.x = dev->mouse.x; + e->root.y = dev->mouse.y; + + e->window = (Ecore_Window)dev->window; + e->event_window = (Ecore_Window)dev->window; + e->root_window = (Ecore_Window)dev->window; + e->same_screen = 1; + + e->modifiers = 0; + if (dev->keyboard.shift) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL; + if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS; + + e->timestamp = ecore_loop_time_get() * 1000.0; + + ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, 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_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_EVENT_MOUSE_MOVE; + } + break; + + case ABS_PRESSURE: + pressure = iev->value; + if ((pressure) && (!prev_pressure)) + { + /* DOWN: mouse is down, but was not before */ + dev->mouse.event = ECORE_EVENT_MOUSE_BUTTON_DOWN; + } + else if ((!pressure) && (prev_pressure)) + { + /* UP: mouse was down, but is not now */ + dev->mouse.event = ECORE_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 EINA_UNUSED) +{ + if (!dev->listen) return; + + if (dev->mouse.event == ECORE_EVENT_MOUSE_MOVE) + { + Ecore_Event_Mouse_Move *ev; + ev = calloc(1,sizeof(Ecore_Event_Mouse_Move)); + ev->x = dev->mouse.x; + ev->y = dev->mouse.y; + ev->root.x = ev->x; + ev->root.y = ev->y; + ev->timestamp = ecore_loop_time_get() * 1000.0; + } + else if (dev->mouse.event == ECORE_EVENT_MOUSE_BUTTON_DOWN) + { + Ecore_Event_Mouse_Button *ev; + ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + ev->x = dev->mouse.x; + ev->y = dev->mouse.y; + ev->root.x = ev->x; + ev->root.y = ev->y; + ev->buttons = 1; + ev->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); + } + else if (dev->mouse.event == ECORE_EVENT_MOUSE_BUTTON_UP) + { + Ecore_Event_Mouse_Button *ev; + ev = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + ev->x = dev->mouse.x; + ev->y = dev->mouse.y; + ev->root.x = ev->x; + ev->root.y = ev->y; + ev->buttons = 1; + ev->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); + } +} + +static Eina_Bool +_ecore_fb_li_device_fd_callback(void *data, Ecore_Fd_Handler *fdh EINA_UNUSED) +{ + 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)); + for(i = 0; i < (int)(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 EINA_TRUE; +} + +/** + * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. + * + * @{ + */ + +/** + * @brief Set the listen mode for an input device . + * + * @param dev The device to set the mode of. + * @param listen @c EINA_FALSE to disable listening mode, @c EINA_TRUE to + * enable it. + * + * This function enables or disables listening on the input device @p dev. + * If @p listen is @c EINA_FALSE, listening mode is disabled, if it is + * @c EINA_TRUE, it is enabled. + */ +EAPI void +ecore_fb_input_device_listen(Ecore_Fb_Input_Device *dev, Eina_Bool 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 + +/** + * @brief Associates an input device with the given @ref Ecore_Evas_Group. + * + * @param dev The input being associated with an @ref Ecore_Evas_Group (not @c NULL). + * @param window The window which this input is being associated to. + * @c NULL will remove any previous association. + * + * Events generated by this device will have a pointer to @p window. If this @p + * window is registered with ecore_event_window_register() or + * ecore_evas_input_event_register(), respective evas events will be delivered + * by the ecore_input_evas system. An example can be seen in the following code: + * + * @code + * Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 800, 600, NULL); + * + * ecore_evas_input_event_register(ee); + * + * device = ecore_fb_input_device_open(device_path); + * if (device) + * ecore_fb_input_device_window_set(device, ee); + * + * @endcode + * + * On the previous code, all input captured on the mentioned device will be + * delivered to the @c Ecore_Evas @c ee. + * + * @since 1.1 + */ +EAPI void +ecore_fb_input_device_window_set(Ecore_Fb_Input_Device *dev, void *window) +{ + if (!dev) return; + + dev->window = window; +} + +/** + * @brief Open an input device. + * + * @param dev The device to open. + * @return The @ref Ecore_Fb_Input_Device object that has been opened. + * + * This function opens the input device named @p dev and returns the + * object for it, or returns @c NULL on failure. + */ +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; +} + +/** + * @brief Close the given device. + * + * @param dev The device to close + * + * This function closes the device @p dev. If @p dev is @c NULL, this + * function does nothing. + */ +EAPI void +ecore_fb_input_device_close(Ecore_Fb_Input_Device *dev) +{ + if (!dev || dev->fd < 0) return; + /* 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); +} + + +/** + * @brief Set the axis size of the given device. + * + * @param dev The device to set the axis size to. + * @param w The width of the axis. + * @param h The height of the axis. + * + * This function sets set the width @p w and height @p h of the axis + * of device @p dev. If @p dev is a relative input device, a width and + * height must set 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; +} + +/** + * @brief Retrieve the name of the given device. + * + * @param dev The device to get the name from. + * @return The name of the device. + * + * This function returns the name of the device @p dev. If @p dev is + * @c NULL, this function returns @c NULL. + */ +EAPI const char * +ecore_fb_input_device_name_get(Ecore_Fb_Input_Device *dev) +{ + if (!dev) return NULL; + return dev->info.name; +} + +/** + * @brief Retrieve the capability of the given device. + * + * @param dev The device to get the name from. + * @return The capability of the device. + * + * This function returns the capability of the device @p dev. If @p dev is + * @c NULL, this function returns ECORE_FB_INPUT_DEVICE_CAP_NONE. + */ +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; +} + +/** + * @brief Set the threshold of mouse clicks of the given device. + * + * @param dev The device to set the threshodl mouse click to. + * @param threshold The threshold value. + * + * This function sets the threshold of mouse clicks of the device + * @p dev to @p threshold. If @p dev is @c NULL, this function does + * nothing. + */ +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; +} + +/** + * @brief Get the threshold of mouse clicks of the given device. + * + * @param dev The device to set the threshodl mouse click from. + * @return The threshold value. + * + * This function returns the threshold of mouse clicks of the device + * @p dev. If @p dev is @c NULL, this function returns 0.0. + */ +EAPI double +ecore_fb_input_device_threshold_click_get(Ecore_Fb_Input_Device *dev) +{ + if (!dev) return 0; + return dev->mouse.threshold; +} + +/** + * @} + */ diff --git a/src/lib/ecore_fb/ecore_fb_private.h b/src/lib/ecore_fb/ecore_fb_private.h new file mode 100644 index 0000000000..797f86305f --- /dev/null +++ b/src/lib/ecore_fb/ecore_fb_private.h @@ -0,0 +1,94 @@ +#ifndef _ECORE_FB_PRIVATE_H +#define _ECORE_FB_PRIVATE_H + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Input.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 + #undef kernel_ulong_t + #undef BITS_PER_LONG +#else + #include +#endif + +#include +#include +#include + +#include + +/* 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; + Eina_Bool did_double; + Eina_Bool did_triple; + /* absolute axis */ + int min_w, min_h; + double rel_w, rel_h; + int event; + int prev_button; + int last_button; + } mouse; + struct + { + int shift; + int ctrl; + int alt; + int lock; + } keyboard; + void *window; +}; + +/* ecore_fb_ts.c */ +EAPI int ecore_fb_ts_init(void); +EAPI void ecore_fb_ts_shutdown(void); +EAPI void ecore_fb_ts_events_window_set(void *window); +EAPI void *ecore_fb_ts_events_window_get(void); +EAPI void ecore_fb_ts_event_window_set(void *window); + +/* ecore_fb_vt.c */ +int ecore_fb_vt_init(void); +void ecore_fb_vt_shutdown(void); + +/* hacks to stop people NEEDING #include */ +#ifndef TS_SET_CAL +#define TS_SET_CAL 0x4014660b +#endif +#ifndef TS_GET_CAL +#define TS_GET_CAL 0x8014660a +#endif + +#endif diff --git a/src/lib/ecore_fb/ecore_fb_ps2.c b/src/lib/ecore_fb/ecore_fb_ps2.c new file mode 100644 index 0000000000..53aa302fef --- /dev/null +++ b/src/lib/ecore_fb/ecore_fb_ps2.c @@ -0,0 +1,223 @@ +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 Eina_Bool _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 Eina_Bool +_ecore_fb_ps2_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_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; + static int did_double = 0; + static 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 EINA_TRUE; + _ecore_fb_ps2_event_byte_count += v; + if (v < num) return EINA_TRUE; + t = ecore_loop_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_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move)); + if (!e) goto retry; + e->x = x; + e->y = y; + e->root.x = e->x; + e->root.y = e->y; + e->window = 1; + e->event_window = e->window; + e->root_window = e->window; + e->same_screen = 1; + e->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_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_Event_Mouse_Button *e; + + e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + if (!e) goto retry; + e->x = x; + e->y = y; + e->root.x = e->x; + e->root.y = e->y; + e->button = i; + e->window = 1; + e->event_window = e->window; + e->root_window = e->window; + e->same_screen = 1; + if ((t - last_time) <= _ecore_fb_double_click_time) + { + e->double_click = 1; + did_double = 1; + } + else + { + did_double = 0; + did_triple = 0; + } + if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time)) + { + did_triple = 1; + e->triple_click = 1; + } + else + { + did_triple = 0; + } + e->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); + } + else if ((!(button & mask)) && ((prev_button & mask))) + { + /* UP: mouse was down, but is not now */ + Ecore_Event_Mouse_Button *e; + + e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + if (!e) goto retry; + e->x = x; + e->y = y; + e->root.x = e->x; + e->root.y = e->y; + e->button = i; + e->window = 1; + e->event_window = e->window; + e->root_window = e->window; + e->same_screen = 1; + if (did_double) + e->double_click = 1; + if (did_triple) + e->triple_click = 1; + e->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_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 EINA_TRUE; +} +/** + * @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; +} + diff --git a/src/lib/ecore_fb/ecore_fb_ts.c b/src/lib/ecore_fb/ecore_fb_ts.c new file mode 100644 index 0000000000..ce9c733c3e --- /dev/null +++ b/src/lib/ecore_fb/ecore_fb_ts.c @@ -0,0 +1,362 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_TSLIB +# include +# include +#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 Eina_Bool _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; +static void *_ecore_fb_ts_event_window = NULL; + +EAPI int +ecore_fb_ts_init(void) +{ +#ifdef HAVE_TSLIB + char *tslib_tsdevice = NULL; + if ( (tslib_tsdevice = getenv("TSLIB_TSDEVICE")) ) + { + 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_handler_handle) + ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle); + if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd); + _ecore_fb_ts_fd = -1; + _ecore_fb_ts_fd_handler_handle = NULL; + _ecore_fb_ts_event_window = NULL; +} + +EAPI void +ecore_fb_ts_event_window_set(void *window) +{ + _ecore_fb_ts_event_window = window; +} + +EAPI void * +ecore_fb_ts_event_window_get(void) +{ + return _ecore_fb_ts_event_window; +} + +/** + * @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 Eina_Bool +_ecore_fb_ts_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_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 = 0.0; + static int did_double = 0; + static 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 */ +#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 + t = ecore_loop_time_get(); + /* add event to queue */ + /* always add a move event */ + if ((pressure) || (prev_pressure)) + { + /* MOVE: mouse is down and was */ + Ecore_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_Event_Mouse_Move)); + if (!e) goto retry; + e->x = x; + e->y = y; + e->root.x = e->x; + e->root.y = e->y; + e->window = 1; + e->event_window = e->window; + e->root_window = e->window; + e->same_screen = 1; + e->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); + } + if ((pressure) && (!prev_pressure)) + { + /* DOWN: mouse is down, but was not now */ + Ecore_Event_Mouse_Button *e; + + e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + if (!e) goto retry; + e->x = x; + e->y = y; + e->root.x = e->x; + e->root.y = e->y; + e->buttons = 1; + if ((t - last_time) <= _ecore_fb_double_click_time) + { + e->double_click = 1; + did_double = 1; + } + else + { + did_double = 0; + did_triple = 0; + } + if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time)) + { + did_triple = 1; + e->triple_click = 1; + } + else + { + did_triple = 0; + } + e->window = 1; + e->event_window = e->window; + e->root_window = e->window; + e->same_screen = 1; + e->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); + } + else if ((!pressure) && (prev_pressure)) + { + /* UP: mouse was down, but is not now */ + Ecore_Event_Mouse_Button *e; + + e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); + if (!e) goto retry; + e->x = prev_x; + e->y = prev_y; + e->root.x = e->x; + e->root.y = e->y; + e->buttons = 1; + if (did_double) + e->double_click = 1; + if (did_triple) + e->triple_click = 1; + e->window = 1; + e->event_window = e->window; + e->root_window = e->window; + e->same_screen = 1; + e->timestamp = ecore_loop_time_get() * 1000.0; + ecore_event_add(ECORE_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; +} + diff --git a/src/lib/ecore_fb/ecore_fb_vt.c b/src/lib/ecore_fb/ecore_fb_vt.c new file mode 100644 index 0000000000..c92c087336 --- /dev/null +++ b/src/lib/ecore_fb/ecore_fb_vt.c @@ -0,0 +1,322 @@ +#ifdef HAVE_CONFIG_H +# include +#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 = -1; +static int _ecore_fb_vt_tty_fd = -1; +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 Eina_Bool _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; + +/* prototypes */ +/* XXX: unused +static void _ecore_fb_vt_switch(int vt); +static void *_ecore_fb_event_filter_start(void *data); +static Eina_Bool _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); +*/ + +static Eina_Bool +_ecore_fb_signal_usr_handler(void *data EINA_UNUSED, int type EINA_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; +} + +/* XXX: unused +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]; +// XXX: unused +// 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] can't open tty %d\n", _ecore_fb_vt_current_vt); + return 0; + } + close(_ecore_fb_vt_tty0_fd); + _ecore_fb_vt_tty0_fd = -1; + /* 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] can't set the mode to KD_GRAPHICS"); + close(_ecore_fb_vt_tty_fd); + _ecore_fb_vt_tty_fd = -1; + 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] can't set the tty mode"); + close(_ecore_fb_vt_tty_fd); + _ecore_fb_vt_tty_fd = -1; + 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 do? */ + /* + _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); + _ecore_fb_vt_tty_fd = -1; + 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); + _ecore_fb_vt_tty_fd = -1; + return 0; + } + /* FIXME assign the fb to the tty in case isn't 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] can't 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] can't 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] can't 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] can't 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 != -1) + { + 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 = -1; + } + + 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; +} + +/** + * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions. + * + * @{ + */ + +/** + * @brief Set a callback called when a virtual terminal is gained. + * + * @param func The callback called when vt is gained. + * @param data The data to pass to the callback. + * + * This function sets the callback @p func which will be called when a + * virtual terminal is gained (for example you press Ctrl-Alt-F1 to go + * to vt1 and your app was using vt1). @p data will be pass to @p func if + * the callback is called. + */ +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; +} + +/** + * @brief Set a callback called when a virtual terminal is lost. + * + * @param func The callback called when vt is lost. + * @param data The data to pass to the callback. + * + * This function sets the callback @p func which will be called when a + * virtual terminal is lost (someone wants the tv from you and you + * want to give up that vt). @p data will be pass to @p func if the + * callback is called. + */ +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; + +} + +/** + * @} + */ + +/* + * This filter should take into account that the MOUSE_MOVE event can be + * triggered by a mouse, not just a touchscreen device, so you can't discard + * them (only those generated by a device that sends events with absolute + * coordinates). + +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 EINA_UNUSED) +{ + Ecore_Fb_Filter_Data *filter_data; + + filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data)); + return filter_data; +} + +static Eina_Bool +_ecore_fb_event_filter_filter(void *data EINA_UNUSED, void *loop_data,int type, void *event EINA_UNUSED) +{ + Ecore_Fb_Filter_Data *filter_data; + + filter_data = loop_data; + if (!filter_data) return EINA_TRUE; + if (type == ECORE_EVENT_MOUSE_MOVE) + { + if ((filter_data->last_event_type) == ECORE_EVENT_MOUSE_MOVE) + { + filter_data->last_event_type = type; + return EINA_FALSE; + } + } + filter_data->last_event_type = type; + return EINA_TRUE; +} + +static void +_ecore_fb_event_filter_end(void *data EINA_UNUSED, void *loop_data) +{ + Ecore_Fb_Filter_Data *filter_data; + + filter_data = loop_data; + if (filter_data) free(filter_data); +} +*/ diff --git a/src/lib/ecore_file/Ecore_File.h b/src/lib/ecore_file/Ecore_File.h new file mode 100644 index 0000000000..30f3bd7d9e --- /dev/null +++ b/src/lib/ecore_file/Ecore_File.h @@ -0,0 +1,190 @@ +#ifndef ECORE_FILE_H +#define ECORE_FILE_H + +/* + * TODO: + * - More events, move/rename of directory file + */ + +#include + +#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 + +/** + * @defgroup Ecore_File_Group Ecore_File - Files and directories convenience functions + * + * @{ + */ + +/** + * @typedef Ecore_File_Monitor + * Abstract type used when monitoring a directory. + */ +typedef struct _Ecore_File_Monitor Ecore_File_Monitor; + +/** + * @typedef Ecore_File_Download_Job + * Abstract type used when aborting a download. + */ +typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job; + +/** + * @typedef _Ecore_File_Event + * The event type returned when a file or directory is monitored. + */ +typedef enum _Ecore_File_Event +{ + ECORE_FILE_EVENT_NONE, /**< No event. */ + ECORE_FILE_EVENT_CREATED_FILE, /**< Created file event. */ + ECORE_FILE_EVENT_CREATED_DIRECTORY, /**< Created directory event. */ + ECORE_FILE_EVENT_DELETED_FILE, /**< Deleted file event. */ + ECORE_FILE_EVENT_DELETED_DIRECTORY, /**< Deleted directory event. */ + ECORE_FILE_EVENT_DELETED_SELF, /**< Deleted monitored directory event. */ + ECORE_FILE_EVENT_MODIFIED, /**< Modified file or directory event. */ + ECORE_FILE_EVENT_CLOSED /**< Closed file event */ +} Ecore_File_Event; + +/** + * @typedef Ecore_File_Monitor_Cb + * Callback type used when a monitored directory has changes. + */ +typedef void (*Ecore_File_Monitor_Cb)(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path); + +/** + * @typedef Ecore_File_Download_Completion_Cb + * Callback type used when a download is finished. + */ +typedef void (*Ecore_File_Download_Completion_Cb)(void *data, const char *file, int status); + +/** + * @typedef _Ecore_File_Progress_Return + * What to do with the download as a return from the + * Ecore_File_Download_Progress_Cb function, if provided. + */ +typedef enum _Ecore_File_Progress_Return +{ + ECORE_FILE_PROGRESS_CONTINUE = 0, /**< Continue the download. */ + ECORE_FILE_PROGRESS_ABORT = 1 /**< Abort the download. */ +} Ecore_File_Progress_Return; + +/** + * @typedef Ecore_File_Download_Progress_Cb + * Callback type used while a download is in progress. + */ +typedef int (*Ecore_File_Download_Progress_Cb)(void *data, + const char *file, + long int dltotal, + long int dlnow, + long int ultotal, + long int ulnow); + +/* File operations */ + +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 Eina_Bool ecore_file_exists (const char *file); +EAPI Eina_Bool ecore_file_is_dir (const char *file); +EAPI Eina_Bool 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 Eina_Bool ecore_file_rmdir (const char *dir); +EAPI Eina_Bool ecore_file_recursive_rm (const char *dir); +EAPI Eina_Bool ecore_file_mkpath (const char *path); +EAPI int ecore_file_mkpaths (const char **paths); +EAPI Eina_Bool ecore_file_cp (const char *src, const char *dst); +EAPI Eina_Bool ecore_file_mv (const char *src, const char *dst); +EAPI Eina_Bool ecore_file_symlink (const char *src, const char *dest); +EAPI char *ecore_file_realpath (const char *file); +EAPI Eina_Bool ecore_file_unlink (const char *file); +EAPI Eina_Bool 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 Eina_Bool ecore_file_can_read (const char *file); +EAPI Eina_Bool ecore_file_can_write (const char *file); +EAPI Eina_Bool 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 Eina_Iterator *ecore_file_ls_iterator (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); + +/* Monitoring */ + +EAPI Ecore_File_Monitor *ecore_file_monitor_add(const char *path, + Ecore_File_Monitor_Cb func, + 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); + +/* Path */ + +EAPI Eina_Bool ecore_file_path_dir_exists(const char *in_dir); +EAPI Eina_Bool ecore_file_app_installed(const char *exe); +EAPI Eina_List *ecore_file_app_list(void); + +/* Download */ + +EAPI Eina_Bool ecore_file_download(const char *url, + const char *dst, + Ecore_File_Download_Completion_Cb completion_cb, + Ecore_File_Download_Progress_Cb progress_cb, + void *data, + Ecore_File_Download_Job **job_ret); +EAPI Eina_Bool ecore_file_download_full(const char *url, + const char *dst, + Ecore_File_Download_Completion_Cb completion_cb, + Ecore_File_Download_Progress_Cb progress_cb, + void *data, + Ecore_File_Download_Job **job_ret, + Eina_Hash *headers); + +EAPI void ecore_file_download_abort_all(void); +EAPI void ecore_file_download_abort(Ecore_File_Download_Job *job); +EAPI Eina_Bool ecore_file_download_protocol_available(const char *protocol); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/ecore_file/ecore_file.c b/src/lib/ecore_file/ecore_file.c new file mode 100644 index 0000000000..6876511fc6 --- /dev/null +++ b/src/lib/ecore_file/ecore_file.c @@ -0,0 +1,1137 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#ifndef _MSC_VER +# include +# include +#endif + +#ifdef _WIN32 +# include +#endif + +#ifdef HAVE_FEATURES_H +# include +#endif +#include +#include + +#ifdef HAVE_ATFILE_SOURCE +# include +#endif + +#include "ecore_file_private.h" + +int _ecore_file_log_dom = -1; +static int _ecore_file_init_count = 0; + +/* externally accessible functions */ + +/** + * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions + * + * @{ + */ + +/** + * @brief Initialize the Ecore_File library. + * + * @return 1 or greater on success, 0 on error. + * + * This function sets up Ecore_File and the services it will use + * (monitoring, downloading, PATH related feature). It returns 0 on + * failure, otherwise it returns the number of times it has already + * been called. + * + * When Ecore_File is not used anymore, call ecore_file_shutdown() + * to shut down the Ecore_File library. + */ +EAPI int +ecore_file_init() +{ + if (++_ecore_file_init_count != 1) + return _ecore_file_init_count; + + if (!ecore_init()) + return --_ecore_file_init_count; + + _ecore_file_log_dom = eina_log_domain_register + ("ecore_file", 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; + */ +} + +/** + * @brief Shut down the Ecore_File library. + * + * @return 0 when the library is completely shut down, 1 or + * greater otherwise. + * + * This function shuts down the Ecore_File library. It returns 0 when it has + * been called the same number of times than ecore_file_init(). In that case + * it shuts down all the services it uses. + */ +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; + + ecore_shutdown(); + + return _ecore_file_init_count; +} + +/** + * @brief Get the time of the last modification to the given file. + * + * @param file The name of the file. + * @return Return the time of the last data modification, or 0 on + * failure. + * + * This function returns the time of the last modification of + * @p file. On failure, it returns 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; +} + +/** + * @brief Get the size of the given file. + * + * @param file The name of the file. + * @return Return the size of the file in bytes, or 0 on failure. + * + * This function returns the size of @p file in bytes. On failure, it + * returns 0. + */ +EAPI long long +ecore_file_size(const char *file) +{ + struct stat st; + + if (stat(file, &st) < 0) return 0; + return st.st_size; +} + +/** + * @brief Check if the given file exists. + * + * @param file The name of the file. + * @return @c EINA_TRUE if the @p file exists, @c EINA_FALSE otherwise. + * + * This function returns @c EINA_TRUE if @p file exists on local filesystem, + * @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_exists(const char *file) +{ + struct stat st; + if (!file) return EINA_FALSE; + + /*Workaround so that "/" returns a true, otherwise we can't monitor "/" in ecore_file_monitor*/ + if (stat(file, &st) < 0 && strcmp(file, "/")) return EINA_FALSE; + return EINA_TRUE; +} + +/** + * @brief Check if the given file is a directory. + * + * @param file The name of the file. + * @return @c EINA_TRUE if the file exists and is a directory, @c EINA_FALSE + * otherwise. + * + * This function returns @c EINA_TRUE if @p file exists exists and is a + * directory on local filesystem, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_is_dir(const char *file) +{ + struct stat st; + + if (stat(file, &st) < 0) return EINA_FALSE; + if (S_ISDIR(st.st_mode)) return EINA_TRUE; + return EINA_FALSE; +} + +static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + +/** + * @brief Create a new directory. + * + * @param dir The name of the directory to create + * @return @c EINA_TRUE on successful creation, @c EINA_FALSE otherwise. + * + * This function creates the directory @p dir with the mode S_IRUSR | + * S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH. On + * success, it returns @c EINA_TRUE, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_mkdir(const char *dir) +{ + if (mkdir(dir, default_mode) < 0) return EINA_FALSE; + return EINA_TRUE; +} + +/** + * @brief Create complete directory in a batch. + * + * @param dirs The list of directories, null terminated. + * @return The number of successful directories created, -1 if dirs is + * @c NULL. + * + * This function creates all the directories that are in the null + * terminated array @p dirs. The function loops over the directories + * and call ecore_file_mkdir(). This function returns -1 if @p dirs is + * @c NULL, otherwise if returns the number of suceesfully created + * directories. + */ +EAPI int +ecore_file_mkdirs(const char **dirs) +{ + int i = 0; + + if (!dirs) return -1; + + for (; *dirs; dirs++) + if (ecore_file_mkdir(*dirs)) + i++; + return i; +} + +/** + * @brief Create complete list of sub-directories in a batch (optimized). + * + * @param base The base directory to act on. + * @param subdirs The list of directories, null terminated. + * @return number of successful directories created, -1 on failure. + * + * This function creates all the directories that are in the null + * terminated array @p dirs in the @p base directory. If @p base does + * not exist, it will be created. The function loops over the directories + * and call ecore_file_mkdir(). The whole path of the directories must + * exist. So if base/a/b/c wants to be created, @p subdirs must + * contain "a", "a/b" and "a/b/c", in that order. This function + * returns -1 if @p dirs or @p base are @c NULL, or if @p base is + * empty ("\0"). It returns 0 is @p base is not a directory or + * invalid, or if it can't be created. Otherwise if returns the number + * of suceesfully created directories. + */ +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; 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; +} + +/** + * @brief Delete the given directory. + * + * @param dir The name of the directory to delete. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function deletes @p dir. It returns @c EINA_TRUE on success, + * @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_rmdir(const char *dir) +{ + if (rmdir(dir) < 0) return EINA_FALSE; + return EINA_TRUE; +} + +/** + * @brief Delete the given file. + * + * @param file The name of the file to delete. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function deletes @p file. It returns @c EINA_TRUE on success, + * @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_unlink(const char *file) +{ + if (unlink(file) < 0) return EINA_FALSE; + return EINA_TRUE; +} + +/** + * @brief Remove the given file or directory. + * + * @param file The name of the file or directory to delete. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function removes @p file. It returns @c EINA_TRUE on success, + * @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_remove(const char *file) +{ + if (remove(file) < 0) return EINA_FALSE; + return EINA_TRUE; +} + +/** + * @brief Delete the given directory and all its contents. + * + * @param dir The name of the directory to delete. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function delete @p dir and all its contents. If @p dir is a + * link only the link is removed. It returns @c EINA_TRUE on success, + * @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_recursive_rm(const char *dir) +{ + struct stat st; + +#ifdef _WIN32 + char buf[PATH_MAX]; + + if (readlink(dir, buf, sizeof(buf) - 1) > 0) + return ecore_file_unlink(dir); + if (stat(dir, &st) == -1) + return EINA_FALSE; +#else + if (lstat(dir, &st) == -1) + return EINA_FALSE; +#endif + + if (S_ISDIR(st.st_mode)) + { + Eina_File_Direct_Info *info; + Eina_Iterator *it; + int ret; + + ret = 1; + it = eina_file_direct_ls(dir); + EINA_ITERATOR_FOREACH(it, info) + { + if (!ecore_file_recursive_rm(info->path)) + ret = 0; + } + eina_iterator_free(it); + + if (!ecore_file_rmdir(dir)) ret = 0; + if (ret) + return EINA_TRUE; + else + return EINA_FALSE; + } + else + { + return ecore_file_unlink(dir); + } +} + +static inline Eina_Bool +_ecore_file_mkpath_if_not_exists(const char *path) +{ + struct stat st; + + /* Windows: path like C: or D: etc are valid, but stat() returns an error */ +#ifdef _WIN32 + if ((strlen(path) == 2) && + ((path[0] >= 'a' && path[0] <= 'z') || + (path[0] >= 'A' && path[0] <= 'Z')) && + (path[1] == ':')) + return EINA_TRUE; +#endif + + if (stat(path, &st) < 0) + return ecore_file_mkdir(path); + else if (!S_ISDIR(st.st_mode)) + return EINA_FALSE; + else + return EINA_TRUE; +} + +/** + * @brief Create a complete path. + * + * @param path The path to create + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function creates @p path and all the subdirectories it + * contains. The separator is '/' or '\'. If @p path exists, this + * function returns @c EINA_TRUE immediately. It returns @c EINA_TRUE on + * success, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_mkpath(const char *path) +{ + char ss[PATH_MAX]; + unsigned int i; + + if (ecore_file_is_dir(path)) + return EINA_TRUE; + + for (i = 0; path[i] != '\0'; ss[i] = path[i], i++) + { + if (i == sizeof(ss) - 1) return EINA_FALSE; + if (((path[i] == '/') || (path[i] == '\\')) && (i > 0)) + { + ss[i] = '\0'; + if (!_ecore_file_mkpath_if_not_exists(ss)) + return EINA_FALSE; + } + } + ss[i] = '\0'; + return _ecore_file_mkpath_if_not_exists(ss); +} + +/** + * @brief Create complete paths in a batch. + * + * @param paths list of paths, null terminated. + * @return number of successful paths created, -1 if paths is NULL. + * + * This function creates all the directories that are in the null + * terminated array @p paths. The function loops over the directories + * and call ecore_file_mkpath(), hence on Windows, '\' must be + * replaced by '/' before calling that function. This function + * returns -1 if @p paths is @c NULL. Otherwise if returns the number + * of suceesfully created directories. + */ +EAPI int +ecore_file_mkpaths(const char **paths) +{ + int i = 0; + + if (!paths) return -1; + + for (; *paths; paths++) + if (ecore_file_mkpath(*paths)) + i++; + return i; +} + +/** + * @brief Copy the given file to the given destination. + * + * @param src The name of the source file. + * @param dst The name of the destination file. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function copies @p src to @p dst. If the absolute path name of + * @p src and @p dst can not be computed, or if they are equal, or if + * the copy fails, the function returns @c EINA_FALSE, otherwise it + * returns @c EINA_TRUE. + */ +EAPI Eina_Bool +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; + Eina_Bool ret = EINA_TRUE; + + if (!realpath(src, realpath1)) return EINA_FALSE; + if (realpath(dst, realpath2) && !strcmp(realpath1, realpath2)) return EINA_FALSE; + + f1 = fopen(src, "rb"); + if (!f1) return EINA_FALSE; + f2 = fopen(dst, "wb"); + if (!f2) + { + fclose(f1); + return EINA_FALSE; + } + while ((num = fread(buf, 1, sizeof(buf), f1)) > 0) + { + if (fwrite(buf, 1, num, f2) != num) ret = EINA_FALSE; + } + fclose(f1); + fclose(f2); + return ret; +} + +/** + * @brief Move the given file to the given destination. + * + * @param src The name of the source file. + * @param dst The name of the destination file. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function moves @p src to @p dst. It returns @c EINA_TRUE on + * success, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +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) 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 EINA_TRUE; + +FAIL: + return EINA_FALSE; +} + +/** + * @brief Create a symbolic link. + * + * @param src The name of the file to link. + * @param dest The name of link. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function create the symbolic link @p dest of @p src. This + * function does not work on Windows. It returns @c EINA_TRUE on success, + * @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_symlink(const char *src, const char *dest) +{ + if (!symlink(src, dest)) return EINA_TRUE; + + return EINA_FALSE; +} + +/** + * @brief Get the canonicalized absolute path name. + * + * @param file The file path. + * @return The canonicalized absolute pathname or an empty string on + * failure. + * + * This function returns the absolute path name of @p file as a newly + * allocated string. If @p file is @c NULL, or on error, this function + * returns an empty string. Otherwise, it returns the absolute path + * name. When not needed anymore, the returned value must be freed. + */ +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 given path. + * + * @param path The complete path. + * @return The file name. + * + * This function returns the file name of @p path. If @p path is + * @c NULL, the functions returns @c NULL. + */ +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; +} + +/** + * @brief Get the directory where the given file resides. + * + * @param file The name of the file. + * @return The directory name. + * + * This function returns the directory where @p file resides as anewly + * allocated string. If @p file is @c NULL or on error, this function + * returns @c NULL. When not needed anymore, the returned value must + * be freed. + */ +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); +} + +/** + * @brief Check if the given file can be read. + * + * @param file The name of the file. + * @return @c EINA_TRUE if the @p file is readable, @c EINA_FALSE otherwise. + * + * This function returns @c EINA_TRUE if @p file can be read, @c EINA_FALSE + * otherwise. + */ +EAPI Eina_Bool +ecore_file_can_read(const char *file) +{ + if (!file) return EINA_FALSE; + if (!access(file, R_OK)) return EINA_TRUE; + return EINA_FALSE; +} + +/** + * @brief Check if the given file can be written. + * + * @param file The name of the file. + * @return @c EINA_TRUE if the @p file is writable, @c EINA_FALSE otherwise. + * + * This function returns @c EINA_TRUE if @p file can be written, @c EINA_FALSE + * otherwise. + */ +EAPI Eina_Bool +ecore_file_can_write(const char *file) +{ + if (!file) return EINA_FALSE; + if (!access(file, W_OK)) return EINA_TRUE; + return EINA_FALSE; +} + +/** + * @brief Check if the given file can be executed. + * + * @param file The name of the file. + * @return @c EINA_TRUE if the @p file can be executed, @c EINA_FALSE + * otherwise. + * + * This function returns @c EINA_TRUE if @p file can be executed, @c EINA_FALSE + * otherwise. + */ +EAPI Eina_Bool +ecore_file_can_exec(const char *file) +{ + if (!file) return EINA_FALSE; + if (!access(file, X_OK)) return EINA_TRUE; + return EINA_FALSE; +} + +/** + * @brief Get the path pointed by the given link. + * + * @param lnk The name of the link. + * @return The path pointed by link or NULL. + * + * This function returns the path pointed by @p link as a newly + * allocated string. This function does not work on Windows. On + * failure, the function returns @c NULL. When not needed anymore, the + * returned value must be freed. + */ +EAPI char * +ecore_file_readlink(const char *lnk) +{ + char buf[PATH_MAX]; + int count; + + if ((count = readlink(lnk, buf, sizeof(buf) - 1)) < 0) return NULL; + buf[count] = 0; + return strdup(buf); +} + +/** + * @brief Get the list of the files and directories in the given + * directory. + * + * @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. + * + * This function returns a list of allocated strings of all the files + * and directories contained in @p dir. 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 '..'. On failure, @c NULL is returned. When not needed + * anymore, the list elements must be freed. + */ +EAPI Eina_List * +ecore_file_ls(const char *dir) +{ + Eina_File_Direct_Info *info; + Eina_Iterator *ls; + Eina_List *list = NULL; + + ls = eina_file_direct_ls(dir); + if (!ls) return NULL; + + EINA_ITERATOR_FOREACH(ls, info) + { + char *f; + + f = strdup(info->path + info->name_start); + list = eina_list_append(list, f); + } + eina_iterator_free(ls); + + list = eina_list_sort(list, eina_list_count(list), EINA_COMPARE_CB(strcoll)); + + return list; +} + +/** + * @brief Return the executable from the given command. + * + * @param app The application command, with parameters. + * @return The executable from @p app as a newly allocated string. Arguments + * are removed and escape characters are handled. If @p app is @c NULL, or + * on failure, the function returns @c NULL. When not needed anymore, the + * returned value must be freed. + */ +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((unsigned char)*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((unsigned char)*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 + { + /* technically 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((unsigned char)*p)) + { + if (restart) + goto restart; + else + break; + } + else + { + *pp = *p; + pp++; + } + } + p++; + } + *pp = 0; + return exe; +} + +/** + * @brief Add the escape sequence ('\\') to the given file name. + * + * @param filename The file name. + * @return The file name with special characters escaped. + * + * This function adds the escape sequence ('\\') to the given file + * name and returns the result as a newly allocated string. If the + * length of the returned string is longer than PATH_MAX, or on + * failure, @c NULL is returned. When not needed anymore, the returned + * value must be freed. + */ +EAPI char * +ecore_file_escape_name(const char *filename) +{ + const char *p; + char *q; + char buf[PATH_MAX]; + + EINA_SAFETY_ON_NULL_RETURN_VAL(filename, NULL); + + p = filename; + q = buf; + while (*p) + { + if ((q - buf) > (PATH_MAX - 6)) return NULL; + if ( + (*p == ' ') || (*p == '\\') || (*p == '\'') || + (*p == '\"') || (*p == ';') || (*p == '!') || + (*p == '#') || (*p == '$') || (*p == '%') || + (*p == '&') || (*p == '*') || (*p == '(') || + (*p == ')') || (*p == '[') || (*p == ']') || + (*p == '{') || (*p == '}') || (*p == '|') || + (*p == '<') || (*p == '>') || (*p == '?') + ) + { + *q = '\\'; + q++; + } + else if (*p == '\t') + { + *q = '\\'; + q++; + *q = '\\'; + q++; + *q = 't'; + q++; + p++; + continue; + } + else if (*p == '\n') + { + *q = '\\'; + q++; + *q = '\\'; + q++; + *q = 'n'; + q++; + p++; + continue; + } + + *q = *p; + q++; + p++; + } + *q = 0; + return strdup(buf); +} + +/** + * @brief Remove the extension from the given file name. + * + * @param path The name of the file. + * @return A newly allocated string with the extension stripped out or + * @c NULL on errors. + * + * This function removes the extension from @p path and returns the + * result as a newly allocated string. If @p path is @c NULL, or on + * failure, the function returns @c NULL. When not needed anymore, the + * returned value must be freed. + */ +EAPI char * +ecore_file_strip_ext(const char *path) +{ + char *p, *file = NULL; + + if (!path) + return 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; +} + +/** + * @brief Check if the given directory is empty. + * + * @param dir The name of the directory to check. + * @return @c 1 if directory is empty, @c 0 if it has at least one file or + * @c -1 in case of errors. + * + * This functions checks if @p dir is empty. The '.' and '..' files + * will be ignored. If @p dir is empty, 1 is returned, if it contains + * at least one file, @c 0 is returned. On failure, @c -1 is returned. + */ +EAPI int +ecore_file_dir_is_empty(const char *dir) +{ + Eina_File_Direct_Info *info; + Eina_Iterator *it; + + it = eina_file_direct_ls(dir); + if (!it) return -1; + + EINA_ITERATOR_FOREACH(it, info) + { + eina_iterator_free(it); + return 0; + } + + eina_iterator_free(it); + return 1; +} + +/** + * @} + */ diff --git a/src/lib/ecore_file/ecore_file_download.c b/src/lib/ecore_file/ecore_file_download.c new file mode 100644 index 0000000000..98d4a1f972 --- /dev/null +++ b/src/lib/ecore_file/ecore_file_download.c @@ -0,0 +1,455 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#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 +#define ECORE_FILE_DOWNLOAD_TIMEOUT 30 + +struct _Ecore_File_Download_Job +{ + ECORE_MAGIC; + + Ecore_Con_Url *url_con; + FILE *file; + + char *dst; + + Ecore_File_Download_Completion_Cb completion_cb; + Ecore_File_Download_Progress_Cb progress_cb; +}; + +#ifdef HAVE_CURL +Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst, + Ecore_File_Download_Completion_Cb completion_cb, + Ecore_File_Download_Progress_Cb progress_cb, + void *data, + Eina_Hash *headers); + +static Eina_Bool _ecore_file_download_url_complete_cb(void *data, int type, void *event); +static Eina_Bool _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; + +static int download_init = 0; + +#endif /* BUILD_ECORE_CON */ + +int +ecore_file_download_init(void) +{ +#ifdef BUILD_ECORE_CON + download_init++; + if (download_init > 1) return 1; + if (!ecore_con_init()) return 0; + if (!ecore_con_url_init()) + { + ecore_con_shutdown(); + 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 + download_init--; + if (download_init > 0) return; + 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(); + ecore_con_shutdown(); +#endif /* BUILD_ECORE_CON */ +} + +#ifdef BUILD_ECORE_CON +# ifdef HAVE_CURL +static Eina_Bool +_ecore_file_download_headers_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata) +{ + Ecore_File_Download_Job *job = fdata; + ecore_con_url_additional_header_add(job->url_con, key, data); + + return EINA_TRUE; +} +# endif +#endif + +static Eina_Bool +_ecore_file_download(const char *url, + const char *dst, + Ecore_File_Download_Completion_Cb completion_cb, + Ecore_File_Download_Progress_Cb progress_cb, + void *data, + Ecore_File_Download_Job **job_ret, + Eina_Hash *headers) +{ +#ifdef BUILD_ECORE_CON + if (!url) + { + CRIT("Download URL is null"); + return EINA_FALSE; + } + + char *dir = ecore_file_dir_get(dst); + + if (!ecore_file_is_dir(dir)) + { + ERR("%s is not a directory", dir); + free(dir); + return EINA_FALSE; + } + free(dir); + if (ecore_file_exists(dst)) + { + WRN("%s already exists", dst); + return EINA_FALSE; + } + + 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, "https://", 8)) || + (!strncmp(url, "ftp://", 6))) + { + /* download */ + Ecore_File_Download_Job *job; + + job = _ecore_file_download_curl(url, dst, completion_cb, progress_cb, data, headers); + if(job_ret) *job_ret = job; + if(job) + return EINA_TRUE; + else + { + ERR("no job returned\n"); + return EINA_FALSE; + } + return job ? EINA_TRUE : EINA_FALSE; + } +# else + else if ((!strncmp(url, "http://", 7)) || (!strncmp(url, "https://", 8)) || + (!strncmp(url, "ftp://", 6))) + { + (void)completion_cb; + (void)progress_cb; + (void)data; + (void)job_ret; + (void)headers; + return EINA_FALSE; + } +# endif + else + { + return EINA_FALSE; + } +#else + (void)url; + (void)dst; + (void)completion_cb; + (void)progress_cb; + (void)data; + (void)job_ret; + (void)headers; + return EINA_FALSE; +#endif /* BUILD_ECORE_CON */ +} + +/** + * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions + * + * @{ + */ + +/** + * @brief Download the given url to the given destination. + * + * @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 Job used to abort the download. + * @return @c EINA_TRUE if the download start or @c EINA_FALSE on failure. + * + * This function starts the download of the URL @p url and saves it to + * @p dst. @p url must provide the protocol, including 'http://', + * 'ftp://' or 'file://'. Ecore_File must be compiled with CURL to + * download using http and ftp protocols. If @p dst is ill-formed, or + * if it already exists, the function returns @c EINA_FALSE. When the + * download is complete, the callback @p completion_cb is called and + * @p data is passed to it. The @p status parameter of @p completion_cb + * will be filled with the status of the download (200, 404,...). The + * @p progress_cb is called during the download operation, each time a + * packet is received or when CURL wants. It can be used to display the + * percentage of the downloaded file. Return 0 from this callback, if provided, + * to continue the operation or anything else to abort the download. The only + * operations that can be aborted are those with protocol 'http' or 'ftp'. In + * that case @p job_ret can be filled. It can be used with + * ecore_file_download_abort() or ecore_file_download_abort_all() to + * respectively abort one or all download operations. This function returns + * @c EINA_TRUE if the download starts, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_file_download(const char *url, + const char *dst, + Ecore_File_Download_Completion_Cb completion_cb, + Ecore_File_Download_Progress_Cb progress_cb, + void *data, + Ecore_File_Download_Job **job_ret) +{ + return _ecore_file_download(url, dst, completion_cb, progress_cb, data, job_ret, NULL); +} + +/** + * @brief Download the given url to the given destination with additional headers. + * + * @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 Job used to abort the download. + * @param headers pointer of header lists. + * @return @c EINA_TRUE if the download start or @c EINA_FALSE on failure. + */ +EAPI Eina_Bool +ecore_file_download_full(const char *url, + const char *dst, + Ecore_File_Download_Completion_Cb completion_cb, + Ecore_File_Download_Progress_Cb progress_cb, + void *data, + Ecore_File_Download_Job **job_ret, + Eina_Hash *headers) +{ + return _ecore_file_download(url, dst, completion_cb, progress_cb, data, job_ret, headers); +} + +/** + * @brief Check if the given protocol is available. + * + * @param protocol The protocol to check. + * @return @c EINA_TRUE if protocol is handled, @c EINA_FALSE otherwise. + * + * This function returns @c EINA_TRUE if @p protocol is supported, + * @c EINA_FALSE otherwise. @p protocol can be 'http://', 'ftp://' or + * 'file://'. Ecore_FILE must be compiled with CURL to handle http and + * ftp protocols. + */ +EAPI Eina_Bool +ecore_file_download_protocol_available(const char *protocol) +{ +#ifdef BUILD_ECORE_CON + if (!strncmp(protocol, "file://", 7)) return EINA_TRUE; +# ifdef HAVE_CURL + else if (!strncmp(protocol, "http://", 7)) return EINA_TRUE; + else if (!strncmp(protocol, "ftp://", 6)) return EINA_TRUE; +# endif +#else + (void)protocol; +#endif /* BUILD_ECORE_CON */ + + return EINA_FALSE; +} + +#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 Eina_Bool +_ecore_file_download_url_complete_cb(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; + + fclose(job->file); + 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); + free(job->dst); + ecore_con_url_free(job->url_con); + free(job); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_ecore_file_download_url_progress_cb(void *data EINA_UNUSED, int type EINA_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 ECORE_CALLBACK_PASS_ON; + + 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 ECORE_CALLBACK_PASS_ON; + } + + return ECORE_CALLBACK_DONE; +} + +Ecore_File_Download_Job * +_ecore_file_download_curl(const char *url, const char *dst, + Ecore_File_Download_Completion_Cb completion_cb, + Ecore_File_Download_Progress_Cb progress_cb, + void *data, + Eina_Hash *headers) +{ + 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; + } + + if (headers) eina_hash_foreach(headers, _ecore_file_download_headers_foreach_cb, job); + 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); + + if (!ecore_con_url_get(job->url_con)) + { + ecore_con_url_free(job->url_con); + _job_list = eina_list_remove(_job_list, job); + fclose(job->file); + ecore_file_remove(job->dst); + free(job->dst); + free(job); + return NULL; + } + + return job; +} +# endif +#endif + +/** + * @brief Abort the given download job and call the completion_cb + * callbck with a status of 1 (error). + * + * @param job The download job to abort. + * + * This function aborts a download operation started by + * ecore_file_download(). @p job is the #Ecore_File_Download_Job + * structure filled by ecore_file_download(). If it is @c NULL, this + * function does nothing. To abort all the currently downloading + * operations, call ecore_file_download_abort_all(). + */ +EAPI void +ecore_file_download_abort(Ecore_File_Download_Job *job) +{ + if (!job) + return; + +#ifdef BUILD_ECORE_CON + if (job->completion_cb) + job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, 1); +# ifdef HAVE_CURL + ecore_con_url_free(job->url_con); +# endif + _job_list = eina_list_remove(_job_list, job); + fclose(job->file); + free(job->dst); + free(job); +#endif /* BUILD_ECORE_CON */ +} + +/** + * @brief Abort all downloads. + * + * This function aborts all the downloads that have been started by + * ecore_file_download(). It loops over the started downloads and call + * ecore_file_download_abort() for each of them. To abort only one + * specific download operation, call ecore_file_download_abort(). + */ +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 */ +} + +/** + * @} + */ diff --git a/src/lib/ecore_file/ecore_file_monitor.c b/src/lib/ecore_file/ecore_file_monitor.c new file mode 100644 index 0000000000..8b07589a9e --- /dev/null +++ b/src/lib/ecore_file/ecore_file_monitor.c @@ -0,0 +1,180 @@ +#ifdef HAVE_CONFIG_H +# include +#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 + } +} + +/** + * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions + * + * @{ + */ + +/** + * @brief Monitor the given path using inotify, Windows notification, 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. + * + * This function monitors @p path. If @p path is @c NULL, or is an + * empty string, or none of the notify methods (Inotify, Windows + * notification or polling) is available, or if @p path is not a file, + * the function returns @c NULL. Otherwise, it returns a newly + * allocated Ecore_File_Monitor object and the monitoring begins. When + * one of the Ecore_File_Event event is notified, @p func is called + * and @p data is passed to @p func. Call ecore_file_monitor_del() to + * stop the monitoring. + */ +EAPI Ecore_File_Monitor * +ecore_file_monitor_add(const char *path, + Ecore_File_Monitor_Cb func, + void *data) +{ + if (!path || !*path) + return NULL; + + 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; +} + +/** + * @brief Stop the monitoring of the given path. + * + * @param em The Ecore_File_Monitor to stop. + * + * This function stops the the monitoring of the path that has been + * monitored by ecore_file_monitor_add(). @p em must be the value + * returned by ecore_file_monitor_add(). If @p em is @c NULL, or none + * of the notify methods (Inotify, Windows notification or polling) is + * availablethis function does nothing. + */ +EAPI void +ecore_file_monitor_del(Ecore_File_Monitor *em) +{ + if (!em) + return; + + 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 + } +} + +/** + * @brief Get the monitored path. + * + * @param em The Ecore_File_Monitor to query. + * @return The path that is monitored by @p em. + * + * This function returns the monitored path that has been + * monitored by ecore_file_monitor_add(). @p em must be the value + * returned by ecore_file_monitor_add(). If @p em is @c NULL, the + * function returns @c NULL. + */ +EAPI const char * +ecore_file_monitor_path_get(Ecore_File_Monitor *em) +{ + if (!em) + return NULL; + return em->path; +} + +/** + * @} + */ diff --git a/src/lib/ecore_file/ecore_file_monitor_inotify.c b/src/lib/ecore_file/ecore_file_monitor_inotify.c new file mode 100644 index 0000000000..1b682fc4a0 --- /dev/null +++ b/src/lib/ecore_file/ecore_file_monitor_inotify.c @@ -0,0 +1,331 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#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) + * - Listen to IN_IGNORED, emitted when the watch is removed + */ + +#ifdef HAVE_INOTIFY + +#include + + +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 pid_t _inotify_fd_pid = -1; + +static Eina_Bool _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; + } + + _inotify_fd_pid = getpid(); + 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); + } + _inotify_fd_pid = -1; + 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; + + if (_inotify_fd_pid == -1) return NULL; + + if (_inotify_fd_pid != getpid()) + { + ecore_file_monitor_inotify_shutdown(); + ecore_file_monitor_inotify_init(); + } + + 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_monitor_inotify_monitor(em, em->path)) + return NULL; + + return em; +} + +void +ecore_file_monitor_inotify_del(Ecore_File_Monitor *em) +{ + int fd; + + if (_monitors) + _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 Eina_Bool +_ecore_file_monitor_inotify_handler(void *data EINA_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 ECORE_CALLBACK_RENEW; +} + +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(buf, mask); +#endif + + if (mask & IN_ATTRIB) + { + em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf); + } + if (mask & IN_CLOSE_WRITE) + { + if (!isdir) + em->func(em->data, em, ECORE_FILE_EVENT_CLOSED, buf); + } + 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 = + IN_ATTRIB | + IN_CLOSE_WRITE | + IN_MOVED_FROM | + IN_MOVED_TO | + IN_DELETE | + IN_CREATE | + IN_MODIFY | + 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) + { + INF("inotify_add_watch failed, file was deleted"); + ecore_file_monitor_inotify_del(em); + return 0; + } + return 1; +} + +#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_ACCESS) + INF("Inotify accessed %s: %s", type, file); + if (mask & IN_MODIFY) + INF("Inotify modified %s: %s", type, file); + if (mask & IN_ATTRIB) + INF("Inotify attributes %s: %s", type, file); + if (mask & IN_CLOSE_WRITE) + INF("Inotify close write %s: %s", type, file); + if (mask & IN_CLOSE_NOWRITE) + INF("Inotify close write %s: %s", type, file); + if (mask & IN_OPEN) + INF("Inotify open %s: %s", type, file); + if (mask & IN_MOVED_FROM) + INF("Inotify moved from %s: %s", type, file); + if (mask & IN_MOVED_TO) + INF("Inotify moved to %s: %s", type, file); + if (mask & IN_DELETE) + INF("Inotify delete %s: %s", type, file); + if (mask & IN_CREATE) + INF("Inotify create %s: %s", type, file); + if (mask & IN_DELETE_SELF) + INF("Inotify delete self %s: %s", type, file); + if (mask & IN_MOVE_SELF) + INF("Inotify move self %s: %s", type, file); + if (mask & IN_UNMOUNT) + INF("Inotify unmount %s: %s", type, file); +} +#endif +#endif /* HAVE_INOTIFY */ diff --git a/src/lib/ecore_file/ecore_file_monitor_poll.c b/src/lib/ecore_file/ecore_file_monitor_poll.c new file mode 100644 index 0000000000..68889a74e8 --- /dev/null +++ b/src/lib/ecore_file/ecore_file_monitor_poll.c @@ -0,0 +1,340 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#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 Eina_Bool _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); + _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em))); + + 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; + } + + 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 Eina_Bool +_ecore_file_monitor_poll_handler(void *data EINA_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 ECORE_CALLBACK_RENEW; +} + +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 mt; + Ecore_File_Event event; + + l = (Ecore_File *) EINA_INLIST_GET(l)->next; + + snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name); + mt = ecore_file_mod_time(buf); + if (mt < 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 ((mt > f->mtime) && !(f->is_dir)) + { + em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf); + _interval = ECORE_FILE_INTERVAL_MIN; + f->mtime = mt; + } + else + f->mtime = mt; + } + + /* Check for new files */ + if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime) + { + Eina_List *files; + Eina_List *fl; + 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, fl, 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_is_dir(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 diff --git a/src/lib/ecore_file/ecore_file_monitor_win32.c b/src/lib/ecore_file/ecore_file_monitor_win32.c new file mode 100644 index 0000000000..7f3af0907b --- /dev/null +++ b/src/lib/ecore_file/ecore_file_monitor_win32.c @@ -0,0 +1,310 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_NOTIFY_WIN32 + +# define WIN32_LEAN_AND_MEAN +# include +# undef WIN32_LEAN_AND_MEAN +# include + +# include "ecore_file_private.h" + + +typedef struct _Ecore_File_Monitor_Win32 Ecore_File_Monitor_Win32; +typedef struct _Ecore_File_Monitor_Win32_Data Ecore_File_Monitor_Win32_Data; + +/* 4096 = 256 * sizeof(FILE_NOTIFY_INFORMATION) */ +# define ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE 4096 +# define ECORE_FILE_MONITOR_WIN32(x) ((Ecore_File_Monitor_Win32 *)(x)) + +struct _Ecore_File_Monitor_Win32_Data +{ + char buffer[ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE]; + OVERLAPPED overlapped; + HANDLE handle; + HANDLE event; + Ecore_File_Monitor *monitor; + Ecore_Win32_Handler *h; + DWORD buf_length; + int is_dir; +}; + +struct _Ecore_File_Monitor_Win32 +{ + Ecore_File_Monitor monitor; + Ecore_File_Monitor_Win32_Data *file; + Ecore_File_Monitor_Win32_Data *dir; +}; + +static Ecore_File_Monitor *_monitors = NULL; + +static Eina_Bool _ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh); + + +static Ecore_File_Monitor_Win32_Data * +_ecore_file_monitor_win32_data_new(Ecore_File_Monitor *monitor, int type) +{ + Ecore_File_Monitor_Win32_Data *md; + DWORD filter; + + md = (Ecore_File_Monitor_Win32_Data *)calloc(1, sizeof(Ecore_File_Monitor_Win32_Data)); + if (!md) return NULL; + + md->handle = CreateFile(monitor->path, + FILE_LIST_DIRECTORY, + FILE_SHARE_READ | + FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | + FILE_FLAG_OVERLAPPED, + NULL); + if (md->handle == INVALID_HANDLE_VALUE) + goto free_md; + + md->event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!md->event) + goto close_handle; + + ZeroMemory (&md->overlapped, sizeof(md->overlapped)); + md->overlapped.hEvent = md->event; + + filter = (type == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME; + filter |= + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_LAST_WRITE | + FILE_NOTIFY_CHANGE_LAST_ACCESS | + FILE_NOTIFY_CHANGE_CREATION | + FILE_NOTIFY_CHANGE_SECURITY; + + if (!ReadDirectoryChangesW(md->handle, + md->buffer, + ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE, + FALSE, + filter, + &md->buf_length, + &md->overlapped, + NULL)) + goto close_event; + + md->h = ecore_main_win32_handler_add(md->event, + _ecore_file_monitor_win32_cb, + md); + if (!md->h) + goto close_event; + + md->monitor = monitor; + md->is_dir = type; + + return md; + + close_event: + CloseHandle(md->event); + close_handle: + CloseHandle(md->handle); + free_md: + free(md); + + return NULL; +} + +static void +_ecore_file_monitor_win32_data_free(Ecore_File_Monitor_Win32_Data *md) +{ + if (!md) return; + + CloseHandle(md->event); + CloseHandle (md->handle); + free (md); +} + +static Eina_Bool +_ecore_file_monitor_win32_cb(void *data, Ecore_Win32_Handler *wh) +{ + char filename[PATH_MAX]; + PFILE_NOTIFY_INFORMATION fni; + Ecore_File_Monitor_Win32_Data *md; + wchar_t *wname; + char *name; + DWORD filter; + DWORD offset; + DWORD buf_length; + Ecore_File_Event event = ECORE_FILE_EVENT_NONE; + + md = (Ecore_File_Monitor_Win32_Data *)data; + + if (!GetOverlappedResult (md->handle, &md->overlapped, &buf_length, TRUE)) + return 1; + + fni = (PFILE_NOTIFY_INFORMATION)md->buffer; + do { + if (!fni) + break; + offset = fni->NextEntryOffset; + + wname = (wchar_t *)malloc(sizeof(wchar_t) * (fni->FileNameLength + 1)); + if (!wname) + return 0; + + memcpy(wname, fni->FileName, fni->FileNameLength); + wname[fni->FileNameLength]='\0'; + name = evil_wchar_to_char(wname); + free(wname); + if (!name) + return 0; + + _snprintf(filename, PATH_MAX, "%s\\%s", md->monitor->path, name); + free(name); + + switch (fni->Action) + { + case FILE_ACTION_ADDED: + if (md->is_dir) + event = ECORE_FILE_EVENT_CREATED_DIRECTORY; + else + event = ECORE_FILE_EVENT_CREATED_FILE; + break; + case FILE_ACTION_REMOVED: + if (md->is_dir) + event = ECORE_FILE_EVENT_DELETED_DIRECTORY; + else + event = ECORE_FILE_EVENT_DELETED_FILE; + break; + case FILE_ACTION_MODIFIED: + if (!md->is_dir) + event = ECORE_FILE_EVENT_MODIFIED; + break; + case FILE_ACTION_RENAMED_OLD_NAME: + if (md->is_dir) + event = ECORE_FILE_EVENT_DELETED_DIRECTORY; + else + event = ECORE_FILE_EVENT_DELETED_FILE; + break; + case FILE_ACTION_RENAMED_NEW_NAME: + if (md->is_dir) + event = ECORE_FILE_EVENT_CREATED_DIRECTORY; + else + event = ECORE_FILE_EVENT_CREATED_FILE; + break; + default: + fprintf(stderr, "unknown event\n"); + event = ECORE_FILE_EVENT_NONE; + break; + } + if (event != ECORE_FILE_EVENT_NONE) + md->monitor->func(md->monitor->data, md->monitor, event, filename); + + fni = (PFILE_NOTIFY_INFORMATION)((LPBYTE)fni + offset); + } while (offset); + + filter = (md->is_dir == 0) ? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME; + filter |= + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_LAST_WRITE | + FILE_NOTIFY_CHANGE_LAST_ACCESS | + FILE_NOTIFY_CHANGE_CREATION | + FILE_NOTIFY_CHANGE_SECURITY; + + ReadDirectoryChangesW(md->handle, + md->buffer, + ECORE_FILE_MONITOR_WIN32_BUFFER_SIZE, + FALSE, + filter, + &md->buf_length, + &md->overlapped, + NULL); + return 1; +} + +int +ecore_file_monitor_win32_init(void) +{ + return 1; +} + +int +ecore_file_monitor_win32_shutdown(void) +{ + return 1; +} + +Ecore_File_Monitor * +ecore_file_monitor_win32_add(const char *path, + void (*func) (void *data, Ecore_File_Monitor *em, + Ecore_File_Event event, + const char *path), + void *data) +{ + Ecore_File_Monitor_Win32 *m; + Ecore_File_Monitor *em; + size_t len; + + if (!path || (*path == '\0')) return NULL; + if (!ecore_file_exists(path) || !ecore_file_is_dir(path)) + return NULL; + if (!func) return NULL; + + em = (Ecore_File_Monitor *)calloc(1, sizeof(Ecore_File_Monitor_Win32)); + if (!em) return NULL; + + em->func = func; + em->data = data; + + em->path = strdup(path); + if (!em->path) + { + free(em); + return NULL; + } + len = strlen(em->path); + if (em->path[len - 1] == '/' || em->path[len - 1] == '\\') + em->path[len - 1] = '\0'; + + m = ECORE_FILE_MONITOR_WIN32(em); + + m->file = _ecore_file_monitor_win32_data_new(em, 0); + if (!m->file) + { + free(em->path); + free(em); + return NULL; + } + + m->dir = _ecore_file_monitor_win32_data_new(em, 1); + if (!m->dir) + { + _ecore_file_monitor_win32_data_free(m->file); + free(em->path); + free(em); + return NULL; + } + + _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em))); + + return em; +} + +void +ecore_file_monitor_win32_del(Ecore_File_Monitor *em) +{ + Ecore_File_Monitor_Win32 *m; + + if (!em) + return; + + m = ECORE_FILE_MONITOR_WIN32(em); + _ecore_file_monitor_win32_data_free(m->dir); + _ecore_file_monitor_win32_data_free(m->file); + free(em->path); + free(em); +} + +#endif diff --git a/src/lib/ecore_file/ecore_file_path.c b/src/lib/ecore_file/ecore_file_path.c new file mode 100644 index 0000000000..c1c54b7c0f --- /dev/null +++ b/src/lib/ecore_file/ecore_file_path.c @@ -0,0 +1,192 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include +#include +#include + +#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) + eina_stringshare_del(dir); +} + +Eina_List * +_ecore_file_path_from_env(const char *env) +{ + Eina_List *path = NULL; + char *env_tmp, *env_path, *p, *last; + + env_tmp = getenv(env); + if (!env_tmp) + return path; + + env_path = alloca(sizeof(char) * strlen(env_tmp) + 1); + memset(env_path, 0, strlen(env_tmp)); + strcpy(env_path, env_tmp); + 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, eina_stringshare_add(last)); + last = p + 1; + } + } + if (p > last) + path = eina_list_append(path, eina_stringshare_add(last)); + + return path; +} + +/** + * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions + * + * @{ + */ + +/** + * @brief Check if the given directory is in PATH. + * + * @param in_dir The name of the directory to search in PATH. + * @return @c EINA_TRUE if the directory exist in PATH, @c EINA_FALSE otherwise. + * + * This function checks if @p in_dir is in the environment variable + * PATH. If @p in_dir is @c NULL, or if PATH is empty, or @p in_dir is + * not in PATH, the function returns @c EINA_FALSE, otherwise it returns + * @c EINA_TRUE. + */ +EAPI Eina_Bool +ecore_file_path_dir_exists(const char *in_dir) +{ + Eina_List *l; + char *dir; + + if (!in_dir) + return EINA_FALSE; + + if (!__ecore_file_path_bin) return EINA_FALSE; + EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir) + { + if (strcmp(dir, in_dir)) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +/** + * @brief Check if the given application is installed. + * + * @param exe The name of the application + * @return @c EINA_TRUE if the @p exe is in PATH and is executable, + * @c EINA_FALSE otherwise. + * + * This function checks if @p exe exists in PATH and is executable. If + * @p exe is @c NULL or is not executable, the function returns + * @c EINA_FALSE, otherwise it returns @c EINA_TRUE. + */ +EAPI Eina_Bool +ecore_file_app_installed(const char *exe) +{ + Eina_List *l; + char *dir; + char buf[PATH_MAX]; + + if (!exe) return EINA_FALSE; + if (ecore_file_can_exec(exe)) return EINA_TRUE; + + EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir) + { + snprintf(buf, sizeof(buf), "%s/%s", dir, exe); + if (ecore_file_can_exec(buf)) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +/** + * @brief Get a list of all the applications installed on the system. + * + * @return An Eina_List containing all the executable files in the + * system. + * + * This function returns a list of allocated strings of all the + * executable files. If no files are found, the function returns + * @c NULL. When not needed anymore, the element of the list must be + * freed. + */ +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; +} + +/** + * @} + */ diff --git a/src/lib/ecore_file/ecore_file_private.h b/src/lib/ecore_file/ecore_file_private.h new file mode 100644 index 0000000000..45d2cbd65c --- /dev/null +++ b/src/lib/ecore_file/ecore_file_private.h @@ -0,0 +1,129 @@ +#ifndef ECORE_FILE_PRIVATE_H_ +#define ECORE_FILE_PRIVATE_H_ + +#ifdef __linux__ +# include +#endif + +#ifdef HAVE_EVIL +# include +#endif + +#ifdef HAVE_ESCAPE +# include +#endif + +#include +#include + +#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 diff --git a/src/lib/ecore_imf/Ecore_IMF.h b/src/lib/ecore_imf/Ecore_IMF.h new file mode 100644 index 0000000000..641ece74a3 --- /dev/null +++ b/src/lib/ecore_imf/Ecore_IMF.h @@ -0,0 +1,577 @@ +#ifndef _ECORE_IMF_H +#define _ECORE_IMF_H + +#include + +#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 + +/** + * @addtogroup Ecore_IMF_Context_Group + * + * @{ + */ +/* ecore_imf_context_input_panel_event_callback_add() flag */ +typedef enum +{ + ECORE_IMF_INPUT_PANEL_STATE_EVENT, /**< called when the state of the input panel is changed. @since 1.7 */ + ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, /**< called when the language of the input panel is changed. @since 1.7 */ + ECORE_IMF_INPUT_PANEL_SHIFT_MODE_EVENT, /**< called when the shift key state of the input panel is changed @since 1.7 */ + ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, /**< called when the size of the input panel is changed. @since 1.7 */ + ECORE_IMF_CANDIDATE_PANEL_STATE_EVENT, /**< called when the state of the candidate word panel is changed. @since 1.7 */ + ECORE_IMF_CANDIDATE_PANEL_GEOMETRY_EVENT /**< called when the size of the candidate word panel is changed. @since 1.7 */ +} Ecore_IMF_Input_Panel_Event; + +typedef enum +{ + ECORE_IMF_INPUT_PANEL_STATE_SHOW, /**< Notification after the display of the input panel @since 1.7 */ + ECORE_IMF_INPUT_PANEL_STATE_HIDE, /**< Notification prior to the dismissal of the input panel @since 1.7 */ + ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW /**< Notification prior to the display of the input panel @since 1.7 */ +} Ecore_IMF_Input_Panel_State; + +typedef enum +{ + ECORE_IMF_INPUT_PANEL_SHIFT_MODE_OFF, /**< @since 1.7 */ + ECORE_IMF_INPUT_PANEL_SHIFT_MODE_ON /**< @since 1.7 */ +} Ecore_IMF_Input_Panel_Shift_Mode; + +typedef enum +{ + ECORE_IMF_CANDIDATE_PANEL_SHOW, /**< Notification after the display of the candidate word panel @since 1.7 */ + ECORE_IMF_CANDIDATE_PANEL_HIDE /**< Notification prior to the dismissal of the candidate word panel @since 1.7 */ +} Ecore_IMF_Candidate_Panel_State; + +/* 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 */ + +/* Preedit attribute info */ +typedef struct _Ecore_IMF_Preedit_Attr Ecore_IMF_Preedit_Attr; + +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 void (*Ecore_IMF_Event_Cb) (void *data, Ecore_IMF_Context *ctx, void *event_info); + +/** + * @typedef Ecore_IMF_Callback_Type + * + * Ecore IMF Event callback types. + * + * @see ecore_imf_context_event_callback_add() + */ +typedef enum +{ + ECORE_IMF_CALLBACK_PREEDIT_START, /**< "PREEDIT_START" is called when a new preediting sequence starts. @since 1.2 */ + ECORE_IMF_CALLBACK_PREEDIT_END, /**< "PREEDIT_END" is called when a preediting sequence has been completed or canceled. @since 1.2 */ + ECORE_IMF_CALLBACK_PREEDIT_CHANGED, /**< "PREEDIT_CHANGED" is called whenever the preedit sequence currently being entered has changed. @since 1.2 */ + ECORE_IMF_CALLBACK_COMMIT, /**< "COMMIT" is called when a complete input sequence has been entered by the user @since 1.2 */ + ECORE_IMF_CALLBACK_DELETE_SURROUNDING /**< "DELETE_SURROUNDING" is called when the input method needs to delete all or part of the context surrounding the cursor @since 1.2 */ +} Ecore_IMF_Callback_Type; + +/** + * @typedef Ecore_IMF_Event_Type + * + * Ecore IMF event types. + * + * @see ecore_imf_context_filter_event() + */ +typedef enum +{ + ECORE_IMF_EVENT_MOUSE_DOWN, /**< Mouse Down event */ + ECORE_IMF_EVENT_MOUSE_UP, /**< Mouse Up event */ + ECORE_IMF_EVENT_MOUSE_IN, /**< Mouse In event */ + ECORE_IMF_EVENT_MOUSE_OUT, /**< Mouse Out event */ + ECORE_IMF_EVENT_MOUSE_MOVE, /**< Mouse Move event */ + ECORE_IMF_EVENT_MOUSE_WHEEL, /**< Mouse Wheel event */ + ECORE_IMF_EVENT_KEY_DOWN, /**< Key Down event */ + ECORE_IMF_EVENT_KEY_UP /**< Key Up event */ +} Ecore_IMF_Event_Type; +/** + * @typedef Ecore_IMF_Keyboard_Modifiers + * Type for Ecore_IMF keyboard modifiers + */ +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_MODIFIER_ALTGR = 1 << 4 /**< "AltGr" is pressed @since 1.7 */ +} Ecore_IMF_Keyboard_Modifiers; + +/** + * @typedef Ecore_IMF_Keyboard_Locks + * Type for Ecore_IMF keyboard locks + */ +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 Ecore_IMF_Mouse_Flags + * Type for Ecore_IMF mouse flags + */ +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; + +/** + * @typedef Ecore_IMF_Preedit_Type + * + * Ecore IMF Preedit style types + * + * @see ecore_imf_context_preedit_string_with_attributes_get() + */ +typedef enum +{ + ECORE_IMF_PREEDIT_TYPE_NONE, /**< None style @since 1.1 */ + ECORE_IMF_PREEDIT_TYPE_SUB1, /**< Substring style 1 @since 1.1 */ + ECORE_IMF_PREEDIT_TYPE_SUB2, /**< Substring style 2 @since 1.1 */ + ECORE_IMF_PREEDIT_TYPE_SUB3, /**< Substring style 3 @since 1.1 */ + ECORE_IMF_PREEDIT_TYPE_SUB4, /**< Substring style 4 @since 1.8 */ + ECORE_IMF_PREEDIT_TYPE_SUB5, /**< Substring style 5 @since 1.8 */ + ECORE_IMF_PREEDIT_TYPE_SUB6, /**< Substring style 6 @since 1.8 */ + ECORE_IMF_PREEDIT_TYPE_SUB7 /**< Substring style 7 @since 1.8 */ +} Ecore_IMF_Preedit_Type; + +/** + * @typedef Ecore_IMF_Autocapital_Type + * + * Autocapitalization Types. + * + * @see ecore_imf_context_autocapital_type_set() + */ +typedef enum +{ + ECORE_IMF_AUTOCAPITAL_TYPE_NONE, /**< No auto-capitalization when typing @since 1.1 */ + ECORE_IMF_AUTOCAPITAL_TYPE_WORD, /**< Autocapitalize each word typed @since 1.1 */ + ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE, /**< Autocapitalize the start of each sentence @since 1.1 */ + ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER, /**< Autocapitalize all letters @since 1.1 */ +} Ecore_IMF_Autocapital_Type; + +/** + * @typedef Ecore_IMF_Input_Panel_Layout + * + * Input panel (virtual keyboard) layout types. + * + * @see ecore_imf_context_input_panel_layout_set() + */ +typedef enum +{ + ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL, /**< Default layout */ + ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER, /**< Number layout */ + ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL, /**< Email layout */ + ECORE_IMF_INPUT_PANEL_LAYOUT_URL, /**< URL layout */ + ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER, /**< Phone Number layout */ + ECORE_IMF_INPUT_PANEL_LAYOUT_IP, /**< IP layout */ + ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH, /**< Month layout */ + ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY, /**< Number Only layout */ + ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID, /**< Never use this */ + ECORE_IMF_INPUT_PANEL_LAYOUT_HEX, /**< Hexadecimal layout @since 1.2 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL, /**< Command-line terminal layout including esc, alt, ctrl key, so on (no auto-correct, no auto-capitalization) @since 1.2 */ + ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD /**< Like normal, but no auto-correct, no auto-capitalization etc. @since 1.2 */ +} Ecore_IMF_Input_Panel_Layout; + +/** + * @typedef Ecore_IMF_Input_Panel_Lang + * + * Input panel (virtual keyboard) language modes. + * + * @see ecore_imf_context_input_panel_language_set() + */ +typedef enum +{ + ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC, /**< Automatic @since 1.2 */ + ECORE_IMF_INPUT_PANEL_LANG_ALPHABET /**< Alphabet @since 1.2 */ +} Ecore_IMF_Input_Panel_Lang; + +/** + * @typedef Ecore_IMF_Input_Panel_Return_Key_Type + * + * "Return" Key types on the input panel (virtual keyboard). + * + * @see ecore_imf_context_input_panel_return_key_type_set() + */ +typedef enum +{ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT, /**< Default @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE, /**< Done @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO, /**< Go @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN, /**< Join @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN, /**< Login @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT, /**< Next @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH, /**< Search or magnifier icon @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND, /**< Send @since 1.2 */ + ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN /**< Sign-in @since 1.8 */ +} Ecore_IMF_Input_Panel_Return_Key_Type; + +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 occurred */ +}; + +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 occurred */ +}; + +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 occurred */ +}; + +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 occurred */ +}; + +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 occurred */ +}; + +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 occurred */ +}; + +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 occurred */ +}; + +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 occurred */ +}; + +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_Preedit_Attr +{ + Ecore_IMF_Preedit_Type preedit_type; /**< preedit style type */ + unsigned int start_index; /**< start index of the range (in bytes) */ + unsigned int end_index; /**< end index of the range (in bytes) */ +}; + +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, Eina_Bool use_preedit); + void (*input_mode_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); + Eina_Bool (*filter_event) (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); + void (*preedit_string_with_attributes_get) (Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos); + void (*prediction_allow_set)(Ecore_IMF_Context *ctx, Eina_Bool prediction); + void (*autocapital_type_set)(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type); + void (*control_panel_show) (Ecore_IMF_Context *ctx); + void (*control_panel_hide) (Ecore_IMF_Context *ctx); + void (*input_panel_layout_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout); + Ecore_IMF_Input_Panel_Layout (*input_panel_layout_get) (Ecore_IMF_Context *ctx); + void (*input_panel_language_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); + Ecore_IMF_Input_Panel_Lang (*input_panel_language_get) (Ecore_IMF_Context *ctx); + void (*cursor_location_set) (Ecore_IMF_Context *ctx, int x, int y, int w, int h); + void (*input_panel_imdata_set)(Ecore_IMF_Context *ctx, const void* data, int len); + void (*input_panel_imdata_get)(Ecore_IMF_Context *ctx, void* data, int *len); + void (*input_panel_return_key_type_set) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type); + void (*input_panel_return_key_disabled_set) (Ecore_IMF_Context *ctx, Eina_Bool disabled); + void (*input_panel_caps_lock_mode_set) (Ecore_IMF_Context *ctx, Eina_Bool mode); + void (*input_panel_geometry_get)(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); + Ecore_IMF_Input_Panel_State (*input_panel_state_get) (Ecore_IMF_Context *ctx); + void (*input_panel_event_callback_add) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), void *data); + void (*input_panel_event_callback_del) (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)); + void (*input_panel_language_locale_get) (Ecore_IMF_Context *ctx, char **lang); + void (*candidate_panel_geometry_get)(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); +}; + +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_window_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas); +EAPI void *ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx); +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_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, 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_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h); +EAPI void ecore_imf_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit); +EAPI void ecore_imf_context_retrieve_surrounding_callback_set(Ecore_IMF_Context *ctx, Eina_Bool (*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 Eina_Bool 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 Eina_Bool 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); +EAPI void ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data); +EAPI void *ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func); +EAPI void ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info); +EAPI void ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction); +EAPI Eina_Bool ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type); +EAPI Ecore_IMF_Autocapital_Type ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx); + +EAPI void ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx); + +EAPI void ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout); +EAPI Ecore_IMF_Input_Panel_Layout ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang); +EAPI Ecore_IMF_Input_Panel_Lang ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx, Eina_Bool enable); +EAPI Eina_Bool ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len); +EAPI void ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len); +EAPI void ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type); +EAPI Ecore_IMF_Input_Panel_Return_Key_Type ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled); +EAPI Eina_Bool ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode); +EAPI Eina_Bool ecore_imf_context_input_panel_caps_lock_mode_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); +EAPI Ecore_IMF_Input_Panel_State ecore_imf_context_input_panel_state_get(Ecore_IMF_Context *ctx); +EAPI void ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value), const void *data); +EAPI void ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Event type, void (*func) (void *data, Ecore_IMF_Context *ctx, int value)); +EAPI void ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx, char **lang); +EAPI void ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h); + +/* 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 diff --git a/src/lib/ecore_imf/Ecore_IMF_Evas.h b/src/lib/ecore_imf/Ecore_IMF_Evas.h new file mode 100644 index 0000000000..5f7cdb90f3 --- /dev/null +++ b/src/lib/ecore_imf/Ecore_IMF_Evas.h @@ -0,0 +1,50 @@ +#ifndef _ECORE_IMF_EVAS_H +#define _ECORE_IMF_EVAS_H + +#include +#include + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# ifdef EFL_ECORE_IMF_EVAS_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 + +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 diff --git a/src/lib/ecore_imf/ecore_imf.c b/src/lib/ecore_imf/ecore_imf.c new file mode 100644 index 0000000000..7cf8a4a9f6 --- /dev/null +++ b/src/lib/ecore_imf/ecore_imf.c @@ -0,0 +1,73 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#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 + ("ecore_imf", 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_imf_module_shutdown(); + eina_log_domain_unregister(_ecore_imf_log_dom); + _ecore_imf_log_dom = -1; + ecore_shutdown(); + return _ecore_imf_init_count; +} diff --git a/src/lib/ecore_imf/ecore_imf_context.c b/src/lib/ecore_imf/ecore_imf_context.c new file mode 100644 index 0000000000..3faa5acbd5 --- /dev/null +++ b/src/lib/ecore_imf/ecore_imf_context.c @@ -0,0 +1,1900 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#include +#include + +#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. + + * Ecore Input Method Context Function defines the interface for EFL input methods. + * An input method is used by EFL text input widgets like elm_entry + * (based on edje_entry) to map from key events to Unicode character strings. + * + * The default input method can be set through setting the ECORE_IMF_MODULE environment variable. + * + * An input method may consume multiple key events in sequence and finally output the composed result. + * This is called preediting, and an input method may provide feedback about + * this process by displaying the intermediate composition states as preedit text. + * + * Immodule is plugin to connect your application and input method framework such as SCIM, ibus, and so on.@n + * ecore_imf_init() should be called to initialize and load immodule.@n + * ecore_imf_shutdown() is used for shutdowning and unloading immodule. + * + * An example of usage of these functions can be found at: + * @li @ref ecore_imf_example_c + */ + +/** + * 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 + * + * Example + * @code + * + * const char *ctx_id; + * const Ecore_IMF_Context_Info *ctx_info; + * Ecore_IMF_Context *imf_context; + * ctx_id = ecore_imf_context_default_id_get(); + * if (ctx_id) + * { + * ctx_info = ecore_imf_context_info_by_id_get(ctx_id); + * if (!ctx_info->canvas_type || + * strcmp(ctx_info->canvas_type, "evas") == 0) + * { + * imf_context = ecore_imf_context_add(ctx_id); + * } + * else + * { + * ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas"); + * if (ctx_id) + * { + * imf_context = ecore_imf_context_add(ctx_id); + * } + * } + * } + * @endcode + */ +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 EINA_TRUE, so let's make sure it's + * set on the immodule */ + ecore_imf_context_use_preedit_set(ctx, EINA_TRUE); + + /* default prediction is EINA_TRUE, so let's make sure it's + * set on the immodule */ + ecore_imf_context_prediction_allow_set(ctx, EINA_TRUE); + + /* default autocapital type is SENTENCE type, so let's make sure it's + * set on the immodule */ + ecore_imf_context_autocapital_type_set(ctx, ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE); + + /* default input panel enabled status is EINA_TRUE, so let's make sure it's + * set on the immodule */ + ecore_imf_context_input_panel_enabled_set(ctx, EINA_TRUE); + + /* default input panel layout type is NORMAL type, so let's make sure it's + * set on the immodule */ + ecore_imf_context_input_panel_layout_set(ctx, ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL); + + /* 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) +{ + Ecore_IMF_Func_Node *fn; + + 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); + + if (ctx->callbacks) + { + EINA_LIST_FREE(ctx->callbacks, fn) + free(fn); + } + + 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 @c 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); + ctx->window = window; +} + +/** + * Get the client window of the Input Method Context + * + * See @ref ecore_imf_context_client_window_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return Return the client window. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void * +ecore_imf_context_client_window_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_client_window_get"); + return NULL; + } + return 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 canvas The client canvas. This may be @c 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_canvas_set"); + return; + } + if (ctx->klass->client_canvas_set) ctx->klass->client_canvas_set(ctx, canvas); + ctx->client_canvas = canvas; +} + +/** + * Get the client canvas of the Input Method Context. + * + * See @ref ecore_imf_context_client_canvas_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return Return the client canvas. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void * +ecore_imf_context_client_canvas_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_client_canvas_get"); + return NULL; + } + return ctx->client_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; + } +} + +/** + * Retrieve the current preedit string, attributes 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 attrs an Eina_List of attributes + * @param cursor_pos Location to store position of cursor (in characters) + * within the preedit string. + * @ingroup Ecore_IMF_Context_Group + * + * Example + * @code + * char *preedit_string; + * int cursor_pos; + * Eina_List *attrs = NULL, *l = NULL; + * Ecore_IMF_Preedit_Attr *attr; + * + * ecore_imf_context_preedit_string_with_attributes_get(imf_context, + * &preedit_string, + * &attrs, &cursor_pos); + * if (!preedit_string) return; + * + * if (strlen(preedit_string) > 0) + * { + * if (attrs) + * { + * EINA_LIST_FOREACH(attrs, l, attr) + * { + * if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1) + * { + * // Something to do + * } + * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2) + * { + * // Something to do + * } + * else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3) + * { + * // Something to do + * } + * } + * } + * } + * + * // delete attribute list + * EINA_LIST_FREE(attrs, attr) free(attr); + * + * free(preedit_string); + * @endcode + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char **str, Eina_List **attrs, int *cursor_pos) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_preedit_string_with_attributes_get"); + return; + } + if (ctx->klass->preedit_string_with_attributes_get) + ctx->klass->preedit_string_with_attributes_get(ctx, str, attrs, cursor_pos); + else + { + if (str) *str = strdup(""); + if (attrs) *attrs = NULL; + 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 + * + * Example + * @code + * static void + * _focus_in_cb(void *data, Evas_Object *o, const char *emission, const char *source) + * { + * ecore_imf_context_reset(imf_context); + * ecore_imf_context_focus_in(imf_context); + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_IN, _focus_in_cb, ed); + * @endcode + */ +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 + * + * Example + * @code + * static void + * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source) + * { + * ecore_imf_context_reset(imf_context); + * ecore_imf_context_focus_out(imf_context); + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed); + * @endcode + */ +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 + * + * Example + * @code + * static void + * _focus_out_cb(void *data, Evas_Object *o, const char *emission, const char *source) + * { + * ecore_imf_context_reset(imf_context); + * ecore_imf_context_focus_out(imf_context); + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_FOCUS_OUT, _focus_out_cb, ed); + * @endcode + */ +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); +} + +/** + * Notify the Input Method Context that a change in the cursor + * location has been made. The location is relative to the canvas. + * The cursor location can be used to determine the position of + * candidate word window in the immodule. + * + * @param ctx An #Ecore_IMF_Context. + * @param x cursor x position. + * @param y cursor y position. + * @param w cursor width. + * @param h cursor height. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_cursor_location_set"); + return; + } + if (ctx->klass->cursor_location_set) ctx->klass->cursor_location_set(ctx, x, y, w, h); +} + +/** + * Set whether the IM context should use the preedit string + * to display feedback. If @c use_preedit is @c EINA_FALSE (default + * is @c EINA_TRUE), 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, Eina_Bool 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 whether the IM context should allow to use the text prediction. + * If @p prediction is @c EINA_FALSE (default is @c EINA_TRUE), then the IM + * context will not display the text prediction window. + * + * @param ctx An #Ecore_IMF_Context. + * @param prediction Whether the IM context should allow to use the text prediction. + * @note Default value is EINA_TRUE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_prediction_allow_set"); + return; + } + + ctx->allow_prediction = prediction; + + if (ctx->klass->prediction_allow_set) + ctx->klass->prediction_allow_set(ctx, prediction); +} + +/** + * Get whether the IM context should allow to use the text prediction. + * + * @param ctx An #Ecore_IMF_Context. + * @return @c EINA_TRUE if it allows to use the text prediction, otherwise + * @c EINA_FALSE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI Eina_Bool +ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_prediction_allow_get"); + return EINA_FALSE; + } + + return ctx->allow_prediction; +} + +/** + * Set the autocapitalization type on the immodule. + * + * @param ctx An #Ecore_IMF_Context. + * @param autocapital_type the autocapitalization type. + * @note Default type is ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_autocapital_type_set"); + return; + } + + ctx->autocapital_type = autocapital_type; + + if (ctx->klass->autocapital_type_set) ctx->klass->autocapital_type_set(ctx, autocapital_type); +} + +/** + * Get the autocapitalization type. + * + * @param ctx An #Ecore_IMF_Context. + * @return The autocapital type being used by @p ctx. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI Ecore_IMF_Autocapital_Type +ecore_imf_context_autocapital_type_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_autocapital_allow_get"); + return ECORE_IMF_AUTOCAPITAL_TYPE_NONE; + } + + return ctx->autocapital_type; +} + +/** + * Set the callback to be used on surrounding_get 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, Eina_Bool (*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 @c EINA_TRUE, then no further processing + * should be done for this event. + * + * Input methods must be able to accept all types of events (simply + * returning @c EINA_FALSE 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 @c EINA_TRUE if the event was handled; otherwise @c EINA_FALSE. + * @ingroup Ecore_IMF_Context_Group + * + * Example + * @code + * static void + * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) + * { + * Evas_Event_Key_Down *ev = event_info; + * if (!ev->keyname) return; + * + * if (imf_context) + * { + * Ecore_IMF_Event_Key_Down ecore_ev; + * ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev); + * if (ecore_imf_context_filter_event(imf_context, + * ECORE_IMF_EVENT_KEY_DOWN, + * (Ecore_IMF_Event *)&ecore_ev)) + * return; + * } + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data); + * @endcode + */ +EAPI Eina_Bool +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 EINA_FALSE; + } + if (ctx->klass->filter_event) return ctx->klass->filter_event(ctx, type, event); + return EINA_FALSE; +} + +/** + * @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 = calloc(1, 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. + * Input methods typically want context in order to constrain input text based on existing text; + * this is important for languages such as Thai where only some sequences of characters are allowed. + * In addition, the text around the insertion point can be used for supporting autocapital feature. + * + * 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 @c EINA_TRUE, 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 @p text. + * @return @c EINA_TRUE if surrounding text was provided; otherwise + * @c EINA_FALSE. + * @ingroup Ecore_IMF_Context_Module_Group + */ +EAPI Eina_Bool +ecore_imf_context_surrounding_get(Ecore_IMF_Context *ctx, char **text, int *cursor_pos) +{ + int result = EINA_FALSE; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_surrounding_get"); + return EINA_FALSE; + } + + 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 EINA_UNUSED, void *event) +{ + free(event); +} + +/** + * Adds ECORE_IMF_EVENT_PREEDIT_START to the event queue. + * + * ECORE_IMF_EVENT_PREEDIT_START should be added when a new preedit sequence starts. + * It's asynchronous method to put event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @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. + * + * ECORE_IMF_EVENT_PREEDIT_END should be added when a new preedit sequence has been completed or canceled. + * It's asynchronous method to put event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @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. + * + * It's asynchronous method to put event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @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 EINA_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. + * + * It's asynchronous method to put event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @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 EINA_UNUSED, void *event) +{ + free(event); +} + +/** + * Adds ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue. + * + * Asks the widget that the input context is attached to to delete characters around the cursor position + * by adding the ECORE_IMF_EVENT_DELETE_SURROUNDING to the event queue. + * Note that offset and n_chars are in characters not in bytes. + * + * It's asynchronous method to put ECORE_IMF_EVENT_DELETE_SURROUNDING event to the event queue. + * ecore_imf_context_event_callback_call() can be used as synchronous method. + * + * @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); +} + +/** + * Add (register) a callback function to a given context event. + * + * This function adds a function callback to the context @p ctx when the + * event of type @p type occurs on it. The function pointer is @p + * func. + * + * The event type @p type to trigger the function may be one of + * #ECORE_IMF_CALLBACK_PREEDIT_START, #ECORE_IMF_CALLBACK_PREEDIT_END, + * #ECORE_IMF_CALLBACK_PREEDIT_CHANGED, #ECORE_IMF_CALLBACK_COMMIT and + * #ECORE_IMF_CALLBACK_DELETE_SURROUNDING. + * + * @param ctx Ecore_IMF_Context to attach a callback to. + * @param type The type of event that will trigger the callback + * @param func The (callback) function to be called when the event is + * triggered + * @param data The data pointer to be passed to @p func + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + * + * Example + * @code + * static void + * _imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info) + * { + * char *commit_str = event_info; + * // something to do + * } + * + * ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, data); + * @endcode + */ +EAPI void +ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data) +{ + Ecore_IMF_Func_Node *fn = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_event_callback_add"); + return; + } + + if (!func) return; + + fn = calloc(1, sizeof (Ecore_IMF_Func_Node)); + if (!fn) return; + + fn->func = func; + fn->data = data; + fn->type = type; + + ctx->callbacks = eina_list_append(ctx->callbacks, fn); +} + +/** + * Delete (unregister) a callback function registered to a given + * context event. + * + * This function removes a function callback from the context @p ctx when the + * event of type @p type occurs on it. The function pointer is @p + * func. + * + * @see ecore_imf_context_event_callback_add() for more details + * + * @param ctx Ecore_IMF_Context to remove a callback from. + * @param type The type of event that was triggering the callback + * @param func The (callback) function that was to be called when the event was triggered + * @return the data pointer + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI void * +ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func) +{ + Eina_List *l = NULL; + Eina_List *l_next = NULL; + Ecore_IMF_Func_Node *fn = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_event_callback_del"); + return NULL; + } + + if (!func) return NULL; + if (!ctx->callbacks) return NULL; + + EINA_LIST_FOREACH_SAFE(ctx->callbacks, l, l_next, fn) + { + if ((fn) && (fn->func == func) && (fn->type == type)) + { + void *tmp = (void *)fn->data; + free(fn); + ctx->callbacks = eina_list_remove_list(ctx->callbacks, l); + return tmp; + } + } + return NULL; +} + +/** + * Call a given callback on the context @p ctx. + * + * ecore_imf_context_preedit_start_event_add(), ecore_imf_context_preedit_end_event_add(), + * ecore_imf_context_preedit_changed_event_add(), ecore_imf_context_commit_event_add() and + * ecore_imf_context_delete_surrounding_event_add() APIs are asynchronous + * because those API adds each event to the event queue. + * + * This API provides the way to call each callback function immediately. + * + * @param ctx Ecore_IMF_Context. + * @param type The type of event that will trigger the callback + * @param event_info The pointer to event specific struct or information to + * pass to the callback functions registered on this event + * @ingroup Ecore_IMF_Context_Module_Group + * @since 1.2.0 + */ +EAPI void +ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info) +{ + Ecore_IMF_Func_Node *fn = NULL; + Eina_List *l = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_event_callback_call"); + return; + } + + EINA_LIST_FOREACH(ctx->callbacks, l, fn) + { + if ((fn) && (fn->type == type) && (fn->func)) + fn->func(fn->data, ctx, event_info); + } +} + +/** + * Ask the Input Method Context to show the control panel of using Input Method. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_control_panel_show(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_control_panel_show"); + return; + } + + if (ctx->klass->control_panel_show) ctx->klass->control_panel_show(ctx); +} + +/** + * Ask the Input Method Context to hide the control panel of using Input Method. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_control_panel_hide(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_control_panel_hide"); + return; + } + + if (ctx->klass->control_panel_hide) ctx->klass->control_panel_hide(ctx); +} + +/** + * Ask the Input Method Context to show the input panel (virtual keyboard). + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_input_panel_show(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_show"); + return; + } + + if (ctx->klass->show) ctx->klass->show(ctx); +} + +/** + * Ask the Input Method Context to hide the input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_input_panel_hide(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_hide"); + return; + } + + if (ctx->klass->hide) ctx->klass->hide(ctx); +} + +/** + * Set the layout of the input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @param layout see #Ecore_IMF_Input_Panel_Layout + * @note Default layout type is ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_input_panel_layout_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_layout_set"); + return; + } + + if (ctx->klass->input_panel_layout_set) + ctx->klass->input_panel_layout_set(ctx, layout); + + ctx->input_panel_layout = layout; +} + +/** + * Get the layout of the current active input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @return layout see #Ecore_IMF_Input_Panel_Layout + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI Ecore_IMF_Input_Panel_Layout +ecore_imf_context_input_panel_layout_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_layout_get"); + return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID; + } + + if (ctx->klass->input_panel_layout_get) + return ctx->input_panel_layout; + else + return ECORE_IMF_INPUT_PANEL_LAYOUT_INVALID; +} + +/** + * Set the language of the input panel. + * This API can be used when you want to show the English keyboard. + * + * @param ctx An #Ecore_IMF_Context. + * @param lang the language to be set to the input panel. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_input_panel_language_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang lang) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_language_set"); + return; + } + + if (ctx->klass->input_panel_language_set) ctx->klass->input_panel_language_set(ctx, lang); + ctx->input_panel_lang = lang; +} + +/** + * Get the language of the input panel. + * + * See @ref ecore_imf_context_input_panel_language_set for more details. + * + * @param ctx An #Ecore_IMF_Context. + * @return Ecore_IMF_Input_Panel_Lang + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI Ecore_IMF_Input_Panel_Lang +ecore_imf_context_input_panel_language_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_language_get"); + return ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC; + } + + return ctx->input_panel_lang; +} + +/** + * Set whether the Input Method Context should request to show the input panel automatically + * when the widget has focus. + * + * @param ctx An #Ecore_IMF_Context. + * @param enabled If true, the input panel will be shown when the widget is clicked or has focus. + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI void +ecore_imf_context_input_panel_enabled_set(Ecore_IMF_Context *ctx, + Eina_Bool enabled) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_enabled_set"); + return; + } + + ctx->input_panel_enabled = enabled; +} + +/** + * Get whether the Input Method Context requests to show the input panel automatically. + * + * @param ctx An #Ecore_IMF_Context. + * @return Return the attribute to show the input panel automatically + * @ingroup Ecore_IMF_Context_Group + * @since 1.1.0 + */ +EAPI Eina_Bool +ecore_imf_context_input_panel_enabled_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_enabled_get"); + return EINA_FALSE; + } + + return ctx->input_panel_enabled; +} + +/** + * Set the input panel-specific data to deliver to the input panel. + * This API is used by applications to deliver specific data to the input panel. + * The data format MUST be negotiated by both application and the input panel. + * The size and format of data are defined by the input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @param data The specific data to be set to the input panel. + * @param len the length of data, in bytes, to send to the input panel + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI void +ecore_imf_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int len) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_imdata_set"); + return; + } + + if (!data) return; + + if (ctx->klass->input_panel_imdata_set) + ctx->klass->input_panel_imdata_set(ctx, data, len); +} + +/** + * Get the specific data of the current active input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @param data The specific data to be got from the input panel + * @param len The length of data + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI void +ecore_imf_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *len) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_imdata_get"); + return; + } + + if (!data) return; + + if (ctx->klass->input_panel_imdata_get) + ctx->klass->input_panel_imdata_get(ctx, data, len); +} + +/** + * Set the "return" key type. This type is used to set string or icon on the "return" key of the input panel. + * + * An input panel displays the string or icon associated with this type + * + * @param ctx An #Ecore_IMF_Context. + * @param return_key_type The type of "return" key on the input panel + * @note Default type is ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT. + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI void +ecore_imf_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Return_Key_Type return_key_type) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_return_key_type_set"); + return; + } + + ctx->input_panel_return_key_type = return_key_type; + if (ctx->klass->input_panel_return_key_type_set) ctx->klass->input_panel_return_key_type_set(ctx, return_key_type); +} + +/** + * Get the "return" key type. + * + * @see ecore_imf_context_input_panel_return_key_type_set() for more details + * + * @param ctx An #Ecore_IMF_Context. + * @return The type of "return" key on the input panel + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI Ecore_IMF_Input_Panel_Return_Key_Type +ecore_imf_context_input_panel_return_key_type_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_return_key_type_get"); + return EINA_FALSE; + } + + return ctx->input_panel_return_key_type; +} + +/** + * Set the return key on the input panel to be disabled. + * + * @param ctx An #Ecore_IMF_Context. + * @param disabled The state + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI void +ecore_imf_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx, Eina_Bool disabled) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_return_key_disabled_set"); + return; + } + + ctx->input_panel_return_key_disabled = disabled; + if (ctx->klass->input_panel_return_key_disabled_set) ctx->klass->input_panel_return_key_disabled_set(ctx, disabled); +} + +/** + * Get whether the return key on the input panel should be disabled or not. + * + * @param ctx An #Ecore_IMF_Context. + * @return @c EINA_TRUE if it should be disabled. + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI Eina_Bool +ecore_imf_context_input_panel_return_key_disabled_get(Ecore_IMF_Context *ctx) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_return_key_disabled_get"); + return EINA_FALSE; + } + + return ctx->input_panel_return_key_disabled; +} + +/** + * Set the caps lock mode on the input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @param mode Turn on caps lock on the input panel if @c EINA_TRUE. + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI void +ecore_imf_context_input_panel_caps_lock_mode_set(Ecore_IMF_Context *ctx, Eina_Bool mode) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_caps_lock_mode_set"); + return; + } + + if (ctx->klass->input_panel_caps_lock_mode_set) + ctx->klass->input_panel_caps_lock_mode_set(ctx, mode); + + ctx->input_panel_caps_lock_mode = mode; +} + +/** + * Get the caps lock mode on the input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @return @c EINA_TRUE if the caps lock is turned on. + * @ingroup Ecore_IMF_Context_Group + * @since 1.2.0 + */ +EAPI Eina_Bool +ecore_imf_context_input_panel_caps_lock_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_panel_caps_lock_mode_get"); + return EINA_FALSE; + } + + return ctx->input_panel_caps_lock_mode; +} + +/** + * Get the position of the current active input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @param x top-left x co-ordinate of the input panel + * @param y top-left y co-ordinate of the input panel + * @param w width of the input panel + * @param h height of the input panel + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ +EAPI void +ecore_imf_context_input_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_geometry_get"); + return; + } + + if (ctx->klass->input_panel_geometry_get) + ctx->klass->input_panel_geometry_get(ctx, x, y, w, h); +} + +/** + * Get state of current active input panel. + * + * @param ctx An #Ecore_IMF_Context. + * @return The state of input panel. + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ +EAPI Ecore_IMF_Input_Panel_State +ecore_imf_context_input_panel_state_get(Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Input_Panel_State state = ECORE_IMF_INPUT_PANEL_STATE_HIDE; + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_state_get"); + return ECORE_IMF_INPUT_PANEL_STATE_HIDE; + } + + if (ctx->klass->input_panel_state_get) + state = ctx->klass->input_panel_state_get(ctx); + + return state; +} + +/** + * Register a callback function which will be called if there is change in input panel state,language,mode etc. + * In order to deregister the callback function + * Use @ref ecore_imf_context_input_panel_event_callback_del. + * + * @param ctx An #Ecore_IMF_Context + * @param type event type + * @param func the callback function + * @param data application-input panel specific data. + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ +EAPI void +ecore_imf_context_input_panel_event_callback_add(Ecore_IMF_Context *ctx, + Ecore_IMF_Input_Panel_Event type, + void (*func) (void *data, Ecore_IMF_Context *ctx, int value), + const void *data) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_event_callback_add"); + return; + } + + if (ctx->klass->input_panel_event_callback_add) + ctx->klass->input_panel_event_callback_add(ctx, type, func, (void *)data); +} + +/** + * Unregister a callback function which will be called if there is change in input panel state, language, mode etc. + * + * @param ctx An #Ecore_IMF_Context. + * @param type An #Ecore_IMF_Input_Panel_Event. + * @param func the callback function + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ +EAPI void +ecore_imf_context_input_panel_event_callback_del(Ecore_IMF_Context *ctx, + Ecore_IMF_Input_Panel_Event type, + void (*func) (void *data, Ecore_IMF_Context *ctx, int value)) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_event_callback_del"); + return; + } + + if (ctx->klass->input_panel_event_callback_del) + ctx->klass->input_panel_event_callback_del(ctx, type, func); +} + +/** + * Get the current language locale of the input panel. + * + * ex) fr_FR + * + * @param ctx An #Ecore_IMF_Context. + * @param lang Location to store the retrieved language string. The + * string retrieved must be freed with free(). + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ +EAPI void +ecore_imf_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx, char **lang) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_input_panel_language_locale_get"); + return; + } + + if (ctx->klass->input_panel_language_locale_get) + ctx->klass->input_panel_language_locale_get(ctx, lang); + else + { + if (lang) *lang = strdup(""); + } +} + +/** + * Get the geometry information of the candidate panel. + * + * @param ctx An #Ecore_IMF_Context. + * @param x top-left x co-ordinate of the candidate panel + * @param y top-left y co-ordinate of the candidate panel + * @param w width of the candidate panel + * @param h height of the candidate panel + * @ingroup Ecore_IMF_Context_Group + * @since 1.3 + */ +EAPI void +ecore_imf_context_candidate_panel_geometry_get(Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h) +{ + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_candidate_panel_geometry_get"); + return; + } + + if (ctx->klass->candidate_panel_geometry_get) + ctx->klass->candidate_panel_geometry_get(ctx, x, y, w, h); +} + diff --git a/src/lib/ecore_imf/ecore_imf_evas.c b/src/lib/ecore_imf/ecore_imf_evas.c new file mode 100644 index 0000000000..4a5f3dd5f4 --- /dev/null +++ b/src/lib/ecore_imf/ecore_imf_evas.c @@ -0,0 +1,324 @@ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "ecore_private.h" +#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. + * Converts each event from Evas to the corresponding event of Ecore_IMF. + * + * An example of usage of these functions can be found at: + * @li @ref ecore_imf_example_c + */ + +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; + if (evas_key_modifier_is_set(evas_modifiers, "AltGr")) + *imf_keyboard_modifiers |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR; +} + +/* 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 + * + * Example + * @code + * static void + * _key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) + * { + * Evas_Event_Key_Down *ev = event_info; + * if (!ev->keyname) return; + * + * if (imf_context) + * { + * Ecore_IMF_Event_Key_Down ecore_ev; + * ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev); + * if (ecore_imf_context_filter_event(imf_context, + * ECORE_IMF_EVENT_KEY_DOWN, + * (Ecore_IMF_Event *)&ecore_ev)) + * return; + * } + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, data); + * @endcode + */ +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 + * + * Example + * @code + * static void + * _key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) + * { + * Evas_Event_Key_Up *ev = event_info; + * if (!ev->keyname) return; + * + * if (imf_context) + * { + * Ecore_IMF_Event_Key_Up ecore_ev; + * ecore_imf_evas_event_key_up_wrap(ev, &ecore_ev); + * if (ecore_imf_context_filter_event(imf_context, + * ECORE_IMF_EVENT_KEY_UP, + * (Ecore_IMF_Event *)&ecore_ev)) + * return; + * } + * } + * + * evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP, _key_up_cb, data); + * @endcode + */ +EAPI void +ecore_imf_evas_event_key_up_wrap(Evas_Event_Key_Up *evas_event, + Ecore_IMF_Event_Key_Up *imf_event) +{ + if (!evas_event) + { + EINA_LOG_ERR("Evas event is missing"); + return; + } + + if (!imf_event) + { + EINA_LOG_ERR("Imf event is missing"); + 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); +} diff --git a/src/lib/ecore_imf/ecore_imf_module.c b/src/lib/ecore_imf/ecore_imf_module.c new file mode 100644 index 0000000000..cbdee47178 --- /dev/null +++ b/src/lib/ecore_imf/ecore_imf_module.c @@ -0,0 +1,212 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include +#include + +#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); + eina_array_free(module_list); + module_list = NULL; + } +} + +static Eina_Bool +_hash_module_available_get(const Eina_Hash *hash EINA_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_CB(_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 EINA_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_CB(_hash_ids_get), &l); + eina_iterator_free(it); + + return l; +} + +static Eina_Bool +_hash_ids_by_canvas_type_get(const Eina_Hash *hash EINA_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_CB(_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; +} diff --git a/src/lib/ecore_imf/ecore_imf_private.h b/src/lib/ecore_imf/ecore_imf_private.h new file mode 100644 index 0000000000..b4ff0f2ee0 --- /dev/null +++ b/src/lib/ecore_imf/ecore_imf_private.h @@ -0,0 +1,84 @@ +#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; +typedef struct _Ecore_IMF_Func_Node Ecore_IMF_Func_Node; + +struct _Ecore_IMF_Context +{ + ECORE_MAGIC; + const Ecore_IMF_Module *module; + const Ecore_IMF_Context_Class *klass; + void *data; + int input_mode; + void *window; + void *client_canvas; + Eina_Bool (*retrieve_surrounding_func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos); + void *retrieve_surrounding_data; + Eina_List *callbacks; + Ecore_IMF_Autocapital_Type autocapital_type; + Ecore_IMF_Input_Panel_Layout input_panel_layout; + Ecore_IMF_Input_Panel_Lang input_panel_lang; + Ecore_IMF_Input_Panel_Return_Key_Type input_panel_return_key_type; + Eina_Bool allow_prediction : 1; + Eina_Bool input_panel_enabled : 1; + Eina_Bool input_panel_return_key_disabled : 1; + Eina_Bool input_panel_caps_lock_mode : 1; +}; + +struct _Ecore_IMF_Module +{ + const Ecore_IMF_Context_Info *info; + Ecore_IMF_Context *(*create)(void); + Ecore_IMF_Context *(*exit)(void); +}; + +struct _Ecore_IMF_Func_Node +{ + void (*func) (); + const void *data; + Ecore_IMF_Callback_Type type; +}; + +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 diff --git a/src/lib/ecore_input/Ecore_Input.h b/src/lib/ecore_input/Ecore_Input.h new file mode 100644 index 0000000000..d1feb220e1 --- /dev/null +++ b/src/lib/ecore_input/Ecore_Input.h @@ -0,0 +1,236 @@ +#ifndef _ECORE_INPUT_H +#define _ECORE_INPUT_H + +#ifdef _WIN32 +# include +#else +# include +#endif + +#include + +#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 +#define ECORE_EVENT_LOCK_SHIFT 0x0300 +#define ECORE_EVENT_MODIFIER_ALTGR 0x0400 /**< @since 1.7 */ + + typedef uintptr_t Ecore_Window; + typedef struct _Ecore_Event_Key Ecore_Event_Key; + typedef struct _Ecore_Event_Mouse_Button Ecore_Event_Mouse_Button; + typedef struct _Ecore_Event_Mouse_Wheel Ecore_Event_Mouse_Wheel; + typedef struct _Ecore_Event_Mouse_Move Ecore_Event_Mouse_Move; + typedef struct _Ecore_Event_Mouse_IO Ecore_Event_Mouse_IO; + typedef struct _Ecore_Event_Modifiers Ecore_Event_Modifiers; + + typedef enum _Ecore_Event_Modifier + { + ECORE_NONE, + ECORE_SHIFT, + ECORE_CTRL, + ECORE_ALT, + ECORE_WIN, + ECORE_SCROLL, + ECORE_CAPS, + ECORE_MODE, /**< @since 1.7 */ + ECORE_LAST + } Ecore_Event_Modifier; + + typedef enum _Ecore_Event_Press + { + ECORE_DOWN, + ECORE_UP + } Ecore_Event_Press; + + typedef enum _Ecore_Event_IO + { + ECORE_IN, + ECORE_OUT + } Ecore_Event_IO; + + typedef enum _Ecore_Compose_State + { + ECORE_COMPOSE_NONE, + ECORE_COMPOSE_MIDDLE, + ECORE_COMPOSE_DONE + } Ecore_Compose_State; + + 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; + }; + + 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; + }; + + 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; + }; + + 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; + }; + + struct _Ecore_Event_Mouse_IO + { + Ecore_Window window; + Ecore_Window event_window; + + unsigned int timestamp; + unsigned int modifiers; + + int x; + int y; + }; + + 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); + + /** + * @since 1.7 + */ + EAPI Ecore_Compose_State ecore_compose_get(const Eina_List *seq, char **seqstr_ret); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/ecore_input/Ecore_Input_Evas.h b/src/lib/ecore_input/Ecore_Input_Evas.h new file mode 100644 index 0000000000..c97274eb0b --- /dev/null +++ b/src/lib/ecore_input/Ecore_Input_Evas.h @@ -0,0 +1,64 @@ +#ifndef _ECORE_INPUT_EVAS_H +#define _ECORE_INPUT_EVAS_H + +#include + +#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_EVAS_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); +typedef void (*Ecore_Event_Multi_Move_Cb)(void *window, int device, int x, int y, double radius, double radius_x, double radius_y, double pressure, double angle, double mx, double my, unsigned int timestamp); +typedef void (*Ecore_Event_Multi_Down_Cb)(void *window, int device, int x, int y, double radius, double radius_x, double radius_y, double pressure, double angle, double mx, double my, Evas_Button_Flags flags, unsigned int timestamp); +typedef void (*Ecore_Event_Multi_Up_Cb)(void *window, int device, int x, int y, double radius, double radius_x, double radius_y, double pressure, double angle, double mx, double my, Evas_Button_Flags flags, unsigned int timestamp); + +EAPI int ecore_event_evas_init(void); +EAPI int ecore_event_evas_shutdown(void); + +EAPI Eina_Bool ecore_event_evas_key_down(void *data, int type, void *event); +EAPI Eina_Bool ecore_event_evas_key_up(void *data, int type, void *event); +EAPI Eina_Bool ecore_event_evas_mouse_button_up(void *data, int type, void *event); +EAPI Eina_Bool ecore_event_evas_mouse_button_down(void *data, int type, void *event); +EAPI Eina_Bool ecore_event_evas_mouse_wheel(void *data, int type, void *event); +EAPI Eina_Bool ecore_event_evas_mouse_move(void *data, int type, void *event); +EAPI Eina_Bool ecore_event_evas_mouse_in(void *data, int type, void *event); +EAPI Eina_Bool 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, Ecore_Event_Multi_Move_Cb move_multi, Ecore_Event_Multi_Down_Cb down_multi, Ecore_Event_Multi_Up_Cb up_multi); +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 diff --git a/src/lib/ecore_input/ecore_input.c b/src/lib/ecore_input/ecore_input.c new file mode 100644 index 0000000000..8f4b1f9bc0 --- /dev/null +++ b/src/lib/ecore_input/ecore_input.c @@ -0,0 +1,127 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#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; + if (!ecore_init()) + { + _ecore_event_init_count--; + return 0; + } + + _ecore_input_log_dom = eina_log_domain_register + ("ecore_input", 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; + ecore_shutdown(); + 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 }, + { "ISO_Level3_Shift", ECORE_MODE, ECORE_EVENT_MODIFIER_ALTGR }, + { "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; +} diff --git a/src/lib/ecore_input/ecore_input_compose.c b/src/lib/ecore_input/ecore_input_compose.c new file mode 100644 index 0000000000..5335a7fe0c --- /dev/null +++ b/src/lib/ecore_input/ecore_input_compose.c @@ -0,0 +1,61 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "Ecore.h" +#include "ecore_private.h" + +#include "Ecore_Input.h" +#include "ecore_input_private.h" + +// some info on a big big big compose table +// http://cgit.freedesktop.org/xorg/lib/libX11/plain/nls/en_US.UTF-8/Compose.pre +// isolate compose tree into its own file - hand crafted into static const c +#include "ecore_input_compose.h" + +EAPI Ecore_Compose_State +ecore_compose_get(const Eina_List *seq, char **seqstr_ret) +{ + Comp *c, *cend; + Eina_List *l; + const char *s; + int i = 0; + + if (!seq) return ECORE_COMPOSE_NONE; + l = (Eina_List *)seq; + s = l->data; + cend = (Comp *)comp + (sizeof(comp) / sizeof(comp[0])); + for (c = (Comp *)comp; c->s && s;) + { + // doesn't match -> jump to next level entry + if (!(!strcmp(s, c->s))) + { + c += c->jump + 1; + if (c >= cend) + { + return ECORE_COMPOSE_NONE; + } + } + else + { + cend = c + c->jump; + // advance to next sequence member + l = l->next; + i++; + if (l) s = l->data; + else s = NULL; + c++; + // if advanced item jump is an endpoint - it's the string we want + if (c->jump == 0) + { + if (seqstr_ret) *seqstr_ret = strdup(c->s); + return ECORE_COMPOSE_DONE; + } + } + } + if (i == 0) return ECORE_COMPOSE_NONE; + return ECORE_COMPOSE_MIDDLE; +} diff --git a/src/lib/ecore_input/ecore_input_compose.h b/src/lib/ecore_input/ecore_input_compose.h new file mode 100644 index 0000000000..9fbfb76616 --- /dev/null +++ b/src/lib/ecore_input/ecore_input_compose.h @@ -0,0 +1,9895 @@ +typedef struct _Comp Comp; +struct _Comp { + const char *s; + int jump; +}; + +static const Comp comp[] = { + {"dead_breve", 124}, + {"dead_breve", 1}, + {"˘", 0}, + {"g", 1}, + {"ğ", 0}, + {"a", 1}, + {"ă", 0}, + {"Greek_IOTA", 1}, + {"Ῐ", 0}, + {"dead_grave", 4}, + {"a", 1}, + {"ằ", 0}, + {"A", 1}, + {"Ằ", 0}, + {"Greek_iota", 1}, + {"ῐ", 0}, + {"e", 1}, + {"ĕ", 0}, + {"agrave", 1}, + {"ằ", 0}, + {"o", 1}, + {"ŏ", 0}, + {"Greek_upsilon", 1}, + {"ῠ", 0}, + {"ahook", 1}, + {"ẳ", 0}, + {"dead_belowdot", 4}, + {"a", 1}, + {"ặ", 0}, + {"A", 1}, + {"Ặ", 0}, + {"space", 1}, + {"˘", 0}, + {"Cyrillic_I", 1}, + {"Й", 0}, + {"Multi_key", 15}, + {"exclam", 4}, + {"a", 1}, + {"ặ", 0}, + {"A", 1}, + {"Ặ", 0}, + {"cedilla", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"comma", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"i", 1}, + {"ĭ", 0}, + {"dead_tilde", 4}, + {"a", 1}, + {"ẵ", 0}, + {"A", 1}, + {"Ẵ", 0}, + {"Cyrillic_a", 1}, + {"ӑ", 0}, + {"Cyrillic_U", 1}, + {"Ў", 0}, + {"nobreakspace", 1}, + {"̆", 0}, + {"u", 1}, + {"ŭ", 0}, + {"G", 1}, + {"Ğ", 0}, + {"Greek_ALPHA", 1}, + {"Ᾰ", 0}, + {"atilde", 1}, + {"ẵ", 0}, + {"Cyrillic_ie", 1}, + {"ӗ", 0}, + {"E", 1}, + {"Ĕ", 0}, + {"Cyrillic_i", 1}, + {"й", 0}, + {"Atilde", 1}, + {"Ẵ", 0}, + {"Cyrillic_zhe", 1}, + {"ӂ", 0}, + {"Greek_alpha", 1}, + {"ᾰ", 0}, + {"Ahook", 1}, + {"Ẳ", 0}, + {"O", 1}, + {"Ŏ", 0}, + {"A", 1}, + {"Ă", 0}, + {"Cyrillic_A", 1}, + {"Ӑ", 0}, + {"dead_hook", 4}, + {"a", 1}, + {"ẳ", 0}, + {"A", 1}, + {"Ẳ", 0}, + {"Cyrillic_ZHE", 1}, + {"Ӂ", 0}, + {"Cyrillic_IE", 1}, + {"Ӗ", 0}, + {"Aacute", 1}, + {"Ắ", 0}, + {"dead_cedilla", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"aacute", 1}, + {"ắ", 0}, + {"dead_acute", 4}, + {"a", 1}, + {"ắ", 0}, + {"A", 1}, + {"Ắ", 0}, + {"Agrave", 1}, + {"Ằ", 0}, + {"I", 1}, + {"Ĭ", 0}, + {"U", 1}, + {"Ŭ", 0}, + {"Cyrillic_u", 1}, + {"ў", 0}, + {"Greek_UPSILON", 1}, + {"Ῠ", 0}, + {"dead_grave", 351}, + {"W", 1}, + {"Ẁ", 0}, + {"dead_breve", 4}, + {"a", 1}, + {"ằ", 0}, + {"A", 1}, + {"Ằ", 0}, + {"a", 1}, + {"à", 0}, + {"Greek_IOTA", 1}, + {"Ὶ", 0}, + {"dead_grave", 1}, + {"`", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ờ", 0}, + {"u", 1}, + {"ừ", 0}, + {"O", 1}, + {"Ờ", 0}, + {"U", 1}, + {"Ừ", 0}, + {"Greek_iota", 1}, + {"ὶ", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ầ", 0}, + {"e", 1}, + {"ề", 0}, + {"o", 1}, + {"ồ", 0}, + {"E", 1}, + {"Ề", 0}, + {"O", 1}, + {"Ồ", 0}, + {"A", 1}, + {"Ầ", 0}, + {"Greek_OMICRON", 1}, + {"Ὸ", 0}, + {"Acircumflex", 1}, + {"Ầ", 0}, + {"Cyrillic_er", 1}, + {"р̀", 0}, + {"e", 1}, + {"è", 0}, + {"o", 1}, + {"ò", 0}, + {"Udiaeresis", 1}, + {"Ǜ", 0}, + {"Greek_upsilon", 1}, + {"ὺ", 0}, + {"uhorn", 1}, + {"ừ", 0}, + {"space", 1}, + {"`", 0}, + {"dead_macron", 8}, + {"e", 1}, + {"ḕ", 0}, + {"o", 1}, + {"ṑ", 0}, + {"E", 1}, + {"Ḕ", 0}, + {"O", 1}, + {"Ṑ", 0}, + {"acircumflex", 1}, + {"ầ", 0}, + {"Ecircumflex", 1}, + {"Ề", 0}, + {"Cyrillic_I", 1}, + {"Ѝ", 0}, + {"y", 1}, + {"ỳ", 0}, + {"Multi_key", 115}, + {"b", 4}, + {"a", 1}, + {"ằ", 0}, + {"A", 1}, + {"Ằ", 0}, + {"parenright", 26}, + {"Greek_IOTA", 1}, + {"Ἲ", 0}, + {"Greek_iota", 1}, + {"ἲ", 0}, + {"Greek_OMICRON", 1}, + {"Ὂ", 0}, + {"Greek_upsilon", 1}, + {"ὒ", 0}, + {"Greek_epsilon", 1}, + {"ἒ", 0}, + {"Greek_ALPHA", 1}, + {"Ἂ", 0}, + {"Greek_omicron", 1}, + {"ὂ", 0}, + {"Greek_eta", 1}, + {"ἢ", 0}, + {"Greek_alpha", 1}, + {"ἂ", 0}, + {"Greek_ETA", 1}, + {"Ἢ", 0}, + {"Greek_EPSILON", 1}, + {"Ἒ", 0}, + {"Greek_omega", 1}, + {"ὢ", 0}, + {"Greek_OMEGA", 1}, + {"Ὢ", 0}, + {"quotedbl", 8}, + {"Greek_iota", 1}, + {"ῒ", 0}, + {"Greek_upsilon", 1}, + {"ῢ", 0}, + {"u", 1}, + {"ǜ", 0}, + {"U", 1}, + {"Ǜ", 0}, + {"plus", 8}, + {"o", 1}, + {"ờ", 0}, + {"u", 1}, + {"ừ", 0}, + {"O", 1}, + {"Ờ", 0}, + {"U", 1}, + {"Ừ", 0}, + {"underscore", 8}, + {"e", 1}, + {"ḕ", 0}, + {"o", 1}, + {"ṑ", 0}, + {"E", 1}, + {"Ḕ", 0}, + {"O", 1}, + {"Ṑ", 0}, + {"macron", 8}, + {"e", 1}, + {"ḕ", 0}, + {"o", 1}, + {"ṑ", 0}, + {"E", 1}, + {"Ḕ", 0}, + {"O", 1}, + {"Ṑ", 0}, + {"parenleft", 28}, + {"Greek_IOTA", 1}, + {"Ἳ", 0}, + {"Greek_iota", 1}, + {"ἳ", 0}, + {"Greek_OMICRON", 1}, + {"Ὃ", 0}, + {"Greek_upsilon", 1}, + {"ὓ", 0}, + {"Greek_epsilon", 1}, + {"ἓ", 0}, + {"Greek_ALPHA", 1}, + {"Ἃ", 0}, + {"Greek_omicron", 1}, + {"ὃ", 0}, + {"Greek_eta", 1}, + {"ἣ", 0}, + {"Greek_alpha", 1}, + {"ἃ", 0}, + {"Greek_ETA", 1}, + {"Ἣ", 0}, + {"Greek_EPSILON", 1}, + {"Ἓ", 0}, + {"Greek_omega", 1}, + {"ὣ", 0}, + {"Greek_OMEGA", 1}, + {"Ὣ", 0}, + {"Greek_UPSILON", 1}, + {"Ὓ", 0}, + {"U", 4}, + {"a", 1}, + {"ằ", 0}, + {"A", 1}, + {"Ằ", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ầ", 0}, + {"e", 1}, + {"ề", 0}, + {"o", 1}, + {"ồ", 0}, + {"E", 1}, + {"Ề", 0}, + {"O", 1}, + {"Ồ", 0}, + {"A", 1}, + {"Ầ", 0}, + {"Cyrillic_O", 1}, + {"О̀", 0}, + {"i", 1}, + {"ì", 0}, + {"n", 1}, + {"ǹ", 0}, + {"Cyrillic_a", 1}, + {"а̀", 0}, + {"Ohorn", 1}, + {"Ờ", 0}, + {"ohorn", 1}, + {"ờ", 0}, + {"Cyrillic_ER", 1}, + {"Р̀", 0}, + {"Greek_epsilon", 1}, + {"ὲ", 0}, + {"Cyrillic_U", 1}, + {"У̀", 0}, + {"nobreakspace", 1}, + {"̀", 0}, + {"V", 1}, + {"Ǜ", 0}, + {"Ocircumflex", 1}, + {"Ồ", 0}, + {"omacron", 1}, + {"ṑ", 0}, + {"ocircumflex", 1}, + {"ồ", 0}, + {"u", 1}, + {"ù", 0}, + {"Greek_ALPHA", 1}, + {"Ὰ", 0}, + {"Cyrillic_ie", 1}, + {"ѐ", 0}, + {"emacron", 1}, + {"ḕ", 0}, + {"E", 1}, + {"È", 0}, + {"Greek_iotadieresis", 1}, + {"ῒ", 0}, + {"Y", 1}, + {"Ỳ", 0}, + {"Cyrillic_i", 1}, + {"ѝ", 0}, + {"dead_dasia", 28}, + {"Greek_IOTA", 1}, + {"Ἳ", 0}, + {"Greek_iota", 1}, + {"ἳ", 0}, + {"Greek_OMICRON", 1}, + {"Ὃ", 0}, + {"Greek_upsilon", 1}, + {"ὓ", 0}, + {"Greek_epsilon", 1}, + {"ἓ", 0}, + {"Greek_ALPHA", 1}, + {"Ἃ", 0}, + {"Greek_omicron", 1}, + {"ὃ", 0}, + {"Greek_eta", 1}, + {"ἣ", 0}, + {"Greek_alpha", 1}, + {"ἃ", 0}, + {"Greek_ETA", 1}, + {"Ἣ", 0}, + {"Greek_EPSILON", 1}, + {"Ἓ", 0}, + {"Greek_omega", 1}, + {"ὣ", 0}, + {"Greek_OMEGA", 1}, + {"Ὣ", 0}, + {"Greek_UPSILON", 1}, + {"Ὓ", 0}, + {"Greek_upsilondieresis", 1}, + {"ῢ", 0}, + {"Greek_omicron", 1}, + {"ὸ", 0}, + {"Greek_eta", 1}, + {"ὴ", 0}, + {"Abreve", 1}, + {"Ằ", 0}, + {"dead_psili", 26}, + {"Greek_IOTA", 1}, + {"Ἲ", 0}, + {"Greek_iota", 1}, + {"ἲ", 0}, + {"Greek_OMICRON", 1}, + {"Ὂ", 0}, + {"Greek_upsilon", 1}, + {"ὒ", 0}, + {"Greek_epsilon", 1}, + {"ἒ", 0}, + {"Greek_ALPHA", 1}, + {"Ἂ", 0}, + {"Greek_omicron", 1}, + {"ὂ", 0}, + {"Greek_eta", 1}, + {"ἢ", 0}, + {"Greek_alpha", 1}, + {"ἂ", 0}, + {"Greek_ETA", 1}, + {"Ἢ", 0}, + {"Greek_EPSILON", 1}, + {"Ἒ", 0}, + {"Greek_omega", 1}, + {"ὢ", 0}, + {"Greek_OMEGA", 1}, + {"Ὢ", 0}, + {"Greek_alpha", 1}, + {"ὰ", 0}, + {"ecircumflex", 1}, + {"ề", 0}, + {"w", 1}, + {"ẁ", 0}, + {"Greek_ETA", 1}, + {"Ὴ", 0}, + {"Cyrillic_o", 1}, + {"о̀", 0}, + {"Emacron", 1}, + {"Ḕ", 0}, + {"v", 1}, + {"ǜ", 0}, + {"O", 1}, + {"Ò", 0}, + {"abreve", 1}, + {"ằ", 0}, + {"A", 1}, + {"À", 0}, + {"Greek_EPSILON", 1}, + {"Ὲ", 0}, + {"Cyrillic_A", 1}, + {"А̀", 0}, + {"Omacron", 1}, + {"Ṑ", 0}, + {"Cyrillic_IE", 1}, + {"Ѐ", 0}, + {"Greek_omega", 1}, + {"ὼ", 0}, + {"dead_diaeresis", 8}, + {"Greek_iota", 1}, + {"ῒ", 0}, + {"Greek_upsilon", 1}, + {"ῢ", 0}, + {"u", 1}, + {"ǜ", 0}, + {"U", 1}, + {"Ǜ", 0}, + {"Uhorn", 1}, + {"Ừ", 0}, + {"Greek_OMEGA", 1}, + {"Ὼ", 0}, + {"udiaeresis", 1}, + {"ǜ", 0}, + {"I", 1}, + {"Ì", 0}, + {"N", 1}, + {"Ǹ", 0}, + {"U", 1}, + {"Ù", 0}, + {"Cyrillic_u", 1}, + {"у̀", 0}, + {"Greek_UPSILON", 1}, + {"Ὺ", 0}, + {"dead_horn", 99}, + {"Uhook", 1}, + {"Ử", 0}, + {"Obelowdot", 1}, + {"Ợ", 0}, + {"Ograve", 1}, + {"Ờ", 0}, + {"dead_grave", 8}, + {"o", 1}, + {"ờ", 0}, + {"u", 1}, + {"ừ", 0}, + {"O", 1}, + {"Ờ", 0}, + {"U", 1}, + {"Ừ", 0}, + {"dead_horn", 1}, + {"̛", 0}, + {"Oacute", 1}, + {"Ớ", 0}, + {"ohook", 1}, + {"ở", 0}, + {"o", 1}, + {"ơ", 0}, + {"Utilde", 1}, + {"Ữ", 0}, + {"dead_belowdot", 8}, + {"o", 1}, + {"ợ", 0}, + {"u", 1}, + {"ự", 0}, + {"O", 1}, + {"Ợ", 0}, + {"U", 1}, + {"Ự", 0}, + {"space", 1}, + {"̛", 0}, + {"ubelowdot", 1}, + {"ự", 0}, + {"oacute", 1}, + {"ớ", 0}, + {"uhook", 1}, + {"ử", 0}, + {"dead_tilde", 8}, + {"o", 1}, + {"ỡ", 0}, + {"u", 1}, + {"ữ", 0}, + {"O", 1}, + {"Ỡ", 0}, + {"U", 1}, + {"Ữ", 0}, + {"Uacute", 1}, + {"Ứ", 0}, + {"Ugrave", 1}, + {"Ừ", 0}, + {"nobreakspace", 1}, + {"̛", 0}, + {"uacute", 1}, + {"ứ", 0}, + {"u", 1}, + {"ư", 0}, + {"otilde", 1}, + {"ỡ", 0}, + {"utilde", 1}, + {"ữ", 0}, + {"Otilde", 1}, + {"Ỡ", 0}, + {"ograve", 1}, + {"ờ", 0}, + {"Ohook", 1}, + {"Ở", 0}, + {"O", 1}, + {"Ơ", 0}, + {"Ubelowdot", 1}, + {"Ự", 0}, + {"dead_hook", 8}, + {"o", 1}, + {"ở", 0}, + {"u", 1}, + {"ử", 0}, + {"O", 1}, + {"Ở", 0}, + {"U", 1}, + {"Ử", 0}, + {"ugrave", 1}, + {"ừ", 0}, + {"obelowdot", 1}, + {"ợ", 0}, + {"dead_acute", 8}, + {"o", 1}, + {"ớ", 0}, + {"u", 1}, + {"ứ", 0}, + {"O", 1}, + {"Ớ", 0}, + {"U", 1}, + {"Ứ", 0}, + {"U", 1}, + {"Ư", 0}, + {"dead_circumflex", 335}, + {"minus", 1}, + {"⁻", 0}, + {"W", 1}, + {"Ŵ", 0}, + {"g", 1}, + {"ĝ", 0}, + {"a", 1}, + {"â", 0}, + {"Ograve", 1}, + {"Ồ", 0}, + {"dead_circumflex", 1}, + {"^", 0}, + {"dead_grave", 12}, + {"a", 1}, + {"ầ", 0}, + {"e", 1}, + {"ề", 0}, + {"o", 1}, + {"ồ", 0}, + {"E", 1}, + {"Ề", 0}, + {"O", 1}, + {"Ồ", 0}, + {"A", 1}, + {"Ầ", 0}, + {"Ehook", 1}, + {"Ể", 0}, + {"1", 1}, + {"¹", 0}, + {"C", 1}, + {"Ĉ", 0}, + {"KP_4", 1}, + {"⁴", 0}, + {"Oacute", 1}, + {"Ố", 0}, + {"Cyrillic_er", 1}, + {"р̂", 0}, + {"ohook", 1}, + {"ổ", 0}, + {"e", 1}, + {"ê", 0}, + {"agrave", 1}, + {"ầ", 0}, + {"KP_6", 1}, + {"⁶", 0}, + {"o", 1}, + {"ô", 0}, + {"ahook", 1}, + {"ẩ", 0}, + {"dead_belowdot", 12}, + {"a", 1}, + {"ậ", 0}, + {"e", 1}, + {"ệ", 0}, + {"o", 1}, + {"ộ", 0}, + {"E", 1}, + {"Ệ", 0}, + {"O", 1}, + {"Ộ", 0}, + {"A", 1}, + {"Ậ", 0}, + {"space", 1}, + {"^", 0}, + {"KP_8", 1}, + {"⁸", 0}, + {"Etilde", 1}, + {"Ễ", 0}, + {"Cyrillic_I", 1}, + {"И̂", 0}, + {"y", 1}, + {"ŷ", 0}, + {"Multi_key", 83}, + {"exclam", 12}, + {"a", 1}, + {"ậ", 0}, + {"e", 1}, + {"ệ", 0}, + {"o", 1}, + {"ộ", 0}, + {"E", 1}, + {"Ệ", 0}, + {"O", 1}, + {"Ộ", 0}, + {"A", 1}, + {"Ậ", 0}, + {"t", 4}, + {"M", 1}, + {"™", 0}, + {"m", 1}, + {"™", 0}, + {"underbar", 24}, + {"a", 1}, + {"ª", 0}, + {"o", 1}, + {"º", 0}, + {"l", 1}, + {"ˡ", 0}, + {"y", 1}, + {"ʸ", 0}, + {"i", 1}, + {"ⁱ", 0}, + {"n", 1}, + {"ⁿ", 0}, + {"j", 1}, + {"ʲ", 0}, + {"x", 1}, + {"ˣ", 0}, + {"w", 1}, + {"ʷ", 0}, + {"r", 1}, + {"ʳ", 0}, + {"s", 1}, + {"ˢ", 0}, + {"h", 1}, + {"ʰ", 0}, + {"S", 4}, + {"M", 1}, + {"℠", 0}, + {"m", 1}, + {"℠", 0}, + {"underscore", 24}, + {"a", 1}, + {"ª", 0}, + {"o", 1}, + {"º", 0}, + {"l", 1}, + {"ˡ", 0}, + {"y", 1}, + {"ʸ", 0}, + {"i", 1}, + {"ⁱ", 0}, + {"n", 1}, + {"ⁿ", 0}, + {"j", 1}, + {"ʲ", 0}, + {"x", 1}, + {"ˣ", 0}, + {"w", 1}, + {"ʷ", 0}, + {"r", 1}, + {"ʳ", 0}, + {"s", 1}, + {"ˢ", 0}, + {"h", 1}, + {"ʰ", 0}, + {"s", 4}, + {"M", 1}, + {"℠", 0}, + {"m", 1}, + {"℠", 0}, + {"T", 4}, + {"M", 1}, + {"™", 0}, + {"m", 1}, + {"™", 0}, + {"oacute", 1}, + {"ố", 0}, + {"Cyrillic_O", 1}, + {"О̂", 0}, + {"i", 1}, + {"î", 0}, + {"KP_9", 1}, + {"⁹", 0}, + {"equal", 1}, + {"⁼", 0}, + {"KP_Space", 1}, + {"²", 0}, + {"dead_tilde", 12}, + {"a", 1}, + {"ẫ", 0}, + {"e", 1}, + {"ễ", 0}, + {"o", 1}, + {"ỗ", 0}, + {"E", 1}, + {"Ễ", 0}, + {"O", 1}, + {"Ỗ", 0}, + {"A", 1}, + {"Ẫ", 0}, + {"7", 1}, + {"⁷", 0}, + {"Cyrillic_a", 1}, + {"а̂", 0}, + {"j", 1}, + {"ĵ", 0}, + {"parenright", 1}, + {"⁾", 0}, + {"Eacute", 1}, + {"Ế", 0}, + {"Cyrillic_ER", 1}, + {"Р̂", 0}, + {"KP_7", 1}, + {"⁷", 0}, + {"Cyrillic_U", 1}, + {"У̂", 0}, + {"nobreakspace", 1}, + {"̂", 0}, + {"u", 1}, + {"û", 0}, + {"z", 1}, + {"ẑ", 0}, + {"G", 1}, + {"Ĝ", 0}, + {"otilde", 1}, + {"ỗ", 0}, + {"H", 1}, + {"Ĥ", 0}, + {"8", 1}, + {"⁸", 0}, + {"KP_1", 1}, + {"¹", 0}, + {"atilde", 1}, + {"ẫ", 0}, + {"3", 1}, + {"³", 0}, + {"Cyrillic_ie", 1}, + {"е̂", 0}, + {"E", 1}, + {"Ê", 0}, + {"S", 1}, + {"Ŝ", 0}, + {"2", 1}, + {"²", 0}, + {"Y", 1}, + {"Ŷ", 0}, + {"Cyrillic_i", 1}, + {"и̂", 0}, + {"Otilde", 1}, + {"Ỗ", 0}, + {"Atilde", 1}, + {"Ẫ", 0}, + {"egrave", 1}, + {"ề", 0}, + {"ograve", 1}, + {"ồ", 0}, + {"plus", 1}, + {"⁺", 0}, + {"6", 1}, + {"⁶", 0}, + {"Ahook", 1}, + {"Ẩ", 0}, + {"w", 1}, + {"ŵ", 0}, + {"Ohook", 1}, + {"Ổ", 0}, + {"Cyrillic_o", 1}, + {"о̂", 0}, + {"4", 1}, + {"⁴", 0}, + {"KP_3", 1}, + {"³", 0}, + {"eacute", 1}, + {"ế", 0}, + {"J", 1}, + {"Ĵ", 0}, + {"O", 1}, + {"Ô", 0}, + {"s", 1}, + {"ŝ", 0}, + {"Z", 1}, + {"Ẑ", 0}, + {"KP_0", 1}, + {"⁰", 0}, + {"A", 1}, + {"Â", 0}, + {"c", 1}, + {"ĉ", 0}, + {"KP_Add", 1}, + {"⁺", 0}, + {"KP_2", 1}, + {"²", 0}, + {"Cyrillic_A", 1}, + {"А̂", 0}, + {"dead_hook", 12}, + {"a", 1}, + {"ẩ", 0}, + {"e", 1}, + {"ể", 0}, + {"o", 1}, + {"ổ", 0}, + {"E", 1}, + {"Ể", 0}, + {"O", 1}, + {"Ổ", 0}, + {"A", 1}, + {"Ẩ", 0}, + {"5", 1}, + {"⁵", 0}, + {"KP_5", 1}, + {"⁵", 0}, + {"9", 1}, + {"⁹", 0}, + {"Cyrillic_IE", 1}, + {"Е̂", 0}, + {"Egrave", 1}, + {"Ề", 0}, + {"0", 1}, + {"⁰", 0}, + {"Aacute", 1}, + {"Ấ", 0}, + {"etilde", 1}, + {"ễ", 0}, + {"aacute", 1}, + {"ấ", 0}, + {"dead_acute", 12}, + {"a", 1}, + {"ấ", 0}, + {"e", 1}, + {"ế", 0}, + {"o", 1}, + {"ố", 0}, + {"E", 1}, + {"Ế", 0}, + {"O", 1}, + {"Ố", 0}, + {"A", 1}, + {"Ấ", 0}, + {"Agrave", 1}, + {"Ầ", 0}, + {"parenleft", 1}, + {"⁽", 0}, + {"h", 1}, + {"ĥ", 0}, + {"I", 1}, + {"Î", 0}, + {"ehook", 1}, + {"ể", 0}, + {"U", 1}, + {"Û", 0}, + {"Cyrillic_u", 1}, + {"у̂", 0}, + {"KP_Equal", 1}, + {"⁼", 0}, + {"dead_currency", 103}, + {"W", 1}, + {"₩", 0}, + {"g", 1}, + {"₲", 0}, + {"a", 1}, + {"؋", 0}, + {"dead_currency", 1}, + {"¤", 0}, + {"C", 1}, + {"₡", 0}, + {"e", 1}, + {"€", 0}, + {"F", 1}, + {"₣", 0}, + {"o", 1}, + {"௹", 0}, + {"l", 1}, + {"£", 0}, + {"t", 1}, + {"৳", 0}, + {"thorn", 1}, + {"৲", 0}, + {"space", 1}, + {"¤", 0}, + {"y", 1}, + {"¥", 0}, + {"b", 1}, + {"฿", 0}, + {"i", 1}, + {"﷼", 0}, + {"k", 1}, + {"₭", 0}, + {"n", 1}, + {"₦", 0}, + {"ccedilla", 1}, + {"₵", 0}, + {"nobreakspace", 1}, + {"¤", 0}, + {"u", 1}, + {"元", 0}, + {"G", 1}, + {"₲", 0}, + {"H", 1}, + {"₴", 0}, + {"E", 1}, + {"₠", 0}, + {"S", 1}, + {"$", 0}, + {"Y", 1}, + {"円", 0}, + {"f", 1}, + {"ƒ", 0}, + {"d", 1}, + {"₫", 0}, + {"D", 1}, + {"₯", 0}, + {"w", 1}, + {"₩", 0}, + {"p", 1}, + {"₰", 0}, + {"P", 1}, + {"₧", 0}, + {"M", 1}, + {"ℳ", 0}, + {"O", 1}, + {"૱", 0}, + {"m", 1}, + {"₥", 0}, + {"r", 1}, + {"₢", 0}, + {"s", 1}, + {"₪", 0}, + {"A", 1}, + {"₳", 0}, + {"R", 1}, + {"₨", 0}, + {"THORN", 1}, + {"৲", 0}, + {"c", 1}, + {"¢", 0}, + {"L", 1}, + {"₤", 0}, + {"T", 1}, + {"₮", 0}, + {"Ccedilla", 1}, + {"₵", 0}, + {"K", 1}, + {"₭", 0}, + {"B", 1}, + {"₱", 0}, + {"dead_cedilla", 4}, + {"C", 1}, + {"₵", 0}, + {"c", 1}, + {"₵", 0}, + {"h", 1}, + {"₴", 0}, + {"I", 1}, + {"៛", 0}, + {"N", 1}, + {"₦", 0}, + {"U", 1}, + {"圓", 0}, + {"dead_belowdiaeresis", 7}, + {"u", 1}, + {"ṳ", 0}, + {"dead_diaeresis", 2}, + {"equal", 1}, + {"⩷", 0}, + {"U", 1}, + {"Ṳ", 0}, + {"dead_belowdot", 167}, + {"minus", 1}, + {"⨪", 0}, + {"W", 1}, + {"Ẉ", 0}, + {"dead_breve", 4}, + {"a", 1}, + {"ặ", 0}, + {"A", 1}, + {"Ặ", 0}, + {"a", 1}, + {"ạ", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ậ", 0}, + {"e", 1}, + {"ệ", 0}, + {"o", 1}, + {"ộ", 0}, + {"E", 1}, + {"Ệ", 0}, + {"O", 1}, + {"Ộ", 0}, + {"A", 1}, + {"Ậ", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ợ", 0}, + {"u", 1}, + {"ự", 0}, + {"O", 1}, + {"Ợ", 0}, + {"U", 1}, + {"Ự", 0}, + {"Acircumflex", 1}, + {"Ậ", 0}, + {"e", 1}, + {"ẹ", 0}, + {"o", 1}, + {"ọ", 0}, + {"l", 1}, + {"ḷ", 0}, + {"t", 1}, + {"ṭ", 0}, + {"dead_belowdot", 1}, + {"̣", 0}, + {"uhorn", 1}, + {"ự", 0}, + {"space", 1}, + {"̣", 0}, + {"dead_macron", 8}, + {"l", 1}, + {"ḹ", 0}, + {"r", 1}, + {"ṝ", 0}, + {"R", 1}, + {"Ṝ", 0}, + {"L", 1}, + {"Ḹ", 0}, + {"acircumflex", 1}, + {"ậ", 0}, + {"Ecircumflex", 1}, + {"Ệ", 0}, + {"y", 1}, + {"ỵ", 0}, + {"b", 1}, + {"ḅ", 0}, + {"Multi_key", 9}, + {"plus", 8}, + {"o", 1}, + {"ợ", 0}, + {"u", 1}, + {"ự", 0}, + {"O", 1}, + {"Ợ", 0}, + {"U", 1}, + {"Ự", 0}, + {"i", 1}, + {"ị", 0}, + {"k", 1}, + {"ḳ", 0}, + {"n", 1}, + {"ṇ", 0}, + {"equal", 1}, + {"⩦", 0}, + {"Ohorn", 1}, + {"Ợ", 0}, + {"ohorn", 1}, + {"ợ", 0}, + {"sabovedot", 1}, + {"ṩ", 0}, + {"nobreakspace", 1}, + {"̣", 0}, + {"V", 1}, + {"Ṿ", 0}, + {"Ocircumflex", 1}, + {"Ộ", 0}, + {"ocircumflex", 1}, + {"ộ", 0}, + {"u", 1}, + {"ụ", 0}, + {"z", 1}, + {"ẓ", 0}, + {"H", 1}, + {"Ḥ", 0}, + {"E", 1}, + {"Ẹ", 0}, + {"S", 1}, + {"Ṣ", 0}, + {"Y", 1}, + {"Ỵ", 0}, + {"d", 1}, + {"ḍ", 0}, + {"D", 1}, + {"Ḍ", 0}, + {"Abreve", 1}, + {"Ặ", 0}, + {"plus", 1}, + {"⨥", 0}, + {"ecircumflex", 1}, + {"ệ", 0}, + {"dead_abovedot", 4}, + {"S", 1}, + {"Ṩ", 0}, + {"s", 1}, + {"ṩ", 0}, + {"w", 1}, + {"ẉ", 0}, + {"v", 1}, + {"ṿ", 0}, + {"M", 1}, + {"Ṃ", 0}, + {"O", 1}, + {"Ọ", 0}, + {"abreve", 1}, + {"ặ", 0}, + {"m", 1}, + {"ṃ", 0}, + {"r", 1}, + {"ṛ", 0}, + {"s", 1}, + {"ṣ", 0}, + {"Z", 1}, + {"Ẓ", 0}, + {"A", 1}, + {"Ạ", 0}, + {"R", 1}, + {"Ṛ", 0}, + {"L", 1}, + {"Ḷ", 0}, + {"T", 1}, + {"Ṭ", 0}, + {"K", 1}, + {"Ḳ", 0}, + {"B", 1}, + {"Ḅ", 0}, + {"Sabovedot", 1}, + {"Ṩ", 0}, + {"Uhorn", 1}, + {"Ự", 0}, + {"h", 1}, + {"ḥ", 0}, + {"I", 1}, + {"Ị", 0}, + {"N", 1}, + {"Ṇ", 0}, + {"U", 1}, + {"Ụ", 0}, + {"dead_macron", 224}, + {"adiaeresis", 1}, + {"ǟ", 0}, + {"g", 1}, + {"ḡ", 0}, + {"a", 1}, + {"ā", 0}, + {"Greek_IOTA", 1}, + {"Ῑ", 0}, + {"Ograve", 1}, + {"Ṑ", 0}, + {"dead_grave", 8}, + {"e", 1}, + {"ḕ", 0}, + {"o", 1}, + {"ṑ", 0}, + {"E", 1}, + {"Ḕ", 0}, + {"O", 1}, + {"Ṑ", 0}, + {"Greek_iota", 1}, + {"ῑ", 0}, + {"Oacute", 1}, + {"Ṓ", 0}, + {"Cyrillic_er", 1}, + {"р̄", 0}, + {"e", 1}, + {"ē", 0}, + {"o", 1}, + {"ō", 0}, + {"Udiaeresis", 1}, + {"Ǖ", 0}, + {"Greek_upsilon", 1}, + {"ῡ", 0}, + {"dead_belowdot", 8}, + {"l", 1}, + {"ḹ", 0}, + {"r", 1}, + {"ṝ", 0}, + {"R", 1}, + {"Ṝ", 0}, + {"L", 1}, + {"Ḹ", 0}, + {"space", 1}, + {"¯", 0}, + {"dead_macron", 1}, + {"¯", 0}, + {"Cyrillic_I", 1}, + {"Ӣ", 0}, + {"y", 1}, + {"ȳ", 0}, + {"Multi_key", 41}, + {"period", 8}, + {"a", 1}, + {"ǡ", 0}, + {"o", 1}, + {"ȱ", 0}, + {"O", 1}, + {"Ȱ", 0}, + {"A", 1}, + {"Ǡ", 0}, + {"exclam", 8}, + {"l", 1}, + {"ḹ", 0}, + {"r", 1}, + {"ṝ", 0}, + {"R", 1}, + {"Ṝ", 0}, + {"L", 1}, + {"Ḹ", 0}, + {"quotedbl", 12}, + {"a", 1}, + {"ǟ", 0}, + {"o", 1}, + {"ȫ", 0}, + {"u", 1}, + {"ǖ", 0}, + {"O", 1}, + {"Ȫ", 0}, + {"A", 1}, + {"Ǟ", 0}, + {"U", 1}, + {"Ǖ", 0}, + {"asciitilde", 4}, + {"o", 1}, + {"ȭ", 0}, + {"O", 1}, + {"Ȭ", 0}, + {"semicolon", 4}, + {"o", 1}, + {"ǭ", 0}, + {"O", 1}, + {"Ǭ", 0}, + {"oacute", 1}, + {"ṓ", 0}, + {"Cyrillic_O", 1}, + {"О̄", 0}, + {"i", 1}, + {"ī", 0}, + {"dead_tilde", 4}, + {"o", 1}, + {"ȭ", 0}, + {"O", 1}, + {"Ȭ", 0}, + {"Cyrillic_a", 1}, + {"а̄", 0}, + {"Eacute", 1}, + {"Ḗ", 0}, + {"Cyrillic_ER", 1}, + {"Р̄", 0}, + {"Cyrillic_U", 1}, + {"Ӯ", 0}, + {"nobreakspace", 1}, + {"̄", 0}, + {"V", 1}, + {"Ǖ", 0}, + {"AE", 1}, + {"Ǣ", 0}, + {"u", 1}, + {"ū", 0}, + {"G", 1}, + {"Ḡ", 0}, + {"Greek_ALPHA", 1}, + {"Ᾱ", 0}, + {"otilde", 1}, + {"ȭ", 0}, + {"Cyrillic_ie", 1}, + {"е̄", 0}, + {"E", 1}, + {"Ē", 0}, + {"Y", 1}, + {"Ȳ", 0}, + {"Cyrillic_i", 1}, + {"ӣ", 0}, + {"dead_ogonek", 4}, + {"o", 1}, + {"ǭ", 0}, + {"O", 1}, + {"Ǭ", 0}, + {"odiaeresis", 1}, + {"ȫ", 0}, + {"Otilde", 1}, + {"Ȭ", 0}, + {"egrave", 1}, + {"ḕ", 0}, + {"dead_greek", 12}, + {"a", 1}, + {"ᾱ", 0}, + {"i", 1}, + {"ῑ", 0}, + {"u", 1}, + {"ῡ", 0}, + {"A", 1}, + {"Ᾱ", 0}, + {"I", 1}, + {"Ῑ", 0}, + {"U", 1}, + {"Ῡ", 0}, + {"ograve", 1}, + {"ṑ", 0}, + {"Greek_alpha", 1}, + {"ᾱ", 0}, + {"dead_abovedot", 8}, + {"a", 1}, + {"ǡ", 0}, + {"o", 1}, + {"ȱ", 0}, + {"O", 1}, + {"Ȱ", 0}, + {"A", 1}, + {"Ǡ", 0}, + {"Cyrillic_o", 1}, + {"о̄", 0}, + {"eacute", 1}, + {"ḗ", 0}, + {"v", 1}, + {"ǖ", 0}, + {"O", 1}, + {"Ō", 0}, + {"A", 1}, + {"Ā", 0}, + {"Odiaeresis", 1}, + {"Ȫ", 0}, + {"Cyrillic_A", 1}, + {"А̄", 0}, + {"Cyrillic_IE", 1}, + {"Е̄", 0}, + {"Egrave", 1}, + {"Ḕ", 0}, + {"dead_diaeresis", 12}, + {"a", 1}, + {"ǟ", 0}, + {"o", 1}, + {"ȫ", 0}, + {"u", 1}, + {"ǖ", 0}, + {"O", 1}, + {"Ȫ", 0}, + {"A", 1}, + {"Ǟ", 0}, + {"U", 1}, + {"Ǖ", 0}, + {"Adiaeresis", 1}, + {"Ǟ", 0}, + {"dead_acute", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"udiaeresis", 1}, + {"ǖ", 0}, + {"I", 1}, + {"Ī", 0}, + {"U", 1}, + {"Ū", 0}, + {"Cyrillic_u", 1}, + {"ӯ", 0}, + {"ae", 1}, + {"ǣ", 0}, + {"Greek_UPSILON", 1}, + {"Ῡ", 0}, + {"dead_doublegrave", 24}, + {"Cyrillic_er", 1}, + {"р̏", 0}, + {"Cyrillic_I", 1}, + {"И̏", 0}, + {"Cyrillic_O", 1}, + {"О̏", 0}, + {"Cyrillic_a", 1}, + {"а̏", 0}, + {"Cyrillic_ER", 1}, + {"Р̏", 0}, + {"Cyrillic_U", 1}, + {"У̏", 0}, + {"Cyrillic_ie", 1}, + {"е̏", 0}, + {"Cyrillic_i", 1}, + {"и̏", 0}, + {"Cyrillic_o", 1}, + {"о̏", 0}, + {"Cyrillic_A", 1}, + {"А̏", 0}, + {"Cyrillic_IE", 1}, + {"Е̏", 0}, + {"Cyrillic_u", 1}, + {"у̏", 0}, + {"Multi_key", 5833}, + {"backslash", 5}, + {"minus", 1}, + {"⍀", 0}, + {"o", 2}, + {"slash", 1}, + {"🙌", 0}, + {"minus", 59}, + {"backslash", 1}, + {"⍀", 0}, + {"minus", 6}, + {"minus", 1}, + {"—", 0}, + {"period", 1}, + {"–", 0}, + {"space", 1}, + {"­", 0}, + {"a", 1}, + {"ā", 0}, + {"e", 1}, + {"ē", 0}, + {"o", 1}, + {"ō", 0}, + {"l", 1}, + {"£", 0}, + {"space", 1}, + {"~", 0}, + {"y", 1}, + {"¥", 0}, + {"i", 1}, + {"ī", 0}, + {"parenright", 1}, + {"}", 0}, + {"u", 1}, + {"ū", 0}, + {"E", 1}, + {"Ē", 0}, + {"Y", 1}, + {"¥", 0}, + {"d", 1}, + {"đ", 0}, + {"D", 1}, + {"Đ", 0}, + {"plus", 1}, + {"±", 0}, + {"colon", 1}, + {"÷", 0}, + {"O", 1}, + {"Ō", 0}, + {"A", 1}, + {"Ā", 0}, + {"L", 1}, + {"£", 0}, + {"comma", 1}, + {"¬", 0}, + {"slash", 1}, + {"⌿", 0}, + {"greater", 1}, + {"→", 0}, + {"parenleft", 1}, + {"{", 0}, + {"I", 1}, + {"Ī", 0}, + {"U", 1}, + {"Ū", 0}, + {"asciicircum", 1}, + {"¯", 0}, + {"period", 130}, + {"minus", 1}, + {"·", 0}, + {"period", 1}, + {"…", 0}, + {"W", 1}, + {"Ẇ", 0}, + {"g", 1}, + {"ġ", 0}, + {"a", 1}, + {"ȧ", 0}, + {"C", 1}, + {"Ċ", 0}, + {"exclam", 4}, + {"S", 1}, + {"Ṩ", 0}, + {"s", 1}, + {"ṩ", 0}, + {"less", 1}, + {"‹", 0}, + {"e", 1}, + {"ė", 0}, + {"F", 1}, + {"Ḟ", 0}, + {"o", 1}, + {"ȯ", 0}, + {"t", 1}, + {"ṫ", 0}, + {"dead_belowdot", 4}, + {"S", 1}, + {"Ṩ", 0}, + {"s", 1}, + {"ṩ", 0}, + {"y", 1}, + {"ẏ", 0}, + {"b", 1}, + {"ḃ", 0}, + {"i", 1}, + {"ı", 0}, + {"n", 1}, + {"ṅ", 0}, + {"equal", 1}, + {"•", 0}, + {"dead_caron", 4}, + {"S", 1}, + {"Ṧ", 0}, + {"s", 1}, + {"ṧ", 0}, + {"x", 1}, + {"ẋ", 0}, + {"z", 1}, + {"ż", 0}, + {"G", 1}, + {"Ġ", 0}, + {"Sacute", 1}, + {"Ṥ", 0}, + {"H", 1}, + {"Ḣ", 0}, + {"E", 1}, + {"Ė", 0}, + {"S", 1}, + {"Ṡ", 0}, + {"Y", 1}, + {"Ẏ", 0}, + {"scaron", 1}, + {"ṧ", 0}, + {"f", 1}, + {"ḟ", 0}, + {"d", 1}, + {"ḋ", 0}, + {"Scaron", 1}, + {"Ṧ", 0}, + {"D", 1}, + {"Ḋ", 0}, + {"acute", 4}, + {"S", 1}, + {"Ṥ", 0}, + {"s", 1}, + {"ṥ", 0}, + {"w", 1}, + {"ẇ", 0}, + {"p", 1}, + {"ṗ", 0}, + {"P", 1}, + {"Ṗ", 0}, + {"apostrophe", 4}, + {"S", 1}, + {"Ṥ", 0}, + {"s", 1}, + {"ṥ", 0}, + {"M", 1}, + {"Ṁ", 0}, + {"O", 1}, + {"Ȯ", 0}, + {"m", 1}, + {"ṁ", 0}, + {"r", 1}, + {"ṙ", 0}, + {"s", 1}, + {"ṡ", 0}, + {"Z", 1}, + {"Ż", 0}, + {"sacute", 1}, + {"ṥ", 0}, + {"A", 1}, + {"Ȧ", 0}, + {"R", 1}, + {"Ṙ", 0}, + {"c", 1}, + {"ċ", 0}, + {"T", 1}, + {"Ṫ", 0}, + {"greater", 1}, + {"›", 0}, + {"B", 1}, + {"Ḃ", 0}, + {"dead_acute", 4}, + {"S", 1}, + {"Ṥ", 0}, + {"s", 1}, + {"ṥ", 0}, + {"X", 1}, + {"Ẋ", 0}, + {"h", 1}, + {"ḣ", 0}, + {"I", 1}, + {"İ", 0}, + {"N", 1}, + {"Ṅ", 0}, + {"asciicircum", 1}, + {"·", 0}, + {"W", 4}, + {"equal", 1}, + {"₩", 0}, + {"asciicircum", 1}, + {"Ŵ", 0}, + {"g", 10}, + {"period", 1}, + {"ġ", 0}, + {"breve", 1}, + {"ğ", 0}, + {"comma", 1}, + {"ģ", 0}, + {"parenleft", 1}, + {"ğ", 0}, + {"U", 1}, + {"ğ", 0}, + {"a", 30}, + {"minus", 1}, + {"ā", 0}, + {"a", 1}, + {"å", 0}, + {"e", 1}, + {"æ", 0}, + {"diaeresis", 1}, + {"ä", 0}, + {"quotedbl", 1}, + {"ä", 0}, + {"acute", 1}, + {"á", 0}, + {"underscore", 1}, + {"ā", 0}, + {"apostrophe", 1}, + {"á", 0}, + {"asterisk", 1}, + {"å", 0}, + {"comma", 1}, + {"ą", 0}, + {"asciitilde", 1}, + {"ã", 0}, + {"greater", 1}, + {"â", 0}, + {"parenleft", 1}, + {"ă", 0}, + {"grave", 1}, + {"à", 0}, + {"asciicircum", 1}, + {"â", 0}, + {"Greek_IOTA", 4}, + {"quotedbl", 1}, + {"Ϊ", 0}, + {"apostrophe", 1}, + {"Ί", 0}, + {"Greek_iota", 485}, + {"dead_grave", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾊ", 0}, + {"Greek_eta", 1}, + {"ᾒ", 0}, + {"Greek_alpha", 1}, + {"ᾂ", 0}, + {"Greek_ETA", 1}, + {"ᾚ", 0}, + {"Greek_omega", 1}, + {"ᾢ", 0}, + {"Greek_OMEGA", 1}, + {"ᾪ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾋ", 0}, + {"Greek_eta", 1}, + {"ᾓ", 0}, + {"Greek_alpha", 1}, + {"ᾃ", 0}, + {"Greek_ETA", 1}, + {"ᾛ", 0}, + {"Greek_omega", 1}, + {"ᾣ", 0}, + {"Greek_OMEGA", 1}, + {"ᾫ", 0}, + {"Greek_eta", 1}, + {"ῂ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾊ", 0}, + {"Greek_eta", 1}, + {"ᾒ", 0}, + {"Greek_alpha", 1}, + {"ᾂ", 0}, + {"Greek_ETA", 1}, + {"ᾚ", 0}, + {"Greek_omega", 1}, + {"ᾢ", 0}, + {"Greek_OMEGA", 1}, + {"ᾪ", 0}, + {"Greek_alpha", 1}, + {"ᾲ", 0}, + {"Greek_omega", 1}, + {"ῲ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾋ", 0}, + {"Greek_eta", 1}, + {"ᾓ", 0}, + {"Greek_alpha", 1}, + {"ᾃ", 0}, + {"Greek_ETA", 1}, + {"ᾛ", 0}, + {"Greek_omega", 1}, + {"ᾣ", 0}, + {"Greek_OMEGA", 1}, + {"ᾫ", 0}, + {"dead_tilde", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾎ", 0}, + {"Greek_eta", 1}, + {"ᾖ", 0}, + {"Greek_alpha", 1}, + {"ᾆ", 0}, + {"Greek_ETA", 1}, + {"ᾞ", 0}, + {"Greek_omega", 1}, + {"ᾦ", 0}, + {"Greek_OMEGA", 1}, + {"ᾮ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾏ", 0}, + {"Greek_eta", 1}, + {"ᾗ", 0}, + {"Greek_alpha", 1}, + {"ᾇ", 0}, + {"Greek_ETA", 1}, + {"ᾟ", 0}, + {"Greek_omega", 1}, + {"ᾧ", 0}, + {"Greek_OMEGA", 1}, + {"ᾯ", 0}, + {"Greek_eta", 1}, + {"ῇ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾎ", 0}, + {"Greek_eta", 1}, + {"ᾖ", 0}, + {"Greek_alpha", 1}, + {"ᾆ", 0}, + {"Greek_ETA", 1}, + {"ᾞ", 0}, + {"Greek_omega", 1}, + {"ᾦ", 0}, + {"Greek_OMEGA", 1}, + {"ᾮ", 0}, + {"Greek_alpha", 1}, + {"ᾷ", 0}, + {"Greek_omega", 1}, + {"ῷ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾏ", 0}, + {"Greek_eta", 1}, + {"ᾗ", 0}, + {"Greek_alpha", 1}, + {"ᾇ", 0}, + {"Greek_ETA", 1}, + {"ᾟ", 0}, + {"Greek_omega", 1}, + {"ᾧ", 0}, + {"Greek_OMEGA", 1}, + {"ᾯ", 0}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾈ", 0}, + {"Greek_eta", 1}, + {"ᾐ", 0}, + {"Greek_alpha", 1}, + {"ᾀ", 0}, + {"Greek_ETA", 1}, + {"ᾘ", 0}, + {"Greek_omega", 1}, + {"ᾠ", 0}, + {"Greek_OMEGA", 1}, + {"ᾨ", 0}, + {"Greek_ALPHA", 1}, + {"ᾼ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾉ", 0}, + {"Greek_eta", 1}, + {"ᾑ", 0}, + {"Greek_alpha", 1}, + {"ᾁ", 0}, + {"Greek_ETA", 1}, + {"ᾙ", 0}, + {"Greek_omega", 1}, + {"ᾡ", 0}, + {"Greek_OMEGA", 1}, + {"ᾩ", 0}, + {"Greek_eta", 1}, + {"ῃ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾈ", 0}, + {"Greek_eta", 1}, + {"ᾐ", 0}, + {"Greek_alpha", 1}, + {"ᾀ", 0}, + {"Greek_ETA", 1}, + {"ᾘ", 0}, + {"Greek_omega", 1}, + {"ᾠ", 0}, + {"Greek_OMEGA", 1}, + {"ᾨ", 0}, + {"quotedbl", 1}, + {"ϊ", 0}, + {"Greek_alpha", 1}, + {"ᾳ", 0}, + {"acute", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_eta", 1}, + {"ῄ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"Greek_alpha", 1}, + {"ᾴ", 0}, + {"Greek_omega", 1}, + {"ῴ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_ETA", 1}, + {"ῌ", 0}, + {"apostrophe", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_eta", 1}, + {"ῄ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"Greek_alpha", 1}, + {"ᾴ", 0}, + {"Greek_omega", 1}, + {"ῴ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_omegaaccent", 1}, + {"ῴ", 0}, + {"asciitilde", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾎ", 0}, + {"Greek_eta", 1}, + {"ᾖ", 0}, + {"Greek_alpha", 1}, + {"ᾆ", 0}, + {"Greek_ETA", 1}, + {"ᾞ", 0}, + {"Greek_omega", 1}, + {"ᾦ", 0}, + {"Greek_OMEGA", 1}, + {"ᾮ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾏ", 0}, + {"Greek_eta", 1}, + {"ᾗ", 0}, + {"Greek_alpha", 1}, + {"ᾇ", 0}, + {"Greek_ETA", 1}, + {"ᾟ", 0}, + {"Greek_omega", 1}, + {"ᾧ", 0}, + {"Greek_OMEGA", 1}, + {"ᾯ", 0}, + {"Greek_eta", 1}, + {"ῇ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾎ", 0}, + {"Greek_eta", 1}, + {"ᾖ", 0}, + {"Greek_alpha", 1}, + {"ᾆ", 0}, + {"Greek_ETA", 1}, + {"ᾞ", 0}, + {"Greek_omega", 1}, + {"ᾦ", 0}, + {"Greek_OMEGA", 1}, + {"ᾮ", 0}, + {"Greek_alpha", 1}, + {"ᾷ", 0}, + {"Greek_omega", 1}, + {"ῷ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾏ", 0}, + {"Greek_eta", 1}, + {"ᾗ", 0}, + {"Greek_alpha", 1}, + {"ᾇ", 0}, + {"Greek_ETA", 1}, + {"ᾟ", 0}, + {"Greek_omega", 1}, + {"ᾧ", 0}, + {"Greek_OMEGA", 1}, + {"ᾯ", 0}, + {"Greek_omega", 1}, + {"ῳ", 0}, + {"Greek_OMEGA", 1}, + {"ῼ", 0}, + {"dead_acute", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_eta", 1}, + {"ῄ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"Greek_alpha", 1}, + {"ᾴ", 0}, + {"Greek_omega", 1}, + {"ῴ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_alphaaccent", 1}, + {"ᾴ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾉ", 0}, + {"Greek_eta", 1}, + {"ᾑ", 0}, + {"Greek_alpha", 1}, + {"ᾁ", 0}, + {"Greek_ETA", 1}, + {"ᾙ", 0}, + {"Greek_omega", 1}, + {"ᾡ", 0}, + {"Greek_OMEGA", 1}, + {"ᾩ", 0}, + {"grave", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾊ", 0}, + {"Greek_eta", 1}, + {"ᾒ", 0}, + {"Greek_alpha", 1}, + {"ᾂ", 0}, + {"Greek_ETA", 1}, + {"ᾚ", 0}, + {"Greek_omega", 1}, + {"ᾢ", 0}, + {"Greek_OMEGA", 1}, + {"ᾪ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾋ", 0}, + {"Greek_eta", 1}, + {"ᾓ", 0}, + {"Greek_alpha", 1}, + {"ᾃ", 0}, + {"Greek_ETA", 1}, + {"ᾛ", 0}, + {"Greek_omega", 1}, + {"ᾣ", 0}, + {"Greek_OMEGA", 1}, + {"ᾫ", 0}, + {"Greek_eta", 1}, + {"ῂ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾊ", 0}, + {"Greek_eta", 1}, + {"ᾒ", 0}, + {"Greek_alpha", 1}, + {"ᾂ", 0}, + {"Greek_ETA", 1}, + {"ᾚ", 0}, + {"Greek_omega", 1}, + {"ᾢ", 0}, + {"Greek_OMEGA", 1}, + {"ᾪ", 0}, + {"Greek_alpha", 1}, + {"ᾲ", 0}, + {"Greek_omega", 1}, + {"ῲ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾋ", 0}, + {"Greek_eta", 1}, + {"ᾓ", 0}, + {"Greek_alpha", 1}, + {"ᾃ", 0}, + {"Greek_ETA", 1}, + {"ᾛ", 0}, + {"Greek_omega", 1}, + {"ᾣ", 0}, + {"Greek_OMEGA", 1}, + {"ᾫ", 0}, + {"Greek_etaaccent", 1}, + {"ῄ", 0}, + {"1", 21}, + {"1", 2}, + {"0", 1}, + {"⅒", 0}, + {"7", 1}, + {"⅐", 0}, + {"8", 1}, + {"⅛", 0}, + {"3", 1}, + {"⅓", 0}, + {"2", 1}, + {"½", 0}, + {"6", 1}, + {"⅙", 0}, + {"4", 1}, + {"¼", 0}, + {"5", 1}, + {"⅕", 0}, + {"9", 1}, + {"⅑", 0}, + {"asciicircum", 1}, + {"¹", 0}, + {"Greek_OMICRON", 2}, + {"apostrophe", 1}, + {"Ό", 0}, + {"C", 26}, + {"period", 1}, + {"Ċ", 0}, + {"C", 3}, + {"C", 2}, + {"P", 1}, + {"☭", 0}, + {"less", 1}, + {"Č", 0}, + {"o", 1}, + {"©", 0}, + {"equal", 1}, + {"€", 0}, + {"E", 1}, + {"₠", 0}, + {"apostrophe", 1}, + {"Ć", 0}, + {"O", 1}, + {"©", 0}, + {"r", 1}, + {"₢", 0}, + {"bar", 1}, + {"¢", 0}, + {"comma", 1}, + {"Ç", 0}, + {"slash", 1}, + {"₡", 0}, + {"exclam", 108}, + {"W", 1}, + {"Ẉ", 0}, + {"a", 1}, + {"ạ", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ợ", 0}, + {"u", 1}, + {"ự", 0}, + {"O", 1}, + {"Ợ", 0}, + {"U", 1}, + {"Ự", 0}, + {"exclam", 1}, + {"¡", 0}, + {"e", 1}, + {"ẹ", 0}, + {"o", 1}, + {"ọ", 0}, + {"l", 1}, + {"ḷ", 0}, + {"t", 1}, + {"ṭ", 0}, + {"uhorn", 1}, + {"ự", 0}, + {"y", 1}, + {"ỵ", 0}, + {"b", 1}, + {"ḅ", 0}, + {"i", 1}, + {"ị", 0}, + {"k", 1}, + {"ḳ", 0}, + {"n", 1}, + {"ṇ", 0}, + {"Ohorn", 1}, + {"Ợ", 0}, + {"ohorn", 1}, + {"ợ", 0}, + {"V", 1}, + {"Ṿ", 0}, + {"u", 1}, + {"ụ", 0}, + {"z", 1}, + {"ẓ", 0}, + {"H", 1}, + {"Ḥ", 0}, + {"E", 1}, + {"Ẹ", 0}, + {"S", 1}, + {"Ṣ", 0}, + {"Y", 1}, + {"Ỵ", 0}, + {"d", 1}, + {"ḍ", 0}, + {"D", 1}, + {"Ḍ", 0}, + {"plus", 8}, + {"o", 1}, + {"ợ", 0}, + {"u", 1}, + {"ự", 0}, + {"O", 1}, + {"Ợ", 0}, + {"U", 1}, + {"Ự", 0}, + {"w", 1}, + {"ẉ", 0}, + {"v", 1}, + {"ṿ", 0}, + {"question", 1}, + {"‽", 0}, + {"M", 1}, + {"Ṃ", 0}, + {"O", 1}, + {"Ọ", 0}, + {"m", 1}, + {"ṃ", 0}, + {"r", 1}, + {"ṛ", 0}, + {"s", 1}, + {"ṣ", 0}, + {"Z", 1}, + {"Ẓ", 0}, + {"A", 1}, + {"Ạ", 0}, + {"R", 1}, + {"Ṛ", 0}, + {"L", 1}, + {"Ḷ", 0}, + {"T", 1}, + {"Ṭ", 0}, + {"K", 1}, + {"Ḳ", 0}, + {"B", 1}, + {"Ḅ", 0}, + {"Uhorn", 1}, + {"Ự", 0}, + {"h", 1}, + {"ḥ", 0}, + {"I", 1}, + {"Ị", 0}, + {"N", 1}, + {"Ṇ", 0}, + {"U", 1}, + {"Ụ", 0}, + {"asciicircum", 1}, + {"¦", 0}, + {"less", 56}, + {"minus", 1}, + {"←", 0}, + {"C", 1}, + {"Č", 0}, + {"less", 1}, + {"«", 0}, + {"e", 1}, + {"ě", 0}, + {"l", 1}, + {"ľ", 0}, + {"t", 1}, + {"ť", 0}, + {"space", 1}, + {"ˇ", 0}, + {"n", 1}, + {"ň", 0}, + {"equal", 1}, + {"≤", 0}, + {"z", 1}, + {"ž", 0}, + {"3", 1}, + {"♥", 0}, + {"E", 1}, + {"Ě", 0}, + {"S", 1}, + {"Š", 0}, + {"d", 1}, + {"ď", 0}, + {"D", 1}, + {"Ď", 0}, + {"quotedbl", 1}, + {"“", 0}, + {"underscore", 1}, + {"≤", 0}, + {"apostrophe", 1}, + {"‘", 0}, + {"r", 1}, + {"ř", 0}, + {"s", 1}, + {"š", 0}, + {"Z", 1}, + {"Ž", 0}, + {"R", 1}, + {"Ř", 0}, + {"c", 1}, + {"č", 0}, + {"L", 1}, + {"Ľ", 0}, + {"T", 1}, + {"Ť", 0}, + {"slash", 1}, + {"\\", 0}, + {"greater", 1}, + {"⋄", 0}, + {"N", 1}, + {"Ň", 0}, + {"KP_Divide", 46}, + {"g", 1}, + {"ǥ", 0}, + {"o", 1}, + {"ø", 0}, + {"l", 1}, + {"ł", 0}, + {"t", 1}, + {"ŧ", 0}, + {"b", 1}, + {"ƀ", 0}, + {"i", 1}, + {"ɨ", 0}, + {"Cyrillic_GHE", 1}, + {"Ғ", 0}, + {"leftarrow", 1}, + {"↚", 0}, + {"Cyrillic_KA", 1}, + {"Ҟ", 0}, + {"rightarrow", 1}, + {"↛", 0}, + {"z", 1}, + {"ƶ", 0}, + {"G", 1}, + {"Ǥ", 0}, + {"H", 1}, + {"Ħ", 0}, + {"d", 1}, + {"đ", 0}, + {"Cyrillic_ka", 1}, + {"ҟ", 0}, + {"D", 1}, + {"Đ", 0}, + {"O", 1}, + {"Ø", 0}, + {"Z", 1}, + {"Ƶ", 0}, + {"L", 1}, + {"Ł", 0}, + {"T", 1}, + {"Ŧ", 0}, + {"Cyrillic_ghe", 1}, + {"ғ", 0}, + {"h", 1}, + {"ħ", 0}, + {"I", 1}, + {"Ɨ", 0}, + {"F", 8}, + {"period", 1}, + {"Ḟ", 0}, + {"l", 1}, + {"ffl", 0}, + {"i", 1}, + {"ffi", 0}, + {"r", 1}, + {"₣", 0}, + {"e", 28}, + {"minus", 1}, + {"ē", 0}, + {"period", 1}, + {"ė", 0}, + {"less", 1}, + {"ě", 0}, + {"e", 1}, + {"ə", 0}, + {"diaeresis", 1}, + {"ë", 0}, + {"equal", 1}, + {"€", 0}, + {"quotedbl", 1}, + {"ë", 0}, + {"acute", 1}, + {"é", 0}, + {"underscore", 1}, + {"ē", 0}, + {"apostrophe", 1}, + {"é", 0}, + {"comma", 1}, + {"ę", 0}, + {"greater", 1}, + {"ê", 0}, + {"grave", 1}, + {"è", 0}, + {"asciicircum", 1}, + {"ê", 0}, + {"o", 52}, + {"minus", 1}, + {"ō", 0}, + {"a", 1}, + {"å", 0}, + {"C", 1}, + {"©", 0}, + {"e", 1}, + {"œ", 0}, + {"o", 1}, + {"°", 0}, + {"diaeresis", 1}, + {"ö", 0}, + {"y", 1}, + {"ẙ", 0}, + {"x", 1}, + {"¤", 0}, + {"u", 1}, + {"ů", 0}, + {"quotedbl", 1}, + {"ö", 0}, + {"acute", 1}, + {"ó", 0}, + {"w", 1}, + {"ẘ", 0}, + {"underscore", 1}, + {"ō", 0}, + {"apostrophe", 1}, + {"ó", 0}, + {"r", 1}, + {"®", 0}, + {"s", 1}, + {"§", 0}, + {"A", 1}, + {"Å", 0}, + {"R", 1}, + {"®", 0}, + {"c", 1}, + {"©", 0}, + {"asciitilde", 1}, + {"õ", 0}, + {"slash", 1}, + {"ø", 0}, + {"greater", 1}, + {"ô", 0}, + {"X", 1}, + {"¤", 0}, + {"grave", 1}, + {"ò", 0}, + {"U", 1}, + {"Ů", 0}, + {"asciicircum", 1}, + {"ô", 0}, + {"l", 12}, + {"minus", 1}, + {"£", 0}, + {"less", 1}, + {"ľ", 0}, + {"v", 1}, + {"|", 0}, + {"apostrophe", 1}, + {"ĺ", 0}, + {"comma", 1}, + {"ļ", 0}, + {"slash", 1}, + {"ł", 0}, + {"Greek_upsilon", 4}, + {"quotedbl", 1}, + {"ϋ", 0}, + {"apostrophe", 1}, + {"ύ", 0}, + {"t", 16}, + {"minus", 1}, + {"ŧ", 0}, + {"period", 1}, + {"ṫ", 0}, + {"less", 1}, + {"ť", 0}, + {"M", 1}, + {"™", 0}, + {"m", 1}, + {"™", 0}, + {"comma", 1}, + {"ţ", 0}, + {"slash", 1}, + {"ŧ", 0}, + {"h", 1}, + {"þ", 0}, + {"diaeresis", 42}, + {"a", 1}, + {"ä", 0}, + {"dead_grave", 1}, + {"῭", 0}, + {"e", 1}, + {"ë", 0}, + {"o", 1}, + {"ö", 0}, + {"y", 1}, + {"ÿ", 0}, + {"i", 1}, + {"ï", 0}, + {"dead_tilde", 1}, + {"῁", 0}, + {"u", 1}, + {"ü", 0}, + {"E", 1}, + {"Ë", 0}, + {"Y", 1}, + {"Ÿ", 0}, + {"acute", 1}, + {"΅", 0}, + {"apostrophe", 1}, + {"΅", 0}, + {"O", 1}, + {"Ö", 0}, + {"asterisk", 1}, + {"⍣", 0}, + {"A", 1}, + {"Ä", 0}, + {"asciitilde", 1}, + {"῁", 0}, + {"greater", 1}, + {"⍩", 0}, + {"dead_acute", 1}, + {"΅", 0}, + {"I", 1}, + {"Ï", 0}, + {"grave", 1}, + {"῭", 0}, + {"U", 1}, + {"Ü", 0}, + {"space", 22}, + {"minus", 1}, + {"~", 0}, + {"period", 1}, + {" ", 0}, + {"less", 1}, + {"ˇ", 0}, + {"space", 1}, + {" ", 0}, + {"apostrophe", 1}, + {"'", 0}, + {"comma", 1}, + {"¸", 0}, + {"asciitilde", 1}, + {"~", 0}, + {"greater", 1}, + {"^", 0}, + {"parenleft", 1}, + {"˘", 0}, + {"grave", 1}, + {"`", 0}, + {"asciicircum", 1}, + {"^", 0}, + {"percent", 2}, + {"o", 1}, + {"‰", 0}, + {"y", 14}, + {"minus", 1}, + {"¥", 0}, + {"diaeresis", 1}, + {"ÿ", 0}, + {"equal", 1}, + {"¥", 0}, + {"quotedbl", 1}, + {"ÿ", 0}, + {"acute", 1}, + {"ý", 0}, + {"apostrophe", 1}, + {"ý", 0}, + {"asciicircum", 1}, + {"ŷ", 0}, + {"b", 83}, + {"period", 1}, + {"ḃ", 0}, + {"g", 1}, + {"ğ", 0}, + {"a", 1}, + {"ă", 0}, + {"Greek_IOTA", 1}, + {"Ῐ", 0}, + {"Greek_iota", 1}, + {"ῐ", 0}, + {"exclam", 4}, + {"a", 1}, + {"ặ", 0}, + {"A", 1}, + {"Ặ", 0}, + {"e", 1}, + {"ĕ", 0}, + {"o", 1}, + {"ŏ", 0}, + {"Greek_upsilon", 1}, + {"ῠ", 0}, + {"dead_belowdot", 4}, + {"a", 1}, + {"ặ", 0}, + {"A", 1}, + {"Ặ", 0}, + {"Cyrillic_I", 1}, + {"Й", 0}, + {"i", 1}, + {"ĭ", 0}, + {"Cyrillic_a", 1}, + {"ӑ", 0}, + {"Cyrillic_U", 1}, + {"Ў", 0}, + {"u", 1}, + {"ŭ", 0}, + {"G", 1}, + {"Ğ", 0}, + {"Greek_ALPHA", 1}, + {"Ᾰ", 0}, + {"Cyrillic_ie", 1}, + {"ӗ", 0}, + {"E", 1}, + {"Ĕ", 0}, + {"Cyrillic_i", 1}, + {"й", 0}, + {"Cyrillic_zhe", 1}, + {"ӂ", 0}, + {"cedilla", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"Greek_alpha", 1}, + {"ᾰ", 0}, + {"O", 1}, + {"Ŏ", 0}, + {"A", 1}, + {"Ă", 0}, + {"Cyrillic_A", 1}, + {"Ӑ", 0}, + {"comma", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"Cyrillic_ZHE", 1}, + {"Ӂ", 0}, + {"Cyrillic_IE", 1}, + {"Ӗ", 0}, + {"dead_cedilla", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"I", 1}, + {"Ĭ", 0}, + {"U", 1}, + {"Ŭ", 0}, + {"Cyrillic_u", 1}, + {"ў", 0}, + {"Greek_UPSILON", 1}, + {"Ῠ", 0}, + {"i", 28}, + {"minus", 1}, + {"ī", 0}, + {"period", 1}, + {"ı", 0}, + {"diaeresis", 1}, + {"ï", 0}, + {"j", 1}, + {"ij", 0}, + {"quotedbl", 1}, + {"ï", 0}, + {"acute", 1}, + {"í", 0}, + {"underscore", 1}, + {"ī", 0}, + {"apostrophe", 1}, + {"í", 0}, + {"comma", 1}, + {"į", 0}, + {"asciitilde", 1}, + {"ĩ", 0}, + {"greater", 1}, + {"î", 0}, + {"semicolon", 1}, + {"į", 0}, + {"grave", 1}, + {"ì", 0}, + {"asciicircum", 1}, + {"î", 0}, + {"k", 4}, + {"k", 1}, + {"ĸ", 0}, + {"comma", 1}, + {"ķ", 0}, + {"n", 10}, + {"g", 1}, + {"ŋ", 0}, + {"less", 1}, + {"ň", 0}, + {"apostrophe", 1}, + {"ń", 0}, + {"comma", 1}, + {"ņ", 0}, + {"asciitilde", 1}, + {"ñ", 0}, + {"equal", 40}, + {"W", 1}, + {"₩", 0}, + {"C", 1}, + {"€", 0}, + {"e", 1}, + {"€", 0}, + {"o", 1}, + {"ő", 0}, + {"y", 1}, + {"¥", 0}, + {"Cyrillic_U", 1}, + {"Ӳ", 0}, + {"u", 1}, + {"ű", 0}, + {"E", 1}, + {"€", 0}, + {"Y", 1}, + {"¥", 0}, + {"d", 1}, + {"₫", 0}, + {"underscore", 1}, + {"≡", 0}, + {"O", 1}, + {"Ő", 0}, + {"Cyrillic_ES", 1}, + {"€", 0}, + {"c", 1}, + {"€", 0}, + {"L", 1}, + {"₤", 0}, + {"slash", 1}, + {"≠", 0}, + {"Cyrillic_IE", 1}, + {"€", 0}, + {"N", 1}, + {"₦", 0}, + {"U", 1}, + {"Ű", 0}, + {"Cyrillic_u", 1}, + {"ӳ", 0}, + {"7", 2}, + {"8", 1}, + {"⅞", 0}, + {"parenright", 32}, + {"minus", 1}, + {"}", 0}, + {"Greek_IOTA", 1}, + {"Ἰ", 0}, + {"Greek_iota", 1}, + {"ἰ", 0}, + {"Greek_OMICRON", 1}, + {"Ὀ", 0}, + {"Greek_upsilon", 1}, + {"ὐ", 0}, + {"parenright", 1}, + {"]", 0}, + {"Greek_epsilon", 1}, + {"ἐ", 0}, + {"Greek_ALPHA", 1}, + {"Ἀ", 0}, + {"Greek_omicron", 1}, + {"ὀ", 0}, + {"Greek_eta", 1}, + {"ἠ", 0}, + {"Greek_rho", 1}, + {"ῤ", 0}, + {"Greek_alpha", 1}, + {"ἀ", 0}, + {"Greek_ETA", 1}, + {"Ἠ", 0}, + {"Greek_EPSILON", 1}, + {"Ἐ", 0}, + {"Greek_omega", 1}, + {"ὠ", 0}, + {"Greek_OMEGA", 1}, + {"Ὠ", 0}, + {"x", 6}, + {"o", 1}, + {"¤", 0}, + {"x", 1}, + {"×", 0}, + {"O", 1}, + {"¤", 0}, + {"Greek_epsilon", 2}, + {"apostrophe", 1}, + {"έ", 0}, + {"braceleft", 2}, + {"braceright", 1}, + {"∅", 0}, + {"underbar", 54}, + {"1", 1}, + {"₁", 0}, + {"KP_4", 1}, + {"₄", 0}, + {"KP_6", 1}, + {"₆", 0}, + {"KP_8", 1}, + {"₈", 0}, + {"KP_9", 1}, + {"₉", 0}, + {"equal", 1}, + {"₌", 0}, + {"KP_Space", 1}, + {"₂", 0}, + {"7", 1}, + {"₇", 0}, + {"parenright", 1}, + {"₎", 0}, + {"KP_7", 1}, + {"₇", 0}, + {"8", 1}, + {"₈", 0}, + {"KP_1", 1}, + {"₁", 0}, + {"3", 1}, + {"₃", 0}, + {"2", 1}, + {"₂", 0}, + {"plus", 1}, + {"₊", 0}, + {"6", 1}, + {"₆", 0}, + {"4", 1}, + {"₄", 0}, + {"KP_3", 1}, + {"₃", 0}, + {"KP_0", 1}, + {"₀", 0}, + {"KP_Add", 1}, + {"₊", 0}, + {"KP_2", 1}, + {"₂", 0}, + {"5", 1}, + {"₅", 0}, + {"KP_5", 1}, + {"₅", 0}, + {"9", 1}, + {"₉", 0}, + {"0", 1}, + {"₀", 0}, + {"parenleft", 1}, + {"₍", 0}, + {"KP_Equal", 1}, + {"₌", 0}, + {"V", 2}, + {"L", 1}, + {"|", 0}, + {"u", 28}, + {"minus", 1}, + {"ū", 0}, + {"diaeresis", 1}, + {"ü", 0}, + {"u", 1}, + {"ŭ", 0}, + {"quotedbl", 1}, + {"ü", 0}, + {"acute", 1}, + {"ú", 0}, + {"underscore", 1}, + {"ū", 0}, + {"apostrophe", 1}, + {"ú", 0}, + {"asterisk", 1}, + {"ů", 0}, + {"comma", 1}, + {"ų", 0}, + {"asciitilde", 1}, + {"ũ", 0}, + {"slash", 1}, + {"µ", 0}, + {"greater", 1}, + {"û", 0}, + {"grave", 1}, + {"ù", 0}, + {"asciicircum", 1}, + {"û", 0}, + {"breve", 4}, + {"g", 1}, + {"ğ", 0}, + {"G", 1}, + {"Ğ", 0}, + {"z", 6}, + {"period", 1}, + {"ż", 0}, + {"less", 1}, + {"ž", 0}, + {"apostrophe", 1}, + {"ź", 0}, + {"G", 10}, + {"period", 1}, + {"Ġ", 0}, + {"breve", 1}, + {"Ğ", 0}, + {"comma", 1}, + {"Ģ", 0}, + {"parenleft", 1}, + {"Ğ", 0}, + {"U", 1}, + {"Ğ", 0}, + {"Greek_ALPHA", 2}, + {"apostrophe", 1}, + {"Ά", 0}, + {"bracketleft", 2}, + {"bracketright", 1}, + {"⌷", 0}, + {"H", 2}, + {"comma", 1}, + {"Ḩ", 0}, + {"8", 2}, + {"8", 1}, + {"∞", 0}, + {"3", 8}, + {"8", 1}, + {"⅜", 0}, + {"4", 1}, + {"¾", 0}, + {"5", 1}, + {"⅗", 0}, + {"asciicircum", 1}, + {"³", 0}, + {"E", 26}, + {"minus", 1}, + {"Ē", 0}, + {"period", 1}, + {"Ė", 0}, + {"less", 1}, + {"Ě", 0}, + {"diaeresis", 1}, + {"Ë", 0}, + {"equal", 1}, + {"€", 0}, + {"quotedbl", 1}, + {"Ë", 0}, + {"acute", 1}, + {"É", 0}, + {"underscore", 1}, + {"Ē", 0}, + {"apostrophe", 1}, + {"É", 0}, + {"comma", 1}, + {"Ę", 0}, + {"greater", 1}, + {"Ê", 0}, + {"grave", 1}, + {"È", 0}, + {"asciicircum", 1}, + {"Ê", 0}, + {"S", 18}, + {"period", 1}, + {"Ṡ", 0}, + {"exclam", 1}, + {"§", 0}, + {"less", 1}, + {"Š", 0}, + {"S", 1}, + {"ẞ", 0}, + {"apostrophe", 1}, + {"Ś", 0}, + {"M", 1}, + {"℠", 0}, + {"O", 1}, + {"§", 0}, + {"m", 1}, + {"℠", 0}, + {"comma", 1}, + {"Ş", 0}, + {"2", 6}, + {"3", 1}, + {"⅔", 0}, + {"5", 1}, + {"⅖", 0}, + {"asciicircum", 1}, + {"²", 0}, + {"Y", 14}, + {"minus", 1}, + {"¥", 0}, + {"diaeresis", 1}, + {"Ÿ", 0}, + {"equal", 1}, + {"¥", 0}, + {"quotedbl", 1}, + {"Ÿ", 0}, + {"acute", 1}, + {"Ý", 0}, + {"apostrophe", 1}, + {"Ý", 0}, + {"asciicircum", 1}, + {"Ŷ", 0}, + {"f", 12}, + {"period", 1}, + {"ḟ", 0}, + {"l", 1}, + {"fl", 0}, + {"i", 1}, + {"fi", 0}, + {"S", 1}, + {"ſ", 0}, + {"f", 1}, + {"ff", 0}, + {"s", 1}, + {"ſ", 0}, + {"Greek_omicron", 2}, + {"apostrophe", 1}, + {"ό", 0}, + {"Greek_eta", 2}, + {"apostrophe", 1}, + {"ή", 0}, + {"d", 14}, + {"minus", 1}, + {"đ", 0}, + {"period", 1}, + {"ḋ", 0}, + {"less", 1}, + {"ď", 0}, + {"i", 1}, + {"⌀", 0}, + {"equal", 1}, + {"₫", 0}, + {"comma", 1}, + {"ḑ", 0}, + {"h", 1}, + {"ð", 0}, + {"D", 10}, + {"minus", 1}, + {"Đ", 0}, + {"period", 1}, + {"Ḋ", 0}, + {"less", 1}, + {"Ď", 0}, + {"H", 1}, + {"Ð", 0}, + {"comma", 1}, + {"Ḑ", 0}, + {"quotedbl", 137}, + {"W", 1}, + {"Ẅ", 0}, + {"a", 1}, + {"ä", 0}, + {"Greek_IOTA", 1}, + {"Ϊ", 0}, + {"Greek_iota", 1}, + {"ϊ", 0}, + {"less", 1}, + {"“", 0}, + {"Umacron", 1}, + {"Ṻ", 0}, + {"Cyrillic_ZE", 1}, + {"Ӟ", 0}, + {"e", 1}, + {"ë", 0}, + {"o", 1}, + {"ö", 0}, + {"Cyrillic_ze", 1}, + {"ӟ", 0}, + {"t", 1}, + {"ẗ", 0}, + {"Greek_upsilon", 1}, + {"ϋ", 0}, + {"dead_macron", 4}, + {"u", 1}, + {"ṻ", 0}, + {"U", 1}, + {"Ṻ", 0}, + {"Cyrillic_I", 1}, + {"Ӥ", 0}, + {"y", 1}, + {"ÿ", 0}, + {"Cyrillic_O", 1}, + {"Ӧ", 0}, + {"i", 1}, + {"ï", 0}, + {"Ukrainian_I", 1}, + {"Ї", 0}, + {"dead_tilde", 4}, + {"o", 1}, + {"ṏ", 0}, + {"O", 1}, + {"Ṏ", 0}, + {"Cyrillic_che", 1}, + {"ӵ", 0}, + {"Cyrillic_a", 1}, + {"ӓ", 0}, + {"x", 1}, + {"ẍ", 0}, + {"Cyrillic_U", 1}, + {"Ӱ", 0}, + {"u", 1}, + {"ü", 0}, + {"otilde", 1}, + {"ṏ", 0}, + {"H", 1}, + {"Ḧ", 0}, + {"Cyrillic_YERU", 1}, + {"Ӹ", 0}, + {"Cyrillic_ie", 1}, + {"ё", 0}, + {"E", 1}, + {"Ë", 0}, + {"Y", 1}, + {"Ÿ", 0}, + {"Cyrillic_i", 1}, + {"ӥ", 0}, + {"Otilde", 1}, + {"Ṏ", 0}, + {"Cyrillic_zhe", 1}, + {"ӝ", 0}, + {"quotedbl", 1}, + {"¨", 0}, + {"umacron", 1}, + {"ṻ", 0}, + {"Cyrillic_yeru", 1}, + {"ӹ", 0}, + {"acute", 1}, + {"̈́", 0}, + {"w", 1}, + {"ẅ", 0}, + {"Cyrillic_CHE", 1}, + {"Ӵ", 0}, + {"Cyrillic_o", 1}, + {"ӧ", 0}, + {"Ukrainian_i", 1}, + {"ї", 0}, + {"Cyrillic_E", 1}, + {"Ӭ", 0}, + {"underscore", 4}, + {"u", 1}, + {"ṻ", 0}, + {"U", 1}, + {"Ṻ", 0}, + {"apostrophe", 1}, + {"̈́", 0}, + {"O", 1}, + {"Ö", 0}, + {"macron", 4}, + {"u", 1}, + {"ṻ", 0}, + {"U", 1}, + {"Ṻ", 0}, + {"A", 1}, + {"Ä", 0}, + {"Cyrillic_A", 1}, + {"Ӓ", 0}, + {"comma", 1}, + {"„", 0}, + {"asciitilde", 4}, + {"o", 1}, + {"ṏ", 0}, + {"O", 1}, + {"Ṏ", 0}, + {"greater", 1}, + {"”", 0}, + {"Cyrillic_ZHE", 1}, + {"Ӝ", 0}, + {"Cyrillic_IE", 1}, + {"Ё", 0}, + {"Cyrillic_e", 1}, + {"ӭ", 0}, + {"dead_acute", 1}, + {"̈́", 0}, + {"X", 1}, + {"Ẍ", 0}, + {"h", 1}, + {"ḧ", 0}, + {"I", 1}, + {"Ï", 0}, + {"U", 1}, + {"Ü", 0}, + {"Cyrillic_u", 1}, + {"ӱ", 0}, + {"Greek_UPSILON", 1}, + {"Ϋ", 0}, + {"plus", 12}, + {"minus", 1}, + {"±", 0}, + {"o", 1}, + {"ơ", 0}, + {"u", 1}, + {"ư", 0}, + {"plus", 1}, + {"#", 0}, + {"O", 1}, + {"Ơ", 0}, + {"U", 1}, + {"Ư", 0}, + {"cedilla", 44}, + {"g", 1}, + {"ģ", 0}, + {"C", 1}, + {"Ç", 0}, + {"e", 1}, + {"ȩ", 0}, + {"l", 1}, + {"ļ", 0}, + {"t", 1}, + {"ţ", 0}, + {"k", 1}, + {"ķ", 0}, + {"n", 1}, + {"ņ", 0}, + {"G", 1}, + {"Ģ", 0}, + {"H", 1}, + {"Ḩ", 0}, + {"E", 1}, + {"Ȩ", 0}, + {"S", 1}, + {"Ş", 0}, + {"d", 1}, + {"ḑ", 0}, + {"D", 1}, + {"Ḑ", 0}, + {"r", 1}, + {"ŗ", 0}, + {"s", 1}, + {"ş", 0}, + {"R", 1}, + {"Ŗ", 0}, + {"c", 1}, + {"ç", 0}, + {"L", 1}, + {"Ļ", 0}, + {"T", 1}, + {"Ţ", 0}, + {"K", 1}, + {"Ķ", 0}, + {"h", 1}, + {"ḩ", 0}, + {"N", 1}, + {"Ņ", 0}, + {"Greek_alpha", 2}, + {"apostrophe", 1}, + {"ά", 0}, + {"dead_abovedot", 3}, + {"f", 2}, + {"s", 1}, + {"ẛ", 0}, + {"acute", 463}, + {"W", 1}, + {"Ẃ", 0}, + {"dead_breve", 4}, + {"a", 1}, + {"ắ", 0}, + {"A", 1}, + {"Ắ", 0}, + {"g", 1}, + {"ǵ", 0}, + {"a", 1}, + {"á", 0}, + {"Greek_IOTA", 1}, + {"Ί", 0}, + {"Greek_iota", 1}, + {"ί", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ớ", 0}, + {"u", 1}, + {"ứ", 0}, + {"O", 1}, + {"Ớ", 0}, + {"U", 1}, + {"Ứ", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ấ", 0}, + {"e", 1}, + {"ế", 0}, + {"o", 1}, + {"ố", 0}, + {"E", 1}, + {"Ế", 0}, + {"O", 1}, + {"Ố", 0}, + {"A", 1}, + {"Ấ", 0}, + {"Greek_OMICRON", 1}, + {"Ό", 0}, + {"Acircumflex", 1}, + {"Ấ", 0}, + {"C", 1}, + {"Ć", 0}, + {"Cyrillic_er", 1}, + {"р́", 0}, + {"e", 1}, + {"é", 0}, + {"KP_Divide", 4}, + {"o", 1}, + {"ǿ", 0}, + {"O", 1}, + {"Ǿ", 0}, + {"Utilde", 1}, + {"Ṹ", 0}, + {"o", 1}, + {"ó", 0}, + {"l", 1}, + {"ĺ", 0}, + {"Udiaeresis", 1}, + {"Ǘ", 0}, + {"Greek_upsilon", 1}, + {"ύ", 0}, + {"uhorn", 1}, + {"ứ", 0}, + {"dead_macron", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"acircumflex", 1}, + {"ấ", 0}, + {"Ecircumflex", 1}, + {"Ế", 0}, + {"Cyrillic_I", 1}, + {"И́", 0}, + {"y", 1}, + {"ý", 0}, + {"b", 4}, + {"a", 1}, + {"ắ", 0}, + {"A", 1}, + {"Ắ", 0}, + {"idiaeresis", 1}, + {"ḯ", 0}, + {"Cyrillic_O", 1}, + {"О́", 0}, + {"i", 1}, + {"í", 0}, + {"k", 1}, + {"ḱ", 0}, + {"n", 1}, + {"ń", 0}, + {"ccedilla", 1}, + {"ḉ", 0}, + {"Cyrillic_GHE", 1}, + {"Ѓ", 0}, + {"dead_tilde", 8}, + {"o", 1}, + {"ṍ", 0}, + {"u", 1}, + {"ṹ", 0}, + {"O", 1}, + {"Ṍ", 0}, + {"U", 1}, + {"Ṹ", 0}, + {"Cyrillic_a", 1}, + {"а́", 0}, + {"parenright", 26}, + {"Greek_IOTA", 1}, + {"Ἴ", 0}, + {"Greek_iota", 1}, + {"ἴ", 0}, + {"Greek_OMICRON", 1}, + {"Ὄ", 0}, + {"Greek_upsilon", 1}, + {"ὔ", 0}, + {"Greek_epsilon", 1}, + {"ἔ", 0}, + {"Greek_ALPHA", 1}, + {"Ἄ", 0}, + {"Greek_omicron", 1}, + {"ὄ", 0}, + {"Greek_eta", 1}, + {"ἤ", 0}, + {"Greek_alpha", 1}, + {"ἄ", 0}, + {"Greek_ETA", 1}, + {"Ἤ", 0}, + {"Greek_EPSILON", 1}, + {"Ἔ", 0}, + {"Greek_omega", 1}, + {"ὤ", 0}, + {"Greek_OMEGA", 1}, + {"Ὤ", 0}, + {"Ohorn", 1}, + {"Ớ", 0}, + {"ohorn", 1}, + {"ớ", 0}, + {"Cyrillic_ER", 1}, + {"Р́", 0}, + {"Greek_epsilon", 1}, + {"έ", 0}, + {"Cyrillic_KA", 1}, + {"Ќ", 0}, + {"Cyrillic_U", 1}, + {"У́", 0}, + {"dead_abovering", 4}, + {"a", 1}, + {"ǻ", 0}, + {"A", 1}, + {"Ǻ", 0}, + {"Ocircumflex", 1}, + {"Ố", 0}, + {"AE", 1}, + {"Ǽ", 0}, + {"omacron", 1}, + {"ṓ", 0}, + {"ocircumflex", 1}, + {"ố", 0}, + {"u", 1}, + {"ú", 0}, + {"z", 1}, + {"ź", 0}, + {"G", 1}, + {"Ǵ", 0}, + {"Greek_ALPHA", 1}, + {"Ά", 0}, + {"otilde", 1}, + {"ṍ", 0}, + {"utilde", 1}, + {"ṹ", 0}, + {"Cyrillic_ie", 1}, + {"е́", 0}, + {"emacron", 1}, + {"ḗ", 0}, + {"E", 1}, + {"É", 0}, + {"S", 1}, + {"Ś", 0}, + {"Greek_iotadieresis", 1}, + {"ΐ", 0}, + {"Y", 1}, + {"Ý", 0}, + {"Cyrillic_i", 1}, + {"и́", 0}, + {"dead_dasia", 28}, + {"Greek_IOTA", 1}, + {"Ἵ", 0}, + {"Greek_iota", 1}, + {"ἵ", 0}, + {"Greek_OMICRON", 1}, + {"Ὅ", 0}, + {"Greek_upsilon", 1}, + {"ὕ", 0}, + {"Greek_epsilon", 1}, + {"ἕ", 0}, + {"Greek_ALPHA", 1}, + {"Ἅ", 0}, + {"Greek_omicron", 1}, + {"ὅ", 0}, + {"Greek_eta", 1}, + {"ἥ", 0}, + {"Greek_alpha", 1}, + {"ἅ", 0}, + {"Greek_ETA", 1}, + {"Ἥ", 0}, + {"Greek_EPSILON", 1}, + {"Ἕ", 0}, + {"Greek_omega", 1}, + {"ὥ", 0}, + {"Greek_OMEGA", 1}, + {"Ὥ", 0}, + {"Greek_UPSILON", 1}, + {"Ὕ", 0}, + {"Greek_upsilondieresis", 1}, + {"ΰ", 0}, + {"Greek_omicron", 1}, + {"ό", 0}, + {"Greek_eta", 1}, + {"ή", 0}, + {"Otilde", 1}, + {"Ṍ", 0}, + {"Cyrillic_ka", 1}, + {"ќ", 0}, + {"Aring", 1}, + {"Ǻ", 0}, + {"Abreve", 1}, + {"Ắ", 0}, + {"dead_psili", 26}, + {"Greek_IOTA", 1}, + {"Ἴ", 0}, + {"Greek_iota", 1}, + {"ἴ", 0}, + {"Greek_OMICRON", 1}, + {"Ὄ", 0}, + {"Greek_upsilon", 1}, + {"ὔ", 0}, + {"Greek_epsilon", 1}, + {"ἔ", 0}, + {"Greek_ALPHA", 1}, + {"Ἄ", 0}, + {"Greek_omicron", 1}, + {"ὄ", 0}, + {"Greek_eta", 1}, + {"ἤ", 0}, + {"Greek_alpha", 1}, + {"ἄ", 0}, + {"Greek_ETA", 1}, + {"Ἤ", 0}, + {"Greek_EPSILON", 1}, + {"Ἔ", 0}, + {"Greek_omega", 1}, + {"ὤ", 0}, + {"Greek_OMEGA", 1}, + {"Ὤ", 0}, + {"quotedbl", 12}, + {"Greek_iota", 1}, + {"ΐ", 0}, + {"Greek_upsilon", 1}, + {"ΰ", 0}, + {"i", 1}, + {"ḯ", 0}, + {"u", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Ḯ", 0}, + {"U", 1}, + {"Ǘ", 0}, + {"plus", 8}, + {"o", 1}, + {"ớ", 0}, + {"u", 1}, + {"ứ", 0}, + {"O", 1}, + {"Ớ", 0}, + {"U", 1}, + {"Ứ", 0}, + {"cedilla", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"Greek_alpha", 1}, + {"ά", 0}, + {"ecircumflex", 1}, + {"ế", 0}, + {"w", 1}, + {"ẃ", 0}, + {"Greek_ETA", 1}, + {"Ή", 0}, + {"Cyrillic_o", 1}, + {"о́", 0}, + {"Emacron", 1}, + {"Ḗ", 0}, + {"Ooblique", 1}, + {"Ǿ", 0}, + {"p", 1}, + {"ṕ", 0}, + {"underscore", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"P", 1}, + {"Ṕ", 0}, + {"M", 1}, + {"Ḿ", 0}, + {"O", 1}, + {"Ó", 0}, + {"abreve", 1}, + {"ắ", 0}, + {"m", 1}, + {"ḿ", 0}, + {"r", 1}, + {"ŕ", 0}, + {"s", 1}, + {"ś", 0}, + {"Z", 1}, + {"Ź", 0}, + {"macron", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"A", 1}, + {"Á", 0}, + {"R", 1}, + {"Ŕ", 0}, + {"c", 1}, + {"ć", 0}, + {"Idiaeresis", 1}, + {"Ḯ", 0}, + {"L", 1}, + {"Ĺ", 0}, + {"Greek_EPSILON", 1}, + {"Έ", 0}, + {"Cyrillic_A", 1}, + {"А́", 0}, + {"comma", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"asciitilde", 8}, + {"o", 1}, + {"ṍ", 0}, + {"u", 1}, + {"ṹ", 0}, + {"O", 1}, + {"Ṍ", 0}, + {"U", 1}, + {"Ṹ", 0}, + {"Ccedilla", 1}, + {"Ḉ", 0}, + {"slash", 4}, + {"o", 1}, + {"ǿ", 0}, + {"O", 1}, + {"Ǿ", 0}, + {"aring", 1}, + {"ǻ", 0}, + {"K", 1}, + {"Ḱ", 0}, + {"Omacron", 1}, + {"Ṓ", 0}, + {"Cyrillic_IE", 1}, + {"Е́", 0}, + {"dead_cedilla", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"Greek_omega", 1}, + {"ώ", 0}, + {"dead_diaeresis", 12}, + {"Greek_iota", 1}, + {"ΐ", 0}, + {"Greek_upsilon", 1}, + {"ΰ", 0}, + {"i", 1}, + {"ḯ", 0}, + {"u", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Ḯ", 0}, + {"U", 1}, + {"Ǘ", 0}, + {"Uhorn", 1}, + {"Ứ", 0}, + {"Greek_OMEGA", 1}, + {"Ώ", 0}, + {"oslash", 1}, + {"ǿ", 0}, + {"Cyrillic_ghe", 1}, + {"ѓ", 0}, + {"parenleft", 28}, + {"Greek_IOTA", 1}, + {"Ἵ", 0}, + {"Greek_iota", 1}, + {"ἵ", 0}, + {"Greek_OMICRON", 1}, + {"Ὅ", 0}, + {"Greek_upsilon", 1}, + {"ὕ", 0}, + {"Greek_epsilon", 1}, + {"ἕ", 0}, + {"Greek_ALPHA", 1}, + {"Ἅ", 0}, + {"Greek_omicron", 1}, + {"ὅ", 0}, + {"Greek_eta", 1}, + {"ἥ", 0}, + {"Greek_alpha", 1}, + {"ἅ", 0}, + {"Greek_ETA", 1}, + {"Ἥ", 0}, + {"Greek_EPSILON", 1}, + {"Ἕ", 0}, + {"Greek_omega", 1}, + {"ὥ", 0}, + {"Greek_OMEGA", 1}, + {"Ὥ", 0}, + {"Greek_UPSILON", 1}, + {"Ὕ", 0}, + {"udiaeresis", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Í", 0}, + {"N", 1}, + {"Ń", 0}, + {"U", 1}, + {"Ú", 0}, + {"Cyrillic_u", 1}, + {"у́", 0}, + {"ae", 1}, + {"ǽ", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ấ", 0}, + {"e", 1}, + {"ế", 0}, + {"o", 1}, + {"ố", 0}, + {"E", 1}, + {"Ế", 0}, + {"O", 1}, + {"Ố", 0}, + {"A", 1}, + {"Ấ", 0}, + {"Greek_UPSILON", 1}, + {"Ύ", 0}, + {"Cyrillic_pe", 2}, + {"Cyrillic_a", 1}, + {"§", 0}, + {"w", 2}, + {"asciicircum", 1}, + {"ŵ", 0}, + {"Greek_ETA", 2}, + {"apostrophe", 1}, + {"Ή", 0}, + {"4", 2}, + {"5", 1}, + {"⅘", 0}, + {"bracketright", 2}, + {"bracketleft", 1}, + {"⌷", 0}, + {"colon", 6}, + {"minus", 1}, + {"÷", 0}, + {"parenright", 1}, + {"☺", 0}, + {"parenleft", 1}, + {"☹", 0}, + {"p", 4}, + {"period", 1}, + {"ṗ", 0}, + {"exclam", 1}, + {"¶", 0}, + {"underscore", 230}, + {"adiaeresis", 1}, + {"ǟ", 0}, + {"period", 8}, + {"a", 1}, + {"ǡ", 0}, + {"o", 1}, + {"ȱ", 0}, + {"O", 1}, + {"Ȱ", 0}, + {"A", 1}, + {"Ǡ", 0}, + {"g", 1}, + {"ḡ", 0}, + {"a", 1}, + {"ā", 0}, + {"Greek_IOTA", 1}, + {"Ῑ", 0}, + {"Greek_iota", 1}, + {"ῑ", 0}, + {"1", 1}, + {"₁", 0}, + {"exclam", 8}, + {"l", 1}, + {"ḹ", 0}, + {"r", 1}, + {"ṝ", 0}, + {"R", 1}, + {"Ṝ", 0}, + {"L", 1}, + {"Ḹ", 0}, + {"KP_4", 1}, + {"₄", 0}, + {"less", 1}, + {"≤", 0}, + {"Cyrillic_er", 1}, + {"р̄", 0}, + {"o", 1}, + {"ō", 0}, + {"e", 1}, + {"ē", 0}, + {"KP_6", 1}, + {"₆", 0}, + {"Udiaeresis", 1}, + {"Ǖ", 0}, + {"Greek_upsilon", 1}, + {"ῡ", 0}, + {"dead_belowdot", 8}, + {"l", 1}, + {"ḹ", 0}, + {"r", 1}, + {"ṝ", 0}, + {"R", 1}, + {"Ṝ", 0}, + {"L", 1}, + {"Ḹ", 0}, + {"KP_8", 1}, + {"₈", 0}, + {"Cyrillic_I", 1}, + {"Ӣ", 0}, + {"y", 1}, + {"ȳ", 0}, + {"Cyrillic_O", 1}, + {"О̄", 0}, + {"i", 1}, + {"ī", 0}, + {"KP_9", 1}, + {"₉", 0}, + {"equal", 1}, + {"₌", 0}, + {"KP_Space", 1}, + {"₂", 0}, + {"dead_tilde", 4}, + {"o", 1}, + {"ȭ", 0}, + {"O", 1}, + {"Ȭ", 0}, + {"7", 1}, + {"₇", 0}, + {"Cyrillic_a", 1}, + {"а̄", 0}, + {"parenright", 1}, + {"₎", 0}, + {"Cyrillic_ER", 1}, + {"Р̄", 0}, + {"KP_7", 1}, + {"₇", 0}, + {"Cyrillic_U", 1}, + {"Ӯ", 0}, + {"AE", 1}, + {"Ǣ", 0}, + {"u", 1}, + {"ū", 0}, + {"G", 1}, + {"Ḡ", 0}, + {"Greek_ALPHA", 1}, + {"Ᾱ", 0}, + {"otilde", 1}, + {"ȭ", 0}, + {"8", 1}, + {"₈", 0}, + {"KP_1", 1}, + {"₁", 0}, + {"3", 1}, + {"₃", 0}, + {"Cyrillic_ie", 1}, + {"е̄", 0}, + {"E", 1}, + {"Ē", 0}, + {"2", 1}, + {"₂", 0}, + {"Y", 1}, + {"Ȳ", 0}, + {"Cyrillic_i", 1}, + {"ӣ", 0}, + {"dead_ogonek", 4}, + {"o", 1}, + {"ǭ", 0}, + {"O", 1}, + {"Ǭ", 0}, + {"odiaeresis", 1}, + {"ȫ", 0}, + {"Otilde", 1}, + {"Ȭ", 0}, + {"quotedbl", 12}, + {"a", 1}, + {"ǟ", 0}, + {"o", 1}, + {"ȫ", 0}, + {"u", 1}, + {"ǖ", 0}, + {"O", 1}, + {"Ȫ", 0}, + {"A", 1}, + {"Ǟ", 0}, + {"U", 1}, + {"Ǖ", 0}, + {"plus", 1}, + {"₊", 0}, + {"6", 1}, + {"₆", 0}, + {"Greek_alpha", 1}, + {"ᾱ", 0}, + {"dead_abovedot", 8}, + {"a", 1}, + {"ǡ", 0}, + {"o", 1}, + {"ȱ", 0}, + {"O", 1}, + {"Ȱ", 0}, + {"A", 1}, + {"Ǡ", 0}, + {"Cyrillic_o", 1}, + {"о̄", 0}, + {"4", 1}, + {"₄", 0}, + {"KP_3", 1}, + {"₃", 0}, + {"underscore", 1}, + {"¯", 0}, + {"apostrophe", 1}, + {"⍘", 0}, + {"O", 1}, + {"Ō", 0}, + {"KP_0", 1}, + {"₀", 0}, + {"A", 1}, + {"Ā", 0}, + {"KP_Add", 1}, + {"₊", 0}, + {"Odiaeresis", 1}, + {"Ȫ", 0}, + {"KP_2", 1}, + {"₂", 0}, + {"Cyrillic_A", 1}, + {"А̄", 0}, + {"asciitilde", 4}, + {"o", 1}, + {"ȭ", 0}, + {"O", 1}, + {"Ȭ", 0}, + {"5", 1}, + {"₅", 0}, + {"greater", 1}, + {"≥", 0}, + {"semicolon", 4}, + {"o", 1}, + {"ǭ", 0}, + {"O", 1}, + {"Ǭ", 0}, + {"KP_5", 1}, + {"₅", 0}, + {"9", 1}, + {"₉", 0}, + {"Cyrillic_IE", 1}, + {"Е̄", 0}, + {"0", 1}, + {"₀", 0}, + {"dead_diaeresis", 12}, + {"a", 1}, + {"ǟ", 0}, + {"o", 1}, + {"ȫ", 0}, + {"u", 1}, + {"ǖ", 0}, + {"O", 1}, + {"Ȫ", 0}, + {"A", 1}, + {"Ǟ", 0}, + {"U", 1}, + {"Ǖ", 0}, + {"Adiaeresis", 1}, + {"Ǟ", 0}, + {"parenleft", 1}, + {"₍", 0}, + {"udiaeresis", 1}, + {"ǖ", 0}, + {"I", 1}, + {"Ī", 0}, + {"U", 1}, + {"Ū", 0}, + {"Cyrillic_u", 1}, + {"ӯ", 0}, + {"ae", 1}, + {"ǣ", 0}, + {"asciicircum", 1}, + {"¯", 0}, + {"Greek_UPSILON", 1}, + {"Ῡ", 0}, + {"KP_Equal", 1}, + {"₌", 0}, + {"v", 8}, + {"l", 1}, + {"|", 0}, + {"z", 1}, + {"ž", 0}, + {"Z", 1}, + {"Ž", 0}, + {"slash", 1}, + {"√", 0}, + {"P", 8}, + {"period", 1}, + {"Ṗ", 0}, + {"exclam", 1}, + {"¶", 0}, + {"t", 1}, + {"₧", 0}, + {"P", 1}, + {"¶", 0}, + {"question", 106}, + {"dead_breve", 4}, + {"a", 1}, + {"ẳ", 0}, + {"A", 1}, + {"Ẳ", 0}, + {"a", 1}, + {"ả", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ẩ", 0}, + {"e", 1}, + {"ể", 0}, + {"o", 1}, + {"ổ", 0}, + {"E", 1}, + {"Ể", 0}, + {"O", 1}, + {"Ổ", 0}, + {"A", 1}, + {"Ẩ", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ở", 0}, + {"u", 1}, + {"ử", 0}, + {"O", 1}, + {"Ở", 0}, + {"U", 1}, + {"Ử", 0}, + {"Acircumflex", 1}, + {"Ẩ", 0}, + {"exclam", 1}, + {"⸘", 0}, + {"e", 1}, + {"ẻ", 0}, + {"o", 1}, + {"ỏ", 0}, + {"uhorn", 1}, + {"ử", 0}, + {"acircumflex", 1}, + {"ẩ", 0}, + {"Ecircumflex", 1}, + {"Ể", 0}, + {"y", 1}, + {"ỷ", 0}, + {"b", 4}, + {"a", 1}, + {"ẳ", 0}, + {"A", 1}, + {"Ẳ", 0}, + {"i", 1}, + {"ỉ", 0}, + {"Ohorn", 1}, + {"Ở", 0}, + {"ohorn", 1}, + {"ở", 0}, + {"Ocircumflex", 1}, + {"Ổ", 0}, + {"ocircumflex", 1}, + {"ổ", 0}, + {"u", 1}, + {"ủ", 0}, + {"E", 1}, + {"Ẻ", 0}, + {"Y", 1}, + {"Ỷ", 0}, + {"Abreve", 1}, + {"Ẳ", 0}, + {"plus", 8}, + {"o", 1}, + {"ở", 0}, + {"u", 1}, + {"ử", 0}, + {"O", 1}, + {"Ở", 0}, + {"U", 1}, + {"Ử", 0}, + {"ecircumflex", 1}, + {"ể", 0}, + {"question", 1}, + {"¿", 0}, + {"O", 1}, + {"Ỏ", 0}, + {"abreve", 1}, + {"ẳ", 0}, + {"A", 1}, + {"Ả", 0}, + {"Uhorn", 1}, + {"Ử", 0}, + {"I", 1}, + {"Ỉ", 0}, + {"U", 1}, + {"Ủ", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ẩ", 0}, + {"e", 1}, + {"ể", 0}, + {"o", 1}, + {"ổ", 0}, + {"E", 1}, + {"Ể", 0}, + {"O", 1}, + {"Ổ", 0}, + {"A", 1}, + {"Ẩ", 0}, + {"apostrophe", 470}, + {"W", 1}, + {"Ẃ", 0}, + {"dead_breve", 4}, + {"a", 1}, + {"ắ", 0}, + {"A", 1}, + {"Ắ", 0}, + {"g", 1}, + {"ǵ", 0}, + {"a", 1}, + {"á", 0}, + {"Greek_IOTA", 1}, + {"Ί", 0}, + {"Greek_iota", 1}, + {"ί", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ớ", 0}, + {"u", 1}, + {"ứ", 0}, + {"O", 1}, + {"Ớ", 0}, + {"U", 1}, + {"Ứ", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ấ", 0}, + {"e", 1}, + {"ế", 0}, + {"o", 1}, + {"ố", 0}, + {"E", 1}, + {"Ế", 0}, + {"O", 1}, + {"Ố", 0}, + {"A", 1}, + {"Ấ", 0}, + {"Greek_OMICRON", 1}, + {"Ό", 0}, + {"Acircumflex", 1}, + {"Ấ", 0}, + {"C", 1}, + {"Ć", 0}, + {"less", 1}, + {"‘", 0}, + {"Cyrillic_er", 1}, + {"р́", 0}, + {"e", 1}, + {"é", 0}, + {"KP_Divide", 4}, + {"o", 1}, + {"ǿ", 0}, + {"O", 1}, + {"Ǿ", 0}, + {"Utilde", 1}, + {"Ṹ", 0}, + {"o", 1}, + {"ó", 0}, + {"l", 1}, + {"ĺ", 0}, + {"Udiaeresis", 1}, + {"Ǘ", 0}, + {"Greek_upsilon", 1}, + {"ύ", 0}, + {"uhorn", 1}, + {"ứ", 0}, + {"space", 1}, + {"'", 0}, + {"dead_macron", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"acircumflex", 1}, + {"ấ", 0}, + {"Ecircumflex", 1}, + {"Ế", 0}, + {"Cyrillic_I", 1}, + {"И́", 0}, + {"y", 1}, + {"ý", 0}, + {"b", 4}, + {"a", 1}, + {"ắ", 0}, + {"A", 1}, + {"Ắ", 0}, + {"idiaeresis", 1}, + {"ḯ", 0}, + {"Cyrillic_O", 1}, + {"О́", 0}, + {"i", 1}, + {"í", 0}, + {"k", 1}, + {"ḱ", 0}, + {"n", 1}, + {"ń", 0}, + {"ccedilla", 1}, + {"ḉ", 0}, + {"Cyrillic_GHE", 1}, + {"Ѓ", 0}, + {"dead_tilde", 8}, + {"o", 1}, + {"ṍ", 0}, + {"u", 1}, + {"ṹ", 0}, + {"O", 1}, + {"Ṍ", 0}, + {"U", 1}, + {"Ṹ", 0}, + {"Cyrillic_a", 1}, + {"а́", 0}, + {"parenright", 26}, + {"Greek_IOTA", 1}, + {"Ἴ", 0}, + {"Greek_iota", 1}, + {"ἴ", 0}, + {"Greek_OMICRON", 1}, + {"Ὄ", 0}, + {"Greek_upsilon", 1}, + {"ὔ", 0}, + {"Greek_epsilon", 1}, + {"ἔ", 0}, + {"Greek_ALPHA", 1}, + {"Ἄ", 0}, + {"Greek_omicron", 1}, + {"ὄ", 0}, + {"Greek_eta", 1}, + {"ἤ", 0}, + {"Greek_alpha", 1}, + {"ἄ", 0}, + {"Greek_ETA", 1}, + {"Ἤ", 0}, + {"Greek_EPSILON", 1}, + {"Ἔ", 0}, + {"Greek_omega", 1}, + {"ὤ", 0}, + {"Greek_OMEGA", 1}, + {"Ὤ", 0}, + {"Ohorn", 1}, + {"Ớ", 0}, + {"ohorn", 1}, + {"ớ", 0}, + {"Cyrillic_ER", 1}, + {"Р́", 0}, + {"Greek_epsilon", 1}, + {"έ", 0}, + {"Cyrillic_KA", 1}, + {"Ќ", 0}, + {"Cyrillic_U", 1}, + {"У́", 0}, + {"dead_abovering", 4}, + {"a", 1}, + {"ǻ", 0}, + {"A", 1}, + {"Ǻ", 0}, + {"Ocircumflex", 1}, + {"Ố", 0}, + {"AE", 1}, + {"Ǽ", 0}, + {"omacron", 1}, + {"ṓ", 0}, + {"ocircumflex", 1}, + {"ố", 0}, + {"u", 1}, + {"ú", 0}, + {"z", 1}, + {"ź", 0}, + {"G", 1}, + {"Ǵ", 0}, + {"Greek_ALPHA", 1}, + {"Ά", 0}, + {"otilde", 1}, + {"ṍ", 0}, + {"utilde", 1}, + {"ṹ", 0}, + {"Cyrillic_ie", 1}, + {"е́", 0}, + {"emacron", 1}, + {"ḗ", 0}, + {"E", 1}, + {"É", 0}, + {"S", 1}, + {"Ś", 0}, + {"Greek_iotadieresis", 1}, + {"ΐ", 0}, + {"Y", 1}, + {"Ý", 0}, + {"Cyrillic_i", 1}, + {"и́", 0}, + {"dead_dasia", 28}, + {"Greek_IOTA", 1}, + {"Ἵ", 0}, + {"Greek_iota", 1}, + {"ἵ", 0}, + {"Greek_OMICRON", 1}, + {"Ὅ", 0}, + {"Greek_upsilon", 1}, + {"ὕ", 0}, + {"Greek_epsilon", 1}, + {"ἕ", 0}, + {"Greek_ALPHA", 1}, + {"Ἅ", 0}, + {"Greek_omicron", 1}, + {"ὅ", 0}, + {"Greek_eta", 1}, + {"ἥ", 0}, + {"Greek_alpha", 1}, + {"ἅ", 0}, + {"Greek_ETA", 1}, + {"Ἥ", 0}, + {"Greek_EPSILON", 1}, + {"Ἕ", 0}, + {"Greek_omega", 1}, + {"ὥ", 0}, + {"Greek_OMEGA", 1}, + {"Ὥ", 0}, + {"Greek_UPSILON", 1}, + {"Ὕ", 0}, + {"Greek_upsilondieresis", 1}, + {"ΰ", 0}, + {"Greek_omicron", 1}, + {"ό", 0}, + {"Greek_eta", 1}, + {"ή", 0}, + {"Otilde", 1}, + {"Ṍ", 0}, + {"Cyrillic_ka", 1}, + {"ќ", 0}, + {"Aring", 1}, + {"Ǻ", 0}, + {"Abreve", 1}, + {"Ắ", 0}, + {"dead_psili", 26}, + {"Greek_IOTA", 1}, + {"Ἴ", 0}, + {"Greek_iota", 1}, + {"ἴ", 0}, + {"Greek_OMICRON", 1}, + {"Ὄ", 0}, + {"Greek_upsilon", 1}, + {"ὔ", 0}, + {"Greek_epsilon", 1}, + {"ἔ", 0}, + {"Greek_ALPHA", 1}, + {"Ἄ", 0}, + {"Greek_omicron", 1}, + {"ὄ", 0}, + {"Greek_eta", 1}, + {"ἤ", 0}, + {"Greek_alpha", 1}, + {"ἄ", 0}, + {"Greek_ETA", 1}, + {"Ἤ", 0}, + {"Greek_EPSILON", 1}, + {"Ἔ", 0}, + {"Greek_omega", 1}, + {"ὤ", 0}, + {"Greek_OMEGA", 1}, + {"Ὤ", 0}, + {"quotedbl", 14}, + {"Greek_iota", 1}, + {"ΐ", 0}, + {"Greek_upsilon", 1}, + {"ΰ", 0}, + {"space", 1}, + {"΅", 0}, + {"i", 1}, + {"ḯ", 0}, + {"u", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Ḯ", 0}, + {"U", 1}, + {"Ǘ", 0}, + {"plus", 8}, + {"o", 1}, + {"ớ", 0}, + {"u", 1}, + {"ứ", 0}, + {"O", 1}, + {"Ớ", 0}, + {"U", 1}, + {"Ứ", 0}, + {"cedilla", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"Greek_alpha", 1}, + {"ά", 0}, + {"ecircumflex", 1}, + {"ế", 0}, + {"w", 1}, + {"ẃ", 0}, + {"Greek_ETA", 1}, + {"Ή", 0}, + {"Cyrillic_o", 1}, + {"о́", 0}, + {"Emacron", 1}, + {"Ḗ", 0}, + {"Ooblique", 1}, + {"Ǿ", 0}, + {"p", 1}, + {"ṕ", 0}, + {"underscore", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"P", 1}, + {"Ṕ", 0}, + {"apostrophe", 1}, + {"´", 0}, + {"M", 1}, + {"Ḿ", 0}, + {"O", 1}, + {"Ó", 0}, + {"abreve", 1}, + {"ắ", 0}, + {"m", 1}, + {"ḿ", 0}, + {"r", 1}, + {"ŕ", 0}, + {"s", 1}, + {"ś", 0}, + {"Z", 1}, + {"Ź", 0}, + {"macron", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"A", 1}, + {"Á", 0}, + {"R", 1}, + {"Ŕ", 0}, + {"c", 1}, + {"ć", 0}, + {"Idiaeresis", 1}, + {"Ḯ", 0}, + {"L", 1}, + {"Ĺ", 0}, + {"Greek_EPSILON", 1}, + {"Έ", 0}, + {"Cyrillic_A", 1}, + {"А́", 0}, + {"comma", 1}, + {"‚", 0}, + {"asciitilde", 8}, + {"o", 1}, + {"ṍ", 0}, + {"u", 1}, + {"ṹ", 0}, + {"O", 1}, + {"Ṍ", 0}, + {"U", 1}, + {"Ṹ", 0}, + {"Ccedilla", 1}, + {"Ḉ", 0}, + {"slash", 4}, + {"o", 1}, + {"ǿ", 0}, + {"O", 1}, + {"Ǿ", 0}, + {"aring", 1}, + {"ǻ", 0}, + {"greater", 1}, + {"’", 0}, + {"K", 1}, + {"Ḱ", 0}, + {"Omacron", 1}, + {"Ṓ", 0}, + {"Cyrillic_IE", 1}, + {"Е́", 0}, + {"dead_cedilla", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"Greek_omega", 1}, + {"ώ", 0}, + {"dead_diaeresis", 12}, + {"Greek_iota", 1}, + {"ΐ", 0}, + {"Greek_upsilon", 1}, + {"ΰ", 0}, + {"i", 1}, + {"ḯ", 0}, + {"u", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Ḯ", 0}, + {"U", 1}, + {"Ǘ", 0}, + {"Uhorn", 1}, + {"Ứ", 0}, + {"Greek_OMEGA", 1}, + {"Ώ", 0}, + {"oslash", 1}, + {"ǿ", 0}, + {"Cyrillic_ghe", 1}, + {"ѓ", 0}, + {"parenleft", 28}, + {"Greek_IOTA", 1}, + {"Ἵ", 0}, + {"Greek_iota", 1}, + {"ἵ", 0}, + {"Greek_OMICRON", 1}, + {"Ὅ", 0}, + {"Greek_upsilon", 1}, + {"ὕ", 0}, + {"Greek_epsilon", 1}, + {"ἕ", 0}, + {"Greek_ALPHA", 1}, + {"Ἅ", 0}, + {"Greek_omicron", 1}, + {"ὅ", 0}, + {"Greek_eta", 1}, + {"ἥ", 0}, + {"Greek_alpha", 1}, + {"ἅ", 0}, + {"Greek_ETA", 1}, + {"Ἥ", 0}, + {"Greek_EPSILON", 1}, + {"Ἕ", 0}, + {"Greek_omega", 1}, + {"ὥ", 0}, + {"Greek_OMEGA", 1}, + {"Ὥ", 0}, + {"Greek_UPSILON", 1}, + {"Ὕ", 0}, + {"udiaeresis", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Í", 0}, + {"N", 1}, + {"Ń", 0}, + {"U", 1}, + {"Ú", 0}, + {"Cyrillic_u", 1}, + {"у́", 0}, + {"ae", 1}, + {"ǽ", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ấ", 0}, + {"e", 1}, + {"ế", 0}, + {"o", 1}, + {"ố", 0}, + {"E", 1}, + {"Ế", 0}, + {"O", 1}, + {"Ố", 0}, + {"A", 1}, + {"Ấ", 0}, + {"Greek_UPSILON", 1}, + {"Ύ", 0}, + {"M", 2}, + {"period", 1}, + {"Ṁ", 0}, + {"O", 40}, + {"minus", 1}, + {"Ō", 0}, + {"C", 1}, + {"©", 0}, + {"diaeresis", 1}, + {"Ö", 0}, + {"x", 1}, + {"¤", 0}, + {"E", 1}, + {"Œ", 0}, + {"S", 1}, + {"§", 0}, + {"quotedbl", 1}, + {"Ö", 0}, + {"acute", 1}, + {"Ó", 0}, + {"underscore", 1}, + {"Ō", 0}, + {"apostrophe", 1}, + {"Ó", 0}, + {"r", 1}, + {"®", 0}, + {"A", 1}, + {"Ⓐ", 0}, + {"R", 1}, + {"®", 0}, + {"c", 1}, + {"©", 0}, + {"asciitilde", 1}, + {"Õ", 0}, + {"slash", 1}, + {"Ø", 0}, + {"greater", 1}, + {"Ô", 0}, + {"X", 1}, + {"¤", 0}, + {"grave", 1}, + {"Ò", 0}, + {"asciicircum", 1}, + {"Ô", 0}, + {"m", 6}, + {"period", 1}, + {"ṁ", 0}, + {"u", 1}, + {"µ", 0}, + {"slash", 1}, + {"₥", 0}, + {"r", 6}, + {"less", 1}, + {"ř", 0}, + {"apostrophe", 1}, + {"ŕ", 0}, + {"comma", 1}, + {"ŗ", 0}, + {"s", 20}, + {"period", 1}, + {"ṡ", 0}, + {"exclam", 1}, + {"§", 0}, + {"less", 1}, + {"š", 0}, + {"o", 1}, + {"§", 0}, + {"cedilla", 1}, + {"ş", 0}, + {"apostrophe", 1}, + {"ś", 0}, + {"M", 1}, + {"℠", 0}, + {"m", 1}, + {"℠", 0}, + {"s", 1}, + {"ß", 0}, + {"comma", 1}, + {"ş", 0}, + {"asterisk", 17}, + {"a", 1}, + {"å", 0}, + {"diaeresis", 1}, + {"⍣", 0}, + {"u", 1}, + {"ů", 0}, + {"apostrophe", 4}, + {"a", 1}, + {"ǻ", 0}, + {"A", 1}, + {"Ǻ", 0}, + {"A", 1}, + {"Å", 0}, + {"0", 1}, + {"°", 0}, + {"U", 1}, + {"Ů", 0}, + {"Z", 6}, + {"period", 1}, + {"Ż", 0}, + {"less", 1}, + {"Ž", 0}, + {"apostrophe", 1}, + {"Ź", 0}, + {"bar", 6}, + {"C", 1}, + {"¢", 0}, + {"c", 1}, + {"¢", 0}, + {"asciitilde", 1}, + {"⍭", 0}, + {"macron", 166}, + {"adiaeresis", 1}, + {"ǟ", 0}, + {"period", 8}, + {"a", 1}, + {"ǡ", 0}, + {"o", 1}, + {"ȱ", 0}, + {"O", 1}, + {"Ȱ", 0}, + {"A", 1}, + {"Ǡ", 0}, + {"g", 1}, + {"ḡ", 0}, + {"a", 1}, + {"ā", 0}, + {"Greek_IOTA", 1}, + {"Ῑ", 0}, + {"Greek_iota", 1}, + {"ῑ", 0}, + {"exclam", 8}, + {"l", 1}, + {"ḹ", 0}, + {"r", 1}, + {"ṝ", 0}, + {"R", 1}, + {"Ṝ", 0}, + {"L", 1}, + {"Ḹ", 0}, + {"Cyrillic_er", 1}, + {"р̄", 0}, + {"e", 1}, + {"ē", 0}, + {"o", 1}, + {"ō", 0}, + {"Udiaeresis", 1}, + {"Ǖ", 0}, + {"Greek_upsilon", 1}, + {"ῡ", 0}, + {"dead_belowdot", 8}, + {"l", 1}, + {"ḹ", 0}, + {"r", 1}, + {"ṝ", 0}, + {"R", 1}, + {"Ṝ", 0}, + {"L", 1}, + {"Ḹ", 0}, + {"Cyrillic_I", 1}, + {"Ӣ", 0}, + {"y", 1}, + {"ȳ", 0}, + {"Cyrillic_O", 1}, + {"О̄", 0}, + {"i", 1}, + {"ī", 0}, + {"dead_tilde", 4}, + {"o", 1}, + {"ȭ", 0}, + {"O", 1}, + {"Ȭ", 0}, + {"Cyrillic_a", 1}, + {"а̄", 0}, + {"Cyrillic_ER", 1}, + {"Р̄", 0}, + {"Cyrillic_U", 1}, + {"Ӯ", 0}, + {"AE", 1}, + {"Ǣ", 0}, + {"u", 1}, + {"ū", 0}, + {"G", 1}, + {"Ḡ", 0}, + {"Greek_ALPHA", 1}, + {"Ᾱ", 0}, + {"otilde", 1}, + {"ȭ", 0}, + {"Cyrillic_ie", 1}, + {"е̄", 0}, + {"E", 1}, + {"Ē", 0}, + {"Y", 1}, + {"Ȳ", 0}, + {"Cyrillic_i", 1}, + {"ӣ", 0}, + {"dead_ogonek", 4}, + {"o", 1}, + {"ǭ", 0}, + {"O", 1}, + {"Ǭ", 0}, + {"odiaeresis", 1}, + {"ȫ", 0}, + {"Otilde", 1}, + {"Ȭ", 0}, + {"quotedbl", 12}, + {"a", 1}, + {"ǟ", 0}, + {"o", 1}, + {"ȫ", 0}, + {"u", 1}, + {"ǖ", 0}, + {"O", 1}, + {"Ȫ", 0}, + {"A", 1}, + {"Ǟ", 0}, + {"U", 1}, + {"Ǖ", 0}, + {"Greek_alpha", 1}, + {"ᾱ", 0}, + {"dead_abovedot", 8}, + {"a", 1}, + {"ǡ", 0}, + {"o", 1}, + {"ȱ", 0}, + {"O", 1}, + {"Ȱ", 0}, + {"A", 1}, + {"Ǡ", 0}, + {"Cyrillic_o", 1}, + {"о̄", 0}, + {"O", 1}, + {"Ō", 0}, + {"A", 1}, + {"Ā", 0}, + {"Odiaeresis", 1}, + {"Ȫ", 0}, + {"Cyrillic_A", 1}, + {"А̄", 0}, + {"asciitilde", 4}, + {"o", 1}, + {"ȭ", 0}, + {"O", 1}, + {"Ȭ", 0}, + {"semicolon", 4}, + {"o", 1}, + {"ǭ", 0}, + {"O", 1}, + {"Ǭ", 0}, + {"Cyrillic_IE", 1}, + {"Е̄", 0}, + {"dead_diaeresis", 12}, + {"a", 1}, + {"ǟ", 0}, + {"o", 1}, + {"ȫ", 0}, + {"u", 1}, + {"ǖ", 0}, + {"O", 1}, + {"Ȫ", 0}, + {"A", 1}, + {"Ǟ", 0}, + {"U", 1}, + {"Ǖ", 0}, + {"Adiaeresis", 1}, + {"Ǟ", 0}, + {"udiaeresis", 1}, + {"ǖ", 0}, + {"I", 1}, + {"Ī", 0}, + {"U", 1}, + {"Ū", 0}, + {"Cyrillic_u", 1}, + {"ӯ", 0}, + {"ae", 1}, + {"ǣ", 0}, + {"Greek_UPSILON", 1}, + {"Ῡ", 0}, + {"A", 32}, + {"minus", 1}, + {"Ā", 0}, + {"diaeresis", 1}, + {"Ä", 0}, + {"E", 1}, + {"Æ", 0}, + {"quotedbl", 1}, + {"Ä", 0}, + {"acute", 1}, + {"Á", 0}, + {"underscore", 1}, + {"Ā", 0}, + {"apostrophe", 1}, + {"Á", 0}, + {"asterisk", 1}, + {"Å", 0}, + {"A", 1}, + {"Å", 0}, + {"comma", 1}, + {"Ą", 0}, + {"T", 1}, + {"@", 0}, + {"asciitilde", 1}, + {"Ã", 0}, + {"greater", 1}, + {"Â", 0}, + {"parenleft", 1}, + {"Ă", 0}, + {"grave", 1}, + {"À", 0}, + {"asciicircum", 1}, + {"Â", 0}, + {"R", 10}, + {"less", 1}, + {"Ř", 0}, + {"apostrophe", 1}, + {"Ŕ", 0}, + {"O", 1}, + {"®", 0}, + {"s", 1}, + {"₨", 0}, + {"comma", 1}, + {"Ŗ", 0}, + {"Cyrillic_ES", 2}, + {"equal", 1}, + {"€", 0}, + {"c", 98}, + {"period", 1}, + {"ċ", 0}, + {"g", 1}, + {"ǧ", 0}, + {"a", 1}, + {"ǎ", 0}, + {"ezh", 1}, + {"ǯ", 0}, + {"C", 1}, + {"Č", 0}, + {"less", 1}, + {"č", 0}, + {"e", 1}, + {"ě", 0}, + {"o", 1}, + {"ǒ", 0}, + {"l", 1}, + {"ľ", 0}, + {"Udiaeresis", 1}, + {"Ǚ", 0}, + {"t", 1}, + {"ť", 0}, + {"i", 1}, + {"ǐ", 0}, + {"k", 1}, + {"ǩ", 0}, + {"n", 1}, + {"ň", 0}, + {"equal", 1}, + {"€", 0}, + {"j", 1}, + {"ǰ", 0}, + {"u", 1}, + {"ǔ", 0}, + {"z", 1}, + {"ž", 0}, + {"G", 1}, + {"Ǧ", 0}, + {"H", 1}, + {"Ȟ", 0}, + {"E", 1}, + {"Ě", 0}, + {"S", 1}, + {"Š", 0}, + {"d", 1}, + {"ď", 0}, + {"D", 1}, + {"Ď", 0}, + {"quotedbl", 4}, + {"u", 1}, + {"ǚ", 0}, + {"U", 1}, + {"Ǚ", 0}, + {"apostrophe", 1}, + {"ć", 0}, + {"O", 1}, + {"Ǒ", 0}, + {"r", 1}, + {"ř", 0}, + {"s", 1}, + {"š", 0}, + {"Z", 1}, + {"Ž", 0}, + {"bar", 1}, + {"¢", 0}, + {"EZH", 1}, + {"Ǯ", 0}, + {"A", 1}, + {"Ǎ", 0}, + {"R", 1}, + {"Ř", 0}, + {"c", 1}, + {"č", 0}, + {"L", 1}, + {"Ľ", 0}, + {"comma", 1}, + {"ç", 0}, + {"T", 1}, + {"Ť", 0}, + {"slash", 1}, + {"¢", 0}, + {"K", 1}, + {"Ǩ", 0}, + {"dead_diaeresis", 4}, + {"u", 1}, + {"ǚ", 0}, + {"U", 1}, + {"Ǚ", 0}, + {"h", 1}, + {"ȟ", 0}, + {"udiaeresis", 1}, + {"ǚ", 0}, + {"I", 1}, + {"Ǐ", 0}, + {"N", 1}, + {"Ň", 0}, + {"U", 1}, + {"Ǔ", 0}, + {"numbersign", 14}, + {"e", 1}, + {"♪", 0}, + {"b", 1}, + {"♭", 0}, + {"q", 1}, + {"♩", 0}, + {"E", 1}, + {"♫", 0}, + {"S", 1}, + {"♬", 0}, + {"f", 1}, + {"♮", 0}, + {"numbersign", 1}, + {"♯", 0}, + {"L", 14}, + {"minus", 1}, + {"£", 0}, + {"less", 1}, + {"Ľ", 0}, + {"equal", 1}, + {"₤", 0}, + {"V", 1}, + {"|", 0}, + {"apostrophe", 1}, + {"Ĺ", 0}, + {"comma", 1}, + {"Ļ", 0}, + {"slash", 1}, + {"Ł", 0}, + {"Greek_EPSILON", 2}, + {"apostrophe", 1}, + {"Έ", 0}, + {"comma", 66}, + {"minus", 1}, + {"¬", 0}, + {"g", 1}, + {"ģ", 0}, + {"a", 1}, + {"ą", 0}, + {"C", 1}, + {"Ç", 0}, + {"e", 1}, + {"ę", 0}, + {"l", 1}, + {"ļ", 0}, + {"t", 1}, + {"ţ", 0}, + {"space", 1}, + {"¸", 0}, + {"i", 1}, + {"į", 0}, + {"k", 1}, + {"ķ", 0}, + {"n", 1}, + {"ņ", 0}, + {"u", 1}, + {"ų", 0}, + {"G", 1}, + {"Ģ", 0}, + {"H", 1}, + {"Ḩ", 0}, + {"E", 1}, + {"Ę", 0}, + {"S", 1}, + {"Ş", 0}, + {"d", 1}, + {"ḑ", 0}, + {"D", 1}, + {"Ḑ", 0}, + {"quotedbl", 1}, + {"„", 0}, + {"apostrophe", 1}, + {"‚", 0}, + {"r", 1}, + {"ŗ", 0}, + {"s", 1}, + {"ş", 0}, + {"A", 1}, + {"Ą", 0}, + {"R", 1}, + {"Ŗ", 0}, + {"c", 1}, + {"ç", 0}, + {"L", 1}, + {"Ļ", 0}, + {"comma", 1}, + {"¸", 0}, + {"T", 1}, + {"Ţ", 0}, + {"K", 1}, + {"Ķ", 0}, + {"h", 1}, + {"ḩ", 0}, + {"I", 1}, + {"Į", 0}, + {"N", 1}, + {"Ņ", 0}, + {"U", 1}, + {"Ų", 0}, + {"T", 16}, + {"minus", 1}, + {"Ŧ", 0}, + {"period", 1}, + {"Ṫ", 0}, + {"less", 1}, + {"Ť", 0}, + {"H", 1}, + {"Þ", 0}, + {"M", 1}, + {"™", 0}, + {"m", 1}, + {"™", 0}, + {"comma", 1}, + {"Ţ", 0}, + {"slash", 1}, + {"Ŧ", 0}, + {"asciitilde", 222}, + {"dead_breve", 4}, + {"a", 1}, + {"ẵ", 0}, + {"A", 1}, + {"Ẵ", 0}, + {"a", 1}, + {"ã", 0}, + {"Greek_iota", 1}, + {"ῖ", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ỡ", 0}, + {"u", 1}, + {"ữ", 0}, + {"O", 1}, + {"Ỡ", 0}, + {"U", 1}, + {"Ữ", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ẫ", 0}, + {"e", 1}, + {"ễ", 0}, + {"o", 1}, + {"ỗ", 0}, + {"E", 1}, + {"Ễ", 0}, + {"O", 1}, + {"Ỗ", 0}, + {"A", 1}, + {"Ẫ", 0}, + {"Acircumflex", 1}, + {"Ẫ", 0}, + {"e", 1}, + {"ẽ", 0}, + {"o", 1}, + {"õ", 0}, + {"Greek_upsilon", 1}, + {"ῦ", 0}, + {"diaeresis", 1}, + {"⍨", 0}, + {"uhorn", 1}, + {"ữ", 0}, + {"space", 1}, + {"~", 0}, + {"acircumflex", 1}, + {"ẫ", 0}, + {"Ecircumflex", 1}, + {"Ễ", 0}, + {"y", 1}, + {"ỹ", 0}, + {"b", 4}, + {"a", 1}, + {"ẵ", 0}, + {"A", 1}, + {"Ẵ", 0}, + {"i", 1}, + {"ĩ", 0}, + {"n", 1}, + {"ñ", 0}, + {"parenright", 18}, + {"Greek_IOTA", 1}, + {"Ἶ", 0}, + {"Greek_iota", 1}, + {"ἶ", 0}, + {"Greek_upsilon", 1}, + {"ὖ", 0}, + {"Greek_ALPHA", 1}, + {"Ἆ", 0}, + {"Greek_eta", 1}, + {"ἦ", 0}, + {"Greek_alpha", 1}, + {"ἆ", 0}, + {"Greek_ETA", 1}, + {"Ἦ", 0}, + {"Greek_omega", 1}, + {"ὦ", 0}, + {"Greek_OMEGA", 1}, + {"Ὦ", 0}, + {"Ohorn", 1}, + {"Ỡ", 0}, + {"ohorn", 1}, + {"ỡ", 0}, + {"Ocircumflex", 1}, + {"Ỗ", 0}, + {"V", 1}, + {"Ṽ", 0}, + {"ocircumflex", 1}, + {"ỗ", 0}, + {"u", 1}, + {"ũ", 0}, + {"E", 1}, + {"Ẽ", 0}, + {"Greek_iotadieresis", 1}, + {"ῗ", 0}, + {"Y", 1}, + {"Ỹ", 0}, + {"dead_dasia", 20}, + {"Greek_IOTA", 1}, + {"Ἷ", 0}, + {"Greek_iota", 1}, + {"ἷ", 0}, + {"Greek_upsilon", 1}, + {"ὗ", 0}, + {"Greek_ALPHA", 1}, + {"Ἇ", 0}, + {"Greek_eta", 1}, + {"ἧ", 0}, + {"Greek_alpha", 1}, + {"ἇ", 0}, + {"Greek_ETA", 1}, + {"Ἧ", 0}, + {"Greek_omega", 1}, + {"ὧ", 0}, + {"Greek_OMEGA", 1}, + {"Ὧ", 0}, + {"Greek_UPSILON", 1}, + {"Ὗ", 0}, + {"Greek_upsilondieresis", 1}, + {"ῧ", 0}, + {"Greek_eta", 1}, + {"ῆ", 0}, + {"Abreve", 1}, + {"Ẵ", 0}, + {"dead_psili", 18}, + {"Greek_IOTA", 1}, + {"Ἶ", 0}, + {"Greek_iota", 1}, + {"ἶ", 0}, + {"Greek_upsilon", 1}, + {"ὖ", 0}, + {"Greek_ALPHA", 1}, + {"Ἆ", 0}, + {"Greek_eta", 1}, + {"ἦ", 0}, + {"Greek_alpha", 1}, + {"ἆ", 0}, + {"Greek_ETA", 1}, + {"Ἦ", 0}, + {"Greek_omega", 1}, + {"ὦ", 0}, + {"Greek_OMEGA", 1}, + {"Ὦ", 0}, + {"quotedbl", 4}, + {"Greek_iota", 1}, + {"ῗ", 0}, + {"Greek_upsilon", 1}, + {"ῧ", 0}, + {"plus", 8}, + {"o", 1}, + {"ỡ", 0}, + {"u", 1}, + {"ữ", 0}, + {"O", 1}, + {"Ỡ", 0}, + {"U", 1}, + {"Ữ", 0}, + {"Greek_alpha", 1}, + {"ᾶ", 0}, + {"ecircumflex", 1}, + {"ễ", 0}, + {"v", 1}, + {"ṽ", 0}, + {"O", 1}, + {"Õ", 0}, + {"abreve", 1}, + {"ẵ", 0}, + {"bar", 1}, + {"⍭", 0}, + {"A", 1}, + {"Ã", 0}, + {"0", 1}, + {"⍬", 0}, + {"Greek_omega", 1}, + {"ῶ", 0}, + {"dead_diaeresis", 4}, + {"Greek_iota", 1}, + {"ῗ", 0}, + {"Greek_upsilon", 1}, + {"ῧ", 0}, + {"Uhorn", 1}, + {"Ữ", 0}, + {"parenleft", 20}, + {"Greek_IOTA", 1}, + {"Ἷ", 0}, + {"Greek_iota", 1}, + {"ἷ", 0}, + {"Greek_upsilon", 1}, + {"ὗ", 0}, + {"Greek_ALPHA", 1}, + {"Ἇ", 0}, + {"Greek_eta", 1}, + {"ἧ", 0}, + {"Greek_alpha", 1}, + {"ἇ", 0}, + {"Greek_ETA", 1}, + {"Ἧ", 0}, + {"Greek_omega", 1}, + {"ὧ", 0}, + {"Greek_OMEGA", 1}, + {"Ὧ", 0}, + {"Greek_UPSILON", 1}, + {"Ὗ", 0}, + {"I", 1}, + {"Ĩ", 0}, + {"N", 1}, + {"Ñ", 0}, + {"U", 1}, + {"Ũ", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ẫ", 0}, + {"e", 1}, + {"ễ", 0}, + {"o", 1}, + {"ỗ", 0}, + {"E", 1}, + {"Ễ", 0}, + {"O", 1}, + {"Ỗ", 0}, + {"A", 1}, + {"Ẫ", 0}, + {"slash", 66}, + {"minus", 1}, + {"⌿", 0}, + {"g", 1}, + {"ǥ", 0}, + {"C", 1}, + {"₡", 0}, + {"less", 1}, + {"\\", 0}, + {"o", 1}, + {"ø", 0}, + {"l", 1}, + {"ł", 0}, + {"t", 1}, + {"ŧ", 0}, + {"b", 1}, + {"ƀ", 0}, + {"i", 1}, + {"ɨ", 0}, + {"equal", 1}, + {"≠", 0}, + {"Cyrillic_GHE", 1}, + {"Ғ", 0}, + {"leftarrow", 1}, + {"↚", 0}, + {"Cyrillic_KA", 1}, + {"Ҟ", 0}, + {"u", 1}, + {"µ", 0}, + {"rightarrow", 1}, + {"↛", 0}, + {"z", 1}, + {"ƶ", 0}, + {"G", 1}, + {"Ǥ", 0}, + {"H", 1}, + {"Ħ", 0}, + {"d", 1}, + {"đ", 0}, + {"Cyrillic_ka", 1}, + {"ҟ", 0}, + {"D", 1}, + {"Đ", 0}, + {"v", 1}, + {"√", 0}, + {"O", 1}, + {"Ø", 0}, + {"m", 1}, + {"₥", 0}, + {"Z", 1}, + {"Ƶ", 0}, + {"c", 1}, + {"¢", 0}, + {"L", 1}, + {"Ł", 0}, + {"T", 1}, + {"Ŧ", 0}, + {"slash", 1}, + {"\\", 0}, + {"Cyrillic_ghe", 1}, + {"ғ", 0}, + {"h", 1}, + {"ħ", 0}, + {"I", 1}, + {"Ɨ", 0}, + {"asciicircum", 1}, + {"|", 0}, + {"5", 4}, + {"8", 1}, + {"⅝", 0}, + {"6", 1}, + {"⅚", 0}, + {"Cyrillic_EN", 4}, + {"Cyrillic_O", 1}, + {"№", 0}, + {"Cyrillic_o", 1}, + {"№", 0}, + {"greater", 36}, + {"a", 1}, + {"â", 0}, + {"less", 1}, + {"⋄", 0}, + {"e", 1}, + {"ê", 0}, + {"o", 1}, + {"ô", 0}, + {"diaeresis", 1}, + {"⍩", 0}, + {"space", 1}, + {"^", 0}, + {"i", 1}, + {"î", 0}, + {"equal", 1}, + {"≥", 0}, + {"u", 1}, + {"û", 0}, + {"E", 1}, + {"Ê", 0}, + {"quotedbl", 1}, + {"”", 0}, + {"underscore", 1}, + {"≥", 0}, + {"apostrophe", 1}, + {"’", 0}, + {"O", 1}, + {"Ô", 0}, + {"A", 1}, + {"Â", 0}, + {"greater", 1}, + {"»", 0}, + {"I", 1}, + {"Î", 0}, + {"U", 1}, + {"Û", 0}, + {"semicolon", 22}, + {"a", 1}, + {"ą", 0}, + {"e", 1}, + {"ę", 0}, + {"o", 1}, + {"ǫ", 0}, + {"i", 1}, + {"į", 0}, + {"u", 1}, + {"ų", 0}, + {"E", 1}, + {"Ę", 0}, + {"underscore", 1}, + {"⍮", 0}, + {"O", 1}, + {"Ǫ", 0}, + {"A", 1}, + {"Ą", 0}, + {"I", 1}, + {"Į", 0}, + {"U", 1}, + {"Ų", 0}, + {"K", 2}, + {"comma", 1}, + {"Ķ", 0}, + {"Cyrillic_IE", 2}, + {"equal", 1}, + {"€", 0}, + {"B", 2}, + {"period", 1}, + {"Ḃ", 0}, + {"0", 6}, + {"3", 1}, + {"↉", 0}, + {"asterisk", 1}, + {"°", 0}, + {"asciitilde", 1}, + {"⍬", 0}, + {"Greek_omega", 2}, + {"apostrophe", 1}, + {"ώ", 0}, + {"Greek_OMEGA", 2}, + {"apostrophe", 1}, + {"Ώ", 0}, + {"X", 4}, + {"o", 1}, + {"¤", 0}, + {"O", 1}, + {"¤", 0}, + {"parenleft", 971}, + {"minus", 1}, + {"{", 0}, + {"W", 2}, + {"parenright", 1}, + {"Ⓦ", 0}, + {"g", 2}, + {"parenright", 1}, + {"ⓖ", 0}, + {"kana_KE", 2}, + {"parenright", 1}, + {"㋘", 0}, + {"a", 2}, + {"parenright", 1}, + {"ⓐ", 0}, + {"Greek_IOTA", 1}, + {"Ἱ", 0}, + {"Greek_iota", 1}, + {"ἱ", 0}, + {"1", 65}, + {"1", 2}, + {"parenright", 1}, + {"⑪", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"⑭", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"⑯", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"⑱", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"⑲", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"⑫", 0}, + {"7", 2}, + {"parenright", 1}, + {"⑰", 0}, + {"parenright", 1}, + {"①", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"⑰", 0}, + {"8", 2}, + {"parenright", 1}, + {"⑱", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"⑪", 0}, + {"3", 2}, + {"parenright", 1}, + {"⑬", 0}, + {"2", 2}, + {"parenright", 1}, + {"⑫", 0}, + {"6", 2}, + {"parenright", 1}, + {"⑯", 0}, + {"4", 2}, + {"parenright", 1}, + {"⑭", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"⑬", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"⑩", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"⑫", 0}, + {"5", 2}, + {"parenright", 1}, + {"⑮", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"⑮", 0}, + {"9", 2}, + {"parenright", 1}, + {"⑲", 0}, + {"0", 2}, + {"parenright", 1}, + {"⑩", 0}, + {"Greek_OMICRON", 1}, + {"Ὁ", 0}, + {"C", 2}, + {"parenright", 1}, + {"Ⓒ", 0}, + {"KP_4", 65}, + {"1", 2}, + {"parenright", 1}, + {"㊶", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"㊹", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"㊻", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"㊽", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"㊾", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"㊷", 0}, + {"7", 2}, + {"parenright", 1}, + {"㊼", 0}, + {"parenright", 1}, + {"④", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"㊼", 0}, + {"8", 2}, + {"parenright", 1}, + {"㊽", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"㊶", 0}, + {"3", 2}, + {"parenright", 1}, + {"㊸", 0}, + {"2", 2}, + {"parenright", 1}, + {"㊷", 0}, + {"6", 2}, + {"parenright", 1}, + {"㊻", 0}, + {"4", 2}, + {"parenright", 1}, + {"㊹", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"㊸", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"㊵", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"㊷", 0}, + {"5", 2}, + {"parenright", 1}, + {"㊺", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"㊺", 0}, + {"9", 2}, + {"parenright", 1}, + {"㊾", 0}, + {"0", 2}, + {"parenright", 1}, + {"㊵", 0}, + {"kana_SA", 2}, + {"parenright", 1}, + {"㋚", 0}, + {"e", 2}, + {"parenright", 1}, + {"ⓔ", 0}, + {"F", 2}, + {"parenright", 1}, + {"Ⓕ", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"⑥", 0}, + {"o", 2}, + {"parenright", 1}, + {"ⓞ", 0}, + {"l", 2}, + {"parenright", 1}, + {"ⓛ", 0}, + {"kana_SE", 2}, + {"parenright", 1}, + {"㋝", 0}, + {"kana_SU", 2}, + {"parenright", 1}, + {"㋜", 0}, + {"t", 2}, + {"parenright", 1}, + {"ⓣ", 0}, + {"kana_ME", 2}, + {"parenright", 1}, + {"㋱", 0}, + {"Greek_upsilon", 1}, + {"ὑ", 0}, + {"kana_WO", 2}, + {"parenright", 1}, + {"㋾", 0}, + {"space", 1}, + {"˘", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"⑧", 0}, + {"Greek_RHO", 1}, + {"Ῥ", 0}, + {"Q", 2}, + {"parenright", 1}, + {"Ⓠ", 0}, + {"y", 2}, + {"parenright", 1}, + {"ⓨ", 0}, + {"b", 2}, + {"parenright", 1}, + {"ⓑ", 0}, + {"kana_YO", 2}, + {"parenright", 1}, + {"㋵", 0}, + {"i", 2}, + {"parenright", 1}, + {"ⓘ", 0}, + {"kana_MA", 2}, + {"parenright", 1}, + {"㋮", 0}, + {"k", 2}, + {"parenright", 1}, + {"ⓚ", 0}, + {"n", 2}, + {"parenright", 1}, + {"ⓝ", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"⑨", 0}, + {"KP_Space", 65}, + {"1", 2}, + {"parenright", 1}, + {"㉑", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"㉔", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"㉖", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"㉘", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"㉙", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"7", 2}, + {"parenright", 1}, + {"㉗", 0}, + {"parenright", 1}, + {"②", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"㉗", 0}, + {"8", 2}, + {"parenright", 1}, + {"㉘", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"㉑", 0}, + {"3", 2}, + {"parenright", 1}, + {"㉓", 0}, + {"2", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"6", 2}, + {"parenright", 1}, + {"㉖", 0}, + {"4", 2}, + {"parenright", 1}, + {"㉔", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"㉓", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"⑳", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"5", 2}, + {"parenright", 1}, + {"㉕", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"㉕", 0}, + {"9", 2}, + {"parenright", 1}, + {"㉙", 0}, + {"0", 2}, + {"parenright", 1}, + {"⑳", 0}, + {"kana_YU", 2}, + {"parenright", 1}, + {"㋴", 0}, + {"kana_TE", 2}, + {"parenright", 1}, + {"㋢", 0}, + {"7", 2}, + {"parenright", 1}, + {"⑦", 0}, + {"kana_NU", 2}, + {"parenright", 1}, + {"㋦", 0}, + {"kana_HO", 2}, + {"parenright", 1}, + {"㋭", 0}, + {"kana_HI", 2}, + {"parenright", 1}, + {"㋪", 0}, + {"j", 2}, + {"parenright", 1}, + {"ⓙ", 0}, + {"kana_E", 2}, + {"parenright", 1}, + {"㋓", 0}, + {"x", 2}, + {"parenright", 1}, + {"ⓧ", 0}, + {"Greek_epsilon", 1}, + {"ἑ", 0}, + {"q", 2}, + {"parenright", 1}, + {"ⓠ", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"⑦", 0}, + {"kana_I", 2}, + {"parenright", 1}, + {"㋑", 0}, + {"kana_WA", 2}, + {"parenright", 1}, + {"㋻", 0}, + {"kana_RU", 2}, + {"parenright", 1}, + {"㋸", 0}, + {"V", 2}, + {"parenright", 1}, + {"Ⓥ", 0}, + {"u", 2}, + {"parenright", 1}, + {"ⓤ", 0}, + {"kana_NI", 2}, + {"parenright", 1}, + {"㋥", 0}, + {"kana_MU", 2}, + {"parenright", 1}, + {"㋰", 0}, + {"kana_CHI", 2}, + {"parenright", 1}, + {"㋠", 0}, + {"kana_HA", 2}, + {"parenright", 1}, + {"㋩", 0}, + {"z", 2}, + {"parenright", 1}, + {"ⓩ", 0}, + {"G", 2}, + {"parenright", 1}, + {"Ⓖ", 0}, + {"Greek_ALPHA", 1}, + {"Ἁ", 0}, + {"H", 2}, + {"parenright", 1}, + {"Ⓗ", 0}, + {"8", 2}, + {"parenright", 1}, + {"⑧", 0}, + {"KP_1", 65}, + {"1", 2}, + {"parenright", 1}, + {"⑪", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"⑭", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"⑯", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"⑱", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"⑲", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"⑫", 0}, + {"7", 2}, + {"parenright", 1}, + {"⑰", 0}, + {"parenright", 1}, + {"①", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"⑰", 0}, + {"8", 2}, + {"parenright", 1}, + {"⑱", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"⑪", 0}, + {"3", 2}, + {"parenright", 1}, + {"⑬", 0}, + {"2", 2}, + {"parenright", 1}, + {"⑫", 0}, + {"6", 2}, + {"parenright", 1}, + {"⑯", 0}, + {"4", 2}, + {"parenright", 1}, + {"⑭", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"⑬", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"⑩", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"⑫", 0}, + {"5", 2}, + {"parenright", 1}, + {"⑮", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"⑮", 0}, + {"9", 2}, + {"parenright", 1}, + {"⑲", 0}, + {"0", 2}, + {"parenright", 1}, + {"⑩", 0}, + {"3", 65}, + {"1", 2}, + {"parenright", 1}, + {"㉛", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"㉞", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"㊱", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"㊳", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"㊴", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"㉜", 0}, + {"7", 2}, + {"parenright", 1}, + {"㊲", 0}, + {"parenright", 1}, + {"③", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"㊲", 0}, + {"8", 2}, + {"parenright", 1}, + {"㊳", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"㉛", 0}, + {"3", 2}, + {"parenright", 1}, + {"㉝", 0}, + {"2", 2}, + {"parenright", 1}, + {"㉜", 0}, + {"6", 2}, + {"parenright", 1}, + {"㊱", 0}, + {"4", 2}, + {"parenright", 1}, + {"㉞", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"㉝", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"㉚", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"㉜", 0}, + {"5", 2}, + {"parenright", 1}, + {"㉟", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"㉟", 0}, + {"9", 2}, + {"parenright", 1}, + {"㊴", 0}, + {"0", 2}, + {"parenright", 1}, + {"㉚", 0}, + {"E", 2}, + {"parenright", 1}, + {"Ⓔ", 0}, + {"S", 2}, + {"parenright", 1}, + {"Ⓢ", 0}, + {"2", 65}, + {"1", 2}, + {"parenright", 1}, + {"㉑", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"㉔", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"㉖", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"㉘", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"㉙", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"7", 2}, + {"parenright", 1}, + {"㉗", 0}, + {"parenright", 1}, + {"②", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"㉗", 0}, + {"8", 2}, + {"parenright", 1}, + {"㉘", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"㉑", 0}, + {"3", 2}, + {"parenright", 1}, + {"㉓", 0}, + {"2", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"6", 2}, + {"parenright", 1}, + {"㉖", 0}, + {"4", 2}, + {"parenright", 1}, + {"㉔", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"㉓", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"⑳", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"5", 2}, + {"parenright", 1}, + {"㉕", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"㉕", 0}, + {"9", 2}, + {"parenright", 1}, + {"㉙", 0}, + {"0", 2}, + {"parenright", 1}, + {"⑳", 0}, + {"Y", 2}, + {"parenright", 1}, + {"Ⓨ", 0}, + {"kana_RA", 2}, + {"parenright", 1}, + {"㋶", 0}, + {"f", 2}, + {"parenright", 1}, + {"ⓕ", 0}, + {"Greek_omicron", 1}, + {"ὁ", 0}, + {"Greek_eta", 1}, + {"ἡ", 0}, + {"kana_HE", 2}, + {"parenright", 1}, + {"㋬", 0}, + {"Greek_rho", 1}, + {"ῥ", 0}, + {"kana_KO", 2}, + {"parenright", 1}, + {"㋙", 0}, + {"d", 2}, + {"parenright", 1}, + {"ⓓ", 0}, + {"kana_NE", 2}, + {"parenright", 1}, + {"㋧", 0}, + {"D", 2}, + {"parenright", 1}, + {"Ⓓ", 0}, + {"kana_FU", 2}, + {"parenright", 1}, + {"㋫", 0}, + {"6", 2}, + {"parenright", 1}, + {"⑥", 0}, + {"Greek_alpha", 1}, + {"ἁ", 0}, + {"kana_A", 2}, + {"parenright", 1}, + {"㋐", 0}, + {"w", 2}, + {"parenright", 1}, + {"ⓦ", 0}, + {"Greek_ETA", 1}, + {"Ἡ", 0}, + {"4", 65}, + {"1", 2}, + {"parenright", 1}, + {"㊶", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"㊹", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"㊻", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"㊽", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"㊾", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"㊷", 0}, + {"7", 2}, + {"parenright", 1}, + {"㊼", 0}, + {"parenright", 1}, + {"④", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"㊼", 0}, + {"8", 2}, + {"parenright", 1}, + {"㊽", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"㊶", 0}, + {"3", 2}, + {"parenright", 1}, + {"㊸", 0}, + {"2", 2}, + {"parenright", 1}, + {"㊷", 0}, + {"6", 2}, + {"parenright", 1}, + {"㊻", 0}, + {"4", 2}, + {"parenright", 1}, + {"㊹", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"㊸", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"㊵", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"㊷", 0}, + {"5", 2}, + {"parenright", 1}, + {"㊺", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"㊺", 0}, + {"9", 2}, + {"parenright", 1}, + {"㊾", 0}, + {"0", 2}, + {"parenright", 1}, + {"㊵", 0}, + {"kana_KU", 2}, + {"parenright", 1}, + {"㋗", 0}, + {"KP_3", 65}, + {"1", 2}, + {"parenright", 1}, + {"㉛", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"㉞", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"㊱", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"㊳", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"㊴", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"㉜", 0}, + {"7", 2}, + {"parenright", 1}, + {"㊲", 0}, + {"parenright", 1}, + {"③", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"㊲", 0}, + {"8", 2}, + {"parenright", 1}, + {"㊳", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"㉛", 0}, + {"3", 2}, + {"parenright", 1}, + {"㉝", 0}, + {"2", 2}, + {"parenright", 1}, + {"㉜", 0}, + {"6", 2}, + {"parenright", 1}, + {"㊱", 0}, + {"4", 2}, + {"parenright", 1}, + {"㉞", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"㉝", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"㉚", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"㉜", 0}, + {"5", 2}, + {"parenright", 1}, + {"㉟", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"㉟", 0}, + {"9", 2}, + {"parenright", 1}, + {"㊴", 0}, + {"0", 2}, + {"parenright", 1}, + {"㉚", 0}, + {"p", 2}, + {"parenright", 1}, + {"ⓟ", 0}, + {"J", 2}, + {"parenright", 1}, + {"Ⓙ", 0}, + {"kana_YA", 2}, + {"parenright", 1}, + {"㋳", 0}, + {"v", 2}, + {"parenright", 1}, + {"ⓥ", 0}, + {"P", 2}, + {"parenright", 1}, + {"Ⓟ", 0}, + {"M", 2}, + {"parenright", 1}, + {"Ⓜ", 0}, + {"O", 2}, + {"parenright", 1}, + {"Ⓞ", 0}, + {"m", 2}, + {"parenright", 1}, + {"ⓜ", 0}, + {"r", 2}, + {"parenright", 1}, + {"ⓡ", 0}, + {"s", 2}, + {"parenright", 1}, + {"ⓢ", 0}, + {"Z", 2}, + {"parenright", 1}, + {"Ⓩ", 0}, + {"kana_U", 2}, + {"parenright", 1}, + {"㋒", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"⓪", 0}, + {"A", 2}, + {"parenright", 1}, + {"Ⓐ", 0}, + {"R", 2}, + {"parenright", 1}, + {"Ⓡ", 0}, + {"kana_TO", 2}, + {"parenright", 1}, + {"㋣", 0}, + {"kana_TA", 2}, + {"parenright", 1}, + {"㋟", 0}, + {"c", 2}, + {"parenright", 1}, + {"ⓒ", 0}, + {"kana_RO", 2}, + {"parenright", 1}, + {"㋺", 0}, + {"L", 2}, + {"parenright", 1}, + {"Ⓛ", 0}, + {"Greek_EPSILON", 1}, + {"Ἑ", 0}, + {"KP_2", 65}, + {"1", 2}, + {"parenright", 1}, + {"㉑", 0}, + {"KP_4", 2}, + {"parenright", 1}, + {"㉔", 0}, + {"KP_6", 2}, + {"parenright", 1}, + {"㉖", 0}, + {"KP_8", 2}, + {"parenright", 1}, + {"㉘", 0}, + {"KP_9", 2}, + {"parenright", 1}, + {"㉙", 0}, + {"KP_Space", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"7", 2}, + {"parenright", 1}, + {"㉗", 0}, + {"parenright", 1}, + {"②", 0}, + {"KP_7", 2}, + {"parenright", 1}, + {"㉗", 0}, + {"8", 2}, + {"parenright", 1}, + {"㉘", 0}, + {"KP_1", 2}, + {"parenright", 1}, + {"㉑", 0}, + {"3", 2}, + {"parenright", 1}, + {"㉓", 0}, + {"2", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"6", 2}, + {"parenright", 1}, + {"㉖", 0}, + {"4", 2}, + {"parenright", 1}, + {"㉔", 0}, + {"KP_3", 2}, + {"parenright", 1}, + {"㉓", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"⑳", 0}, + {"KP_2", 2}, + {"parenright", 1}, + {"㉒", 0}, + {"5", 2}, + {"parenright", 1}, + {"㉕", 0}, + {"KP_5", 2}, + {"parenright", 1}, + {"㉕", 0}, + {"9", 2}, + {"parenright", 1}, + {"㉙", 0}, + {"0", 2}, + {"parenright", 1}, + {"⑳", 0}, + {"kana_O", 2}, + {"parenright", 1}, + {"㋔", 0}, + {"kana_RI", 2}, + {"parenright", 1}, + {"㋷", 0}, + {"T", 2}, + {"parenright", 1}, + {"Ⓣ", 0}, + {"kana_KA", 2}, + {"parenright", 1}, + {"㋕", 0}, + {"kana_MI", 2}, + {"parenright", 1}, + {"㋯", 0}, + {"5", 8}, + {"parenright", 1}, + {"⑤", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"㊿", 0}, + {"0", 2}, + {"parenright", 1}, + {"㊿", 0}, + {"kana_KI", 2}, + {"parenright", 1}, + {"㋖", 0}, + {"KP_5", 8}, + {"parenright", 1}, + {"⑤", 0}, + {"KP_0", 2}, + {"parenright", 1}, + {"㊿", 0}, + {"0", 2}, + {"parenright", 1}, + {"㊿", 0}, + {"K", 2}, + {"parenright", 1}, + {"Ⓚ", 0}, + {"9", 2}, + {"parenright", 1}, + {"⑨", 0}, + {"kana_SO", 2}, + {"parenright", 1}, + {"㋞", 0}, + {"B", 2}, + {"parenright", 1}, + {"Ⓑ", 0}, + {"kana_TSU", 2}, + {"parenright", 1}, + {"㋡", 0}, + {"0", 2}, + {"parenright", 1}, + {"⓪", 0}, + {"kana_MO", 2}, + {"parenright", 1}, + {"㋲", 0}, + {"Greek_omega", 1}, + {"ὡ", 0}, + {"kana_NO", 2}, + {"parenright", 1}, + {"㋨", 0}, + {"Greek_OMEGA", 1}, + {"Ὡ", 0}, + {"kana_NA", 2}, + {"parenright", 1}, + {"㋤", 0}, + {"X", 2}, + {"parenright", 1}, + {"Ⓧ", 0}, + {"parenleft", 1}, + {"[", 0}, + {"h", 2}, + {"parenright", 1}, + {"ⓗ", 0}, + {"I", 2}, + {"parenright", 1}, + {"Ⓘ", 0}, + {"N", 2}, + {"parenright", 1}, + {"Ⓝ", 0}, + {"kana_SHI", 2}, + {"parenright", 1}, + {"㋛", 0}, + {"U", 2}, + {"parenright", 1}, + {"Ⓤ", 0}, + {"kana_RE", 2}, + {"parenright", 1}, + {"㋹", 0}, + {"Greek_UPSILON", 1}, + {"Ὑ", 0}, + {"h", 2}, + {"comma", 1}, + {"ḩ", 0}, + {"I", 28}, + {"minus", 1}, + {"Ī", 0}, + {"period", 1}, + {"İ", 0}, + {"diaeresis", 1}, + {"Ï", 0}, + {"j", 1}, + {"IJ", 0}, + {"quotedbl", 1}, + {"Ï", 0}, + {"acute", 1}, + {"Í", 0}, + {"underscore", 1}, + {"Ī", 0}, + {"J", 1}, + {"IJ", 0}, + {"apostrophe", 1}, + {"Í", 0}, + {"comma", 1}, + {"Į", 0}, + {"asciitilde", 1}, + {"Ĩ", 0}, + {"greater", 1}, + {"Î", 0}, + {"grave", 1}, + {"Ì", 0}, + {"asciicircum", 1}, + {"Î", 0}, + {"N", 16}, + {"less", 1}, + {"Ň", 0}, + {"o", 1}, + {"№", 0}, + {"equal", 1}, + {"₦", 0}, + {"G", 1}, + {"Ŋ", 0}, + {"apostrophe", 1}, + {"Ń", 0}, + {"O", 1}, + {"№", 0}, + {"comma", 1}, + {"Ņ", 0}, + {"asciitilde", 1}, + {"Ñ", 0}, + {"grave", 362}, + {"W", 1}, + {"Ẁ", 0}, + {"dead_breve", 4}, + {"a", 1}, + {"ằ", 0}, + {"A", 1}, + {"Ằ", 0}, + {"a", 1}, + {"à", 0}, + {"Greek_IOTA", 1}, + {"Ὶ", 0}, + {"Greek_iota", 1}, + {"ὶ", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ờ", 0}, + {"u", 1}, + {"ừ", 0}, + {"O", 1}, + {"Ờ", 0}, + {"U", 1}, + {"Ừ", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ầ", 0}, + {"e", 1}, + {"ề", 0}, + {"o", 1}, + {"ồ", 0}, + {"E", 1}, + {"Ề", 0}, + {"O", 1}, + {"Ồ", 0}, + {"A", 1}, + {"Ầ", 0}, + {"Greek_OMICRON", 1}, + {"Ὸ", 0}, + {"Acircumflex", 1}, + {"Ầ", 0}, + {"Cyrillic_er", 1}, + {"р̀", 0}, + {"e", 1}, + {"è", 0}, + {"o", 1}, + {"ò", 0}, + {"Udiaeresis", 1}, + {"Ǜ", 0}, + {"Greek_upsilon", 1}, + {"ὺ", 0}, + {"uhorn", 1}, + {"ừ", 0}, + {"space", 1}, + {"`", 0}, + {"dead_macron", 8}, + {"e", 1}, + {"ḕ", 0}, + {"o", 1}, + {"ṑ", 0}, + {"E", 1}, + {"Ḕ", 0}, + {"O", 1}, + {"Ṑ", 0}, + {"acircumflex", 1}, + {"ầ", 0}, + {"Ecircumflex", 1}, + {"Ề", 0}, + {"Cyrillic_I", 1}, + {"Ѝ", 0}, + {"y", 1}, + {"ỳ", 0}, + {"b", 4}, + {"a", 1}, + {"ằ", 0}, + {"A", 1}, + {"Ằ", 0}, + {"Cyrillic_O", 1}, + {"О̀", 0}, + {"i", 1}, + {"ì", 0}, + {"n", 1}, + {"ǹ", 0}, + {"Cyrillic_a", 1}, + {"а̀", 0}, + {"parenright", 26}, + {"Greek_IOTA", 1}, + {"Ἲ", 0}, + {"Greek_iota", 1}, + {"ἲ", 0}, + {"Greek_OMICRON", 1}, + {"Ὂ", 0}, + {"Greek_upsilon", 1}, + {"ὒ", 0}, + {"Greek_epsilon", 1}, + {"ἒ", 0}, + {"Greek_ALPHA", 1}, + {"Ἂ", 0}, + {"Greek_omicron", 1}, + {"ὂ", 0}, + {"Greek_eta", 1}, + {"ἢ", 0}, + {"Greek_alpha", 1}, + {"ἂ", 0}, + {"Greek_ETA", 1}, + {"Ἢ", 0}, + {"Greek_EPSILON", 1}, + {"Ἒ", 0}, + {"Greek_omega", 1}, + {"ὢ", 0}, + {"Greek_OMEGA", 1}, + {"Ὢ", 0}, + {"Ohorn", 1}, + {"Ờ", 0}, + {"ohorn", 1}, + {"ờ", 0}, + {"Cyrillic_ER", 1}, + {"Р̀", 0}, + {"Greek_epsilon", 1}, + {"ὲ", 0}, + {"Cyrillic_U", 1}, + {"У̀", 0}, + {"Ocircumflex", 1}, + {"Ồ", 0}, + {"omacron", 1}, + {"ṑ", 0}, + {"ocircumflex", 1}, + {"ồ", 0}, + {"u", 1}, + {"ù", 0}, + {"Greek_ALPHA", 1}, + {"Ὰ", 0}, + {"Cyrillic_ie", 1}, + {"ѐ", 0}, + {"emacron", 1}, + {"ḕ", 0}, + {"E", 1}, + {"È", 0}, + {"Greek_iotadieresis", 1}, + {"ῒ", 0}, + {"Y", 1}, + {"Ỳ", 0}, + {"Cyrillic_i", 1}, + {"ѝ", 0}, + {"dead_dasia", 28}, + {"Greek_IOTA", 1}, + {"Ἳ", 0}, + {"Greek_iota", 1}, + {"ἳ", 0}, + {"Greek_OMICRON", 1}, + {"Ὃ", 0}, + {"Greek_upsilon", 1}, + {"ὓ", 0}, + {"Greek_epsilon", 1}, + {"ἓ", 0}, + {"Greek_ALPHA", 1}, + {"Ἃ", 0}, + {"Greek_omicron", 1}, + {"ὃ", 0}, + {"Greek_eta", 1}, + {"ἣ", 0}, + {"Greek_alpha", 1}, + {"ἃ", 0}, + {"Greek_ETA", 1}, + {"Ἣ", 0}, + {"Greek_EPSILON", 1}, + {"Ἓ", 0}, + {"Greek_omega", 1}, + {"ὣ", 0}, + {"Greek_OMEGA", 1}, + {"Ὣ", 0}, + {"Greek_UPSILON", 1}, + {"Ὓ", 0}, + {"Greek_upsilondieresis", 1}, + {"ῢ", 0}, + {"Greek_omicron", 1}, + {"ὸ", 0}, + {"Greek_eta", 1}, + {"ὴ", 0}, + {"Abreve", 1}, + {"Ằ", 0}, + {"dead_psili", 26}, + {"Greek_IOTA", 1}, + {"Ἲ", 0}, + {"Greek_iota", 1}, + {"ἲ", 0}, + {"Greek_OMICRON", 1}, + {"Ὂ", 0}, + {"Greek_upsilon", 1}, + {"ὒ", 0}, + {"Greek_epsilon", 1}, + {"ἒ", 0}, + {"Greek_ALPHA", 1}, + {"Ἂ", 0}, + {"Greek_omicron", 1}, + {"ὂ", 0}, + {"Greek_eta", 1}, + {"ἢ", 0}, + {"Greek_alpha", 1}, + {"ἂ", 0}, + {"Greek_ETA", 1}, + {"Ἢ", 0}, + {"Greek_EPSILON", 1}, + {"Ἒ", 0}, + {"Greek_omega", 1}, + {"ὢ", 0}, + {"Greek_OMEGA", 1}, + {"Ὢ", 0}, + {"quotedbl", 8}, + {"Greek_iota", 1}, + {"ῒ", 0}, + {"Greek_upsilon", 1}, + {"ῢ", 0}, + {"u", 1}, + {"ǜ", 0}, + {"U", 1}, + {"Ǜ", 0}, + {"plus", 8}, + {"o", 1}, + {"ờ", 0}, + {"u", 1}, + {"ừ", 0}, + {"O", 1}, + {"Ờ", 0}, + {"U", 1}, + {"Ừ", 0}, + {"Greek_alpha", 1}, + {"ὰ", 0}, + {"ecircumflex", 1}, + {"ề", 0}, + {"w", 1}, + {"ẁ", 0}, + {"Greek_ETA", 1}, + {"Ὴ", 0}, + {"Cyrillic_o", 1}, + {"о̀", 0}, + {"Emacron", 1}, + {"Ḕ", 0}, + {"underscore", 8}, + {"e", 1}, + {"ḕ", 0}, + {"o", 1}, + {"ṑ", 0}, + {"E", 1}, + {"Ḕ", 0}, + {"O", 1}, + {"Ṑ", 0}, + {"O", 1}, + {"Ò", 0}, + {"abreve", 1}, + {"ằ", 0}, + {"macron", 8}, + {"e", 1}, + {"ḕ", 0}, + {"o", 1}, + {"ṑ", 0}, + {"E", 1}, + {"Ḕ", 0}, + {"O", 1}, + {"Ṑ", 0}, + {"A", 1}, + {"À", 0}, + {"Greek_EPSILON", 1}, + {"Ὲ", 0}, + {"Cyrillic_A", 1}, + {"А̀", 0}, + {"Omacron", 1}, + {"Ṑ", 0}, + {"Cyrillic_IE", 1}, + {"Ѐ", 0}, + {"Greek_omega", 1}, + {"ὼ", 0}, + {"dead_diaeresis", 8}, + {"Greek_iota", 1}, + {"ῒ", 0}, + {"Greek_upsilon", 1}, + {"ῢ", 0}, + {"u", 1}, + {"ǜ", 0}, + {"U", 1}, + {"Ǜ", 0}, + {"Uhorn", 1}, + {"Ừ", 0}, + {"Greek_OMEGA", 1}, + {"Ὼ", 0}, + {"parenleft", 28}, + {"Greek_IOTA", 1}, + {"Ἳ", 0}, + {"Greek_iota", 1}, + {"ἳ", 0}, + {"Greek_OMICRON", 1}, + {"Ὃ", 0}, + {"Greek_upsilon", 1}, + {"ὓ", 0}, + {"Greek_epsilon", 1}, + {"ἓ", 0}, + {"Greek_ALPHA", 1}, + {"Ἃ", 0}, + {"Greek_omicron", 1}, + {"ὃ", 0}, + {"Greek_eta", 1}, + {"ἣ", 0}, + {"Greek_alpha", 1}, + {"ἃ", 0}, + {"Greek_ETA", 1}, + {"Ἣ", 0}, + {"Greek_EPSILON", 1}, + {"Ἓ", 0}, + {"Greek_omega", 1}, + {"ὣ", 0}, + {"Greek_OMEGA", 1}, + {"Ὣ", 0}, + {"Greek_UPSILON", 1}, + {"Ὓ", 0}, + {"udiaeresis", 1}, + {"ǜ", 0}, + {"I", 1}, + {"Ì", 0}, + {"N", 1}, + {"Ǹ", 0}, + {"grave", 24}, + {"Cyrillic_er", 1}, + {"р̏", 0}, + {"Cyrillic_I", 1}, + {"И̏", 0}, + {"Cyrillic_O", 1}, + {"О̏", 0}, + {"Cyrillic_a", 1}, + {"а̏", 0}, + {"Cyrillic_ER", 1}, + {"Р̏", 0}, + {"Cyrillic_U", 1}, + {"У̏", 0}, + {"Cyrillic_ie", 1}, + {"е̏", 0}, + {"Cyrillic_i", 1}, + {"и̏", 0}, + {"Cyrillic_o", 1}, + {"о̏", 0}, + {"Cyrillic_A", 1}, + {"А̏", 0}, + {"Cyrillic_IE", 1}, + {"Е̏", 0}, + {"Cyrillic_u", 1}, + {"у̏", 0}, + {"U", 1}, + {"Ù", 0}, + {"Cyrillic_u", 1}, + {"у̀", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ầ", 0}, + {"e", 1}, + {"ề", 0}, + {"o", 1}, + {"ồ", 0}, + {"E", 1}, + {"Ề", 0}, + {"O", 1}, + {"Ồ", 0}, + {"A", 1}, + {"Ầ", 0}, + {"Greek_UPSILON", 1}, + {"Ὺ", 0}, + {"U", 106}, + {"minus", 1}, + {"Ū", 0}, + {"g", 1}, + {"ğ", 0}, + {"a", 1}, + {"ă", 0}, + {"Greek_IOTA", 1}, + {"Ῐ", 0}, + {"Greek_iota", 1}, + {"ῐ", 0}, + {"exclam", 4}, + {"a", 1}, + {"ặ", 0}, + {"A", 1}, + {"Ặ", 0}, + {"e", 1}, + {"ĕ", 0}, + {"o", 1}, + {"ŏ", 0}, + {"Greek_upsilon", 1}, + {"ῠ", 0}, + {"diaeresis", 1}, + {"Ü", 0}, + {"dead_belowdot", 4}, + {"a", 1}, + {"ặ", 0}, + {"A", 1}, + {"Ặ", 0}, + {"space", 5}, + {"comma", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"Cyrillic_I", 1}, + {"Й", 0}, + {"i", 1}, + {"ĭ", 0}, + {"Cyrillic_a", 1}, + {"ӑ", 0}, + {"Cyrillic_U", 1}, + {"Ў", 0}, + {"u", 1}, + {"ŭ", 0}, + {"G", 1}, + {"Ğ", 0}, + {"Greek_ALPHA", 1}, + {"Ᾰ", 0}, + {"Cyrillic_ie", 1}, + {"ӗ", 0}, + {"E", 1}, + {"Ĕ", 0}, + {"Cyrillic_i", 1}, + {"й", 0}, + {"Cyrillic_zhe", 1}, + {"ӂ", 0}, + {"quotedbl", 1}, + {"Ü", 0}, + {"cedilla", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"Greek_alpha", 1}, + {"ᾰ", 0}, + {"acute", 1}, + {"Ú", 0}, + {"underscore", 1}, + {"Ū", 0}, + {"apostrophe", 1}, + {"Ú", 0}, + {"O", 1}, + {"Ŏ", 0}, + {"asterisk", 1}, + {"Ů", 0}, + {"A", 1}, + {"Ă", 0}, + {"Cyrillic_A", 1}, + {"Ӑ", 0}, + {"comma", 1}, + {"Ų", 0}, + {"asciitilde", 1}, + {"Ũ", 0}, + {"greater", 1}, + {"Û", 0}, + {"Cyrillic_ZHE", 1}, + {"Ӂ", 0}, + {"Cyrillic_IE", 1}, + {"Ӗ", 0}, + {"dead_cedilla", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"I", 1}, + {"Ĭ", 0}, + {"grave", 1}, + {"Ù", 0}, + {"U", 1}, + {"Ŭ", 0}, + {"Cyrillic_u", 1}, + {"ў", 0}, + {"asciicircum", 1}, + {"Û", 0}, + {"Greek_UPSILON", 1}, + {"Ῠ", 0}, + {"asciicircum", 214}, + {"minus", 1}, + {"¯", 0}, + {"period", 1}, + {"·", 0}, + {"W", 1}, + {"Ŵ", 0}, + {"g", 1}, + {"ĝ", 0}, + {"a", 1}, + {"â", 0}, + {"1", 1}, + {"¹", 0}, + {"C", 1}, + {"Ĉ", 0}, + {"KP_4", 1}, + {"⁴", 0}, + {"exclam", 12}, + {"a", 1}, + {"ậ", 0}, + {"e", 1}, + {"ệ", 0}, + {"o", 1}, + {"ộ", 0}, + {"E", 1}, + {"Ệ", 0}, + {"O", 1}, + {"Ộ", 0}, + {"A", 1}, + {"Ậ", 0}, + {"Cyrillic_er", 1}, + {"р̂", 0}, + {"o", 1}, + {"ô", 0}, + {"e", 1}, + {"ê", 0}, + {"KP_6", 1}, + {"⁶", 0}, + {"dead_belowdot", 12}, + {"a", 1}, + {"ậ", 0}, + {"e", 1}, + {"ệ", 0}, + {"o", 1}, + {"ộ", 0}, + {"E", 1}, + {"Ệ", 0}, + {"O", 1}, + {"Ộ", 0}, + {"A", 1}, + {"Ậ", 0}, + {"space", 1}, + {"^", 0}, + {"KP_8", 1}, + {"⁸", 0}, + {"Cyrillic_I", 1}, + {"И̂", 0}, + {"y", 1}, + {"ŷ", 0}, + {"Cyrillic_O", 1}, + {"О̂", 0}, + {"i", 1}, + {"î", 0}, + {"KP_9", 1}, + {"⁹", 0}, + {"equal", 1}, + {"⁼", 0}, + {"KP_Space", 1}, + {"²", 0}, + {"7", 1}, + {"⁷", 0}, + {"Cyrillic_a", 1}, + {"а̂", 0}, + {"j", 1}, + {"ĵ", 0}, + {"parenright", 1}, + {"⁾", 0}, + {"Cyrillic_ER", 1}, + {"Р̂", 0}, + {"KP_7", 1}, + {"⁷", 0}, + {"underbar", 24}, + {"a", 1}, + {"ª", 0}, + {"o", 1}, + {"º", 0}, + {"l", 1}, + {"ˡ", 0}, + {"y", 1}, + {"ʸ", 0}, + {"i", 1}, + {"ⁱ", 0}, + {"n", 1}, + {"ⁿ", 0}, + {"j", 1}, + {"ʲ", 0}, + {"x", 1}, + {"ˣ", 0}, + {"w", 1}, + {"ʷ", 0}, + {"r", 1}, + {"ʳ", 0}, + {"s", 1}, + {"ˢ", 0}, + {"h", 1}, + {"ʰ", 0}, + {"Cyrillic_U", 1}, + {"У̂", 0}, + {"u", 1}, + {"û", 0}, + {"z", 1}, + {"ẑ", 0}, + {"G", 1}, + {"Ĝ", 0}, + {"H", 1}, + {"Ĥ", 0}, + {"8", 1}, + {"⁸", 0}, + {"KP_1", 1}, + {"¹", 0}, + {"3", 1}, + {"³", 0}, + {"Cyrillic_ie", 1}, + {"е̂", 0}, + {"E", 1}, + {"Ê", 0}, + {"S", 1}, + {"Ŝ", 0}, + {"2", 1}, + {"²", 0}, + {"Y", 1}, + {"Ŷ", 0}, + {"Cyrillic_i", 1}, + {"и̂", 0}, + {"plus", 1}, + {"⁺", 0}, + {"6", 1}, + {"⁶", 0}, + {"w", 1}, + {"ŵ", 0}, + {"Cyrillic_o", 1}, + {"о̂", 0}, + {"4", 1}, + {"⁴", 0}, + {"KP_3", 1}, + {"³", 0}, + {"underscore", 24}, + {"a", 1}, + {"ª", 0}, + {"o", 1}, + {"º", 0}, + {"l", 1}, + {"ˡ", 0}, + {"y", 1}, + {"ʸ", 0}, + {"i", 1}, + {"ⁱ", 0}, + {"n", 1}, + {"ⁿ", 0}, + {"j", 1}, + {"ʲ", 0}, + {"x", 1}, + {"ˣ", 0}, + {"w", 1}, + {"ʷ", 0}, + {"r", 1}, + {"ʳ", 0}, + {"s", 1}, + {"ˢ", 0}, + {"h", 1}, + {"ʰ", 0}, + {"J", 1}, + {"Ĵ", 0}, + {"O", 1}, + {"Ô", 0}, + {"s", 1}, + {"ŝ", 0}, + {"Z", 1}, + {"Ẑ", 0}, + {"KP_0", 1}, + {"⁰", 0}, + {"A", 1}, + {"Â", 0}, + {"c", 1}, + {"ĉ", 0}, + {"KP_Add", 1}, + {"⁺", 0}, + {"KP_2", 1}, + {"²", 0}, + {"Cyrillic_A", 1}, + {"А̂", 0}, + {"slash", 1}, + {"|", 0}, + {"5", 1}, + {"⁵", 0}, + {"KP_5", 1}, + {"⁵", 0}, + {"9", 1}, + {"⁹", 0}, + {"Cyrillic_IE", 1}, + {"Е̂", 0}, + {"0", 1}, + {"⁰", 0}, + {"parenleft", 1}, + {"⁽", 0}, + {"h", 1}, + {"ĥ", 0}, + {"I", 1}, + {"Î", 0}, + {"U", 1}, + {"Û", 0}, + {"Cyrillic_u", 1}, + {"у̂", 0}, + {"KP_Equal", 1}, + {"⁼", 0}, + {"Greek_UPSILON", 4}, + {"quotedbl", 1}, + {"Ϋ", 0}, + {"apostrophe", 1}, + {"Ύ", 0}, + {"dead_belowcircumflex", 24}, + {"e", 1}, + {"ḙ", 0}, + {"l", 1}, + {"ḽ", 0}, + {"t", 1}, + {"ṱ", 0}, + {"n", 1}, + {"ṋ", 0}, + {"u", 1}, + {"ṷ", 0}, + {"E", 1}, + {"Ḙ", 0}, + {"d", 1}, + {"ḓ", 0}, + {"D", 1}, + {"Ḓ", 0}, + {"L", 1}, + {"Ḽ", 0}, + {"T", 1}, + {"Ṱ", 0}, + {"N", 1}, + {"Ṋ", 0}, + {"U", 1}, + {"Ṷ", 0}, + {"dead_caron", 134}, + {"minus", 1}, + {"₋", 0}, + {"g", 1}, + {"ǧ", 0}, + {"a", 1}, + {"ǎ", 0}, + {"1", 1}, + {"₁", 0}, + {"ezh", 1}, + {"ǯ", 0}, + {"C", 1}, + {"Č", 0}, + {"e", 1}, + {"ě", 0}, + {"o", 1}, + {"ǒ", 0}, + {"l", 1}, + {"ľ", 0}, + {"Udiaeresis", 1}, + {"Ǚ", 0}, + {"t", 1}, + {"ť", 0}, + {"space", 1}, + {"ˇ", 0}, + {"Multi_key", 5}, + {"quotedbl", 4}, + {"u", 1}, + {"ǚ", 0}, + {"U", 1}, + {"Ǚ", 0}, + {"i", 1}, + {"ǐ", 0}, + {"k", 1}, + {"ǩ", 0}, + {"n", 1}, + {"ň", 0}, + {"equal", 1}, + {"₌", 0}, + {"dead_caron", 1}, + {"ˇ", 0}, + {"7", 1}, + {"₇", 0}, + {"j", 1}, + {"ǰ", 0}, + {"parenright", 1}, + {"₎", 0}, + {"sabovedot", 1}, + {"ṧ", 0}, + {"nobreakspace", 1}, + {"̌", 0}, + {"V", 1}, + {"Ǚ", 0}, + {"u", 1}, + {"ǔ", 0}, + {"z", 1}, + {"ž", 0}, + {"G", 1}, + {"Ǧ", 0}, + {"H", 1}, + {"Ȟ", 0}, + {"8", 1}, + {"₈", 0}, + {"3", 1}, + {"₃", 0}, + {"E", 1}, + {"Ě", 0}, + {"S", 1}, + {"Š", 0}, + {"2", 1}, + {"₂", 0}, + {"d", 1}, + {"ď", 0}, + {"D", 1}, + {"Ď", 0}, + {"plus", 1}, + {"₊", 0}, + {"6", 1}, + {"₆", 0}, + {"dead_abovedot", 4}, + {"S", 1}, + {"Ṧ", 0}, + {"s", 1}, + {"ṧ", 0}, + {"4", 1}, + {"₄", 0}, + {"v", 1}, + {"ǚ", 0}, + {"O", 1}, + {"Ǒ", 0}, + {"r", 1}, + {"ř", 0}, + {"s", 1}, + {"š", 0}, + {"Z", 1}, + {"Ž", 0}, + {"EZH", 1}, + {"Ǯ", 0}, + {"A", 1}, + {"Ǎ", 0}, + {"R", 1}, + {"Ř", 0}, + {"c", 1}, + {"č", 0}, + {"L", 1}, + {"Ľ", 0}, + {"T", 1}, + {"Ť", 0}, + {"5", 1}, + {"₅", 0}, + {"K", 1}, + {"Ǩ", 0}, + {"9", 1}, + {"₉", 0}, + {"0", 1}, + {"₀", 0}, + {"Sabovedot", 1}, + {"Ṧ", 0}, + {"dead_diaeresis", 4}, + {"u", 1}, + {"ǚ", 0}, + {"U", 1}, + {"Ǚ", 0}, + {"parenleft", 1}, + {"₍", 0}, + {"h", 1}, + {"ȟ", 0}, + {"udiaeresis", 1}, + {"ǚ", 0}, + {"I", 1}, + {"Ǐ", 0}, + {"N", 1}, + {"Ň", 0}, + {"U", 1}, + {"Ǔ", 0}, + {"dead_tilde", 266}, + {"dead_breve", 4}, + {"a", 1}, + {"ẵ", 0}, + {"A", 1}, + {"Ẵ", 0}, + {"a", 1}, + {"ã", 0}, + {"Greek_iota", 1}, + {"ῖ", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ỡ", 0}, + {"u", 1}, + {"ữ", 0}, + {"O", 1}, + {"Ỡ", 0}, + {"U", 1}, + {"Ữ", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ẫ", 0}, + {"e", 1}, + {"ễ", 0}, + {"o", 1}, + {"ỗ", 0}, + {"E", 1}, + {"Ễ", 0}, + {"O", 1}, + {"Ỗ", 0}, + {"A", 1}, + {"Ẫ", 0}, + {"Acircumflex", 1}, + {"Ẫ", 0}, + {"less", 1}, + {"≲", 0}, + {"Oacute", 1}, + {"Ṍ", 0}, + {"e", 1}, + {"ẽ", 0}, + {"o", 1}, + {"õ", 0}, + {"Greek_upsilon", 1}, + {"ῦ", 0}, + {"uhorn", 1}, + {"ữ", 0}, + {"space", 1}, + {"~", 0}, + {"dead_macron", 4}, + {"o", 1}, + {"ȭ", 0}, + {"O", 1}, + {"Ȭ", 0}, + {"acircumflex", 1}, + {"ẫ", 0}, + {"Ecircumflex", 1}, + {"Ễ", 0}, + {"y", 1}, + {"ỹ", 0}, + {"Multi_key", 77}, + {"b", 4}, + {"a", 1}, + {"ẵ", 0}, + {"A", 1}, + {"Ẵ", 0}, + {"parenright", 18}, + {"Greek_IOTA", 1}, + {"Ἶ", 0}, + {"Greek_iota", 1}, + {"ἶ", 0}, + {"Greek_upsilon", 1}, + {"ὖ", 0}, + {"Greek_ALPHA", 1}, + {"Ἆ", 0}, + {"Greek_eta", 1}, + {"ἦ", 0}, + {"Greek_alpha", 1}, + {"ἆ", 0}, + {"Greek_ETA", 1}, + {"Ἦ", 0}, + {"Greek_omega", 1}, + {"ὦ", 0}, + {"Greek_OMEGA", 1}, + {"Ὦ", 0}, + {"quotedbl", 4}, + {"Greek_iota", 1}, + {"ῗ", 0}, + {"Greek_upsilon", 1}, + {"ῧ", 0}, + {"plus", 8}, + {"o", 1}, + {"ỡ", 0}, + {"u", 1}, + {"ữ", 0}, + {"O", 1}, + {"Ỡ", 0}, + {"U", 1}, + {"Ữ", 0}, + {"parenleft", 20}, + {"Greek_IOTA", 1}, + {"Ἷ", 0}, + {"Greek_iota", 1}, + {"ἷ", 0}, + {"Greek_upsilon", 1}, + {"ὗ", 0}, + {"Greek_ALPHA", 1}, + {"Ἇ", 0}, + {"Greek_eta", 1}, + {"ἧ", 0}, + {"Greek_alpha", 1}, + {"ἇ", 0}, + {"Greek_ETA", 1}, + {"Ἧ", 0}, + {"Greek_omega", 1}, + {"ὧ", 0}, + {"Greek_OMEGA", 1}, + {"Ὧ", 0}, + {"Greek_UPSILON", 1}, + {"Ὗ", 0}, + {"U", 4}, + {"a", 1}, + {"ẵ", 0}, + {"A", 1}, + {"Ẵ", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ẫ", 0}, + {"e", 1}, + {"ễ", 0}, + {"o", 1}, + {"ỗ", 0}, + {"E", 1}, + {"Ễ", 0}, + {"O", 1}, + {"Ỗ", 0}, + {"A", 1}, + {"Ẫ", 0}, + {"oacute", 1}, + {"ṍ", 0}, + {"i", 1}, + {"ĩ", 0}, + {"n", 1}, + {"ñ", 0}, + {"equal", 1}, + {"≃", 0}, + {"dead_tilde", 1}, + {"~", 0}, + {"Uacute", 1}, + {"Ṹ", 0}, + {"Ohorn", 1}, + {"Ỡ", 0}, + {"ohorn", 1}, + {"ỡ", 0}, + {"nobreakspace", 1}, + {"̃", 0}, + {"V", 1}, + {"Ṽ", 0}, + {"Ocircumflex", 1}, + {"Ỗ", 0}, + {"omacron", 1}, + {"ȭ", 0}, + {"uacute", 1}, + {"ṹ", 0}, + {"ocircumflex", 1}, + {"ỗ", 0}, + {"u", 1}, + {"ũ", 0}, + {"E", 1}, + {"Ẽ", 0}, + {"Greek_iotadieresis", 1}, + {"ῗ", 0}, + {"Y", 1}, + {"Ỹ", 0}, + {"dead_dasia", 20}, + {"Greek_IOTA", 1}, + {"Ἷ", 0}, + {"Greek_iota", 1}, + {"ἷ", 0}, + {"Greek_upsilon", 1}, + {"ὗ", 0}, + {"Greek_ALPHA", 1}, + {"Ἇ", 0}, + {"Greek_eta", 1}, + {"ἧ", 0}, + {"Greek_alpha", 1}, + {"ἇ", 0}, + {"Greek_ETA", 1}, + {"Ἧ", 0}, + {"Greek_omega", 1}, + {"ὧ", 0}, + {"Greek_OMEGA", 1}, + {"Ὧ", 0}, + {"Greek_UPSILON", 1}, + {"Ὗ", 0}, + {"Greek_upsilondieresis", 1}, + {"ῧ", 0}, + {"odiaeresis", 1}, + {"ṏ", 0}, + {"Greek_eta", 1}, + {"ῆ", 0}, + {"Abreve", 1}, + {"Ẵ", 0}, + {"dead_psili", 18}, + {"Greek_IOTA", 1}, + {"Ἶ", 0}, + {"Greek_iota", 1}, + {"ἶ", 0}, + {"Greek_upsilon", 1}, + {"ὖ", 0}, + {"Greek_ALPHA", 1}, + {"Ἆ", 0}, + {"Greek_eta", 1}, + {"ἦ", 0}, + {"Greek_alpha", 1}, + {"ἆ", 0}, + {"Greek_ETA", 1}, + {"Ἦ", 0}, + {"Greek_omega", 1}, + {"ὦ", 0}, + {"Greek_OMEGA", 1}, + {"Ὦ", 0}, + {"Greek_alpha", 1}, + {"ᾶ", 0}, + {"ecircumflex", 1}, + {"ễ", 0}, + {"v", 1}, + {"ṽ", 0}, + {"O", 1}, + {"Õ", 0}, + {"abreve", 1}, + {"ẵ", 0}, + {"A", 1}, + {"Ã", 0}, + {"Odiaeresis", 1}, + {"Ṏ", 0}, + {"greater", 1}, + {"≳", 0}, + {"Omacron", 1}, + {"Ȭ", 0}, + {"Greek_omega", 1}, + {"ῶ", 0}, + {"dead_diaeresis", 8}, + {"Greek_iota", 1}, + {"ῗ", 0}, + {"o", 1}, + {"ṏ", 0}, + {"Greek_upsilon", 1}, + {"ῧ", 0}, + {"O", 1}, + {"Ṏ", 0}, + {"Uhorn", 1}, + {"Ữ", 0}, + {"dead_acute", 8}, + {"o", 1}, + {"ṍ", 0}, + {"u", 1}, + {"ṹ", 0}, + {"O", 1}, + {"Ṍ", 0}, + {"U", 1}, + {"Ṹ", 0}, + {"I", 1}, + {"Ĩ", 0}, + {"N", 1}, + {"Ñ", 0}, + {"U", 1}, + {"Ũ", 0}, + {"dead_belowcomma", 14}, + {"t", 1}, + {"ț", 0}, + {"space", 1}, + {",", 0}, + {"dead_belowcomma", 1}, + {",", 0}, + {"nobreakspace", 1}, + {"̦", 0}, + {"S", 1}, + {"Ș", 0}, + {"s", 1}, + {"ș", 0}, + {"T", 1}, + {"Ț", 0}, + {"dead_doubleacute", 18}, + {"o", 1}, + {"ő", 0}, + {"space", 1}, + {"˝", 0}, + {"Cyrillic_U", 1}, + {"Ӳ", 0}, + {"dead_doubleacute", 1}, + {"˝", 0}, + {"nobreakspace", 1}, + {"̋", 0}, + {"u", 1}, + {"ű", 0}, + {"O", 1}, + {"Ő", 0}, + {"U", 1}, + {"Ű", 0}, + {"Cyrillic_u", 1}, + {"ӳ", 0}, + {"dead_abovering", 27}, + {"a", 1}, + {"å", 0}, + {"space", 1}, + {"°", 0}, + {"y", 1}, + {"ẙ", 0}, + {"dead_abovering", 1}, + {"°", 0}, + {"nobreakspace", 1}, + {"̊", 0}, + {"u", 1}, + {"ů", 0}, + {"w", 1}, + {"ẘ", 0}, + {"A", 1}, + {"Å", 0}, + {"Aacute", 1}, + {"Ǻ", 0}, + {"aacute", 1}, + {"ǻ", 0}, + {"dead_acute", 4}, + {"a", 1}, + {"ǻ", 0}, + {"A", 1}, + {"Ǻ", 0}, + {"U", 1}, + {"Ů", 0}, + {"Greek_accentdieresis", 4}, + {"Greek_iota", 1}, + {"ΐ", 0}, + {"Greek_upsilon", 1}, + {"ΰ", 0}, + {"dead_voiced_sound", 46}, + {"kana_KE", 1}, + {"ゲ", 0}, + {"kana_SA", 1}, + {"ザ", 0}, + {"kana_SE", 1}, + {"ゼ", 0}, + {"kana_SU", 1}, + {"ズ", 0}, + {"kana_WO", 1}, + {"ヺ", 0}, + {"kana_TE", 1}, + {"デ", 0}, + {"kana_HO", 1}, + {"ボ", 0}, + {"kana_HI", 1}, + {"ビ", 0}, + {"kana_WA", 1}, + {"ヷ", 0}, + {"kana_CHI", 1}, + {"ヂ", 0}, + {"kana_HA", 1}, + {"バ", 0}, + {"kana_HE", 1}, + {"ベ", 0}, + {"kana_KO", 1}, + {"ゴ", 0}, + {"kana_FU", 1}, + {"ブ", 0}, + {"kana_KU", 1}, + {"グ", 0}, + {"kana_U", 1}, + {"ヴ", 0}, + {"kana_TO", 1}, + {"ド", 0}, + {"kana_TA", 1}, + {"ダ", 0}, + {"kana_KA", 1}, + {"ガ", 0}, + {"kana_KI", 1}, + {"ギ", 0}, + {"kana_SO", 1}, + {"ゾ", 0}, + {"kana_TSU", 1}, + {"ヅ", 0}, + {"kana_SHI", 1}, + {"ジ", 0}, + {"dead_belowtilde", 14}, + {"e", 1}, + {"ḛ", 0}, + {"i", 1}, + {"ḭ", 0}, + {"u", 1}, + {"ṵ", 0}, + {"E", 1}, + {"Ḛ", 0}, + {"plus", 1}, + {"⨦", 0}, + {"I", 1}, + {"Ḭ", 0}, + {"U", 1}, + {"Ṵ", 0}, + {"dead_ogonek", 35}, + {"a", 1}, + {"ą", 0}, + {"e", 1}, + {"ę", 0}, + {"o", 1}, + {"ǫ", 0}, + {"space", 1}, + {"˛", 0}, + {"dead_macron", 4}, + {"o", 1}, + {"ǭ", 0}, + {"O", 1}, + {"Ǭ", 0}, + {"i", 1}, + {"į", 0}, + {"nobreakspace", 1}, + {"̨", 0}, + {"omacron", 1}, + {"ǭ", 0}, + {"u", 1}, + {"ų", 0}, + {"E", 1}, + {"Ę", 0}, + {"dead_ogonek", 1}, + {"˛", 0}, + {"O", 1}, + {"Ǫ", 0}, + {"A", 1}, + {"Ą", 0}, + {"Omacron", 1}, + {"Ǭ", 0}, + {"I", 1}, + {"Į", 0}, + {"U", 1}, + {"Ų", 0}, + {"dead_dasia", 32}, + {"Greek_IOTA", 1}, + {"Ἱ", 0}, + {"Greek_iota", 1}, + {"ἱ", 0}, + {"Greek_OMICRON", 1}, + {"Ὁ", 0}, + {"Greek_upsilon", 1}, + {"ὑ", 0}, + {"Greek_RHO", 1}, + {"Ῥ", 0}, + {"Greek_epsilon", 1}, + {"ἑ", 0}, + {"Greek_ALPHA", 1}, + {"Ἁ", 0}, + {"Greek_omicron", 1}, + {"ὁ", 0}, + {"Greek_eta", 1}, + {"ἡ", 0}, + {"Greek_rho", 1}, + {"ῥ", 0}, + {"Greek_alpha", 1}, + {"ἁ", 0}, + {"Greek_ETA", 1}, + {"Ἡ", 0}, + {"Greek_EPSILON", 1}, + {"Ἑ", 0}, + {"Greek_omega", 1}, + {"ὡ", 0}, + {"Greek_OMEGA", 1}, + {"Ὡ", 0}, + {"Greek_UPSILON", 1}, + {"Ὑ", 0}, + {"dead_iota", 491}, + {"dead_grave", 59}, + {"Multi_key", 26}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾊ", 0}, + {"Greek_eta", 1}, + {"ᾒ", 0}, + {"Greek_alpha", 1}, + {"ᾂ", 0}, + {"Greek_ETA", 1}, + {"ᾚ", 0}, + {"Greek_omega", 1}, + {"ᾢ", 0}, + {"Greek_OMEGA", 1}, + {"ᾪ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾋ", 0}, + {"Greek_eta", 1}, + {"ᾓ", 0}, + {"Greek_alpha", 1}, + {"ᾃ", 0}, + {"Greek_ETA", 1}, + {"ᾛ", 0}, + {"Greek_omega", 1}, + {"ᾣ", 0}, + {"Greek_OMEGA", 1}, + {"ᾫ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾋ", 0}, + {"Greek_eta", 1}, + {"ᾓ", 0}, + {"Greek_alpha", 1}, + {"ᾃ", 0}, + {"Greek_ETA", 1}, + {"ᾛ", 0}, + {"Greek_omega", 1}, + {"ᾣ", 0}, + {"Greek_OMEGA", 1}, + {"ᾫ", 0}, + {"Greek_eta", 1}, + {"ῂ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾊ", 0}, + {"Greek_eta", 1}, + {"ᾒ", 0}, + {"Greek_alpha", 1}, + {"ᾂ", 0}, + {"Greek_ETA", 1}, + {"ᾚ", 0}, + {"Greek_omega", 1}, + {"ᾢ", 0}, + {"Greek_OMEGA", 1}, + {"ᾪ", 0}, + {"Greek_alpha", 1}, + {"ᾲ", 0}, + {"Greek_omega", 1}, + {"ῲ", 0}, + {"space", 1}, + {"ͺ", 0}, + {"Multi_key", 262}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾈ", 0}, + {"Greek_eta", 1}, + {"ᾐ", 0}, + {"Greek_alpha", 1}, + {"ᾀ", 0}, + {"Greek_ETA", 1}, + {"ᾘ", 0}, + {"Greek_omega", 1}, + {"ᾠ", 0}, + {"Greek_OMEGA", 1}, + {"ᾨ", 0}, + {"acute", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_eta", 1}, + {"ῄ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"Greek_alpha", 1}, + {"ᾴ", 0}, + {"Greek_omega", 1}, + {"ῴ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"apostrophe", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_eta", 1}, + {"ῄ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"Greek_alpha", 1}, + {"ᾴ", 0}, + {"Greek_omega", 1}, + {"ῴ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"asciitilde", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾎ", 0}, + {"Greek_eta", 1}, + {"ᾖ", 0}, + {"Greek_alpha", 1}, + {"ᾆ", 0}, + {"Greek_ETA", 1}, + {"ᾞ", 0}, + {"Greek_omega", 1}, + {"ᾦ", 0}, + {"Greek_OMEGA", 1}, + {"ᾮ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾏ", 0}, + {"Greek_eta", 1}, + {"ᾗ", 0}, + {"Greek_alpha", 1}, + {"ᾇ", 0}, + {"Greek_ETA", 1}, + {"ᾟ", 0}, + {"Greek_omega", 1}, + {"ᾧ", 0}, + {"Greek_OMEGA", 1}, + {"ᾯ", 0}, + {"Greek_eta", 1}, + {"ῇ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾎ", 0}, + {"Greek_eta", 1}, + {"ᾖ", 0}, + {"Greek_alpha", 1}, + {"ᾆ", 0}, + {"Greek_ETA", 1}, + {"ᾞ", 0}, + {"Greek_omega", 1}, + {"ᾦ", 0}, + {"Greek_OMEGA", 1}, + {"ᾮ", 0}, + {"Greek_alpha", 1}, + {"ᾷ", 0}, + {"Greek_omega", 1}, + {"ῷ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾏ", 0}, + {"Greek_eta", 1}, + {"ᾗ", 0}, + {"Greek_alpha", 1}, + {"ᾇ", 0}, + {"Greek_ETA", 1}, + {"ᾟ", 0}, + {"Greek_omega", 1}, + {"ᾧ", 0}, + {"Greek_OMEGA", 1}, + {"ᾯ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾉ", 0}, + {"Greek_eta", 1}, + {"ᾑ", 0}, + {"Greek_alpha", 1}, + {"ᾁ", 0}, + {"Greek_ETA", 1}, + {"ᾙ", 0}, + {"Greek_omega", 1}, + {"ᾡ", 0}, + {"Greek_OMEGA", 1}, + {"ᾩ", 0}, + {"grave", 58}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾊ", 0}, + {"Greek_eta", 1}, + {"ᾒ", 0}, + {"Greek_alpha", 1}, + {"ᾂ", 0}, + {"Greek_ETA", 1}, + {"ᾚ", 0}, + {"Greek_omega", 1}, + {"ᾢ", 0}, + {"Greek_OMEGA", 1}, + {"ᾪ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾋ", 0}, + {"Greek_eta", 1}, + {"ᾓ", 0}, + {"Greek_alpha", 1}, + {"ᾃ", 0}, + {"Greek_ETA", 1}, + {"ᾛ", 0}, + {"Greek_omega", 1}, + {"ᾣ", 0}, + {"Greek_OMEGA", 1}, + {"ᾫ", 0}, + {"Greek_eta", 1}, + {"ῂ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾊ", 0}, + {"Greek_eta", 1}, + {"ᾒ", 0}, + {"Greek_alpha", 1}, + {"ᾂ", 0}, + {"Greek_ETA", 1}, + {"ᾚ", 0}, + {"Greek_omega", 1}, + {"ᾢ", 0}, + {"Greek_OMEGA", 1}, + {"ᾪ", 0}, + {"Greek_alpha", 1}, + {"ᾲ", 0}, + {"Greek_omega", 1}, + {"ῲ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾋ", 0}, + {"Greek_eta", 1}, + {"ᾓ", 0}, + {"Greek_alpha", 1}, + {"ᾃ", 0}, + {"Greek_ETA", 1}, + {"ᾛ", 0}, + {"Greek_omega", 1}, + {"ᾣ", 0}, + {"Greek_OMEGA", 1}, + {"ᾫ", 0}, + {"dead_tilde", 59}, + {"Multi_key", 26}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾎ", 0}, + {"Greek_eta", 1}, + {"ᾖ", 0}, + {"Greek_alpha", 1}, + {"ᾆ", 0}, + {"Greek_ETA", 1}, + {"ᾞ", 0}, + {"Greek_omega", 1}, + {"ᾦ", 0}, + {"Greek_OMEGA", 1}, + {"ᾮ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾏ", 0}, + {"Greek_eta", 1}, + {"ᾗ", 0}, + {"Greek_alpha", 1}, + {"ᾇ", 0}, + {"Greek_ETA", 1}, + {"ᾟ", 0}, + {"Greek_omega", 1}, + {"ᾧ", 0}, + {"Greek_OMEGA", 1}, + {"ᾯ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾏ", 0}, + {"Greek_eta", 1}, + {"ᾗ", 0}, + {"Greek_alpha", 1}, + {"ᾇ", 0}, + {"Greek_ETA", 1}, + {"ᾟ", 0}, + {"Greek_omega", 1}, + {"ᾧ", 0}, + {"Greek_OMEGA", 1}, + {"ᾯ", 0}, + {"Greek_eta", 1}, + {"ῇ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾎ", 0}, + {"Greek_eta", 1}, + {"ᾖ", 0}, + {"Greek_alpha", 1}, + {"ᾆ", 0}, + {"Greek_ETA", 1}, + {"ᾞ", 0}, + {"Greek_omega", 1}, + {"ᾦ", 0}, + {"Greek_OMEGA", 1}, + {"ᾮ", 0}, + {"Greek_alpha", 1}, + {"ᾷ", 0}, + {"Greek_omega", 1}, + {"ῷ", 0}, + {"Greek_ALPHA", 1}, + {"ᾼ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾉ", 0}, + {"Greek_eta", 1}, + {"ᾑ", 0}, + {"Greek_alpha", 1}, + {"ᾁ", 0}, + {"Greek_ETA", 1}, + {"ᾙ", 0}, + {"Greek_omega", 1}, + {"ᾡ", 0}, + {"Greek_OMEGA", 1}, + {"ᾩ", 0}, + {"Greek_eta", 1}, + {"ῃ", 0}, + {"dead_iota", 1}, + {"ͺ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾈ", 0}, + {"Greek_eta", 1}, + {"ᾐ", 0}, + {"Greek_alpha", 1}, + {"ᾀ", 0}, + {"Greek_ETA", 1}, + {"ᾘ", 0}, + {"Greek_omega", 1}, + {"ᾠ", 0}, + {"Greek_OMEGA", 1}, + {"ᾨ", 0}, + {"Greek_alpha", 1}, + {"ᾳ", 0}, + {"Greek_ETA", 1}, + {"ῌ", 0}, + {"Greek_omegaaccent", 1}, + {"ῴ", 0}, + {"Greek_omega", 1}, + {"ῳ", 0}, + {"Greek_OMEGA", 1}, + {"ῼ", 0}, + {"dead_acute", 59}, + {"Multi_key", 26}, + {"parenright", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"parenleft", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"dead_dasia", 12}, + {"Greek_ALPHA", 1}, + {"ᾍ", 0}, + {"Greek_eta", 1}, + {"ᾕ", 0}, + {"Greek_alpha", 1}, + {"ᾅ", 0}, + {"Greek_ETA", 1}, + {"ᾝ", 0}, + {"Greek_omega", 1}, + {"ᾥ", 0}, + {"Greek_OMEGA", 1}, + {"ᾭ", 0}, + {"Greek_eta", 1}, + {"ῄ", 0}, + {"dead_psili", 12}, + {"Greek_ALPHA", 1}, + {"ᾌ", 0}, + {"Greek_eta", 1}, + {"ᾔ", 0}, + {"Greek_alpha", 1}, + {"ᾄ", 0}, + {"Greek_ETA", 1}, + {"ᾜ", 0}, + {"Greek_omega", 1}, + {"ᾤ", 0}, + {"Greek_OMEGA", 1}, + {"ᾬ", 0}, + {"Greek_alpha", 1}, + {"ᾴ", 0}, + {"Greek_omega", 1}, + {"ῴ", 0}, + {"Greek_alphaaccent", 1}, + {"ᾴ", 0}, + {"Greek_etaaccent", 1}, + {"ῄ", 0}, + {"dead_greek", 121}, + {"W", 1}, + {"Ω", 0}, + {"g", 1}, + {"γ", 0}, + {"a", 1}, + {"α", 0}, + {"e", 1}, + {"ε", 0}, + {"F", 1}, + {"Φ", 0}, + {"o", 1}, + {"ο", 0}, + {"l", 1}, + {"λ", 0}, + {"t", 1}, + {"τ", 0}, + {"space", 1}, + {"µ", 0}, + {"dead_macron", 12}, + {"a", 1}, + {"ᾱ", 0}, + {"i", 1}, + {"ῑ", 0}, + {"u", 1}, + {"ῡ", 0}, + {"A", 1}, + {"Ᾱ", 0}, + {"I", 1}, + {"Ῑ", 0}, + {"U", 1}, + {"Ῡ", 0}, + {"Q", 1}, + {"Χ", 0}, + {"y", 1}, + {"ψ", 0}, + {"b", 1}, + {"β", 0}, + {"i", 1}, + {"ι", 0}, + {"k", 1}, + {"κ", 0}, + {"n", 1}, + {"ν", 0}, + {"j", 1}, + {"θ", 0}, + {"x", 1}, + {"ξ", 0}, + {"q", 1}, + {"χ", 0}, + {"nobreakspace", 1}, + {"µ", 0}, + {"u", 1}, + {"υ", 0}, + {"z", 1}, + {"ζ", 0}, + {"G", 1}, + {"Γ", 0}, + {"H", 1}, + {"Η", 0}, + {"E", 1}, + {"Ε", 0}, + {"S", 1}, + {"Σ", 0}, + {"Y", 1}, + {"Ψ", 0}, + {"f", 1}, + {"φ", 0}, + {"d", 1}, + {"δ", 0}, + {"dead_greek", 1}, + {"µ", 0}, + {"D", 1}, + {"Δ", 0}, + {"w", 1}, + {"ω", 0}, + {"p", 1}, + {"π", 0}, + {"J", 1}, + {"Θ", 0}, + {"P", 1}, + {"Π", 0}, + {"M", 1}, + {"Μ", 0}, + {"O", 1}, + {"Ο", 0}, + {"m", 1}, + {"μ", 0}, + {"r", 1}, + {"ρ", 0}, + {"s", 1}, + {"σ", 0}, + {"Z", 1}, + {"Ζ", 0}, + {"dead_stroke", 2}, + {"r", 1}, + {"ϼ", 0}, + {"A", 1}, + {"Α", 0}, + {"R", 1}, + {"Ρ", 0}, + {"L", 1}, + {"Λ", 0}, + {"T", 1}, + {"Τ", 0}, + {"dead_hook", 2}, + {"U", 1}, + {"ϒ", 0}, + {"K", 1}, + {"Κ", 0}, + {"B", 1}, + {"Β", 0}, + {"X", 1}, + {"Ξ", 0}, + {"h", 1}, + {"η", 0}, + {"I", 1}, + {"Ι", 0}, + {"N", 1}, + {"Ν", 0}, + {"U", 1}, + {"Υ", 0}, + {"dead_invertedbreve", 24}, + {"Cyrillic_er", 1}, + {"р̑", 0}, + {"Cyrillic_I", 1}, + {"И̑", 0}, + {"Cyrillic_O", 1}, + {"О̑", 0}, + {"Cyrillic_a", 1}, + {"а̑", 0}, + {"Cyrillic_ER", 1}, + {"Р̑", 0}, + {"Cyrillic_U", 1}, + {"У̑", 0}, + {"Cyrillic_ie", 1}, + {"е̑", 0}, + {"Cyrillic_i", 1}, + {"и̑", 0}, + {"Cyrillic_o", 1}, + {"о̑", 0}, + {"Cyrillic_A", 1}, + {"А̑", 0}, + {"Cyrillic_IE", 1}, + {"Е̑", 0}, + {"Cyrillic_u", 1}, + {"у̑", 0}, + {"dead_psili", 28}, + {"Greek_IOTA", 1}, + {"Ἰ", 0}, + {"Greek_iota", 1}, + {"ἰ", 0}, + {"Greek_OMICRON", 1}, + {"Ὀ", 0}, + {"Greek_upsilon", 1}, + {"ὐ", 0}, + {"Greek_epsilon", 1}, + {"ἐ", 0}, + {"Greek_ALPHA", 1}, + {"Ἀ", 0}, + {"Greek_omicron", 1}, + {"ὀ", 0}, + {"Greek_eta", 1}, + {"ἠ", 0}, + {"Greek_rho", 1}, + {"ῤ", 0}, + {"Greek_alpha", 1}, + {"ἀ", 0}, + {"Greek_ETA", 1}, + {"Ἠ", 0}, + {"Greek_EPSILON", 1}, + {"Ἐ", 0}, + {"Greek_omega", 1}, + {"ὠ", 0}, + {"Greek_OMEGA", 1}, + {"Ὠ", 0}, + {"dead_abovedot", 159}, + {"W", 1}, + {"Ẇ", 0}, + {"g", 1}, + {"ġ", 0}, + {"a", 1}, + {"ȧ", 0}, + {"C", 1}, + {"Ċ", 0}, + {"e", 1}, + {"ė", 0}, + {"F", 1}, + {"Ḟ", 0}, + {"o", 1}, + {"ȯ", 0}, + {"l", 1}, + {"ŀ", 0}, + {"t", 1}, + {"ṫ", 0}, + {"dead_belowdot", 4}, + {"S", 1}, + {"Ṩ", 0}, + {"s", 1}, + {"ṩ", 0}, + {"space", 1}, + {"˙", 0}, + {"dead_macron", 8}, + {"a", 1}, + {"ǡ", 0}, + {"o", 1}, + {"ȱ", 0}, + {"O", 1}, + {"Ȱ", 0}, + {"A", 1}, + {"Ǡ", 0}, + {"y", 1}, + {"ẏ", 0}, + {"b", 1}, + {"ḃ", 0}, + {"Multi_key", 23}, + {"exclam", 4}, + {"S", 1}, + {"Ṩ", 0}, + {"s", 1}, + {"ṩ", 0}, + {"f", 2}, + {"s", 1}, + {"ẛ", 0}, + {"acute", 4}, + {"S", 1}, + {"Ṥ", 0}, + {"s", 1}, + {"ṥ", 0}, + {"apostrophe", 4}, + {"S", 1}, + {"Ṥ", 0}, + {"s", 1}, + {"ṥ", 0}, + {"c", 4}, + {"S", 1}, + {"Ṧ", 0}, + {"s", 1}, + {"ṧ", 0}, + {"i", 1}, + {"ı", 0}, + {"n", 1}, + {"ṅ", 0}, + {"dead_caron", 4}, + {"S", 1}, + {"Ṧ", 0}, + {"s", 1}, + {"ṧ", 0}, + {"j", 1}, + {"ȷ", 0}, + {"x", 1}, + {"ẋ", 0}, + {"amacron", 1}, + {"ǡ", 0}, + {"nobreakspace", 1}, + {"̇", 0}, + {"omacron", 1}, + {"ȱ", 0}, + {"z", 1}, + {"ż", 0}, + {"G", 1}, + {"Ġ", 0}, + {"Sacute", 1}, + {"Ṥ", 0}, + {"H", 1}, + {"Ḣ", 0}, + {"E", 1}, + {"Ė", 0}, + {"S", 1}, + {"Ṡ", 0}, + {"Y", 1}, + {"Ẏ", 0}, + {"scaron", 1}, + {"ṧ", 0}, + {"f", 1}, + {"ḟ", 0}, + {"d", 1}, + {"ḋ", 0}, + {"Scaron", 1}, + {"Ṧ", 0}, + {"D", 1}, + {"Ḋ", 0}, + {"dead_abovedot", 1}, + {"˙", 0}, + {"w", 1}, + {"ẇ", 0}, + {"p", 1}, + {"ṗ", 0}, + {"P", 1}, + {"Ṗ", 0}, + {"M", 1}, + {"Ṁ", 0}, + {"O", 1}, + {"Ȯ", 0}, + {"m", 1}, + {"ṁ", 0}, + {"r", 1}, + {"ṙ", 0}, + {"s", 1}, + {"ṡ", 0}, + {"Z", 1}, + {"Ż", 0}, + {"sacute", 1}, + {"ṥ", 0}, + {"dead_stroke", 2}, + {"j", 1}, + {"ɟ", 0}, + {"A", 1}, + {"Ȧ", 0}, + {"R", 1}, + {"Ṙ", 0}, + {"c", 1}, + {"ċ", 0}, + {"L", 1}, + {"Ŀ", 0}, + {"T", 1}, + {"Ṫ", 0}, + {"Omacron", 1}, + {"Ȱ", 0}, + {"B", 1}, + {"Ḃ", 0}, + {"Amacron", 1}, + {"Ǡ", 0}, + {"dead_acute", 4}, + {"S", 1}, + {"Ṥ", 0}, + {"s", 1}, + {"ṥ", 0}, + {"X", 1}, + {"Ẋ", 0}, + {"h", 1}, + {"ḣ", 0}, + {"I", 1}, + {"İ", 0}, + {"N", 1}, + {"Ṅ", 0}, + {"dead_double_grave", 24}, + {"a", 1}, + {"ȁ", 0}, + {"e", 1}, + {"ȅ", 0}, + {"o", 1}, + {"ȍ", 0}, + {"i", 1}, + {"ȉ", 0}, + {"u", 1}, + {"ȕ", 0}, + {"E", 1}, + {"Ȅ", 0}, + {"O", 1}, + {"Ȍ", 0}, + {"r", 1}, + {"ȑ", 0}, + {"A", 1}, + {"Ȁ", 0}, + {"R", 1}, + {"Ȑ", 0}, + {"I", 1}, + {"Ȉ", 0}, + {"U", 1}, + {"Ȕ", 0}, + {"dead_semivoiced_sound", 10}, + {"kana_HO", 1}, + {"ポ", 0}, + {"kana_HI", 1}, + {"ピ", 0}, + {"kana_HA", 1}, + {"パ", 0}, + {"kana_HE", 1}, + {"ペ", 0}, + {"kana_FU", 1}, + {"プ", 0}, + {"dead_stroke", 101}, + {"g", 1}, + {"ǥ", 0}, + {"a", 1}, + {"ⱥ", 0}, + {"C", 1}, + {"Ȼ", 0}, + {"less", 1}, + {"≮", 0}, + {"Oacute", 1}, + {"Ǿ", 0}, + {"e", 1}, + {"ɇ", 0}, + {"o", 1}, + {"ø", 0}, + {"l", 1}, + {"ł", 0}, + {"t", 1}, + {"ŧ", 0}, + {"space", 1}, + {"/", 0}, + {"y", 1}, + {"ɏ", 0}, + {"b", 1}, + {"ƀ", 0}, + {"oacute", 1}, + {"ǿ", 0}, + {"i", 1}, + {"ɨ", 0}, + {"equal", 1}, + {"≠", 0}, + {"j", 1}, + {"ɉ", 0}, + {"nobreakspace", 1}, + {"̸", 0}, + {"u", 1}, + {"ʉ", 0}, + {"greaterthanequal", 1}, + {"≱", 0}, + {"z", 1}, + {"ƶ", 0}, + {"G", 1}, + {"Ǥ", 0}, + {"H", 1}, + {"Ħ", 0}, + {"E", 1}, + {"Ɇ", 0}, + {"2", 1}, + {"ƻ", 0}, + {"Y", 1}, + {"Ɏ", 0}, + {"d", 1}, + {"đ", 0}, + {"dead_greek", 2}, + {"r", 1}, + {"ϼ", 0}, + {"D", 1}, + {"Đ", 0}, + {"dead_abovedot", 2}, + {"j", 1}, + {"ɟ", 0}, + {"lessthanequal", 1}, + {"≰", 0}, + {"p", 1}, + {"ᵽ", 0}, + {"J", 1}, + {"Ɉ", 0}, + {"P", 1}, + {"Ᵽ", 0}, + {"O", 1}, + {"Ø", 0}, + {"r", 1}, + {"ɍ", 0}, + {"Z", 1}, + {"Ƶ", 0}, + {"dead_stroke", 1}, + {"/", 0}, + {"A", 1}, + {"Ⱥ", 0}, + {"R", 1}, + {"Ɍ", 0}, + {"c", 1}, + {"ȼ", 0}, + {"L", 1}, + {"Ł", 0}, + {"T", 1}, + {"Ŧ", 0}, + {"greater", 1}, + {"≯", 0}, + {"B", 1}, + {"Ƀ", 0}, + {"dead_acute", 4}, + {"o", 1}, + {"ǿ", 0}, + {"O", 1}, + {"Ǿ", 0}, + {"h", 1}, + {"ħ", 0}, + {"I", 1}, + {"Ɨ", 0}, + {"U", 1}, + {"Ʉ", 0}, + {"dead_hook", 179}, + {"W", 1}, + {"Ⱳ", 0}, + {"dead_breve", 4}, + {"a", 1}, + {"ẳ", 0}, + {"A", 1}, + {"Ẳ", 0}, + {"g", 1}, + {"ɠ", 0}, + {"a", 1}, + {"ả", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ẩ", 0}, + {"e", 1}, + {"ể", 0}, + {"o", 1}, + {"ổ", 0}, + {"E", 1}, + {"Ể", 0}, + {"O", 1}, + {"Ổ", 0}, + {"A", 1}, + {"Ẩ", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ở", 0}, + {"u", 1}, + {"ử", 0}, + {"O", 1}, + {"Ở", 0}, + {"U", 1}, + {"Ử", 0}, + {"Acircumflex", 1}, + {"Ẩ", 0}, + {"C", 1}, + {"Ƈ", 0}, + {"e", 1}, + {"ẻ", 0}, + {"F", 1}, + {"Ƒ", 0}, + {"o", 1}, + {"ỏ", 0}, + {"t", 1}, + {"ƭ", 0}, + {"schwa", 1}, + {"ɚ", 0}, + {"uhorn", 1}, + {"ử", 0}, + {"space", 1}, + {"̉", 0}, + {"acircumflex", 1}, + {"ẩ", 0}, + {"Ecircumflex", 1}, + {"Ể", 0}, + {"y", 1}, + {"ỷ", 0}, + {"b", 1}, + {"ɓ", 0}, + {"Multi_key", 32}, + {"b", 4}, + {"a", 1}, + {"ẳ", 0}, + {"A", 1}, + {"Ẳ", 0}, + {"plus", 8}, + {"o", 1}, + {"ở", 0}, + {"u", 1}, + {"ử", 0}, + {"O", 1}, + {"Ở", 0}, + {"U", 1}, + {"Ử", 0}, + {"U", 4}, + {"a", 1}, + {"ẳ", 0}, + {"A", 1}, + {"Ẳ", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ẩ", 0}, + {"e", 1}, + {"ể", 0}, + {"o", 1}, + {"ổ", 0}, + {"E", 1}, + {"Ể", 0}, + {"O", 1}, + {"Ổ", 0}, + {"A", 1}, + {"Ẩ", 0}, + {"i", 1}, + {"ỉ", 0}, + {"k", 1}, + {"ƙ", 0}, + {"n", 1}, + {"ɲ", 0}, + {"Ohorn", 1}, + {"Ở", 0}, + {"ohorn", 1}, + {"ở", 0}, + {"q", 1}, + {"ʠ", 0}, + {"nobreakspace", 1}, + {"̉", 0}, + {"V", 1}, + {"Ʋ", 0}, + {"Ocircumflex", 1}, + {"Ổ", 0}, + {"ocircumflex", 1}, + {"ổ", 0}, + {"u", 1}, + {"ủ", 0}, + {"z", 1}, + {"ȥ", 0}, + {"G", 1}, + {"Ɠ", 0}, + {"E", 1}, + {"Ẻ", 0}, + {"Y", 1}, + {"Ỷ", 0}, + {"f", 1}, + {"ƒ", 0}, + {"d", 1}, + {"ɗ", 0}, + {"dead_greek", 2}, + {"U", 1}, + {"ϒ", 0}, + {"D", 1}, + {"Ɗ", 0}, + {"Abreve", 1}, + {"Ẳ", 0}, + {"ecircumflex", 1}, + {"ể", 0}, + {"w", 1}, + {"ⱳ", 0}, + {"p", 1}, + {"ƥ", 0}, + {"v", 1}, + {"ʋ", 0}, + {"P", 1}, + {"Ƥ", 0}, + {"M", 1}, + {"Ɱ", 0}, + {"O", 1}, + {"Ỏ", 0}, + {"abreve", 1}, + {"ẳ", 0}, + {"m", 1}, + {"ɱ", 0}, + {"r", 1}, + {"ɼ", 0}, + {"s", 1}, + {"ʂ", 0}, + {"Z", 1}, + {"Ȥ", 0}, + {"A", 1}, + {"Ả", 0}, + {"c", 1}, + {"ƈ", 0}, + {"T", 1}, + {"Ƭ", 0}, + {"dead_hook", 1}, + {"̉", 0}, + {"K", 1}, + {"Ƙ", 0}, + {"B", 1}, + {"Ɓ", 0}, + {"Uhorn", 1}, + {"Ử", 0}, + {"h", 1}, + {"ɦ", 0}, + {"I", 1}, + {"Ỉ", 0}, + {"N", 1}, + {"Ɲ", 0}, + {"U", 1}, + {"Ủ", 0}, + {"dead_belowbreve", 4}, + {"H", 1}, + {"Ḫ", 0}, + {"h", 1}, + {"ḫ", 0}, + {"dead_cedilla", 73}, + {"dead_breve", 4}, + {"e", 1}, + {"ḝ", 0}, + {"E", 1}, + {"Ḝ", 0}, + {"g", 1}, + {"ģ", 0}, + {"dead_currency", 4}, + {"C", 1}, + {"₵", 0}, + {"c", 1}, + {"₵", 0}, + {"C", 1}, + {"Ç", 0}, + {"e", 1}, + {"ȩ", 0}, + {"l", 1}, + {"ļ", 0}, + {"t", 1}, + {"ţ", 0}, + {"ColonSign", 1}, + {"₵", 0}, + {"space", 1}, + {"¸", 0}, + {"k", 1}, + {"ķ", 0}, + {"n", 1}, + {"ņ", 0}, + {"nobreakspace", 1}, + {"̧", 0}, + {"G", 1}, + {"Ģ", 0}, + {"H", 1}, + {"Ḩ", 0}, + {"E", 1}, + {"Ȩ", 0}, + {"S", 1}, + {"Ş", 0}, + {"Cacute", 1}, + {"Ḉ", 0}, + {"d", 1}, + {"ḑ", 0}, + {"D", 1}, + {"Ḑ", 0}, + {"cent", 1}, + {"₵", 0}, + {"cacute", 1}, + {"ḉ", 0}, + {"r", 1}, + {"ŗ", 0}, + {"s", 1}, + {"ş", 0}, + {"R", 1}, + {"Ŗ", 0}, + {"c", 1}, + {"ç", 0}, + {"L", 1}, + {"Ļ", 0}, + {"T", 1}, + {"Ţ", 0}, + {"K", 1}, + {"Ķ", 0}, + {"dead_cedilla", 1}, + {"¸", 0}, + {"dead_acute", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"h", 1}, + {"ḩ", 0}, + {"N", 1}, + {"Ņ", 0}, + {"dead_inverted_breve", 24}, + {"a", 1}, + {"ȃ", 0}, + {"e", 1}, + {"ȇ", 0}, + {"o", 1}, + {"ȏ", 0}, + {"i", 1}, + {"ȋ", 0}, + {"u", 1}, + {"ȗ", 0}, + {"E", 1}, + {"Ȇ", 0}, + {"O", 1}, + {"Ȏ", 0}, + {"r", 1}, + {"ȓ", 0}, + {"A", 1}, + {"Ȃ", 0}, + {"R", 1}, + {"Ȓ", 0}, + {"I", 1}, + {"Ȋ", 0}, + {"U", 1}, + {"Ȗ", 0}, + {"dead_diaeresis", 190}, + {"W", 1}, + {"Ẅ", 0}, + {"a", 1}, + {"ä", 0}, + {"Greek_IOTA", 1}, + {"Ϊ", 0}, + {"dead_grave", 4}, + {"u", 1}, + {"ǜ", 0}, + {"U", 1}, + {"Ǜ", 0}, + {"Greek_iota", 1}, + {"ϊ", 0}, + {"Umacron", 1}, + {"Ṻ", 0}, + {"Cyrillic_ZE", 1}, + {"Ӟ", 0}, + {"dead_belowdiaeresis", 2}, + {"equal", 1}, + {"⩷", 0}, + {"e", 1}, + {"ë", 0}, + {"o", 1}, + {"ö", 0}, + {"iacute", 1}, + {"ḯ", 0}, + {"Cyrillic_ze", 1}, + {"ӟ", 0}, + {"t", 1}, + {"ẗ", 0}, + {"Greek_upsilon", 1}, + {"ϋ", 0}, + {"space", 1}, + {"\"", 0}, + {"dead_macron", 12}, + {"a", 1}, + {"ǟ", 0}, + {"o", 1}, + {"ȫ", 0}, + {"u", 1}, + {"ṻ", 0}, + {"O", 1}, + {"Ȫ", 0}, + {"A", 1}, + {"Ǟ", 0}, + {"U", 1}, + {"Ṻ", 0}, + {"Cyrillic_I", 1}, + {"Ӥ", 0}, + {"y", 1}, + {"ÿ", 0}, + {"Multi_key", 15}, + {"underscore", 4}, + {"u", 1}, + {"ṻ", 0}, + {"U", 1}, + {"Ṻ", 0}, + {"macron", 4}, + {"u", 1}, + {"ṻ", 0}, + {"U", 1}, + {"Ṻ", 0}, + {"asciitilde", 4}, + {"o", 1}, + {"ṏ", 0}, + {"O", 1}, + {"Ṏ", 0}, + {"Cyrillic_O", 1}, + {"Ӧ", 0}, + {"i", 1}, + {"ï", 0}, + {"Ukrainian_I", 1}, + {"Ї", 0}, + {"dead_caron", 4}, + {"u", 1}, + {"ǚ", 0}, + {"U", 1}, + {"Ǚ", 0}, + {"dead_tilde", 4}, + {"o", 1}, + {"ṏ", 0}, + {"O", 1}, + {"Ṏ", 0}, + {"Cyrillic_che", 1}, + {"ӵ", 0}, + {"Uacute", 1}, + {"Ǘ", 0}, + {"Cyrillic_a", 1}, + {"ӓ", 0}, + {"Ugrave", 1}, + {"Ǜ", 0}, + {"x", 1}, + {"ẍ", 0}, + {"amacron", 1}, + {"ǟ", 0}, + {"Cyrillic_U", 1}, + {"Ӱ", 0}, + {"nobreakspace", 1}, + {"̈", 0}, + {"omacron", 1}, + {"ȫ", 0}, + {"uacute", 1}, + {"ǘ", 0}, + {"u", 1}, + {"ü", 0}, + {"otilde", 1}, + {"ṏ", 0}, + {"Iacute", 1}, + {"Ḯ", 0}, + {"H", 1}, + {"Ḧ", 0}, + {"Cyrillic_YERU", 1}, + {"Ӹ", 0}, + {"Cyrillic_ie", 1}, + {"ё", 0}, + {"E", 1}, + {"Ë", 0}, + {"Y", 1}, + {"Ÿ", 0}, + {"Cyrillic_i", 1}, + {"ӥ", 0}, + {"Otilde", 1}, + {"Ṏ", 0}, + {"Cyrillic_zhe", 1}, + {"ӝ", 0}, + {"umacron", 1}, + {"ṻ", 0}, + {"Cyrillic_yeru", 1}, + {"ӹ", 0}, + {"acute", 1}, + {"̈́", 0}, + {"w", 1}, + {"ẅ", 0}, + {"Cyrillic_CHE", 1}, + {"Ӵ", 0}, + {"Cyrillic_o", 1}, + {"ӧ", 0}, + {"Ukrainian_i", 1}, + {"ї", 0}, + {"Cyrillic_E", 1}, + {"Ӭ", 0}, + {"apostrophe", 1}, + {"̈́", 0}, + {"O", 1}, + {"Ö", 0}, + {"A", 1}, + {"Ä", 0}, + {"Cyrillic_A", 1}, + {"Ӓ", 0}, + {"ugrave", 1}, + {"ǜ", 0}, + {"Omacron", 1}, + {"Ȫ", 0}, + {"Cyrillic_ZHE", 1}, + {"Ӝ", 0}, + {"Cyrillic_IE", 1}, + {"Ё", 0}, + {"dead_diaeresis", 1}, + {"¨", 0}, + {"Amacron", 1}, + {"Ǟ", 0}, + {"Cyrillic_e", 1}, + {"ӭ", 0}, + {"dead_acute", 14}, + {"Greek_iota", 1}, + {"ΐ", 0}, + {"Greek_upsilon", 1}, + {"ΰ", 0}, + {"space", 1}, + {"΅", 0}, + {"i", 1}, + {"ḯ", 0}, + {"u", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Ḯ", 0}, + {"U", 1}, + {"Ǘ", 0}, + {"X", 1}, + {"Ẍ", 0}, + {"h", 1}, + {"ḧ", 0}, + {"I", 1}, + {"Ï", 0}, + {"U", 1}, + {"Ü", 0}, + {"Cyrillic_u", 1}, + {"ӱ", 0}, + {"Greek_UPSILON", 1}, + {"Ϋ", 0}, + {"dead_acute", 500}, + {"W", 1}, + {"Ẃ", 0}, + {"dead_breve", 4}, + {"a", 1}, + {"ắ", 0}, + {"A", 1}, + {"Ắ", 0}, + {"g", 1}, + {"ǵ", 0}, + {"a", 1}, + {"á", 0}, + {"Greek_IOTA", 1}, + {"Ί", 0}, + {"Greek_iota", 1}, + {"ί", 0}, + {"dead_horn", 8}, + {"o", 1}, + {"ớ", 0}, + {"u", 1}, + {"ứ", 0}, + {"O", 1}, + {"Ớ", 0}, + {"U", 1}, + {"Ứ", 0}, + {"dead_circumflex", 12}, + {"a", 1}, + {"ấ", 0}, + {"e", 1}, + {"ế", 0}, + {"o", 1}, + {"ố", 0}, + {"E", 1}, + {"Ế", 0}, + {"O", 1}, + {"Ố", 0}, + {"A", 1}, + {"Ấ", 0}, + {"Greek_OMICRON", 1}, + {"Ό", 0}, + {"Acircumflex", 1}, + {"Ấ", 0}, + {"C", 1}, + {"Ć", 0}, + {"Cyrillic_er", 1}, + {"р́", 0}, + {"e", 1}, + {"é", 0}, + {"Utilde", 1}, + {"Ṹ", 0}, + {"o", 1}, + {"ó", 0}, + {"l", 1}, + {"ĺ", 0}, + {"Udiaeresis", 1}, + {"Ǘ", 0}, + {"Greek_upsilon", 1}, + {"ύ", 0}, + {"uhorn", 1}, + {"ứ", 0}, + {"space", 1}, + {"'", 0}, + {"dead_macron", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"acircumflex", 1}, + {"ấ", 0}, + {"Ecircumflex", 1}, + {"Ế", 0}, + {"Cyrillic_I", 1}, + {"И́", 0}, + {"y", 1}, + {"ý", 0}, + {"Multi_key", 153}, + {"KP_Divide", 4}, + {"o", 1}, + {"ǿ", 0}, + {"O", 1}, + {"Ǿ", 0}, + {"o", 4}, + {"a", 1}, + {"ǻ", 0}, + {"A", 1}, + {"Ǻ", 0}, + {"b", 4}, + {"a", 1}, + {"ắ", 0}, + {"A", 1}, + {"Ắ", 0}, + {"parenright", 26}, + {"Greek_IOTA", 1}, + {"Ἴ", 0}, + {"Greek_iota", 1}, + {"ἴ", 0}, + {"Greek_OMICRON", 1}, + {"Ὄ", 0}, + {"Greek_upsilon", 1}, + {"ὔ", 0}, + {"Greek_epsilon", 1}, + {"ἔ", 0}, + {"Greek_ALPHA", 1}, + {"Ἄ", 0}, + {"Greek_omicron", 1}, + {"ὄ", 0}, + {"Greek_eta", 1}, + {"ἤ", 0}, + {"Greek_alpha", 1}, + {"ἄ", 0}, + {"Greek_ETA", 1}, + {"Ἤ", 0}, + {"Greek_EPSILON", 1}, + {"Ἔ", 0}, + {"Greek_omega", 1}, + {"ὤ", 0}, + {"Greek_OMEGA", 1}, + {"Ὤ", 0}, + {"quotedbl", 12}, + {"Greek_iota", 1}, + {"ΐ", 0}, + {"Greek_upsilon", 1}, + {"ΰ", 0}, + {"i", 1}, + {"ḯ", 0}, + {"u", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Ḯ", 0}, + {"U", 1}, + {"Ǘ", 0}, + {"plus", 8}, + {"o", 1}, + {"ớ", 0}, + {"u", 1}, + {"ứ", 0}, + {"O", 1}, + {"Ớ", 0}, + {"U", 1}, + {"Ứ", 0}, + {"cedilla", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"underscore", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"macron", 8}, + {"e", 1}, + {"ḗ", 0}, + {"o", 1}, + {"ṓ", 0}, + {"E", 1}, + {"Ḗ", 0}, + {"O", 1}, + {"Ṓ", 0}, + {"comma", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"asciitilde", 8}, + {"o", 1}, + {"ṍ", 0}, + {"u", 1}, + {"ṹ", 0}, + {"O", 1}, + {"Ṍ", 0}, + {"U", 1}, + {"Ṹ", 0}, + {"slash", 4}, + {"o", 1}, + {"ǿ", 0}, + {"O", 1}, + {"Ǿ", 0}, + {"parenleft", 28}, + {"Greek_IOTA", 1}, + {"Ἵ", 0}, + {"Greek_iota", 1}, + {"ἵ", 0}, + {"Greek_OMICRON", 1}, + {"Ὅ", 0}, + {"Greek_upsilon", 1}, + {"ὕ", 0}, + {"Greek_epsilon", 1}, + {"ἕ", 0}, + {"Greek_ALPHA", 1}, + {"Ἅ", 0}, + {"Greek_omicron", 1}, + {"ὅ", 0}, + {"Greek_eta", 1}, + {"ἥ", 0}, + {"Greek_alpha", 1}, + {"ἅ", 0}, + {"Greek_ETA", 1}, + {"Ἥ", 0}, + {"Greek_EPSILON", 1}, + {"Ἕ", 0}, + {"Greek_omega", 1}, + {"ὥ", 0}, + {"Greek_OMEGA", 1}, + {"Ὥ", 0}, + {"Greek_UPSILON", 1}, + {"Ὕ", 0}, + {"U", 4}, + {"a", 1}, + {"ắ", 0}, + {"A", 1}, + {"Ắ", 0}, + {"asciicircum", 12}, + {"a", 1}, + {"ấ", 0}, + {"e", 1}, + {"ế", 0}, + {"o", 1}, + {"ố", 0}, + {"E", 1}, + {"Ế", 0}, + {"O", 1}, + {"Ố", 0}, + {"A", 1}, + {"Ấ", 0}, + {"idiaeresis", 1}, + {"ḯ", 0}, + {"Cyrillic_O", 1}, + {"О́", 0}, + {"i", 1}, + {"í", 0}, + {"k", 1}, + {"ḱ", 0}, + {"n", 1}, + {"ń", 0}, + {"ccedilla", 1}, + {"ḉ", 0}, + {"Cyrillic_GHE", 1}, + {"Ѓ", 0}, + {"dead_tilde", 8}, + {"o", 1}, + {"ṍ", 0}, + {"u", 1}, + {"ṹ", 0}, + {"O", 1}, + {"Ṍ", 0}, + {"U", 1}, + {"Ṹ", 0}, + {"Cyrillic_a", 1}, + {"а́", 0}, + {"Ohorn", 1}, + {"Ớ", 0}, + {"ohorn", 1}, + {"ớ", 0}, + {"sabovedot", 1}, + {"ṥ", 0}, + {"Cyrillic_ER", 1}, + {"Р́", 0}, + {"Greek_epsilon", 1}, + {"έ", 0}, + {"Cyrillic_KA", 1}, + {"Ќ", 0}, + {"Cyrillic_U", 1}, + {"У́", 0}, + {"dead_abovering", 4}, + {"a", 1}, + {"ǻ", 0}, + {"A", 1}, + {"Ǻ", 0}, + {"nobreakspace", 1}, + {"́", 0}, + {"V", 1}, + {"Ǘ", 0}, + {"Ocircumflex", 1}, + {"Ố", 0}, + {"AE", 1}, + {"Ǽ", 0}, + {"omacron", 1}, + {"ṓ", 0}, + {"ocircumflex", 1}, + {"ố", 0}, + {"u", 1}, + {"ú", 0}, + {"z", 1}, + {"ź", 0}, + {"G", 1}, + {"Ǵ", 0}, + {"Greek_ALPHA", 1}, + {"Ά", 0}, + {"otilde", 1}, + {"ṍ", 0}, + {"utilde", 1}, + {"ṹ", 0}, + {"Cyrillic_ie", 1}, + {"е́", 0}, + {"emacron", 1}, + {"ḗ", 0}, + {"E", 1}, + {"É", 0}, + {"S", 1}, + {"Ś", 0}, + {"Greek_iotadieresis", 1}, + {"ΐ", 0}, + {"Y", 1}, + {"Ý", 0}, + {"Cyrillic_i", 1}, + {"и́", 0}, + {"dead_dasia", 28}, + {"Greek_IOTA", 1}, + {"Ἵ", 0}, + {"Greek_iota", 1}, + {"ἵ", 0}, + {"Greek_OMICRON", 1}, + {"Ὅ", 0}, + {"Greek_upsilon", 1}, + {"ὕ", 0}, + {"Greek_epsilon", 1}, + {"ἕ", 0}, + {"Greek_ALPHA", 1}, + {"Ἅ", 0}, + {"Greek_omicron", 1}, + {"ὅ", 0}, + {"Greek_eta", 1}, + {"ἥ", 0}, + {"Greek_alpha", 1}, + {"ἅ", 0}, + {"Greek_ETA", 1}, + {"Ἥ", 0}, + {"Greek_EPSILON", 1}, + {"Ἕ", 0}, + {"Greek_omega", 1}, + {"ὥ", 0}, + {"Greek_OMEGA", 1}, + {"Ὥ", 0}, + {"Greek_UPSILON", 1}, + {"Ὕ", 0}, + {"Greek_upsilondieresis", 1}, + {"ΰ", 0}, + {"Greek_omicron", 1}, + {"ό", 0}, + {"Greek_eta", 1}, + {"ή", 0}, + {"Otilde", 1}, + {"Ṍ", 0}, + {"Cyrillic_ka", 1}, + {"ќ", 0}, + {"Aring", 1}, + {"Ǻ", 0}, + {"Abreve", 1}, + {"Ắ", 0}, + {"dead_psili", 26}, + {"Greek_IOTA", 1}, + {"Ἴ", 0}, + {"Greek_iota", 1}, + {"ἴ", 0}, + {"Greek_OMICRON", 1}, + {"Ὄ", 0}, + {"Greek_upsilon", 1}, + {"ὔ", 0}, + {"Greek_epsilon", 1}, + {"ἔ", 0}, + {"Greek_ALPHA", 1}, + {"Ἄ", 0}, + {"Greek_omicron", 1}, + {"ὄ", 0}, + {"Greek_eta", 1}, + {"ἤ", 0}, + {"Greek_alpha", 1}, + {"ἄ", 0}, + {"Greek_ETA", 1}, + {"Ἤ", 0}, + {"Greek_EPSILON", 1}, + {"Ἔ", 0}, + {"Greek_omega", 1}, + {"ὤ", 0}, + {"Greek_OMEGA", 1}, + {"Ὤ", 0}, + {"Greek_alpha", 1}, + {"ά", 0}, + {"ecircumflex", 1}, + {"ế", 0}, + {"dead_abovedot", 4}, + {"S", 1}, + {"Ṥ", 0}, + {"s", 1}, + {"ṥ", 0}, + {"w", 1}, + {"ẃ", 0}, + {"Greek_ETA", 1}, + {"Ή", 0}, + {"Cyrillic_o", 1}, + {"о́", 0}, + {"Emacron", 1}, + {"Ḗ", 0}, + {"Ooblique", 1}, + {"Ǿ", 0}, + {"p", 1}, + {"ṕ", 0}, + {"v", 1}, + {"ǘ", 0}, + {"P", 1}, + {"Ṕ", 0}, + {"M", 1}, + {"Ḿ", 0}, + {"O", 1}, + {"Ó", 0}, + {"abreve", 1}, + {"ắ", 0}, + {"m", 1}, + {"ḿ", 0}, + {"r", 1}, + {"ŕ", 0}, + {"s", 1}, + {"ś", 0}, + {"Z", 1}, + {"Ź", 0}, + {"dead_stroke", 4}, + {"o", 1}, + {"ǿ", 0}, + {"O", 1}, + {"Ǿ", 0}, + {"A", 1}, + {"Á", 0}, + {"R", 1}, + {"Ŕ", 0}, + {"c", 1}, + {"ć", 0}, + {"Idiaeresis", 1}, + {"Ḯ", 0}, + {"L", 1}, + {"Ĺ", 0}, + {"Greek_EPSILON", 1}, + {"Έ", 0}, + {"Cyrillic_A", 1}, + {"А́", 0}, + {"Ccedilla", 1}, + {"Ḉ", 0}, + {"aring", 1}, + {"ǻ", 0}, + {"K", 1}, + {"Ḱ", 0}, + {"Omacron", 1}, + {"Ṓ", 0}, + {"Cyrillic_IE", 1}, + {"Е́", 0}, + {"Sabovedot", 1}, + {"Ṥ", 0}, + {"dead_cedilla", 4}, + {"C", 1}, + {"Ḉ", 0}, + {"c", 1}, + {"ḉ", 0}, + {"Greek_omega", 1}, + {"ώ", 0}, + {"dead_diaeresis", 14}, + {"Greek_iota", 1}, + {"ΐ", 0}, + {"Greek_upsilon", 1}, + {"ΰ", 0}, + {"space", 1}, + {"΅", 0}, + {"i", 1}, + {"ḯ", 0}, + {"u", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Ḯ", 0}, + {"U", 1}, + {"Ǘ", 0}, + {"Uhorn", 1}, + {"Ứ", 0}, + {"Greek_OMEGA", 1}, + {"Ώ", 0}, + {"dead_acute", 1}, + {"´", 0}, + {"oslash", 1}, + {"ǿ", 0}, + {"Cyrillic_ghe", 1}, + {"ѓ", 0}, + {"udiaeresis", 1}, + {"ǘ", 0}, + {"I", 1}, + {"Í", 0}, + {"N", 1}, + {"Ń", 0}, + {"U", 1}, + {"Ú", 0}, + {"Cyrillic_u", 1}, + {"у́", 0}, + {"ae", 1}, + {"ǽ", 0}, + {"Greek_UPSILON", 1}, + {"Ύ", 0}, + {"dead_belowmacron", 34}, + {"l", 1}, + {"ḻ", 0}, + {"t", 1}, + {"ṯ", 0}, + {"b", 1}, + {"ḇ", 0}, + {"k", 1}, + {"ḵ", 0}, + {"n", 1}, + {"ṉ", 0}, + {"z", 1}, + {"ẕ", 0}, + {"d", 1}, + {"ḏ", 0}, + {"D", 1}, + {"Ḏ", 0}, + {"r", 1}, + {"ṟ", 0}, + {"Z", 1}, + {"Ẕ", 0}, + {"R", 1}, + {"Ṟ", 0}, + {"L", 1}, + {"Ḻ", 0}, + {"T", 1}, + {"Ṯ", 0}, + {"K", 1}, + {"Ḵ", 0}, + {"B", 1}, + {"Ḇ", 0}, + {"h", 1}, + {"ẖ", 0}, + {"N", 1}, + {"Ṉ", 0}, + {"dead_belowring", 6}, + {"a", 1}, + {"ḁ", 0}, + {"bar", 1}, + {"⫰", 0}, + {"A", 1}, + {"Ḁ", 0}, + {NULL, 0}, +}; diff --git a/src/lib/ecore_input/ecore_input_evas.c b/src/lib/ecore_input/ecore_input_evas.c new file mode 100644 index 0000000000..1f5b38e03c --- /dev/null +++ b/src/lib/ecore_input/ecore_input_evas.c @@ -0,0 +1,418 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#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; + Ecore_Event_Multi_Move_Cb move_multi; + Ecore_Event_Multi_Down_Cb down_multi; + Ecore_Event_Multi_Up_Cb up_multi; + 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_MODIFIER_ALTGR) + evas_key_modifier_on(e, "AltGr"); + else evas_key_modifier_off(e, "AltGr"); + + 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"); + + if (modifiers & ECORE_EVENT_LOCK_SHIFT) + evas_key_lock_on(e, "Shift_Lock"); + else evas_key_lock_off(e, "Shift_Lock"); +} + +EAPI void +ecore_event_window_register(Ecore_Window id, void *window, Evas *evas, + Ecore_Event_Mouse_Move_Cb move_mouse, + Ecore_Event_Multi_Move_Cb move_multi, + Ecore_Event_Multi_Down_Cb down_multi, + Ecore_Event_Multi_Up_Cb up_multi) +{ + 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->move_multi = move_multi; + w->down_multi = down_multi; + w->up_multi = up_multi; + 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_modifier_add(evas, "AltGr"); + 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 Eina_Bool +_ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press) +{ + Ecore_Input_Window *lookup; + + lookup = _ecore_event_window_match(e->event_window); + if (!lookup) return ECORE_CALLBACK_PASS_ON; + 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 ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_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->event_window); + if (!lookup) return ECORE_CALLBACK_PASS_ON; + 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) + { + if (lookup->down_multi) + lookup->down_multi(lookup->window, 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); + else + 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 + { + if (lookup->up_multi) + lookup->up_multi(lookup->window, 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); + 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 ECORE_CALLBACK_PASS_ON; +} + +EAPI Eina_Bool +ecore_event_evas_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Event_Mouse_Move *e; + Ecore_Input_Window *lookup; + + e = event; + lookup = _ecore_event_window_match(e->event_window); + if (!lookup) return ECORE_CALLBACK_PASS_ON; + if (e->multi.device == 0) + { + ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers); + if (lookup->move_mouse) + lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp); + else + evas_event_feed_mouse_move(lookup->evas, e->x, e->y, e->timestamp, + NULL); + } + else + { + if (lookup->move_multi) + lookup->move_multi(lookup->window, 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); + 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 ECORE_CALLBACK_PASS_ON; +} + +EAPI Eina_Bool +ecore_event_evas_mouse_button_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_DOWN); +} + +EAPI Eina_Bool +ecore_event_evas_mouse_button_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP); +} + +static Eina_Bool +_ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io) +{ + Ecore_Input_Window *lookup; + + lookup = _ecore_event_window_match(e->event_window); + if (!lookup) return ECORE_CALLBACK_PASS_ON; + 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 ECORE_CALLBACK_PASS_ON; +} + +EAPI Eina_Bool +ecore_event_evas_key_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_DOWN); +} + +EAPI Eina_Bool +ecore_event_evas_key_up(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_UP); +} + +EAPI Eina_Bool +ecore_event_evas_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + Ecore_Event_Mouse_Wheel *e; + Ecore_Input_Window *lookup; + + e = event; + lookup = _ecore_event_window_match(e->event_window); + if (!lookup) return ECORE_CALLBACK_PASS_ON; + 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 ECORE_CALLBACK_PASS_ON; +} + +EAPI Eina_Bool +ecore_event_evas_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +{ + return _ecore_event_evas_mouse_io((Ecore_Event_Mouse_IO *)event, ECORE_IN); +} + +EAPI Eina_Bool +ecore_event_evas_mouse_out(void *data EINA_UNUSED, int type EINA_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 + ("ecore_input_evas", 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; +} diff --git a/src/lib/ecore_input/ecore_input_evas_private.h b/src/lib/ecore_input/ecore_input_evas_private.h new file mode 100644 index 0000000000..c19cfbf675 --- /dev/null +++ b/src/lib/ecore_input/ecore_input_evas_private.h @@ -0,0 +1,37 @@ +#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 diff --git a/src/lib/ecore_input/ecore_input_private.h b/src/lib/ecore_input/ecore_input_private.h new file mode 100644 index 0000000000..5660a2024a --- /dev/null +++ b/src/lib/ecore_input/ecore_input_private.h @@ -0,0 +1,37 @@ +#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 diff --git a/src/lib/ecore_ipc/Ecore_Ipc.h b/src/lib/ecore_ipc/Ecore_Ipc.h new file mode 100644 index 0000000000..f77870f84d --- /dev/null +++ b/src/lib/ecore_ipc/Ecore_Ipc.h @@ -0,0 +1,328 @@ +#ifndef _ECORE_IPC_H +#define _ECORE_IPC_H + +#include + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# ifdef EFL_ECORE_IPC_BUILD +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif +# 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 + +typedef struct _Ecore_Ipc_Server Ecore_Ipc_Server; /**< An IPC connection handle */ +typedef struct _Ecore_Ipc_Client Ecore_Ipc_Client; /**< An IPC connection handle */ + +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 = (1 << 4), + ECORE_IPC_NO_PROXY = (1 << 5) +} 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 Eina_Bool 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 const 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 const 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 diff --git a/src/lib/ecore_ipc/ecore_ipc.c b/src/lib/ecore_ipc/ecore_ipc.c new file mode 100644 index 0000000000..a421febdf9 --- /dev/null +++ b/src/lib/ecore_ipc/ecore_ipc.c @@ -0,0 +1,1599 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef HAVE_NETINET_IN_H +# include +# include +#endif + +#ifdef HAVE_WINSOCK2_H +# include +#endif + +#include +#include +#include + +#include "Ecore_Ipc.h" +#include "ecore_ipc_private.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; + +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 Eina_Bool _ecore_ipc_event_client_add(void *data, int ev_type, void *ev); +static Eina_Bool _ecore_ipc_event_client_del(void *data, int ev_type, void *ev); +static Eina_Bool _ecore_ipc_event_server_add(void *data, int ev_type, void *ev); +static Eina_Bool _ecore_ipc_event_server_del(void *data, int ev_type, void *ev); +static Eina_Bool _ecore_ipc_event_client_data(void *data, int ev_type, void *ev); +static Eina_Bool _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 + ("ecore_ipc", 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; + + Eina_List *l, *l2; + Ecore_Ipc_Server *svr; + EINA_LIST_FOREACH_SAFE(servers, l, l2, svr) + ecore_ipc_server_del(svr); + + 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; + + if (!name) return NULL; + + 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; + int features; + + svr = calloc(1, sizeof(Ecore_Ipc_Server)); + if (!svr) return NULL; + type = compl_type & ECORE_IPC_TYPE; + features = compl_type & ECORE_IPC_SSL; + if ((features & ECORE_IPC_USE_SSL) == ECORE_IPC_USE_SSL) + extra |= ECORE_CON_USE_SSL; + if ((features & ECORE_IPC_NO_PROXY) == ECORE_IPC_NO_PROXY) + extra |= ECORE_CON_NO_PROXY; + 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); + if (svr->server) 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 EINA_TRUE if the server is connected, @c EINA_FALSE otherwise. + * @ingroup Ecore_IPC_Server_Group + */ +EAPI Eina_Bool +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 EINA_FALSE; + } + 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->clients; +} + +#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 const 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; + } + EINA_SAFETY_ON_TRUE_RETURN_VAL(!cl->client, 0); + EINA_SAFETY_ON_TRUE_RETURN_VAL(!ecore_con_client_connected_get(cl->client), 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 cl->svr; +} + +/** + * 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 = cl->svr; + if (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 cl 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; +} + +/** + * Gets the max data payload size for an Ipc message in bytes + * + * @param cl The given client. + * @return The maximum data payload size in bytes on success, @c -1 on failure. + * @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 @c NULL is + * returned. + * @ingroup Ecore_Ipc_Client_Group + */ +EAPI const 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 Eina_Bool +_ecore_ipc_event_client_add(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev) +{ + Ecore_Con_Event_Client_Add *e; + Ecore_Ipc_Server *svr; + + e = ev; + svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client)); + if (!eina_list_data_find(servers, svr)) return ECORE_CALLBACK_RENEW; + /* handling code here */ + { + Ecore_Ipc_Client *cl; + + cl = calloc(1, sizeof(Ecore_Ipc_Client)); + if (!cl) return ECORE_CALLBACK_CANCEL; + cl->svr = svr; + 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); + 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 ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_ecore_ipc_event_client_del(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev) +{ + Ecore_Con_Event_Client_Del *e; + Ecore_Ipc_Server *svr; + + e = ev; + if (!e->client) return ECORE_CALLBACK_RENEW; + svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client)); + if (!eina_list_data_find(servers, svr)) return ECORE_CALLBACK_RENEW; + /* handling code here */ + { + Ecore_Ipc_Client *cl; + + cl = ecore_con_client_data_get(e->client); + cl->client = NULL; + { + Ecore_Ipc_Event_Client_Del *e2; + + 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 ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_ecore_ipc_event_server_add(void *data EINA_UNUSED, int ev_type EINA_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 ECORE_CALLBACK_RENEW; + /* 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 ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_ecore_ipc_event_server_del(void *data EINA_UNUSED, int ev_type EINA_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 ECORE_CALLBACK_RENEW; + /* handling code here */ + { + Ecore_Ipc_Server *svr; + + svr = ecore_con_server_data_get(e->server); + svr->server = NULL; + 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 ECORE_CALLBACK_CANCEL; +} + +#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 Eina_Bool +_ecore_ipc_event_client_data(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *ev) +{ + Ecore_Con_Event_Client_Data *e; + Ecore_Ipc_Server *svr; + + e = ev; + svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client)); + if (!eina_list_data_find(servers, svr)) return ECORE_CALLBACK_RENEW; + /* 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 ECORE_CALLBACK_CANCEL; + } + 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 ECORE_CALLBACK_CANCEL; + } + + 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; + int max, max2; + + buf = NULL; + 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 ECORE_CALLBACK_CANCEL; + 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 ECORE_CALLBACK_CANCEL; + } + 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 ECORE_CALLBACK_CANCEL; + } + memcpy(buf, cl->buf + offset, cl->buf_size - offset); + free(cl->buf); + cl->buf = buf; + cl->buf_size -= offset; + } + } + return ECORE_CALLBACK_CANCEL; +} + +#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 Eina_Bool +_ecore_ipc_event_server_data(void *data EINA_UNUSED, int ev_type EINA_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 ECORE_CALLBACK_RENEW; + /* 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 ECORE_CALLBACK_CANCEL; + } + 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 ECORE_CALLBACK_CANCEL; + } + + 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 ECORE_CALLBACK_CANCEL; + 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 ECORE_CALLBACK_CANCEL; + } + 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 ECORE_CALLBACK_CANCEL; + } + memcpy(buf, svr->buf + offset, svr->buf_size - offset); + free(svr->buf); + svr->buf = buf; + svr->buf_size -= offset; + } + } + return ECORE_CALLBACK_CANCEL; +} + +static void +_ecore_ipc_event_client_add_free(void *data EINA_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 EINA_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 EINA_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 EINA_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 EINA_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 EINA_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); +} diff --git a/src/lib/ecore_ipc/ecore_ipc_private.h b/src/lib/ecore_ipc/ecore_ipc_private.h new file mode 100644 index 0000000000..bedaab167c --- /dev/null +++ b/src/lib/ecore_ipc/ecore_ipc_private.h @@ -0,0 +1,105 @@ +#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__) + +#define ECORE_MAGIC_IPC_SERVER 0x87786556 +#define ECORE_MAGIC_IPC_CLIENT 0x78875665 + +typedef struct _Ecore_Ipc_Msg_Head Ecore_Ipc_Msg_Head; +#define ECORE_IPC_TYPE 0x0f +#define ECORE_IPC_SSL 0xf0 + +#if defined (_MSC_VER) || (defined (__SUNPRO_C) && __SUNPRO_C < 0x5100) +# pragma pack(1) +# define ECORE_IPC_STRUCT_PACKED +#elif defined (__GNUC__) || (defined (__SUNPRO_C) && __SUNPRO_C >= 0x5100) +# define ECORE_IPC_STRUCT_PACKED __attribute__((packed)) +#else +# define ECORE_IPC_STRUCT_PACKED +#endif + +#ifdef __sgi +#pragma pack 4 +#endif +struct _Ecore_Ipc_Msg_Head +{ + int major; + int minor; + int ref; + int ref_to; + int response; + int size; +} ECORE_IPC_STRUCT_PACKED; +#ifdef __sgi +#pragma pack 0 +#endif + +struct _Ecore_Ipc_Client +{ + ECORE_MAGIC; + Ecore_Con_Client *client; + Ecore_Ipc_Server *svr; + 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; + 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 diff --git a/src/lib/ecore_sdl/Ecore_Sdl.h b/src/lib/ecore_sdl/Ecore_Sdl.h new file mode 100644 index 0000000000..359e974718 --- /dev/null +++ b/src/lib/ecore_sdl/Ecore_Sdl.h @@ -0,0 +1,114 @@ +#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_GOT_FOCUS; +EAPI extern int ECORE_SDL_EVENT_LOST_FOCUS; +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 diff --git a/src/lib/ecore_sdl/Ecore_Sdl_Keys.h b/src/lib/ecore_sdl/Ecore_Sdl_Keys.h new file mode 100644 index 0000000000..4d0b60b854 --- /dev/null +++ b/src/lib/ecore_sdl/Ecore_Sdl_Keys.h @@ -0,0 +1,266 @@ +#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", "" }, +#ifndef BUILD_ECORE_EVAS_SDL_130 + { SDLK_FIRST, "First", "First" }, +#endif + { 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, "asterisk", "*" }, + { 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 */ + +#ifndef BUILD_ECORE_EVAS_SDL_130 + /* 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", "" }, +#endif + /* 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__ */ diff --git a/src/lib/ecore_sdl/ecore_sdl.c b/src/lib/ecore_sdl/ecore_sdl.c new file mode 100644 index 0000000000..f4a8faedb0 --- /dev/null +++ b/src/lib/ecore_sdl/ecore_sdl.c @@ -0,0 +1,334 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include +#include "Ecore_Sdl.h" +#include "Ecore_Sdl_Keys.h" +#include "ecore_sdl_private.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, + EINA_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, + EINA_UNUSED int length, + EINA_UNUSED void *data) +{ + return node->key - *key; +} + +/** + * @defgroup Ecore_Sdl_Library_Group SDL Library Functions + * + * Functions used to set up and shut down the Ecore_Sdl 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 EINA_UNUSED) +{ + if(++_ecore_sdl_init_count != 1) + return _ecore_sdl_init_count; + _ecore_sdl_log_dom = eina_log_domain_register + ("ecore_sdl", 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 timestamp) +{ + Ecore_Event_Key *ev; + unsigned int i; + + ev = malloc(sizeof(Ecore_Event_Key)); + if (!ev) return NULL; + + ev->timestamp = timestamp; + ev->window = 0; + ev->event_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 timestamp; + + while(SDL_PollEvent(&event)) + { + timestamp = (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 = timestamp; + ev->window = 0; + ev->event_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; + + /* Must set multi touch device to 0 or it will get ignored */ + ev->multi.device = 0; + ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; + ev->multi.pressure = ev->multi.angle = 0; + ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 0; + + 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 = timestamp; + ev->window = 0; + ev->event_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 = timestamp; + ev->window = 0; + ev->event_window = 0; + ev->modifiers = 0; /* FIXME: keep modifier around. */ + ev->buttons = event.button.button; + ev->double_click = 0; + ev->triple_click = 0; + + /* Must set multi touch device to 0 or it will get ignored */ + ev->multi.device = 0; + ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; + ev->multi.pressure = ev->multi.angle = 0; + ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 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 = timestamp; + ev->window = 0; + ev->event_window = 0; + ev->modifiers = 0; /* FIXME: keep modifier around. */ + ev->buttons = event.button.button; + ev->double_click = 0; + ev->triple_click = 0; + + /* Must set multi touch device to 0 or it will get ignored */ + ev->multi.device = 0; + ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; + ev->multi.pressure = ev->multi.angle = 0; + ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 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, timestamp); + if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL); + } + + ev = _ecore_sdl_event_key(&event, timestamp); + 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, timestamp); + 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; + } + } +} diff --git a/src/lib/ecore_sdl/ecore_sdl_private.h b/src/lib/ecore_sdl/ecore_sdl_private.h new file mode 100644 index 0000000000..37e957015d --- /dev/null +++ b/src/lib/ecore_sdl/ecore_sdl_private.h @@ -0,0 +1,36 @@ +#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 diff --git a/src/lib/ecore_wayland/Ecore_Wayland.h b/src/lib/ecore_wayland/Ecore_Wayland.h new file mode 100644 index 0000000000..5281c6f8f3 --- /dev/null +++ b/src/lib/ecore_wayland/Ecore_Wayland.h @@ -0,0 +1,392 @@ +#ifndef _ECORE_WAYLAND_H_ +# define _ECORE_WAYLAND_H_ + +/* + * Wayland supoprt is considered experimental as wayland itself is still + * unstable and liable to change core protocol. If you use this api, it is + * possible it will break in future, until this notice is removed. + */ + +# include +# include +# include +# include + +# ifdef EAPI +# undef EAPI +# endif + +# ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +# else +# define EAPI +# endif + +typedef enum _Ecore_Wl_Window_Type Ecore_Wl_Window_Type; +typedef enum _Ecore_Wl_Window_Buffer_Type Ecore_Wl_Window_Buffer_Type; + +typedef struct _Ecore_Wl_Display Ecore_Wl_Display; +typedef struct _Ecore_Wl_Output Ecore_Wl_Output; +typedef struct _Ecore_Wl_Input Ecore_Wl_Input; +# ifndef _ECORE_WAYLAND_WINDOW_PREDEF +typedef struct _Ecore_Wl_Window Ecore_Wl_Window; +# endif +typedef struct _Ecore_Wl_Dnd Ecore_Wl_Dnd; /** @since 1.7 */ +typedef struct _Ecore_Wl_Dnd_Source Ecore_Wl_Dnd_Source; +typedef struct _Ecore_Wl_Dnd_Target Ecore_Wl_Dnd_Target; + +typedef struct _Ecore_Wl_Event_Mouse_In Ecore_Wl_Event_Mouse_In; +typedef struct _Ecore_Wl_Event_Mouse_Out Ecore_Wl_Event_Mouse_Out; +typedef struct _Ecore_Wl_Event_Focus_In Ecore_Wl_Event_Focus_In; +typedef struct _Ecore_Wl_Event_Focus_Out Ecore_Wl_Event_Focus_Out; +typedef struct _Ecore_Wl_Event_Window_Configure Ecore_Wl_Event_Window_Configure; +typedef struct _Ecore_Wl_Event_Dnd_Enter Ecore_Wl_Event_Dnd_Enter; +typedef struct _Ecore_Wl_Event_Dnd_Position Ecore_Wl_Event_Dnd_Position; +typedef struct _Ecore_Wl_Event_Dnd_Leave Ecore_Wl_Event_Dnd_Leave; +typedef struct _Ecore_Wl_Event_Dnd_Drop Ecore_Wl_Event_Dnd_Drop; +typedef struct _Ecore_Wl_Event_Data_Source_Send Ecore_Wl_Event_Data_Source_Send; /** @since 1.7 */ +typedef struct _Ecore_Wl_Event_Selection_Data_Ready Ecore_Wl_Event_Selection_Data_Ready; /** @since 1.7 */ +typedef struct _Ecore_Wl_Event_Interfaces_Bound Ecore_Wl_Event_Interfaces_Bound; + +enum _Ecore_Wl_Window_Type +{ + ECORE_WL_WINDOW_TYPE_NONE, + ECORE_WL_WINDOW_TYPE_TOPLEVEL, + ECORE_WL_WINDOW_TYPE_FULLSCREEN, + ECORE_WL_WINDOW_TYPE_MAXIMIZED, + ECORE_WL_WINDOW_TYPE_TRANSIENT, + ECORE_WL_WINDOW_TYPE_MENU, + ECORE_WL_WINDOW_TYPE_CUSTOM +}; + +enum _Ecore_Wl_Window_Buffer_Type +{ + ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW, + ECORE_WL_WINDOW_BUFFER_TYPE_EGL_IMAGE, + ECORE_WL_WINDOW_BUFFER_TYPE_SHM +}; + +struct _Ecore_Wl_Display +{ + struct + { + struct wl_display *display; + struct wl_registry *registry; + struct wl_compositor *compositor; + struct wl_shell *shell; + struct wl_shell *desktop_shell; + struct wl_shm *shm; + struct wl_data_device_manager *data_device_manager; + } wl; + + int fd; + unsigned int mask; + unsigned int serial; + Ecore_Fd_Handler *fd_hdl; + + struct wl_list inputs; + struct wl_list outputs; + + struct + { + struct xkb_context *context; + } xkb; + + struct wl_cursor_theme *cursor_theme; + + Ecore_Wl_Output *output; + Ecore_Wl_Input *input; + + void (*output_configure)(Ecore_Wl_Output *output, void *data); + void *data; +}; + +struct _Ecore_Wl_Output +{ + Ecore_Wl_Display *display; + struct wl_output *output; + Eina_Rectangle allocation; + int mw, mh; + struct wl_list link; + + void (*destroy) (Ecore_Wl_Output *output, void *data); + void *data; +}; + +struct _Ecore_Wl_Input +{ + Ecore_Wl_Display *display; + struct wl_seat *seat; + struct wl_pointer *pointer; + struct wl_keyboard *keyboard; + struct wl_touch *touch; + + const char *cursor_name; + struct wl_surface *cursor_surface; + struct wl_callback *cursor_frame_cb; + + struct wl_data_device *data_device; + + Ecore_Wl_Window *pointer_focus; + Ecore_Wl_Window *keyboard_focus; + + unsigned int button; + unsigned int timestamp; + unsigned int modifiers; + unsigned int pointer_enter_serial; + int sx, sy; + + struct wl_list link; + + Ecore_Wl_Window *grab; + unsigned int grab_button; + + Ecore_Wl_Dnd_Source *drag_source; + Ecore_Wl_Dnd_Source *selection_source; + Ecore_Wl_Dnd *dnd; /** @since 1.7 */ + + struct + { + struct xkb_keymap *keymap; + struct xkb_state *state; + xkb_mod_mask_t control_mask; + xkb_mod_mask_t alt_mask; + xkb_mod_mask_t shift_mask; + } xkb; + + struct + { + Ecore_Fd_Handler *hdlr; + int timerfd; + unsigned int sym, key, time; + } repeat; +}; + +struct _Ecore_Wl_Window +{ + Ecore_Wl_Display *display; + Ecore_Wl_Window *parent; + + struct wl_surface *surface; + struct wl_shell_surface *shell_surface; + + struct + { + struct wl_region *input, *opaque; + } region; + + int id; + int x, y; + int edges; + + Eina_Rectangle allocation, pending_allocation; + Eina_Rectangle saved_allocation, server_allocation; + + /* Eina_Bool redraw_scheduled : 1; */ + /* Eina_Bool resize_scheduled : 1; */ + Eina_Bool alpha : 1; + Eina_Bool transparent : 1; + Eina_Bool moving : 1; + Eina_Bool resizing : 1; + + Ecore_Wl_Window_Type type; + Ecore_Wl_Window_Buffer_Type buffer_type; + + Ecore_Wl_Input *pointer_device; + Ecore_Wl_Input *keyboard_device; + + Eina_Bool frame_pending; + struct wl_callback *frame_callback; + /* FIXME: Ideally we should record the cursor name for this window + * so we can compare and avoid unnecessary cursor set calls to wayland */ + + void *data; +}; + +struct _Ecore_Wl_Event_Mouse_In +{ + int modifiers; + int x, y; + struct + { + int x, y; + } root; + unsigned int window; + unsigned int event_window; + unsigned int root_window; + unsigned int timestamp; +}; + +struct _Ecore_Wl_Event_Mouse_Out +{ + int modifiers; + int x, y; + struct + { + int x, y; + } root; + unsigned int window; + unsigned int event_window; + unsigned int root_window; + unsigned int timestamp; +}; + +struct _Ecore_Wl_Event_Focus_In +{ + unsigned int win; + unsigned int timestamp; +}; + +struct _Ecore_Wl_Event_Focus_Out +{ + unsigned int win; + unsigned int timestamp; +}; + +struct _Ecore_Wl_Event_Window_Configure +{ + unsigned int win; + unsigned int event_win; + int x, y, w, h; +}; + +struct _Ecore_Wl_Event_Dnd_Enter +{ + unsigned int win, source; + char **types; + int num_types; + struct + { + int x, y; + } position; +}; + +struct _Ecore_Wl_Event_Dnd_Position +{ + unsigned int win, source; + struct + { + int x, y; + } position; +}; + +struct _Ecore_Wl_Event_Dnd_Leave +{ + unsigned int win, source; +}; + +struct _Ecore_Wl_Event_Dnd_Drop +{ + unsigned int win, source; + struct + { + int x, y; + } position; +}; + +/** @since 1.7 */ +struct _Ecore_Wl_Event_Data_Source_Send +{ + char *type; + int fd; +}; + +/** @since 1.7 */ +struct _Ecore_Wl_Event_Selection_Data_Ready +{ + char *data; + int len; + Eina_Bool done; +}; + +struct _Ecore_Wl_Event_Interfaces_Bound +{ + Eina_Bool compositor : 1; + Eina_Bool shm : 1; + Eina_Bool shell : 1; +}; + +/** + * @file + * @brief Ecore functions for dealing with the Wayland window system + * + * Ecore_Wl provides a wrapper and convenience functions for using the + * Wayland window system. Function groups for this part of the library + * include the following: + * + * @li @ref Ecore_Wl_Init_Group + * @li @ref Ecore_Wl_Display_Group + * @li @ref Ecore_Wl_Flush_Group + * @li @ref Ecore_Wl_Window_Group + */ + +EAPI extern int ECORE_WL_EVENT_MOUSE_IN; +EAPI extern int ECORE_WL_EVENT_MOUSE_OUT; +EAPI extern int ECORE_WL_EVENT_FOCUS_IN; +EAPI extern int ECORE_WL_EVENT_FOCUS_OUT; +EAPI extern int ECORE_WL_EVENT_WINDOW_CONFIGURE; +EAPI extern int ECORE_WL_EVENT_DND_ENTER; +EAPI extern int ECORE_WL_EVENT_DND_POSITION; +EAPI extern int ECORE_WL_EVENT_DND_LEAVE; +EAPI extern int ECORE_WL_EVENT_DND_DROP; +EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_TARGET; /** @since 1.7 */ +EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_SEND; /** @since 1.7 */ +EAPI extern int ECORE_WL_EVENT_DATA_SOURCE_CANCELLED; /** @since 1.7 */ +EAPI extern int ECORE_WL_EVENT_SELECTION_DATA_READY; /** @since 1.7 */ +EAPI extern int ECORE_WL_EVENT_INTERFACES_BOUND; + +EAPI int ecore_wl_init(const char *name); +EAPI int ecore_wl_shutdown(void); +EAPI void ecore_wl_flush(void); +EAPI void ecore_wl_sync(void); +EAPI struct wl_shm *ecore_wl_shm_get(void); +EAPI struct wl_display *ecore_wl_display_get(void); +EAPI void ecore_wl_screen_size_get(int *w, int *h); +EAPI void ecore_wl_pointer_xy_get(int *x, int *y); +EAPI int ecore_wl_dpi_get(void); +EAPI void ecore_wl_display_iterate(void); +EAPI struct wl_cursor *ecore_wl_cursor_get(const char *cursor_name); + +EAPI void ecore_wl_input_grab(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button); +EAPI void ecore_wl_input_ungrab(Ecore_Wl_Input *input); +EAPI void ecore_wl_input_pointer_set(Ecore_Wl_Input *input, struct wl_surface *surface, int hot_x, int hot_y); +EAPI void ecore_wl_input_cursor_from_name_set(Ecore_Wl_Input *input, const char *cursor_name); +EAPI void ecore_wl_input_cursor_default_restore(Ecore_Wl_Input *input); + +EAPI struct wl_list ecore_wl_outputs_get(void); + +EAPI Ecore_Wl_Window *ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buffer_type); +EAPI void ecore_wl_window_free(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y); +EAPI void ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location); +EAPI void ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h); +EAPI void ecore_wl_window_buffer_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer, int x, int y); +EAPI void ecore_wl_window_show(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_hide(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_raise(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized); +EAPI void ecore_wl_window_fullscreen_set(Ecore_Wl_Window *win, Eina_Bool fullscreen); +EAPI void ecore_wl_window_transparent_set(Ecore_Wl_Window *win, Eina_Bool transparent); +EAPI void ecore_wl_window_update_size(Ecore_Wl_Window *win, int w, int h); +EAPI void ecore_wl_window_update_location(Ecore_Wl_Window *win, int x, int y); +EAPI struct wl_surface *ecore_wl_window_surface_get(Ecore_Wl_Window *win); +EAPI struct wl_shell_surface *ecore_wl_window_shell_surface_get(Ecore_Wl_Window *win); +EAPI Ecore_Wl_Window *ecore_wl_window_find(unsigned int id); +EAPI void ecore_wl_window_type_set(Ecore_Wl_Window *win, Ecore_Wl_Window_Type type); +EAPI void ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_surface *surface, int hot_x, int hot_y); +EAPI void ecore_wl_window_cursor_from_name_set(Ecore_Wl_Window *win, const char *cursor_name); +EAPI void ecore_wl_window_cursor_default_restore(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_parent_set(Ecore_Wl_Window *win, Ecore_Wl_Window *parent); + +/** @since 1.7 */ +EAPI Eina_Bool ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered); +EAPI Eina_Bool ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type); +EAPI Ecore_Wl_Dnd *ecore_wl_dnd_get(); +EAPI Eina_Bool ecore_wl_dnd_start_drag(); +EAPI Eina_Bool ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd); + +#endif diff --git a/src/lib/ecore_wayland/ecore_wl.c b/src/lib/ecore_wayland/ecore_wl.c new file mode 100644 index 0000000000..481ba790b6 --- /dev/null +++ b/src/lib/ecore_wayland/ecore_wl.c @@ -0,0 +1,497 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include "ecore_wl_private.h" + +/* local function prototypes */ +static Eina_Bool _ecore_wl_shutdown(Eina_Bool close); +static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl); +static void _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version EINA_UNUSED); +static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd); +static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd); + +/* local variables */ +static int _ecore_wl_init_count = 0; +static const struct wl_registry_listener _ecore_wl_registry_listener = +{ + _ecore_wl_cb_handle_global, + NULL // handle_global_remove +}; + +/* external variables */ +int _ecore_wl_log_dom = -1; +Ecore_Wl_Display *_ecore_wl_disp = NULL; + +EAPI int ECORE_WL_EVENT_MOUSE_IN = 0; +EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0; +EAPI int ECORE_WL_EVENT_FOCUS_IN = 0; +EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0; +EAPI int ECORE_WL_EVENT_WINDOW_CONFIGURE = 0; +EAPI int ECORE_WL_EVENT_DND_ENTER = 0; +EAPI int ECORE_WL_EVENT_DND_POSITION = 0; +EAPI int ECORE_WL_EVENT_DND_LEAVE = 0; +EAPI int ECORE_WL_EVENT_DND_DROP = 0; +EAPI int ECORE_WL_EVENT_DATA_SOURCE_TARGET = 0; +EAPI int ECORE_WL_EVENT_DATA_SOURCE_SEND = 0; +EAPI int ECORE_WL_EVENT_SELECTION_DATA_READY = 0; +EAPI int ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = 0; +EAPI int ECORE_WL_EVENT_INTERFACES_BOUND = 0; + +/** + * @defgroup Ecore_Wl_Init_Group Wayland Library Init and Shutdown Functions + * + * Functions that start and shutdown the Ecore Wayland Library. + */ + +/** + * Initialize the Wayland 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_Wl_Init_Group + */ +EAPI int +ecore_wl_init(const char *name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (++_ecore_wl_init_count != 1) return _ecore_wl_init_count; + + if (!eina_init()) return --_ecore_wl_init_count; + + _ecore_wl_log_dom = + eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR); + if (_ecore_wl_log_dom < 0) + { + EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland"); + eina_shutdown(); + return --_ecore_wl_init_count; + } + + if (!ecore_init()) + { + ERR("Could not initialize ecore"); + eina_log_domain_unregister(_ecore_wl_log_dom); + _ecore_wl_log_dom = -1; + eina_shutdown(); + return --_ecore_wl_init_count; + } + + if (!ecore_event_init()) + { + ERR("Could not initialize ecore_event"); + eina_log_domain_unregister(_ecore_wl_log_dom); + _ecore_wl_log_dom = -1; + ecore_shutdown(); + eina_shutdown(); + return --_ecore_wl_init_count; + } + + if (!ECORE_WL_EVENT_MOUSE_IN) + { + ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new(); + ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new(); + ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new(); + ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new(); + ECORE_WL_EVENT_WINDOW_CONFIGURE = ecore_event_type_new(); + ECORE_WL_EVENT_DND_ENTER = ecore_event_type_new(); + ECORE_WL_EVENT_DND_POSITION = ecore_event_type_new(); + ECORE_WL_EVENT_DND_LEAVE = ecore_event_type_new(); + ECORE_WL_EVENT_DND_DROP = ecore_event_type_new(); + ECORE_WL_EVENT_DATA_SOURCE_TARGET = ecore_event_type_new(); + ECORE_WL_EVENT_DATA_SOURCE_SEND = ecore_event_type_new(); + ECORE_WL_EVENT_SELECTION_DATA_READY = ecore_event_type_new(); + ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = ecore_event_type_new(); + ECORE_WL_EVENT_INTERFACES_BOUND = ecore_event_type_new(); + } + + if (!(_ecore_wl_disp = malloc(sizeof(Ecore_Wl_Display)))) + { + ERR("Could not allocate memory for Ecore_Wl_Display structure"); + eina_log_domain_unregister(_ecore_wl_log_dom); + _ecore_wl_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return --_ecore_wl_init_count; + } + + memset(_ecore_wl_disp, 0, sizeof(Ecore_Wl_Display)); + + if (!(_ecore_wl_disp->wl.display = wl_display_connect(name))) + { + ERR("Could not connect to Wayland display"); + eina_log_domain_unregister(_ecore_wl_log_dom); + _ecore_wl_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return --_ecore_wl_init_count; + } + + _ecore_wl_disp->fd = wl_display_get_fd(_ecore_wl_disp->wl.display); + + _ecore_wl_disp->fd_hdl = + ecore_main_fd_handler_add(_ecore_wl_disp->fd, + ECORE_FD_READ | ECORE_FD_WRITE, + _ecore_wl_cb_handle_data, _ecore_wl_disp, + NULL, NULL); + + wl_list_init(&_ecore_wl_disp->inputs); + wl_list_init(&_ecore_wl_disp->outputs); + + _ecore_wl_disp->wl.registry = + wl_display_get_registry(_ecore_wl_disp->wl.display); + wl_registry_add_listener(_ecore_wl_disp->wl.registry, + &_ecore_wl_registry_listener, _ecore_wl_disp); + + wl_display_dispatch(_ecore_wl_disp->wl.display); + + if (!_ecore_wl_xkb_init(_ecore_wl_disp)) + { + ERR("Could not initialize XKB"); + free(_ecore_wl_disp); + eina_log_domain_unregister(_ecore_wl_log_dom); + _ecore_wl_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return --_ecore_wl_init_count; + } + + _ecore_wl_window_init(); + + return _ecore_wl_init_count; +} + +/** + * Shuts down the Ecore Wayland Library + * + * In shutting down the library, the Wayland 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_Wl_Init_Group + */ +EAPI int +ecore_wl_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_wl_shutdown(EINA_TRUE); +} + +/** + * @defgroup Ecore_Wl_Flush_Group Wayland Synchronization Functions + * + * Functions that ensure that all commands which have been issued by the + * Ecore Wayland library have been sent to the server. + */ + +/** + * Sends all Wayland commands to the Wayland Display. + * + * @ingroup Ecore_Wl_Flush_Group + * @since 1.2 + */ +EAPI void +ecore_wl_flush(void) +{ +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + wl_display_flush(_ecore_wl_disp->wl.display); +} + +/** + * Flushes the command buffer and waits until all requests have been + * processed by the server. + * + * @ingroup Ecore_Wl_Flush_Group + * @since 1.2 + */ +EAPI void +ecore_wl_sync(void) +{ +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + wl_display_sync(_ecore_wl_disp->wl.display); +} + +/** + * @defgroup Ecore_Wl_Display_Group Wayland Display Functions + * + * Functions that set and retrieve various information about the Wayland Display. + */ + +/** + * Retrieves the Wayland Shm Interface used for the current Wayland connection. + * + * @return The current wayland shm interface + * + * @ingroup Ecore_Wl_Display_Group + * @since 1.2 + */ +EAPI struct wl_shm * +ecore_wl_shm_get(void) +{ + return _ecore_wl_disp->wl.shm; +} + +/** + * Retrieves the Wayland Display Interface used for the current Wayland connection. + * + * @return The current wayland display interface + * + * @ingroup Ecore_Wl_Display_Group + * @since 1.2 + */ +EAPI struct wl_display * +ecore_wl_display_get(void) +{ + return _ecore_wl_disp->wl.display; +} + +/** + * Retrieves the size of the current screen. + * + * @param w where to return the width. May be NULL. Returns 0 on error. + * @param h where to return the height. May be NULL. Returns 0 on error. + * + * @ingroup Ecore_Wl_Display_Group + * @since 1.2 + */ +EAPI void +ecore_wl_screen_size_get(int *w, int *h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (w) *w = 0; + if (h) *h = 0; + + if (!_ecore_wl_disp->output) return; + + if (w) *w = _ecore_wl_disp->output->allocation.w; + if (h) *h = _ecore_wl_disp->output->allocation.h; +} + +/* @since 1.2 */ +EAPI void +ecore_wl_pointer_xy_get(int *x, int *y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_wl_input_pointer_xy_get(x, y); +} + +/** + * Return the screen DPI + * + * This is a simplistic call to get DPI. It does not account for differing + * DPI in the x and y axes nor does it account for multihead or xinerama and + * xrandr where different parts of the screen may have different DPI etc. + * + * @return the general screen DPI (dots/pixels per inch). + * + * @since 1.2 + */ +EAPI int +ecore_wl_dpi_get(void) +{ + int w, mw; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_ecore_wl_disp->output) return 75; + + mw = _ecore_wl_disp->output->mw; + if (mw <= 0) return 75; + + w = _ecore_wl_disp->output->allocation.w; + /* FIXME: NB: Hrrrmmm, need to verify this. xorg code is using a different + * formula to calc this */ + return (((w * 254) / mw) + 5) / 10; +} + +EAPI void +ecore_wl_display_iterate(void) +{ + wl_display_dispatch(_ecore_wl_disp->wl.display); +} + +/** + * Retrieves the requested cursor from the cursor theme + * + * @param cursor_name The desired cursor name to be looked up in the theme + * @return the cursor or NULL if the cursor cannot be found + * + * @since 1.2 + */ +EAPI struct wl_cursor * +ecore_wl_cursor_get(const char *cursor_name) +{ + if ((!_ecore_wl_disp) || (!_ecore_wl_disp->cursor_theme)) + return NULL; + + return wl_cursor_theme_get_cursor(_ecore_wl_disp->cursor_theme, + cursor_name); +} + +/* local functions */ +static Eina_Bool +_ecore_wl_shutdown(Eina_Bool close) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (--_ecore_wl_init_count != 0) return _ecore_wl_init_count; + if (!_ecore_wl_disp) return _ecore_wl_init_count; + + _ecore_wl_window_shutdown(); + + if (_ecore_wl_disp->fd_hdl) + ecore_main_fd_handler_del(_ecore_wl_disp->fd_hdl); + + if (close) + { + Ecore_Wl_Output *out, *tout; + Ecore_Wl_Input *in, *tin; + + wl_list_for_each_safe(out, tout, &_ecore_wl_disp->outputs, link) + _ecore_wl_output_del(out); + + wl_list_for_each_safe(in, tin, &_ecore_wl_disp->inputs, link) + _ecore_wl_input_del(in); + + _ecore_wl_xkb_shutdown(_ecore_wl_disp); + + if (_ecore_wl_disp->wl.shell) + wl_shell_destroy(_ecore_wl_disp->wl.shell); + if (_ecore_wl_disp->wl.shm) wl_shm_destroy(_ecore_wl_disp->wl.shm); + if (_ecore_wl_disp->wl.data_device_manager) + wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager); + if (_ecore_wl_disp->wl.compositor) + wl_compositor_destroy(_ecore_wl_disp->wl.compositor); + if (_ecore_wl_disp->wl.display) + { + wl_registry_destroy(_ecore_wl_disp->wl.registry); + wl_display_flush(_ecore_wl_disp->wl.display); + wl_display_disconnect(_ecore_wl_disp->wl.display); + } + free(_ecore_wl_disp); + } + + ecore_event_shutdown(); + ecore_shutdown(); + + eina_log_domain_unregister(_ecore_wl_log_dom); + _ecore_wl_log_dom = -1; + eina_shutdown(); + + return _ecore_wl_init_count; +} + +static Eina_Bool +_ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl) +{ + Ecore_Wl_Display *ewd; + + /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ + + if (!(ewd = data)) return ECORE_CALLBACK_RENEW; + + /* FIXME: This should also catch ECORE_FD_ERROR and exit */ + + /* wl_display_dispatch_pending(ewd->wl.display); */ + + if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ)) + wl_display_dispatch(ewd->wl.display); + else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE)) + wl_display_flush(ewd->wl.display); + + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version EINA_UNUSED) +{ + Ecore_Wl_Display *ewd; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ewd = data; + + if (!strcmp(interface, "wl_compositor")) + { + ewd->wl.compositor = + wl_registry_bind(registry, id, &wl_compositor_interface, 1); + } + else if (!strcmp(interface, "wl_output")) + _ecore_wl_output_add(ewd, id); + else if (!strcmp(interface, "wl_seat")) + _ecore_wl_input_add(ewd, id); + else if (!strcmp(interface, "wl_shell")) + { + ewd->wl.shell = + wl_registry_bind(registry, id, &wl_shell_interface, 1); + } + else if (!strcmp(interface, "wl_shm")) + { + ewd->wl.shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); + + /* FIXME: We should not hard-code a cursor size here, and we should + * also import the theme name from a config or env variable */ + ewd->cursor_theme = wl_cursor_theme_load(NULL, 32, ewd->wl.shm); + } + else if (!strcmp(interface, "wl_data_device_manager")) + { + ewd->wl.data_device_manager = + wl_registry_bind(registry, id, &wl_data_device_manager_interface, 1); + } + + if ((ewd->wl.compositor) && (ewd->wl.shm) && (ewd->wl.shell)) + { + Ecore_Wl_Event_Interfaces_Bound *ev; + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Interfaces_Bound)))) + return; + + ev->compositor = (ewd->wl.compositor != NULL); + ev->shm = (ewd->wl.shm != NULL); + ev->shell = (ewd->wl.shell != NULL); + + ecore_event_add(ECORE_WL_EVENT_INTERFACES_BOUND, ev, NULL, NULL); + } +} + +static Eina_Bool +_ecore_wl_xkb_init(Ecore_Wl_Display *ewd) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ewd->xkb.context = xkb_context_new(0))) + return EINA_FALSE; + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xkb_context_unref(ewd->xkb.context); + + return EINA_TRUE; +} + +struct wl_data_source * +_ecore_wl_create_data_source(Ecore_Wl_Display *ewd) +{ + return wl_data_device_manager_create_data_source(ewd->wl.data_device_manager); +} diff --git a/src/lib/ecore_wayland/ecore_wl_dnd.c b/src/lib/ecore_wayland/ecore_wl_dnd.c new file mode 100644 index 0000000000..403e3b9f6b --- /dev/null +++ b/src/lib/ecore_wayland/ecore_wl_dnd.c @@ -0,0 +1,485 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "ecore_wl_private.h" + +struct _dnd_task +{ + void *data; + Ecore_Fd_Cb cb; +}; + +struct _dnd_read_ctx +{ + int epoll_fd; + struct epoll_event *ep; +}; + +/* local function prototypes */ +static void _ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, const char *type); +static void _ecore_wl_dnd_cb_enter_free(void *data EINA_UNUSED, void *event); + +static void _ecore_wl_dnd_data_source_target(void *data, struct wl_data_source *source, const char *mime_type); +static void _ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd); +static void _ecore_wl_dnd_data_source_cancelled(void *data, struct wl_data_source *source); +static void _ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char *type); + +/* wayland listeners */ +static const struct wl_data_offer_listener _ecore_wl_data_offer_listener = +{ + _ecore_wl_dnd_offer, +}; + +static const struct wl_data_source_listener _ecore_wl_data_source_listener = +{ + _ecore_wl_dnd_data_source_target, + _ecore_wl_dnd_data_source_send, + _ecore_wl_dnd_data_source_cancelled +}; + +extern Ecore_Wl_Dnd *glb_dnd; + +EAPI Ecore_Wl_Dnd * +ecore_wl_dnd_get() +{ + return glb_dnd; +} + +EAPI Eina_Bool +ecore_wl_dnd_start_drag(Ecore_Wl_Dnd *dnd EINA_UNUSED) +{ + //TODO: + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered) +{ + char **p; + const char **type; + + dnd->data_source = _ecore_wl_create_data_source(dnd->ewd); + + /* free old types */ + if (dnd->types_offered.data) + { + wl_array_for_each(p, &dnd->types_offered) + free(*p); + wl_array_release(&dnd->types_offered); + wl_array_init(&dnd->types_offered); + } + + for (type = types_offered; *type; type++) + { + p = wl_array_add(&dnd->types_offered, sizeof(*p)); + *p = strdup(*type); + wl_data_source_offer(dnd->data_source, *p); + } + + wl_data_source_add_listener(dnd->data_source, &_ecore_wl_data_source_listener, dnd); + + _ecore_wl_input_set_selection(dnd->input, dnd->data_source); + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type) +{ + char **p; + Ecore_Wl_Input *input; + + input = dnd->input; + + if (!input->selection_source) return EINA_FALSE; + + wl_array_for_each(p, &input->selection_source->types) + if (strcmp(type, *p) == 0) break; + + if (!*p) return EINA_FALSE; + + _ecore_wl_dnd_source_receive_data(input->selection_source, type); + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd) +{ + Ecore_Wl_Input *input; + + input = dnd->input; + return (input->selection_source != NULL); +} + +/* local functions */ +static void +_ecore_wl_dnd_data_source_target(void *data EINA_UNUSED, struct wl_data_source *source EINA_UNUSED, const char *mime_type EINA_UNUSED) +{ + //TODO: +} + +static void +_ecore_wl_dnd_cb_data_source_send_free(void *data EINA_UNUSED, void *event) +{ + Ecore_Wl_Event_Data_Source_Send *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = event)) return; + + free(ev->type); + free(ev); +} + +static void +_ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd) +{ + Ecore_Wl_Event_Data_Source_Send *event; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!data) return; + + if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Send)))) return; + + event->type = strdup(mime_type); + event->fd = fd; + + ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, event, _ecore_wl_dnd_cb_data_source_send_free, NULL); +} + +static void +_ecore_wl_dnd_data_source_cancelled(void *data EINA_UNUSED, struct wl_data_source *source) +{ + wl_data_source_destroy(source); +} + +void +_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer) +{ + Ecore_Wl_Dnd_Source *source; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source)))) return; + wl_array_init(&source->types); + source->refcount = 1; + source->input = input; + source->offer = offer; + wl_data_offer_add_listener(source->offer, + &_ecore_wl_data_offer_listener, source); +} + +void +_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp EINA_UNUSED, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer) +{ + Ecore_Wl_Event_Dnd_Enter *event; + Ecore_Wl_Input *input; + Ecore_Wl_Window *win; + char **p; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!(input = data)) || (!offer)) return; + + if (!(input->drag_source = wl_data_offer_get_user_data(offer))) + return; + + win = wl_surface_get_user_data(surface); +// input->pointer_focus = win; + + p = wl_array_add(&input->drag_source->types, sizeof(*p)); + *p = NULL; + + if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return; + + event->win = win->id; + if (input->drag_source->input) + { + if (input->drag_source->input->keyboard_focus) + event->source = input->drag_source->input->keyboard_focus->id; + } + + event->position.x = wl_fixed_to_int(x); + event->position.y = wl_fixed_to_int(y); + event->num_types = input->drag_source->types.size; + event->types = input->drag_source->types.data; + + ecore_event_add(ECORE_WL_EVENT_DND_ENTER, event, + _ecore_wl_dnd_cb_enter_free, NULL); +} + +void +_ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device EINA_UNUSED) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + /* FIXME: NB: This MAY need to raise a wl_event_dnd_leave for the + * source window */ + _ecore_wl_dnd_del(input->drag_source); + input->drag_source = NULL; +} + +void +_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x, wl_fixed_t y) +{ + Ecore_Wl_Event_Dnd_Position *event; + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + + input->sx = wl_fixed_to_int(x); + input->sy = wl_fixed_to_int(y); + + if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return; + + if (input->drag_source) + { + if (input->drag_source->input) + { + if (input->drag_source->input->pointer_focus) + event->win = input->drag_source->input->pointer_focus->id; + if (input->drag_source->input->keyboard_focus) + event->source = input->drag_source->input->keyboard_focus->id; + } + } + + event->position.x = input->sx; + event->position.y = input->sy; + + ecore_event_add(ECORE_WL_EVENT_DND_POSITION, event, NULL, NULL); +} + +void +_ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device EINA_UNUSED) +{ + Ecore_Wl_Event_Dnd_Drop *event; + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + + if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return; + + if (input->drag_source) + { + if (input->drag_source->input) + { + if (input->drag_source->input->pointer_focus) + event->win = input->drag_source->input->pointer_focus->id; + if (input->drag_source->input->keyboard_focus) + event->source = input->drag_source->input->keyboard_focus->id; + } + } + + event->position.x = input->sx; + event->position.y = input->sy; + + ecore_event_add(ECORE_WL_EVENT_DND_DROP, event, NULL, NULL); +} + +void +_ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + if (input->selection_source) _ecore_wl_dnd_del(input->selection_source); + input->selection_source = NULL; + if (offer) + { + char **p; + + input->selection_source = wl_data_offer_get_user_data(offer); + p = wl_array_add(&input->selection_source->types, sizeof(*p)); + *p = NULL; + } +} + +void +_ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!source) return; + source->refcount--; + if (source->refcount == 0) + { + char **p; + + wl_data_offer_destroy(source->offer); + for (p = source->types.data; *p; p++) + free(*p); + wl_array_release(&source->types); + free(source); + } +} + +/* local functions */ +static void +_ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, const char *type) +{ + Ecore_Wl_Dnd_Source *source; + char **p; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(source = data)) return; + p = wl_array_add(&source->types, sizeof(*p)); + *p = strdup(type); +} + +static void +_ecore_wl_dnd_cb_enter_free(void *data EINA_UNUSED, void *event) +{ + Ecore_Wl_Event_Dnd_Enter *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = event)) return; + free(ev); +} + +static void +_ecore_wl_dnd_cb_selection_data_ready_free(void *data EINA_UNUSED, void *event) +{ + Ecore_Wl_Event_Selection_Data_Ready *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = event)) return; + + free(ev->data); + free(ev); +} + +static Eina_Bool +_ecore_wl_dnd_read_data(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + int len; + char buffer[4096]; + Ecore_Wl_Dnd_Source *source; + Ecore_Wl_Event_Selection_Data_Ready *event; + Eina_Bool ret; + + source = data; + + len = read(source->fd, buffer, sizeof buffer); + + if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Selection_Data_Ready)))) + return ECORE_CALLBACK_CANCEL; + + if (len <= 0) + { + close(source->fd); + _ecore_wl_dnd_del(source); + event->done = EINA_TRUE; + event->data = NULL; + event->len = 0; + ret = ECORE_CALLBACK_CANCEL; + } + else + { + event->data = malloc(len + 1); + if (!event->data) return ECORE_CALLBACK_CANCEL; + strncpy(event->data, buffer, len); + event->data[len] = '\0'; + event->len = len; + event->done = EINA_FALSE; + ret = ECORE_CALLBACK_RENEW; + } + + ecore_event_add(ECORE_WL_EVENT_SELECTION_DATA_READY, event, + _ecore_wl_dnd_cb_selection_data_ready_free, NULL); + return ret; +} + + +static Eina_Bool +_ecore_wl_dnd_idler_cb(void *data) +{ + struct _dnd_read_ctx *ctx; + struct _dnd_task *task; + int count, i; + + ctx = data; + count = epoll_wait(ctx->epoll_fd, ctx->ep, 1, 0); + for (i = 0; i < count; i++) + { + task = ctx->ep->data.ptr; + if (task->cb(task->data, NULL) == ECORE_CALLBACK_CANCEL) + { + free(ctx->ep); + free(task); + free(ctx); + return ECORE_CALLBACK_CANCEL; + } + } + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char *type) +{ + int epoll_fd; + struct epoll_event *ep = NULL; + struct _dnd_task *task = NULL; + struct _dnd_read_ctx *read_ctx = NULL; + int p[2]; + + if (pipe2(p, O_CLOEXEC) == -1) + return; + + wl_data_offer_receive(source->offer, type, p[1]); + close(p[1]); + + /* Due to http://trac.enlightenment.org/e/ticket/1208, + * use epoll and idle handler instead of ecore_main_fd_handler_add() */ + + ep = calloc(1, sizeof(struct epoll_event)); + if (!ep) goto err; + + task = calloc(1, sizeof(struct _dnd_task)); + if (!task) goto err; + + read_ctx = calloc(1, sizeof(struct _dnd_read_ctx)); + if (!read_ctx) goto err; + + epoll_fd = epoll_create1(0); + if (epoll_fd < 0) goto err; + + task->data = source; + task->cb = _ecore_wl_dnd_read_data; + ep->events = EPOLLIN; + ep->data.ptr = task; + + if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err; + + read_ctx->epoll_fd = epoll_fd; + read_ctx->ep = ep; + + if (!ecore_idler_add(_ecore_wl_dnd_idler_cb, read_ctx)) goto err; + + source->refcount++; + source->fd = p[0]; + return; + +err: + if (ep) free(ep); + if (task) free(task); + if (read_ctx) free(read_ctx); + close(p[0]); + return; +} diff --git a/src/lib/ecore_wayland/ecore_wl_input.c b/src/lib/ecore_wayland/ecore_wl_input.c new file mode 100644 index 0000000000..b8485fb625 --- /dev/null +++ b/src/lib/ecore_wayland/ecore_wl_input.c @@ -0,0 +1,1208 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +/** + * NB: Events that receive a 'serial' instead of timestamp + * + * input_device_attach (for pointer image) + * input_device_button_event (button press/release) + * input_device_key_press + * input_device_pointer_enter + * input_device_pointer_leave + * input_device_keyboard_enter + * input_device_keyboard_leave + * input_device_touch_down + * input_device_touch_up + * + **/ + +#include "ecore_wl_private.h" +#include +#include + +/* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... + * What about other OSs ?? */ +#ifdef __linux__ +# include +#else +# define BTN_LEFT 0x110 +# define BTN_RIGHT 0x111 +# define BTN_MIDDLE 0x112 +# define BTN_SIDE 0x113 +# define BTN_EXTRA 0x114 +# define BTN_FORWARD 0x115 +# define BTN_BACK 0x116 +#endif + +Ecore_Wl_Dnd *glb_dnd = NULL; + +/* local function prototypes */ +static void _ecore_wl_input_seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps); + +static void _ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy); +static void _ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface); +static void _ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy); +static void _ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state); +static void _ecore_wl_input_cb_pointer_axis(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, unsigned int axis, wl_fixed_t value); +static void _ecore_wl_input_cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED); +static void _ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size); +static void _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface, struct wl_array *keys EINA_UNUSED); +static void _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface); +static void _ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int key, unsigned int state); +static void _ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial EINA_UNUSED, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group); +static Eina_Bool _ecore_wl_input_cb_keyboard_repeat(void *data, Ecore_Fd_Handler *handler EINA_UNUSED); +static void _ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface EINA_UNUSED, int id EINA_UNUSED, wl_fixed_t x, wl_fixed_t y); +static void _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id EINA_UNUSED); +static void _ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id EINA_UNUSED, wl_fixed_t x, wl_fixed_t y); +static void _ecore_wl_input_cb_touch_frame(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED); +static void _ecore_wl_input_cb_touch_cancel(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED); +static void _ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); +static void _ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer); +static void _ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device); +static void _ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, wl_fixed_t x, wl_fixed_t y); +static void _ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device); +static void _ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); + +static void _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); +static void _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); +static void _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); +static void _ecore_wl_input_focus_in_send(Ecore_Wl_Input *input EINA_UNUSED, Ecore_Wl_Window *win, unsigned int timestamp); +static void _ecore_wl_input_focus_out_send(Ecore_Wl_Input *input EINA_UNUSED, Ecore_Wl_Window *win, unsigned int timestamp); +static void _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); +static void _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp); +static void _ecore_wl_input_mouse_wheel_send(Ecore_Wl_Input *input, unsigned int axis, int value, unsigned int timestamp); + +/* static int _ecore_wl_input_keysym_to_string(unsigned int symbol, char *buffer, int len); */ + +/* wayland interfaces */ +static const struct wl_pointer_listener pointer_listener = +{ + _ecore_wl_input_cb_pointer_enter, + _ecore_wl_input_cb_pointer_leave, + _ecore_wl_input_cb_pointer_motion, + _ecore_wl_input_cb_pointer_button, + _ecore_wl_input_cb_pointer_axis, +}; + +static const struct wl_keyboard_listener keyboard_listener = +{ + _ecore_wl_input_cb_keyboard_keymap, + _ecore_wl_input_cb_keyboard_enter, + _ecore_wl_input_cb_keyboard_leave, + _ecore_wl_input_cb_keyboard_key, + _ecore_wl_input_cb_keyboard_modifiers, +}; + +static const struct wl_touch_listener touch_listener = +{ + _ecore_wl_input_cb_touch_down, + _ecore_wl_input_cb_touch_up, + _ecore_wl_input_cb_touch_motion, + _ecore_wl_input_cb_touch_frame, + _ecore_wl_input_cb_touch_cancel +}; + +static const struct wl_seat_listener _ecore_wl_seat_listener = +{ + _ecore_wl_input_seat_handle_capabilities, +}; + +static const struct wl_data_device_listener _ecore_wl_data_listener = +{ + _ecore_wl_input_cb_data_offer, + _ecore_wl_input_cb_data_enter, + _ecore_wl_input_cb_data_leave, + _ecore_wl_input_cb_data_motion, + _ecore_wl_input_cb_data_drop, + _ecore_wl_input_cb_data_selection +}; + +static const struct wl_callback_listener _ecore_wl_pointer_surface_listener = +{ + _ecore_wl_input_cb_pointer_frame +}; + +/* local variables */ +static int _pointer_x, _pointer_y; + +EAPI void +ecore_wl_input_grab(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int button) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!input) return; + input->grab = win; + input->grab_button = button; +} + +EAPI void +ecore_wl_input_ungrab(Ecore_Wl_Input *input) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!input) return; + input->grab = NULL; + input->grab_button = 0; +} + +EAPI void +ecore_wl_input_pointer_set(Ecore_Wl_Input *input, struct wl_surface *surface, int hot_x, int hot_y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (input) + wl_pointer_set_cursor(input->pointer, input->pointer_enter_serial, + surface, hot_x, hot_y); +} + +EAPI void +ecore_wl_input_cursor_from_name_set(Ecore_Wl_Input *input, const char *cursor_name) +{ + struct wl_cursor_image *cursor_image; + struct wl_buffer *buffer; + struct wl_cursor *cursor; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!input) return; + + eina_stringshare_replace(&input->cursor_name, cursor_name); + + /* No cursor. Set to default Left Pointer */ + if (!cursor_name) + eina_stringshare_replace(&input->cursor_name, "left_ptr"); + + /* try to get this cursor from the theme */ + if (!(cursor = ecore_wl_cursor_get(input->cursor_name))) + { + /* if the theme does not have this cursor, default to left pointer */ + if (!(cursor = ecore_wl_cursor_get("left_ptr"))) + return; + } + + if ((!cursor->images) || (!cursor->images[0])) + { + ecore_wl_input_pointer_set(input, NULL, 0, 0); + return; + } + + cursor_image = cursor->images[0]; + if ((buffer = wl_cursor_image_get_buffer(cursor_image))) + { + ecore_wl_input_pointer_set(input, input->cursor_surface, + cursor_image->hotspot_x, + cursor_image->hotspot_y); + wl_surface_attach(input->cursor_surface, buffer, 0, 0); + wl_surface_damage(input->cursor_surface, 0, 0, + cursor_image->width, cursor_image->height); + wl_surface_commit(input->cursor_surface); + + if (!input->cursor_frame_cb) + _ecore_wl_input_cb_pointer_frame(input, NULL, 0); + } +} + +EAPI void +ecore_wl_input_cursor_default_restore(Ecore_Wl_Input *input) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!input) return; + + /* Restore to default wayland cursor */ + ecore_wl_input_cursor_from_name_set(input, "left_ptr"); +} + +/* local functions */ +void +_ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = malloc(sizeof(Ecore_Wl_Input)))) return; + + memset(input, 0, sizeof(Ecore_Wl_Input)); + + input->display = ewd; + input->pointer_focus = NULL; + input->keyboard_focus = NULL; + + input->seat = + wl_registry_bind(ewd->wl.registry, id, &wl_seat_interface, 1); + wl_list_insert(ewd->inputs.prev, &input->link); + + wl_seat_add_listener(input->seat, + &_ecore_wl_seat_listener, input); + wl_seat_set_user_data(input->seat, input); + + input->data_device = + wl_data_device_manager_get_data_device(ewd->wl.data_device_manager, + input->seat); + wl_data_device_add_listener(input->data_device, + &_ecore_wl_data_listener, input); + input->cursor_surface = + wl_compositor_create_surface(_ecore_wl_disp->wl.compositor); + + input->repeat.timerfd = + timerfd_create(CLOCK_MONOTONIC, (TFD_CLOEXEC | TFD_NONBLOCK)); + + input->repeat.hdlr = + ecore_main_fd_handler_add(input->repeat.timerfd, ECORE_FD_READ, + _ecore_wl_input_cb_keyboard_repeat, input, + NULL, NULL); + + ewd->input = input; + + /* create Ecore_Wl_Dnd */ + if (!glb_dnd) + if (!(glb_dnd = calloc(1, sizeof(Ecore_Wl_Dnd)))) return; + glb_dnd->ewd = ewd; + glb_dnd->input = input; + input->dnd = glb_dnd; + wl_array_init(&glb_dnd->types_offered); +} + +void +_ecore_wl_input_del(Ecore_Wl_Input *input) +{ + if (!input) return; + + if (input->cursor_name) eina_stringshare_del(input->cursor_name); + input->cursor_name = NULL; + + if (input->keyboard_focus) + { + Ecore_Wl_Window *win = NULL; + + if ((win = input->keyboard_focus)) + win->keyboard_device = NULL; + + input->keyboard_focus = NULL; + } + + if (input->drag_source) _ecore_wl_dnd_del(input->drag_source); + input->drag_source = NULL; + + if (input->selection_source) _ecore_wl_dnd_del(input->selection_source); + input->selection_source = NULL; + + if (input->data_device) wl_data_device_destroy(input->data_device); + + if (input->xkb.state) + xkb_state_unref(input->xkb.state); + if (input->xkb.keymap) + xkb_map_unref(input->xkb.keymap); + + if (input->cursor_surface) + wl_surface_destroy(input->cursor_surface); + + wl_list_remove(&input->link); + if (input->seat) wl_seat_destroy(input->seat); + + if (input->repeat.hdlr) ecore_main_fd_handler_del(input->repeat.hdlr); + input->repeat.hdlr = NULL; + + if (input->repeat.timerfd) close(input->repeat.timerfd); + input->repeat.timerfd = 0; + + free(input); +} + +void +_ecore_wl_input_pointer_xy_get(int *x, int *y) +{ + if (x) *x = _pointer_x; + if (y) *y = _pointer_y; +} + +static void +_ecore_wl_input_seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) +{ + Ecore_Wl_Input *input; + + if (!(input = data)) return; + + if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!input->pointer)) + { + input->pointer = wl_seat_get_pointer(seat); + wl_pointer_set_user_data(input->pointer, input); + wl_pointer_add_listener(input->pointer, &pointer_listener, input); + } + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && (input->pointer)) + { + wl_pointer_destroy(input->pointer); + input->pointer = NULL; + } + + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && (!input->keyboard)) + { + input->keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_set_user_data(input->keyboard, input); + wl_keyboard_add_listener(input->keyboard, &keyboard_listener, input); + } + else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (input->keyboard)) + { + wl_keyboard_destroy(input->keyboard); + input->keyboard = NULL; + } + + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && (!input->touch)) + { + input->touch = wl_seat_get_touch(seat); + wl_touch_set_user_data(input->touch, input); + wl_touch_add_listener(input->touch, &touch_listener, input); + } + else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && (input->touch)) + { + wl_touch_destroy(input->touch); + input->touch = NULL; + } +} + + +static void +_ecore_wl_input_cb_pointer_motion(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, wl_fixed_t sx, wl_fixed_t sy) +{ + Ecore_Wl_Input *input; + + /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ + + if (!(input = data)) return; + + _pointer_x = input->sx = wl_fixed_to_int(sx); + _pointer_y = input->sy = wl_fixed_to_int(sy); + + input->timestamp = timestamp; + + if (input->pointer_focus) + _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp); +} + +static void +_ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int button, unsigned int state) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + + input->timestamp = timestamp; + input->display->serial = serial; + +// _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp); + + if (state) + { + if ((input->pointer_focus) && (!input->grab) && (state)) + ecore_wl_input_grab(input, input->pointer_focus, button); + + input->button = button; + _ecore_wl_input_mouse_down_send(input, input->pointer_focus, + timestamp); + } + else + { + _ecore_wl_input_mouse_up_send(input, input->pointer_focus, + timestamp); + input->button = 0; + + if ((input->grab) && (input->grab_button == button) && (!state)) + ecore_wl_input_ungrab(input); + } + +// _ecore_wl_input_mouse_move_send(input, timestamp); +} + +static void +_ecore_wl_input_cb_pointer_axis(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int timestamp, unsigned int axis, wl_fixed_t value) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + _ecore_wl_input_mouse_wheel_send(input, axis, wl_fixed_to_int(value), + timestamp); +} + +static void +_ecore_wl_input_cb_pointer_frame(void *data, struct wl_callback *callback, unsigned int timestamp EINA_UNUSED) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + + if (callback) + { + if (callback != input->cursor_frame_cb) return; + wl_callback_destroy(callback); + input->cursor_frame_cb = NULL; + } + + if (!input->cursor_name) + { + ecore_wl_input_pointer_set(input, NULL, 0, 0); + return; + } + + if (!input->cursor_frame_cb) + { + input->cursor_frame_cb = wl_surface_frame(input->cursor_surface); + wl_callback_add_listener(input->cursor_frame_cb, + &_ecore_wl_pointer_surface_listener, input); + } +} + +static void +_ecore_wl_input_cb_keyboard_keymap(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int format, int fd, unsigned int size) +{ + Ecore_Wl_Input *input; + char *map = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) + { + close(fd); + return; + } + + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) + { + close(fd); + return; + } + + map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) + { + close(fd); + return; + } + + input->xkb.keymap = + xkb_map_new_from_string(input->display->xkb.context, map, + XKB_KEYMAP_FORMAT_TEXT_V1, 0); + + munmap(map, size); + close(fd); + + if (!(input->xkb.keymap)) return; + if (!(input->xkb.state = xkb_state_new(input->xkb.keymap))) + { + xkb_map_unref(input->xkb.keymap); + input->xkb.keymap = NULL; + return; + } + + input->xkb.control_mask = + 1 << xkb_map_mod_get_index(input->xkb.keymap, "Control"); + input->xkb.alt_mask = + 1 << xkb_map_mod_get_index(input->xkb.keymap, "Mod1"); + input->xkb.shift_mask = + 1 << xkb_map_mod_get_index(input->xkb.keymap, "Shift"); +} + +static void +_ecore_wl_input_cb_keyboard_key(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state) +{ + Ecore_Wl_Input *input; + Ecore_Wl_Window *win; + unsigned int code, num; + const xkb_keysym_t *syms; + xkb_keysym_t sym = XKB_KEY_NoSymbol; + xkb_mod_mask_t mask; + char string[32], key[32], keyname[32];// compose[32]; + Ecore_Event_Key *e; + struct itimerspec ts; + int len = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + input->display->serial = serial; + + /* xkb rules reflect X broken keycodes, so offset by 8 */ + code = keycode + 8; + + win = input->keyboard_focus; + if ((!win) || (win->keyboard_device != input) || (!input->xkb.state)) + return; + + mask = xkb_state_serialize_mods(input->xkb.state, + XKB_STATE_DEPRESSED | XKB_STATE_LATCHED); + + input->modifiers = 0; + + /* The Ecore_Event_Modifiers don't quite match the X mask bits */ + if (mask & input->xkb.control_mask) + input->modifiers |= ECORE_EVENT_MODIFIER_CTRL; + if (mask & input->xkb.alt_mask) + input->modifiers |= ECORE_EVENT_MODIFIER_ALT; + if (mask & input->xkb.shift_mask) + input->modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + + num = xkb_key_get_syms(input->xkb.state, code, &syms); + if (num == 1) sym = syms[0]; + + memset(key, 0, sizeof(key)); + xkb_keysym_get_name(sym, key, sizeof(key)); + + memset(keyname, 0, sizeof(keyname)); + xkb_keysym_get_name(sym, keyname, sizeof(keyname)); + if (keyname[0] == '\0') + snprintf(keyname, sizeof(keyname), "Keycode-%i", code); + + memset(string, 0, sizeof(string)); + if (xkb_keysym_to_utf8(sym, string, 32) <= 0) + { + /* FIXME: NB: We may need to add more checks here for other + * non-printable characters */ + if ((sym == XKB_KEY_Tab) || (sym == XKB_KEY_ISO_Left_Tab)) + string[len++] = '\t'; + } + + /* FIXME: NB: Start hacking on compose key support */ + /* memset(compose, 0, sizeof(compose)); */ + /* if (sym == XKB_KEY_Multi_key) */ + /* { */ + /* if (xkb_keysym_to_utf8(sym, compose, 32) <= 0) */ + /* compose[0] = '\0'; */ + /* } */ + + e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + + ((string[0] != '\0') ? strlen(string) : 0) + 3); + if (!e) return; + + e->keyname = (char *)(e + 1); + e->key = e->keyname + strlen(keyname) + 1; + e->string = strlen(string) ? e->key + strlen(key) + 1 : NULL; + e->compose = e->string; + + strcpy((char *)e->keyname, keyname); + strcpy((char *)e->key, key); + if (strlen(string)) strcpy((char *)e->string, string); + + e->window = win->id; + e->event_window = win->id; + e->timestamp = timestamp; + e->modifiers = input->modifiers; + + if (state) + ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); + else + ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); + + if ((!state) && (keycode == input->repeat.key)) + { + input->repeat.sym = 0; + input->repeat.key = 0; + input->repeat.time = 0; + + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + ts.it_value.tv_sec = 0; + ts.it_value.tv_nsec = 0; + + timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); + } + else if ((state) && + ((!input->repeat.key) || + ((keycode) && (keycode != input->repeat.key)))) + { + input->repeat.sym = sym; + input->repeat.key = keycode; + input->repeat.time = timestamp; + + /* interval after expires */ + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 35 * 1000 * 1000; + + /* initial expiration */ + ts.it_value.tv_sec = 0; + ts.it_value.tv_nsec = 500 * 1000 * 1000; + + timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); + } +} + +static void +_ecore_wl_input_cb_keyboard_modifiers(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial EINA_UNUSED, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + xkb_state_update_mask(input->xkb.state, depressed, latched, + locked, 0, 0, group); +} + +static Eina_Bool +_ecore_wl_input_cb_keyboard_repeat(void *data, Ecore_Fd_Handler *handler EINA_UNUSED) +{ + Ecore_Wl_Input *input; + Ecore_Wl_Window *win = NULL; + unsigned long long int xp; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return ECORE_CALLBACK_RENEW; + + /* Trap for EAGAIN */ + if (read(input->repeat.timerfd, &xp, sizeof(xp)) != sizeof(xp)) + return ECORE_CALLBACK_RENEW; + + if ((win = input->keyboard_focus)) + _ecore_wl_input_cb_keyboard_key(input, NULL, input->display->serial, + input->repeat.time, + input->repeat.key, EINA_TRUE); + + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) +{ + Ecore_Wl_Input *input; + Ecore_Wl_Window *win = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!surface) return; + if (!(input = data)) return; + + if (!input->timestamp) + { + struct timeval tv; + + gettimeofday(&tv, NULL); + input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000); + } + + input->sx = wl_fixed_to_double(sx); + input->sy = wl_fixed_to_double(sy); + input->display->serial = serial; + input->pointer_enter_serial = serial; + + /* The cursor on the surface is undefined until we set it */ + ecore_wl_input_cursor_from_name_set(input, "left_ptr"); + + if ((win = wl_surface_get_user_data(surface))) + { + win->pointer_device = input; + input->pointer_focus = win; + + _ecore_wl_input_mouse_in_send(input, win, input->timestamp); + } + + /* NB: This whole 'if' below is a major HACK due to wayland's stupidness + * of not sending a mouse_up (or any notification at all for that matter) + * when a move or resize grab is finished */ + if (input->grab) + { + /* NB: This COULD mean a move has finished, or it could mean that + * a 'drag' is being done to a different surface */ + + if ((input->grab == win) && (win->moving)) + { + /* NB: 'Fake' a mouse_up for move finished */ + win->moving = EINA_FALSE; + _ecore_wl_input_mouse_up_send(input, win, input->timestamp); + + input->button = 0; + + if ((input->grab) && (input->grab_button == BTN_LEFT)) + ecore_wl_input_ungrab(input); + } + else if ((input->grab == win) && (win->resizing)) + { + /* NB: 'Fake' a mouse_up for resize finished */ + win->resizing = EINA_FALSE; + _ecore_wl_input_mouse_up_send(input, win, input->timestamp); + + input->button = 0; + + if ((input->grab) && (input->grab_button == BTN_LEFT)) + ecore_wl_input_ungrab(input); + } + /* FIXME: Test d-n-d and potentially add needed case here */ + } +} + +static void +_ecore_wl_input_cb_pointer_leave(void *data, struct wl_pointer *pointer EINA_UNUSED, unsigned int serial, struct wl_surface *surface) +{ + Ecore_Wl_Input *input; + Ecore_Wl_Window *win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!surface) return; + if (!(input = data)) return; + + input->display->serial = serial; + + if (!surface) return; + if (!(win = wl_surface_get_user_data(surface))) return; + + win->pointer_device = NULL; + input->pointer_focus = NULL; + + /* _ecore_wl_input_mouse_move_send(input, win, input->timestamp); */ + _ecore_wl_input_mouse_out_send(input, win, input->timestamp); + + if (input->grab) + { + /* move or resize started */ + + /* printf("Pointer Leave WITH a Grab\n"); */ + } +} + +static void +_ecore_wl_input_cb_keyboard_enter(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface, struct wl_array *keys EINA_UNUSED) +{ + Ecore_Wl_Input *input; + Ecore_Wl_Window *win = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!surface) return; + if (!(input = data)) return; + + if (!input->timestamp) + { + struct timeval tv; + + gettimeofday(&tv, NULL); + input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000); + } + + input->display->serial = serial; + + if (!(win = wl_surface_get_user_data(surface))) return; + + win->keyboard_device = input; + input->keyboard_focus = win; + + _ecore_wl_input_focus_in_send(input, win, input->timestamp); +} + +static void +_ecore_wl_input_cb_keyboard_leave(void *data, struct wl_keyboard *keyboard EINA_UNUSED, unsigned int serial, struct wl_surface *surface) +{ + Ecore_Wl_Input *input; + Ecore_Wl_Window *win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!surface) return; + if (!(input = data)) return; + + if (input->repeat.timerfd) + { + struct itimerspec ts; + + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + ts.it_value.tv_sec = 0; + ts.it_value.tv_nsec = 0; + + timerfd_settime(input->repeat.timerfd, 0, &ts, NULL); + } + + if (!input->timestamp) + { + struct timeval tv; + + gettimeofday(&tv, NULL); + input->timestamp = (tv.tv_sec * 1000 + tv.tv_usec / 1000); + } + + input->display->serial = serial; + + if (!surface) return; + if (!(win = wl_surface_get_user_data(surface))) return; + + win->keyboard_device = NULL; + _ecore_wl_input_focus_out_send(input, win, input->timestamp); + + input->keyboard_focus = NULL; +} + +static void +_ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, struct wl_surface *surface EINA_UNUSED, int id EINA_UNUSED, wl_fixed_t x, wl_fixed_t y) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!surface) return; + if (!(input = data)) return; + + /* FIXME: NB: Not sure yet if input->timestamp should be set here. + * This needs to be tested with an actual touch device */ + /* input->timestamp = timestamp; */ + input->display->serial = serial; + input->button = BTN_LEFT; + input->sx = wl_fixed_to_int(x); + input->sy = wl_fixed_to_int(y); + _ecore_wl_input_cb_pointer_enter(data, NULL, serial, surface, x, y); + _ecore_wl_input_mouse_down_send(input, input->pointer_focus, timestamp); +} + +static void +_ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int serial, unsigned int timestamp, int id EINA_UNUSED) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + + /* FIXME: NB: Not sure yet if input->timestamp should be set here. + * This needs to be tested with an actual touch device */ + /* input->timestamp = timestamp; */ + input->button = BTN_LEFT; + input->display->serial = serial; + _ecore_wl_input_mouse_up_send(input, input->pointer_focus, timestamp); + input->button = 0; +} + +static void +_ecore_wl_input_cb_touch_motion(void *data, struct wl_touch *touch EINA_UNUSED, unsigned int timestamp, int id EINA_UNUSED, wl_fixed_t x, wl_fixed_t y) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(input = data)) return; + + /* FIXME: NB: Not sure yet if input->timestamp should be set here. + * This needs to be tested with an actual touch device */ + /* input->timestamp = timestamp; */ + input->sx = wl_fixed_to_int(x); + input->sy = wl_fixed_to_int(y); + + _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp); +} + +static void +_ecore_wl_input_cb_touch_frame(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +} + +static void +_ecore_wl_input_cb_touch_cancel(void *data EINA_UNUSED, struct wl_touch *touch EINA_UNUSED) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +} + +static void +_ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_wl_dnd_add(data, data_device, offer); +} + +static void +_ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!surface) return; + + _ecore_wl_dnd_enter(data, data_device, timestamp, surface, x, y, offer); +} + +static void +_ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_wl_dnd_leave(data, data_device); +} + +static void +_ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, wl_fixed_t x, wl_fixed_t y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_wl_dnd_motion(data, data_device, timestamp, x, y); +} + +static void +_ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_wl_dnd_drop(data, data_device); +} + +static void +_ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_wl_dnd_selection(data, data_device, offer); +} + +static void +_ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) +{ + Ecore_Event_Mouse_Move *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return; + + ev->timestamp = timestamp; + ev->x = input->sx; + ev->y = input->sy; + /* ev->root.x = input->sx; */ + /* ev->root.y = input->sy; */ + ev->modifiers = input->modifiers; + ev->multi.device = 0; + ev->multi.radius = 1; + ev->multi.radius_x = 1; + ev->multi.radius_y = 1; + ev->multi.pressure = 1.0; + ev->multi.angle = 0.0; + ev->multi.x = input->sx; + ev->multi.y = input->sy; + + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } + + ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); +} + +static void +_ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) +{ + Ecore_Wl_Event_Mouse_In *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return; + + ev->x = input->sx; + ev->y = input->sy; + /* ev->root.x = input->sx; */ + /* ev->root.y = input->sy; */ + ev->modifiers = input->modifiers; + ev->timestamp = timestamp; + + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } + + ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL); +} + +static void +_ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) +{ + Ecore_Wl_Event_Mouse_Out *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return; + + ev->x = input->sx; + ev->y = input->sy; + /* ev->root.x = input->sx; */ + /* ev->root.y = input->sy; */ + ev->modifiers = input->modifiers; + ev->timestamp = timestamp; + + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } + + ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL); +} + +static void +_ecore_wl_input_focus_in_send(Ecore_Wl_Input *input EINA_UNUSED, Ecore_Wl_Window *win, unsigned int timestamp) +{ + Ecore_Wl_Event_Focus_In *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return; + ev->timestamp = timestamp; + if (win) ev->win = win->id; + ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL); +} + +static void +_ecore_wl_input_focus_out_send(Ecore_Wl_Input *input EINA_UNUSED, Ecore_Wl_Window *win, unsigned int timestamp) +{ + Ecore_Wl_Event_Focus_Out *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return; + ev->timestamp = timestamp; + if (win) ev->win = win->id; + ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL); +} + +static void +_ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) +{ + Ecore_Event_Mouse_Button *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return; + + if (input->button == BTN_LEFT) + ev->buttons = 1; + else if (input->button == BTN_MIDDLE) + ev->buttons = 2; + else if (input->button == BTN_RIGHT) + ev->buttons = 3; + else + ev->buttons = input->button; + + ev->timestamp = timestamp; + ev->x = input->sx; + ev->y = input->sy; + /* ev->root.x = input->sx; */ + /* ev->root.y = input->sy; */ + ev->modifiers = input->modifiers; + + /* FIXME: Need to get these from wayland somehow */ + ev->double_click = 0; + ev->triple_click = 0; + + ev->multi.device = 0; + ev->multi.radius = 1; + ev->multi.radius_x = 1; + ev->multi.radius_y = 1; + ev->multi.pressure = 1.0; + ev->multi.angle = 0.0; + ev->multi.x = input->sx; + ev->multi.y = input->sy; + + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } + + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); +} + +static void +_ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, Ecore_Wl_Window *win, unsigned int timestamp) +{ + Ecore_Event_Mouse_Button *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return; + + if (input->button == BTN_LEFT) + ev->buttons = 1; + else if (input->button == BTN_MIDDLE) + ev->buttons = 2; + else if (input->button == BTN_RIGHT) + ev->buttons = 3; + else + ev->buttons = input->button; + + ev->timestamp = timestamp; + ev->x = input->sx; + ev->y = input->sy; + /* ev->root.x = input->sx; */ + /* ev->root.y = input->sy; */ + ev->modifiers = input->modifiers; + + /* FIXME: Need to get these from wayland somehow */ + ev->double_click = 0; + ev->triple_click = 0; + + ev->multi.device = 0; + ev->multi.radius = 1; + ev->multi.radius_x = 1; + ev->multi.radius_y = 1; + ev->multi.pressure = 1.0; + ev->multi.angle = 0.0; + ev->multi.x = input->sx; + ev->multi.y = input->sy; + + if (win) + { + ev->window = win->id; + ev->event_window = win->id; + } + + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); +} + +static void +_ecore_wl_input_mouse_wheel_send(Ecore_Wl_Input *input, unsigned int axis, int value, unsigned int timestamp) +{ + Ecore_Event_Mouse_Wheel *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return; + + ev->timestamp = timestamp; + ev->modifiers = input->modifiers; + ev->x = input->sx; + ev->y = input->sy; + /* ev->root.x = input->sx; */ + /* ev->root.y = input->sy; */ + + if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) + { + ev->direction = 0; + ev->z = value; + } + else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) + { + ev->direction = 1; + ev->z = value; + } + + if (input->grab) + { + ev->window = input->grab->id; + ev->event_window = input->grab->id; + } + else if (input->pointer_focus) + { + ev->window = input->pointer_focus->id; + ev->event_window = input->pointer_focus->id; + } + + ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); +} + +void +_ecore_wl_input_set_selection(Ecore_Wl_Input *input, struct wl_data_source *source) +{ + wl_data_device_set_selection(input->data_device, source, input->display->serial); +} + diff --git a/src/lib/ecore_wayland/ecore_wl_output.c b/src/lib/ecore_wayland/ecore_wl_output.c new file mode 100644 index 0000000000..5498895007 --- /dev/null +++ b/src/lib/ecore_wayland/ecore_wl_output.c @@ -0,0 +1,87 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ecore_wl_private.h" + +/* local function prototypes */ +static void _ecore_wl_output_cb_geometry(void *data, struct wl_output *wl_output EINA_UNUSED, int x, int y, int w, int h, int subpixel EINA_UNUSED, const char *make EINA_UNUSED, const char *model EINA_UNUSED, int transform EINA_UNUSED); +static void _ecore_wl_output_cb_mode(void *data, struct wl_output *wl_output EINA_UNUSED, unsigned int flags, int w, int h, int refresh EINA_UNUSED); + +/* wayland listeners */ +static const struct wl_output_listener _ecore_wl_output_listener = +{ + _ecore_wl_output_cb_geometry, + _ecore_wl_output_cb_mode +}; + +/* @since 1.2 */ +EAPI struct wl_list +ecore_wl_outputs_get(void) +{ + return _ecore_wl_disp->outputs; +} + +void +_ecore_wl_output_add(Ecore_Wl_Display *ewd, unsigned int id) +{ + Ecore_Wl_Output *output; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(output = malloc(sizeof(Ecore_Wl_Output)))) return; + + memset(output, 0, sizeof(Ecore_Wl_Output)); + + output->display = ewd; + + output->output = + wl_registry_bind(ewd->wl.registry, id, &wl_output_interface, 1); + + wl_list_insert(ewd->outputs.prev, &output->link); + wl_output_add_listener(output->output, &_ecore_wl_output_listener, output); +} + +void +_ecore_wl_output_del(Ecore_Wl_Output *output) +{ + if (!output) return; + if (output->destroy) (*output->destroy)(output, output->data); + if (output->output) wl_output_destroy(output->output); + wl_list_remove(&output->link); + free(output); +} + +/* local functions */ +static void +_ecore_wl_output_cb_geometry(void *data, struct wl_output *wl_output EINA_UNUSED, int x, int y, int w, int h, int subpixel EINA_UNUSED, const char *make EINA_UNUSED, const char *model EINA_UNUSED, int transform EINA_UNUSED) +{ + Ecore_Wl_Output *output; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + output = data; + output->allocation.x = x; + output->allocation.y = y; + output->mw = w; + output->mh = h; +} + +static void +_ecore_wl_output_cb_mode(void *data, struct wl_output *wl_output EINA_UNUSED, unsigned int flags, int w, int h, int refresh EINA_UNUSED) +{ + Ecore_Wl_Output *output; + Ecore_Wl_Display *ewd; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + output = data; + ewd = output->display; + if (flags & WL_OUTPUT_MODE_CURRENT) + { + output->allocation.w = w; + output->allocation.h = h; + _ecore_wl_disp->output = output; + if (ewd->output_configure) (*ewd->output_configure)(output, ewd->data); + } +} diff --git a/src/lib/ecore_wayland/ecore_wl_private.h b/src/lib/ecore_wayland/ecore_wl_private.h new file mode 100644 index 0000000000..ecd7a110b3 --- /dev/null +++ b/src/lib/ecore_wayland/ecore_wl_private.h @@ -0,0 +1,103 @@ +#ifndef _ECORE_WAYLAND_PRIVATE_H +# define _ECORE_WAYLAND_PRIVATE_H + +# include +# include + +# include "Ecore.h" +# include "Ecore_Input.h" +# include "Ecore_Wayland.h" + +//# define LOGFNS 1 + +# ifdef LOGFNS +# include +# define LOGFN(fl, ln, fn) printf("-ECORE-WL: %25s: %5i - %s\n", fl, ln, fn); +# else +# define LOGFN(fl, ln, fn) +# endif + +extern int _ecore_wl_log_dom; +extern Ecore_Wl_Display *_ecore_wl_disp; + +# ifdef ECORE_WL_DEFAULT_LOG_COLOR +# undef ECORE_WL_DEFAULT_LOG_COLOR +# endif +# define ECORE_WL_DEFAULT_LOG_COLOR EINA_COLOR_BLUE + +# ifdef ERR +# undef ERR +# endif +# define ERR(...) EINA_LOG_DOM_ERR(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef DBG +# undef DBG +# endif +# define DBG(...) EINA_LOG_DOM_DBG(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef INF +# undef INF +# endif +# define INF(...) EINA_LOG_DOM_INFO(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef WRN +# undef WRN +# endif +# define WRN(...) EINA_LOG_DOM_WARN(_ecore_wl_log_dom, __VA_ARGS__) + +# ifdef CRIT +# undef CRIT +# endif +# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_wl_log_dom, __VA_ARGS__) + +struct _Ecore_Wl_Dnd +{ + Ecore_Wl_Display *ewd; + Ecore_Wl_Input *input; + + /* As provider */ + struct wl_data_source *data_source; + struct wl_array types_offered; + + /* TODO: dnd specific fields */ +}; + +struct _Ecore_Wl_Dnd_Source +{ + struct wl_data_offer *offer; + Ecore_Wl_Input *input; + struct wl_array types; + int refcount; + int fd; + int x, y; + + /* TODO: task & data_func */ + void *data; +}; + +struct _Ecore_Wl_Dnd_Target +{ + Ecore_Wl_Dnd_Source *source; +}; + +void _ecore_wl_window_init(void); +void _ecore_wl_window_shutdown(void); + +void _ecore_wl_output_add(Ecore_Wl_Display *ewd, unsigned int id); +void _ecore_wl_output_del(Ecore_Wl_Output *output); + +void _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id); +void _ecore_wl_input_del(Ecore_Wl_Input *input); +void _ecore_wl_input_pointer_xy_get(int *x, int *y); +void _ecore_wl_input_set_selection(Ecore_Wl_Input *input, struct wl_data_source *source); + +void _ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device, struct wl_data_offer *offer); +void _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer); +void _ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device); +void _ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, int x, int y); +void _ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device); +void _ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); +void _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source); + +struct wl_data_source *_ecore_wl_create_data_source(Ecore_Wl_Display *ewd); +#endif diff --git a/src/lib/ecore_wayland/ecore_wl_window.c b/src/lib/ecore_wayland/ecore_wl_window.c new file mode 100644 index 0000000000..3d221e9f2a --- /dev/null +++ b/src/lib/ecore_wayland/ecore_wl_window.c @@ -0,0 +1,707 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ecore_wl_private.h" + +/* local function prototypes */ +static void _ecore_wl_window_cb_ping(void *data EINA_UNUSED, struct wl_shell_surface *shell_surface, unsigned int serial); +static void _ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED, unsigned int edges, int w, int h); +static void _ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED); +static void _ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output EINA_UNUSED); +static void _ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output EINA_UNUSED); +static void _ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h); +static char *_ecore_wl_window_id_str_get(unsigned int win_id); + +/* local variables */ +static Eina_Hash *_windows = NULL; + +/* wayland listeners */ +static const struct wl_surface_listener _ecore_wl_surface_listener = +{ + _ecore_wl_window_cb_surface_enter, + _ecore_wl_window_cb_surface_leave +}; + +static const struct wl_shell_surface_listener _ecore_wl_shell_surface_listener = +{ + _ecore_wl_window_cb_ping, + _ecore_wl_window_cb_configure, + _ecore_wl_window_cb_popup_done +}; + +/* internal functions */ +void +_ecore_wl_window_init(void) +{ + if (!_windows) + _windows = eina_hash_string_superfast_new(NULL); +} + +void +_ecore_wl_window_shutdown(void) +{ + eina_hash_free(_windows); + _windows = NULL; +} + +/** + * @defgroup Ecore_Wl_Window_Group Wayland Library Init and Shutdown Functions + * + * Functions that can be used to create a Wayland 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 + * @param buffer_type The type of the buffer to be used to create a new Ecore_Wl_Window. + * + * @return The new window + * + * @ingroup Ecore_Wl_Window_Group + * @since 1.2 + */ +EAPI Ecore_Wl_Window * +ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buffer_type) +{ + Ecore_Wl_Window *win; + static int _win_id = 1; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(win = malloc(sizeof(Ecore_Wl_Window)))) + { + ERR("Failed to allocate an Ecore Wayland Window"); + return NULL; + } + + memset(win, 0, sizeof(Ecore_Wl_Window)); + + win->display = _ecore_wl_disp; + win->parent = parent; + win->allocation.x = x; + win->allocation.y = y; + win->allocation.w = w; + win->allocation.h = h; + win->saved_allocation = win->allocation; + win->transparent = EINA_FALSE; + /* win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; */ + win->type = ECORE_WL_WINDOW_TYPE_NONE; + win->buffer_type = buffer_type; + win->id = _win_id++; + + eina_hash_add(_windows, _ecore_wl_window_id_str_get(win->id), win); + return win; +} + +/** + * Deletes the given window + * + * @param win The given window + * + * @ingroup Ecore_Wl_Window_Group + * @since 1.2 + */ +EAPI void +ecore_wl_window_free(Ecore_Wl_Window *win) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + eina_hash_del(_windows, _ecore_wl_window_id_str_get(win->id), win); + + wl_list_for_each(input, &_ecore_wl_disp->inputs, link) + { + if ((input->pointer_focus) && (input->pointer_focus == win)) + input->pointer_focus = NULL; + if ((input->keyboard_focus) && (input->keyboard_focus == win)) + input->keyboard_focus = NULL; + } + + if (win->region.input) wl_region_destroy(win->region.input); + win->region.input = NULL; + if (win->region.opaque) wl_region_destroy(win->region.opaque); + win->region.opaque = NULL; + if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface); + win->shell_surface = NULL; + + if (win->surface) wl_surface_destroy(win->surface); + win->surface = NULL; + + /* HMMM, why was this disabled ? */ + free(win); +} + +/** + * Signals for Wayland to initiate a window move. + * + * The position requested (@p x, @p y) is not honored by Wayland because + * Wayland does not allow specific window placement to be set. + * + * @param win The window to move. + * @param x X Position + * @param y Y Position + * + * @ingroup Ecore_Wl_Window_Group + * @since 1.2 + */ +EAPI void +ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + win->allocation.x = x; + win->allocation.y = y; + + if (win->shell_surface) + { + Ecore_Wl_Input *input; + + if (!(input = win->keyboard_device)) + { + if (win->parent) + { + if (!(input = win->parent->keyboard_device)) + input = win->parent->pointer_device; + } + } + + if ((!input) || (!input->seat)) return; + + wl_shell_surface_move(win->shell_surface, input->seat, + input->display->serial); + } +} + +/** + * Signals for Wayland to initiate a window resize. + * + * The size requested (@p w, @p h) is not honored by Wayland because + * Wayland does not allow specific window sizes to be set. + * + * @param win The window to resize. + * @param w Width + * @param h Height + * @param location The edge of the window from where the resize should start. + * + * @ingroup Ecore_Wl_Window_Group + * @since 1.2 + */ +EAPI void +ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + if (win->type != ECORE_WL_WINDOW_TYPE_FULLSCREEN) + { + win->allocation.w = w; + win->allocation.h = h; + + win->region.input = + wl_compositor_create_region(_ecore_wl_disp->wl.compositor); + wl_region_add(win->region.input, win->allocation.x, win->allocation.y, + win->allocation.w, win->allocation.h); + } + + if (!win->transparent) + { + win->region.opaque = + wl_compositor_create_region(_ecore_wl_disp->wl.compositor); + wl_region_add(win->region.opaque, win->allocation.x, win->allocation.y, + win->allocation.w, win->allocation.h); + } + + if (win->shell_surface) + { + Ecore_Wl_Input *input; + + if (!(input = win->keyboard_device)) + { + if (win->parent) + { + if (!(input = win->parent->keyboard_device)) + input = win->parent->pointer_device; + } + } + + if ((!input) || (!input->seat)) return; + + wl_shell_surface_resize(win->shell_surface, input->seat, + input->display->serial, location); + } +} + +EAPI void +ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (win->surface) + { + wl_surface_damage(win->surface, x, y, w, h); + wl_surface_commit(win->surface); + } +} + +EAPI void +ecore_wl_window_buffer_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + switch (win->buffer_type) + { + case ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW: + win->server_allocation = win->allocation; + break; + case ECORE_WL_WINDOW_BUFFER_TYPE_EGL_IMAGE: + case ECORE_WL_WINDOW_BUFFER_TYPE_SHM: + if (win->surface) + { + if (win->edges & 4) // resizing from the left + x = win->server_allocation.w - win->allocation.w; + else + x = 0; + + if (win->edges & 1) // resizing from the top + y = win->server_allocation.h - win->allocation.h; + else + y = 0; + + win->edges = 0; + + /* if (buffer) */ + wl_surface_attach(win->surface, buffer, x, y); + wl_surface_damage(win->surface, 0, 0, + win->allocation.w, win->allocation.h); + wl_surface_commit(win->surface); + + win->server_allocation = win->allocation; + } + break; + default: + return; + } + + if (win->region.input) + { + wl_surface_set_input_region(win->surface, win->region.input); + wl_region_destroy(win->region.input); + win->region.input = NULL; + } + + if (win->region.opaque) + { + wl_surface_set_opaque_region(win->surface, win->region.opaque); + wl_region_destroy(win->region.opaque); + win->region.opaque = NULL; + } +} + +/** + * Shows a window + * + * Synonymous to "mapping" a window in Wayland System terminology. + * + * @param win The window to show. + * + * @ingroup Ecore_Wl_Window_Group + * @since 1.2 + */ +EAPI void +ecore_wl_window_show(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (win->surface) return; + + win->surface = wl_compositor_create_surface(_ecore_wl_disp->wl.compositor); + wl_surface_set_user_data(win->surface, win); + /* wl_surface_add_listener(win->surface, &_ecore_wl_surface_listener, win); */ + + win->shell_surface = + wl_shell_get_shell_surface(_ecore_wl_disp->wl.shell, win->surface); + wl_shell_surface_add_listener(win->shell_surface, + &_ecore_wl_shell_surface_listener, win); + + switch (win->type) + { + case ECORE_WL_WINDOW_TYPE_FULLSCREEN: + wl_shell_surface_set_fullscreen(win->shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + 0, NULL); + break; + case ECORE_WL_WINDOW_TYPE_MAXIMIZED: + wl_shell_surface_set_maximized(win->shell_surface, NULL); + break; + case ECORE_WL_WINDOW_TYPE_TRANSIENT: + wl_shell_surface_set_transient(win->shell_surface, + win->parent->surface, + win->allocation.x, win->allocation.y, 0); + break; + case ECORE_WL_WINDOW_TYPE_MENU: + wl_shell_surface_set_popup(win->shell_surface, + _ecore_wl_disp->input->seat, + _ecore_wl_disp->serial, + win->parent->surface, + win->allocation.x, win->allocation.y, 0); + break; + case ECORE_WL_WINDOW_TYPE_NONE: + win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; + /* fallthrough */ + case ECORE_WL_WINDOW_TYPE_TOPLEVEL: + wl_shell_surface_set_toplevel(win->shell_surface); + break; + default: + break; + } + + /* if (win->type != ECORE_WL_WINDOW_TYPE_FULLSCREEN) */ + /* { */ + /* win->region.input = */ + /* wl_compositor_create_region(_ecore_wl_disp->wl.compositor); */ + /* wl_region_add(win->region.input, win->allocation.x, win->allocation.y, */ + /* win->allocation.w, win->allocation.h); */ + /* } */ + + /* if (!win->transparent) */ + /* { */ + /* win->region.opaque = */ + /* wl_compositor_create_region(_ecore_wl_disp->wl.compositor); */ + /* wl_region_add(win->region.opaque, win->allocation.x, win->allocation.y, */ + /* win->allocation.w, win->allocation.h); */ + /* } */ +} + +/** + * Hides a window + * + * Synonymous to "unmapping" a window in Wayland System terminology. + * + * @param win The window to hide. + * + * @ingroup Ecore_Wl_Window_Group + * @since 1.2 + */ +EAPI void +ecore_wl_window_hide(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface); + win->shell_surface = NULL; + if (win->surface) wl_surface_destroy(win->surface); + win->surface = NULL; +} + +/** + * Raises a window + * + * @param win The window to raise. + * + * @ingroup Ecore_Wl_Window_Group + * @since 1.2 + */ +EAPI void +ecore_wl_window_raise(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (win->shell_surface) + wl_shell_surface_set_toplevel(win->shell_surface); +} + +EAPI void +ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + if ((win->type == ECORE_WL_WINDOW_TYPE_MAXIMIZED) == maximized) return; + if (win->type == ECORE_WL_WINDOW_TYPE_TOPLEVEL) + { + win->saved_allocation = win->allocation; + if (win->shell_surface) + wl_shell_surface_set_maximized(win->shell_surface, NULL); + win->type = ECORE_WL_WINDOW_TYPE_MAXIMIZED; + } + else if (win->type == ECORE_WL_WINDOW_TYPE_MAXIMIZED) + { + if (win->shell_surface) + wl_shell_surface_set_toplevel(win->shell_surface); + win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; + _ecore_wl_window_configure_send(win, win->saved_allocation.w, + win->saved_allocation.h); + } +} + +EAPI void +ecore_wl_window_fullscreen_set(Ecore_Wl_Window *win, Eina_Bool fullscreen) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if ((win->type == ECORE_WL_WINDOW_TYPE_FULLSCREEN) == fullscreen) return; + if (fullscreen) + { + win->type = ECORE_WL_WINDOW_TYPE_FULLSCREEN; + win->saved_allocation = win->allocation; + if (win->shell_surface) + wl_shell_surface_set_fullscreen(win->shell_surface, + WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, + 0, NULL); + } + else + { + if (win->shell_surface) + wl_shell_surface_set_toplevel(win->shell_surface); + win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; + _ecore_wl_window_configure_send(win, win->saved_allocation.w, + win->saved_allocation.h); + } +} + +EAPI void +ecore_wl_window_transparent_set(Ecore_Wl_Window *win, Eina_Bool transparent) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + win->transparent = transparent; + if (win->region.opaque) wl_region_destroy(win->region.opaque); + win->region.opaque = NULL; + if (!win->transparent) + { + win->region.opaque = + wl_compositor_create_region(_ecore_wl_disp->wl.compositor); + wl_region_add(win->region.opaque, win->allocation.x, win->allocation.y, + win->allocation.w, win->allocation.h); + } +} + +EAPI void +ecore_wl_window_update_size(Ecore_Wl_Window *win, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + win->allocation.w = w; + win->allocation.h = h; +} + +EAPI void +ecore_wl_window_update_location(Ecore_Wl_Window *win, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + win->allocation.x = x; + win->allocation.y = y; +} + +EAPI struct wl_surface * +ecore_wl_window_surface_get(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return NULL; + return win->surface; +} + +/* @since 1.2 */ +EAPI struct wl_shell_surface * +ecore_wl_window_shell_surface_get(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return NULL; + return win->shell_surface; +} + +EAPI Ecore_Wl_Window * +ecore_wl_window_find(unsigned int id) +{ + Ecore_Wl_Window *win = NULL; + + win = eina_hash_find(_windows, _ecore_wl_window_id_str_get(id)); + return win; +} + +EAPI void +ecore_wl_window_type_set(Ecore_Wl_Window *win, Ecore_Wl_Window_Type type) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + win->type = type; +} + +EAPI void +ecore_wl_window_pointer_set(Ecore_Wl_Window *win, struct wl_surface *surface, int hot_x, int hot_y) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + if ((input = win->pointer_device)) + ecore_wl_input_pointer_set(input, surface, hot_x, hot_y); +} + +EAPI void +ecore_wl_window_cursor_from_name_set(Ecore_Wl_Window *win, const char *cursor_name) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + if ((input = win->pointer_device)) + ecore_wl_input_cursor_from_name_set(input, cursor_name); +} + +EAPI void +ecore_wl_window_cursor_default_restore(Ecore_Wl_Window *win) +{ + Ecore_Wl_Input *input; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + if ((input = win->pointer_device)) + ecore_wl_input_cursor_default_restore(input); +} + +/* @since 1.2 */ +EAPI void +ecore_wl_window_parent_set(Ecore_Wl_Window *win, Ecore_Wl_Window *parent) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + win->parent = parent; +} + +/* local functions */ +static void +_ecore_wl_window_cb_ping(void *data EINA_UNUSED, struct wl_shell_surface *shell_surface, unsigned int serial) +{ + if (!shell_surface) return; + wl_shell_surface_pong(shell_surface, serial); +} + +static void +_ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED, unsigned int edges, int w, int h) +{ + Ecore_Wl_Window *win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(win = data)) return; + + if ((w <= 0) || (h <= 0)) return; + + if ((win->allocation.w != w) || (win->allocation.h != h)) + { + win->edges = edges; + if (win->region.input) wl_region_destroy(win->region.input); + win->region.input = NULL; + if (win->region.opaque) wl_region_destroy(win->region.opaque); + win->region.opaque = NULL; + + _ecore_wl_window_configure_send(win, w, h); + } +} + +static void +_ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED) +{ + Ecore_Wl_Window *win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!shell_surface) return; + if (!(win = data)) return; + ecore_wl_input_ungrab(win->pointer_device); +} + +static void +_ecore_wl_window_cb_surface_enter(void *data, struct wl_surface *surface, struct wl_output *output EINA_UNUSED) +{ + Ecore_Wl_Window *win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!surface) return; + if (!(win = data)) return; +} + +static void +_ecore_wl_window_cb_surface_leave(void *data, struct wl_surface *surface, struct wl_output *output EINA_UNUSED) +{ + Ecore_Wl_Window *win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!surface) return; + if (!(win = data)) return; +} + +static void +_ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h) +{ + Ecore_Wl_Event_Window_Configure *ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Window_Configure)))) return; + ev->win = win->id; + ev->event_win = win->id; + ev->x = win->allocation.x; + ev->y = win->allocation.y; + ev->w = w; + ev->h = h; + ecore_event_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL); +} + +static char * +_ecore_wl_window_id_str_get(unsigned int win_id) +{ + const char *vals = "qWeRtYuIoP5$&<~"; + static char id[9]; + unsigned int val; + + val = win_id; + 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; +} diff --git a/src/lib/ecore_win32/Ecore_Win32.h b/src/lib/ecore_win32/Ecore_Win32.h new file mode 100644 index 0000000000..ae1bd4ec8c --- /dev/null +++ b/src/lib/ecore_win32/Ecore_Win32.h @@ -0,0 +1,526 @@ +#ifndef __ECORE_WIN32_H__ +#define __ECORE_WIN32_H__ + +/* + * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND + * THE API MAY CHANGE. + */ + +#ifndef ECORE_WIN32_WIP_POZEFLKSD +# ifdef _MSC_VER +# pragma message ("You are using a work in progress API. This API is not stable") +# pragma message ("and is subject to change. You use this at your own risk.") +# else +# warning "You are using a work in progress API. This API is not stable" +# warning "and is subject to change. You use this at your own risk." +# endif +#endif + +#include + +#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 + +/** + * @defgroup Ecore_Win32_Group Ecore_Win32 library + * + * @{ + */ + +/** + * @typedef Ecore_Win32_Window_State + * State of a window. + */ +typedef enum +{ + ECORE_WIN32_WINDOW_STATE_ICONIFIED, /**< iconified window */ + ECORE_WIN32_WINDOW_STATE_MODAL, /**< modal dialog box */ + ECORE_WIN32_WINDOW_STATE_STICKY, /**< sticky window */ + ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT, /**< maximum vertical sized window */ + ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ, /**< maximum horizontal sized window */ + ECORE_WIN32_WINDOW_STATE_MAXIMIZED, /**< maximum sized window */ + ECORE_WIN32_WINDOW_STATE_SHADED, /**< shaded window */ + ECORE_WIN32_WINDOW_STATE_HIDDEN, /**< hidden (minimized or iconified) window */ + ECORE_WIN32_WINDOW_STATE_FULLSCREEN, /**< fullscreen window */ + ECORE_WIN32_WINDOW_STATE_ABOVE, /**< above window */ + ECORE_WIN32_WINDOW_STATE_BELOW, /**< below window */ + ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION, /**< To document */ + ECORE_WIN32_WINDOW_STATE_UNKNOWN /**< Unknown state */ +} Ecore_Win32_Window_State; + +/** + * @typedef Ecore_Win32_Window_Type + * Type of a window. + */ +typedef enum +{ + ECORE_WIN32_WINDOW_TYPE_DESKTOP, /**< Desktop feature */ + ECORE_WIN32_WINDOW_TYPE_DOCK, /**< Dock window (should be on top of other windows) */ + ECORE_WIN32_WINDOW_TYPE_TOOLBAR, /**< Toolbar window */ + ECORE_WIN32_WINDOW_TYPE_MENU, /**< Menu window */ + ECORE_WIN32_WINDOW_TYPE_UTILITY, /**< Small persistent utility window, such as a palette or toolbox */ + ECORE_WIN32_WINDOW_TYPE_SPLASH, /**< Splash screen window displayed as an application is starting up */ + ECORE_WIN32_WINDOW_TYPE_DIALOG, /**< Dialog window */ + ECORE_WIN32_WINDOW_TYPE_NORMAL, /**< Normal top-level window */ + ECORE_WIN32_WINDOW_TYPE_UNKNOWN /**< Unknown type */ +} Ecore_Win32_Window_Type; + +/** + * @typedef Ecore_Win32_Cursor_Shape + * Shape of a cursor. + */ +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; + +/** + * @typedef Ecore_Win32_DnD_State + * State of a DnD operation. + */ +typedef enum +{ + ECORE_WIN32_DND_EVENT_DRAG_ENTER = 1, /**< Drag enter */ + ECORE_WIN32_DND_EVENT_DRAG_OVER = 2, /**< Drag over */ + ECORE_WIN32_DND_EVENT_DRAG_LEAVE = 3, /**< Drag leave */ + ECORE_WIN32_DND_EVENT_DROP = 4 /**< Drop */ +} Ecore_Win32_DnD_State; + +/** + * @typedef Ecore_Win32_Window + * Abstract type for a window. + */ +typedef struct _Ecore_Win32_Window Ecore_Win32_Window; + +/** + * @typedef Ecore_Win32_Cursor + * Abstract type for a cursor. + */ +typedef void Ecore_Win32_Cursor; + + +/** + * @typedef Ecore_Win32_Event_Mouse_In + * Event sent when the mouse enters the window. + */ +typedef struct _Ecore_Win32_Event_Mouse_In Ecore_Win32_Event_Mouse_In; + +/** + * @typedef Ecore_Win32_Event_Mouse_Out + * Event sent when the mouse leaves the window. + */ +typedef struct _Ecore_Win32_Event_Mouse_Out Ecore_Win32_Event_Mouse_Out; + +/** + * @typedef Ecore_Win32_Event_Window_Focus_In + * Event sent when the window gets the focus. + */ +typedef struct _Ecore_Win32_Event_Window_Focus_In Ecore_Win32_Event_Window_Focus_In; + +/** + * @typedef Ecore_Win32_Event_Window_Focus_Out + * Event sent when the window looses the focus. + */ +typedef struct _Ecore_Win32_Event_Window_Focus_Out Ecore_Win32_Event_Window_Focus_Out; + +/** + * @typedef Ecore_Win32_Event_Window_Damage + * Event sent when the window is damaged. + */ +typedef struct _Ecore_Win32_Event_Window_Damage Ecore_Win32_Event_Window_Damage; + +/** + * @typedef Ecore_Win32_Event_Window_Create + * Event sent when the window is created. + */ +typedef struct _Ecore_Win32_Event_Window_Create Ecore_Win32_Event_Window_Create; + +/** + * @typedef Ecore_Win32_Event_Window_Destroy + * Event sent when the window is destroyed. + */ +typedef struct _Ecore_Win32_Event_Window_Destroy Ecore_Win32_Event_Window_Destroy; + +/** + * @typedef Ecore_Win32_Event_Window_Hide + * Event sent when the window is hidden. + */ +typedef struct _Ecore_Win32_Event_Window_Hide Ecore_Win32_Event_Window_Hide; + +/** + * @typedef Ecore_Win32_Event_Window_Show + * Event sent when the window is shown. + */ +typedef struct _Ecore_Win32_Event_Window_Show Ecore_Win32_Event_Window_Show; + +/** + * @typedef Ecore_Win32_Event_Window_Configure + * Event sent when the window is configured. + */ +typedef struct _Ecore_Win32_Event_Window_Configure Ecore_Win32_Event_Window_Configure; + +/** + * @typedef Ecore_Win32_Event_Window_Resize + * Event sent when the window is resized. + */ +typedef struct _Ecore_Win32_Event_Window_Resize Ecore_Win32_Event_Window_Resize; + +/** + * @typedef Ecore_Win32_Event_Window_Delete_Request + * Event sent when the window is deleted. + */ +typedef struct _Ecore_Win32_Event_Window_Delete_Request Ecore_Win32_Event_Window_Delete_Request; + +/** + * @struct _Ecore_Win32_Event_Mouse_In + * Event sent when the mouse enters the window. + */ +struct _Ecore_Win32_Event_Mouse_In +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + int x; /**< The x coordinate where the mouse leaved */ + int y; /**< The y coordinate where the mouse entered */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Mouse_Out + * Event sent when the mouse leaves the window. + */ +struct _Ecore_Win32_Event_Mouse_Out +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + int x; /**< The x coordinate where the mouse leaved */ + int y; /**< The y coordinate where the mouse leaved */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Focus_In + * Event sent when the window gets the focus. + */ +struct _Ecore_Win32_Event_Window_Focus_In +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Focus_Out + * Event sent when the window looses the focus. + */ +struct _Ecore_Win32_Event_Window_Focus_Out +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Damage + * Event sent when the window is damaged. + */ +struct _Ecore_Win32_Event_Window_Damage +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + int x; /**< The x coordinate of the top left corner of the damaged region */ + int y; /**< The y coordinate of the top left corner of the damaged region */ + int width; /**< The width of the damaged region */ + int height; /**< The time the event occurred */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Create + * Event sent when the window is created. + */ +struct _Ecore_Win32_Event_Window_Create +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Destroy + * Event sent when the window is destroyed. + */ +struct _Ecore_Win32_Event_Window_Destroy +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Hide + * Event sent when the window is hidden. + */ +struct _Ecore_Win32_Event_Window_Hide +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Show + * Event sent when the window is shown. + */ +struct _Ecore_Win32_Event_Window_Show +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Configure + * Event sent when the window is configured. + */ +struct _Ecore_Win32_Event_Window_Configure +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + Ecore_Win32_Window *abovewin; + int x; /**< The new x coordinate of the top left corner */ + int y; /**< The new y coordinate of the top left corner */ + int width; /**< The new width */ + int height; /**< The new height */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Resize + * Event sent when the window is resized. + */ +struct _Ecore_Win32_Event_Window_Resize +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + int width; /**< The new width */ + int height; /**< The new height */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_Win32_Event_Window_Delete_Request + * Event sent when the window is deleted. + */ +struct _Ecore_Win32_Event_Window_Delete_Request +{ + Ecore_Win32_Window *window; /**< The window that received the event */ + unsigned long timestamp; /**< The time the event occurred */ +}; + +/** + * @typedef Ecore_Win32_Dnd_DropTarget_Callback + * Callback type for Drop operations. See ecore_win32_dnd_register_drop_target(). + */ +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; /**< Ecore_Event for the #Ecore_Win32_Event_Mouse_In event */ +EAPI extern int ECORE_WIN32_EVENT_MOUSE_OUT; /**< Ecore_Event for the #Ecore_Win32_Event_Mouse_Out event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_IN; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Focus_In event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_FOCUS_OUT; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Focus_Out event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the Ecore_Win32_Event_Damage event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_CREATE; /**< Ecore_Event for the Ecore_Win32_Event_Create event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the Ecore_Win32_Event_Destroy event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_HIDE; /**< Ecore_Event for the Ecore_Win32_Event_Hide event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_SHOW; /**< Ecore_Event for the Ecore_Win32_Event_Show event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_CONFIGURE; /**< Ecore_Event for the Ecore_Win32_Event_Configure event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_RESIZE; /**< Ecore_Event for the Ecore_Win32_Event_Resize event */ +EAPI extern int ECORE_WIN32_EVENT_WINDOW_DELETE_REQUEST; /**< Ecore_Event for the #Ecore_Win32_Event_Window_Delete_Request event */ + + +/* Core */ + +EAPI int ecore_win32_init(); +EAPI int ecore_win32_shutdown(); +EAPI int ecore_win32_screen_depth_get(); +EAPI void ecore_win32_double_click_time_set(double t); +EAPI double ecore_win32_double_click_time_get(void); +EAPI unsigned long ecore_win32_current_time_get(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(Ecore_Win32_Window *window); + +EAPI void *ecore_win32_window_focus_get(void); + +EAPI void ecore_win32_window_iconified_set(Ecore_Win32_Window *window, + Eina_Bool on); + +EAPI void ecore_win32_window_borderless_set(Ecore_Win32_Window *window, + Eina_Bool on); + +EAPI void ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window, + Eina_Bool on); + +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_shaped_new(Ecore_Win32_Cursor_Shape shape); + +EAPI void ecore_win32_cursor_size_get(int *width, int *height); + + + +/* Drag and drop */ +EAPI int ecore_win32_dnd_init(); +EAPI int ecore_win32_dnd_shutdown(); +EAPI Eina_Bool ecore_win32_dnd_begin(const char *data, + int size); +EAPI Eina_Bool 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__ */ diff --git a/src/lib/ecore_win32/ecore_win32.c b/src/lib/ecore_win32/ecore_win32.c new file mode 100644 index 0000000000..b571d74d1b --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32.c @@ -0,0 +1,841 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include + +#include +#include +#include + +#include "Ecore_Win32.h" +#include "ecore_win32_private.h" + +/*============================================================================* + * Local * + *============================================================================*/ + +/** + * @cond LOCAL + */ + +/* OLE IID for Drag'n Drop */ + +# define INITGUID +# include +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); + +#define IDI_ICON 101 + +static int _ecore_win32_init_count = 0; + +static void +_ecore_win32_size_check(Ecore_Win32_Window *win, int w, int h, int *dx, int *dy) +{ + int minimal_width; + int minimal_height; + + minimal_width = GetSystemMetrics(SM_CXMIN); + minimal_height = GetSystemMetrics(SM_CYMIN); + if ((w) < MAX(minimal_width, (int)win->min_width)) + *dx = 0; + if ((w) > (int)win->max_width) + *dx = 0; + if ((h) < MAX(minimal_height, (int)win->min_height)) + *dy = 0; + if ((h) > (int)win->max_height) + *dy = 0; +} + +LRESULT CALLBACK +_ecore_win32_window_procedure(HWND window, + UINT message, + WPARAM window_param, + LPARAM data_param) +{ + Ecore_Win32_Callback_Data *data; + POINTS point; + 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->timestamp = GetMessageTime(); + coord = GetMessagePos(); + point = MAKEPOINTS(coord); + data->x = point.x; + data->y = point.y; + data->discard_ctrl = EINA_FALSE; + + switch (data->message) + { + /* Keyboard input notifications */ + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if ((data->message == WM_KEYDOWN) && + (data->window_param == VK_CONTROL) && + ((HIWORD(data->data_param) & KF_EXTENDED) == 0)) + { + /* Ctrl left key is pressed */ + BOOL res; + MSG next_msg; + + /* + * we check if the next message + * - is a WM_KEYDOWN + * - has the same timestamp than the Ctrl one + * - is the key press of the right Alt key + */ + res = PeekMessage(&next_msg, data->window, + WM_KEYDOWN, WM_KEYDOWN, + PM_NOREMOVE); + if (res && + (next_msg.wParam == VK_MENU) && + (next_msg.time == data->timestamp) && + (HIWORD(next_msg.lParam) & KF_EXTENDED)) + { + INF("discard left Ctrl key press (sent by AltGr key press)"); + data->discard_ctrl = EINA_TRUE; + } + } + _ecore_win32_event_handle_key_press(data, 1); + return 0; + case WM_CHAR: + case WM_SYSCHAR: + INF("char message"); + _ecore_win32_event_handle_key_press(data, 0); + return 0; + case WM_KEYUP: + case WM_SYSKEYUP: + INF("keyup message"); + if ((data->window_param == VK_CONTROL) && + ((HIWORD(data->data_param) & KF_EXTENDED) == 0)) + { + /* Ctrl left key is pressed */ + BOOL res; + MSG next_msg; + + /* + * we check if the next message + * - is a WM_KEYUP or WM_SYSKEYUP + * - has the same timestamp than the Ctrl one + * - is the key release of the right Alt key + */ + res = PeekMessage(&next_msg, data->window, + WM_KEYUP, WM_SYSKEYUP, + PM_NOREMOVE); + if (res && + ((next_msg.message == WM_KEYUP) || + (next_msg.message == WM_SYSKEYUP)) && + (next_msg.wParam == VK_MENU) && + (next_msg.time == data->timestamp) && + (HIWORD(next_msg.lParam) & KF_EXTENDED)) + { + INF("discard left Ctrl key release (sent by AltGr key release)"); + data->discard_ctrl = EINA_TRUE; + } + } + _ecore_win32_event_handle_key_release(data); + return 0; + case WM_SETFOCUS: + INF("setfocus message"); + _ecore_win32_event_handle_focus_in(data); + return 0; + case WM_KILLFOCUS: + INF("kill focus message"); + _ecore_win32_event_handle_focus_out(data); + return 0; + /* Mouse input notifications */ + case WM_LBUTTONDOWN: + INF("left button down message"); + SetCapture(window); + _ecore_win32_event_handle_button_press(data, 1); + return 0; + case WM_MBUTTONDOWN: + INF("middle button down message"); + _ecore_win32_event_handle_button_press(data, 2); + return 0; + case WM_RBUTTONDOWN: + INF("right button down message"); + _ecore_win32_event_handle_button_press(data, 3); + return 0; + case WM_LBUTTONUP: + { + Ecore_Win32_Window *w = NULL; + + INF("left button up message"); + + ReleaseCapture(); + w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA); + if (w->drag.dragging) + { + w->drag.dragging = 0; + return 0; + } + + _ecore_win32_event_handle_button_release(data, 1); + return 0; + } + case WM_MBUTTONUP: + INF("middle button up message"); + _ecore_win32_event_handle_button_release(data, 2); + return 0; + case WM_RBUTTONUP: + INF("right button up message"); + _ecore_win32_event_handle_button_release(data, 3); + return 0; + case WM_MOUSEMOVE: + { + RECT rect; + Ecore_Win32_Window *w = NULL; + + INF("moue move message"); + + w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA); + + if (w->drag.dragging) + { + POINT pt; + + pt.x = GET_X_LPARAM(data_param); + pt.y = GET_Y_LPARAM(data_param); + if (ClientToScreen(window, &pt)) + { + if (w->drag.type == HTCAPTION) + { + int dx; + int dy; + + dx = pt.x - w->drag.px; + dy = pt.y - w->drag.py; + ecore_win32_window_move(w, w->drag.x + dx, w->drag.y + dy); + w->drag.x += dx; + w->drag.y += dy; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + if (w->drag.type == HTLEFT) + { + int dw; + + dw = pt.x - w->drag.px; + ecore_win32_window_move_resize(w, w->drag.x + dw, w->drag.y, w->drag.w - dw, w->drag.h); + w->drag.x += dw; + w->drag.w -= dw; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + if (w->drag.type == HTRIGHT) + { + int dw; + + dw = pt.x - w->drag.px; + ecore_win32_window_resize(w, w->drag.w + dw, w->drag.h); + w->drag.w += dw; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + if (w->drag.type == HTTOP) + { + int dh; + + dh = pt.y - w->drag.py; + ecore_win32_window_move_resize(w, w->drag.x, w->drag.y + dh, w->drag.w, w->drag.h - dh); + w->drag.y += dh; + w->drag.h -= dh; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + if (w->drag.type == HTBOTTOM) + { + int dh; + + dh = pt.y - w->drag.py; + ecore_win32_window_resize(w, w->drag.w, w->drag.h + dh); + w->drag.h += dh; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + if (w->drag.type == HTTOPLEFT) + { + int dx; + int dy; + int dh; + int dw; + + dw = pt.x - w->drag.px; + dh = pt.y - w->drag.py; + dx = dw; + dy = dh; + _ecore_win32_size_check(w, + w->drag.w - dw, w->drag.h - dh, + &dx, &dy); + + ecore_win32_window_move_resize(w, w->drag.x + dx, w->drag.y + dy, w->drag.w - dw, w->drag.h - dh); + w->drag.x += dx; + w->drag.y += dy; + w->drag.w -= dw; + w->drag.h -= dh; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + if (w->drag.type == HTTOPRIGHT) + { + int dx; + int dy; + int dh; + int dw; + + dw = pt.x - w->drag.px; + dh = pt.y - w->drag.py; + dx = dw; + dy = dh; + _ecore_win32_size_check(w, + w->drag.w, w->drag.h - dh, + &dx, &dy); + ecore_win32_window_move_resize(w, w->drag.x, w->drag.y + dy, w->drag.w, w->drag.h - dh); + w->drag.y += dy; + w->drag.w += dw; + w->drag.h -= dh; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + if (w->drag.type == HTBOTTOMLEFT) + { + int dx; + int dy; + int dh; + int dw; + + dw = pt.x - w->drag.px; + dh = pt.y - w->drag.py; + dx = dw; + dy = dh; + _ecore_win32_size_check(w, + w->drag.w - dw, w->drag.h + dh, + &dx, &dy); + ecore_win32_window_move_resize(w, w->drag.x + dx, w->drag.y, w->drag.w - dw, w->drag.h + dh); + w->drag.x += dx; + w->drag.w -= dw; + w->drag.h += dh; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + if (w->drag.type == HTBOTTOMRIGHT) + { + int dh; + int dw; + + dw = pt.x - w->drag.px; + dh = pt.y - w->drag.py; + ecore_win32_window_resize(w, w->drag.w + dw, w->drag.h + dh); + w->drag.w += dw; + w->drag.h += dh; + w->drag.px = pt.x; + w->drag.py = pt.y; + return 0; + } + } + } + + 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: + INF("mouse wheel message"); + _ecore_win32_event_handle_button_press(data, 4); + return 0; + /* Window notifications */ + case WM_CREATE: + INF("create window message"); + _ecore_win32_event_handle_create_notify(data); + return 0; + case WM_DESTROY: + INF("destroy window message"); + _ecore_win32_event_handle_destroy_notify(data); + return 0; + case WM_SHOWWINDOW: + INF("show window message"); + if ((data->data_param == SW_OTHERUNZOOM) || + (data->data_param == SW_OTHERZOOM)) + 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: + INF("close window message"); + _ecore_win32_event_handle_delete_request(data); + return 0; + case WM_GETMINMAXINFO: + INF("get min max info window message"); + return TRUE; + case WM_MOVING: + INF("moving window message"); + _ecore_win32_event_handle_configure_notify(data); + return TRUE; + case WM_MOVE: + INF("move window message"); + return 0; + case WM_SIZING: + INF("sizing window message"); + _ecore_win32_event_handle_resize(data); + _ecore_win32_event_handle_configure_notify(data); + return TRUE; + case WM_SIZE: + INF("size window message"); + 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: + INF("position changed window message"); + _ecore_win32_event_handle_configure_notify(data); + _ecore_win32_event_handle_expose(data); + return 0; + case WM_ENTERSIZEMOVE: + INF("enter size move window message"); + return 0; + case WM_EXITSIZEMOVE: + INF("exit size move window message"); + return 0; + case WM_NCLBUTTONDOWN: + INF("non client left button down window message"); + + if (((DWORD)window_param == HTCAPTION) || + ((DWORD)window_param == HTBOTTOM) || + ((DWORD)window_param == HTBOTTOMLEFT) || + ((DWORD)window_param == HTBOTTOMRIGHT) || + ((DWORD)window_param == HTLEFT) || + ((DWORD)window_param == HTRIGHT) || + ((DWORD)window_param == HTTOP) || + ((DWORD)window_param == HTTOPLEFT) || + ((DWORD)window_param == HTTOPRIGHT)) + { + Ecore_Win32_Window *w; + + w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA); + ecore_win32_window_geometry_get(w, + NULL, NULL, + &w->drag.w, &w->drag.h); + SetCapture(window); + w->drag.type = (DWORD)window_param; + w->drag.px = GET_X_LPARAM(data_param); + w->drag.py = GET_Y_LPARAM(data_param); + w->drag.dragging = 1; + return 0; + } + return DefWindowProc(window, message, window_param, data_param); + case WM_SYSCOMMAND: + INF("sys command window message %d", (int)window_param); + + if ((((DWORD)window_param & 0xfff0) == SC_MOVE) || + (((DWORD)window_param & 0xfff0) == SC_SIZE)) + { + Ecore_Win32_Window *w; + + INF("sys command MOVE or SIZE window message : %dx%d", GET_X_LPARAM(data_param), GET_Y_LPARAM(data_param)); + + w = (Ecore_Win32_Window *)GetWindowLongPtr(window, GWLP_USERDATA); + w->drag.dragging = 1; + return 0; + } + return DefWindowProc(window, message, window_param, data_param); + /* GDI notifications */ + case WM_ERASEBKGND: + return 1; + case WM_PAINT: + { + RECT rect; + + INF("paint message"); + + 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: + INF("set redraw message"); + return 0; + case WM_SYNCPAINT: + INF("sync paint message"); + return 0; + default: + return DefWindowProc(window, message, window_param, data_param); + } +} + +/** + * @endcond + */ + + +/*============================================================================* + * Global * + *============================================================================*/ + + +HINSTANCE _ecore_win32_instance = NULL; +double _ecore_win32_double_click_time = 0.25; +unsigned 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; + +/*============================================================================* + * API * + *============================================================================*/ + +/** + * @addtogroup Ecore_Win32_Group Ecore_Win32 library + * + * Ecore_Win32 is a library that wraps Windows graphic functions + * and integrate them nicely into the Ecore main loop. + * + * @section Ecore_Win32_Sec_Init Initialisation / Shutdown + * + * To fill... + * + * @section Ecore_Win32_Sec_Icons How to set icons to an application + * + * It is possible to also sets the icon of the application easily: + * + * @li Create an icon with your favorite image creator. The Gimp is a + * good choice. Create several images of size 16, 32 and 48. You can + * also create images of size 24, 64, 128 and 256. Paste all of them + * in the image of size 16 as a layer. Save the image of size 16 with + * the name my_icon.ico. Put it where the source code of the + * application is located. + * @li Create my_icon_rc.rc file with your code editor and add in it: + * @code + * 101 ICON DISCARDABLE "my_icon.ico" + * @endcode + * @li With Visual Studio, put that file in the 'Resource file' part + * of the project. + * @li With MinGW, you have to compile it with windres: + * @code + * windres my_icon_rc.rc my_icon_rc.o + * @endcode + * and add my_icon_rc.o to the object files of the application. + * + * @note The value 101 must not be changed, it's the ID used + * internally by Ecore_Win32 to get the icons. + * + * @{ + */ + +/** + * @brief Initialize the Ecore_Win32 library. + * + * @return 1 or greater on success, 0 on error. + * + * This function sets up the Windows graphic system. It returns 0 on + * failure, otherwise it returns the number of times it has already been + * called. + * + * When Ecore_Win32 is not used anymore, call ecore_win32_shutdown() + * to shut down the Ecore_Win32 library. + */ +EAPI int +ecore_win32_init() +{ + WNDCLASSEX wc; + HICON icon; + HICON icon_sm; + + if (++_ecore_win32_init_count != 1) + return _ecore_win32_init_count; + + if (!eina_init()) + return --_ecore_win32_init_count; + + _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; + } + + icon = LoadImage(_ecore_win32_instance, + MAKEINTRESOURCE(IDI_ICON), + IMAGE_ICON, + GetSystemMetrics(SM_CXICON), + GetSystemMetrics(SM_CYICON), + LR_DEFAULTCOLOR); + icon_sm = LoadImage(_ecore_win32_instance, + MAKEINTRESOURCE(IDI_ICON), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTCOLOR); + if (!icon) + icon = LoadIcon (NULL, IDI_APPLICATION); + if (!icon_sm) + icon_sm = LoadIcon (NULL, IDI_APPLICATION); + + memset (&wc, 0, sizeof (WNDCLASSEX)); + wc.cbSize = sizeof (WNDCLASSEX); + 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 = icon; + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wc.lpszMenuName = NULL; + wc.lpszClassName = ECORE_WIN32_WINDOW_CLASS; + wc.hIconSm = icon_sm; + + if(!RegisterClassEx(&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; +} + +/** + * @brief Shut down the Ecore_Win32 library. + * + * @return 0 when the library is completely shut down, 1 or + * greater otherwise. + * + * This function shuts down the Ecore_Win32 library. It returns 0 when it has + * been called the same number of times than ecore_win32_init(). In that case + * it shuts down all the Windows graphic system. + */ +EAPI 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; +} + +/** + * @brief Retrieve the depth of the screen. + * + * @return The depth of the screen. + * + * This function returns the depth of the screen. If an error occurs, + * it returns 0. + */ +EAPI 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; +} + +/** + * @brief Sets the timeout for a double and triple clicks to be flagged. + * + * @param t The time in seconds. + * + * This function sets the time @p t 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. + */ +EAPI void +ecore_win32_double_click_time_set(double t) +{ + if (t < 0.0) t = 0.0; + _ecore_win32_double_click_time = t; +} + +/** + * @brief Retrieve the double and triple click flag timeout. + * + * @return The timeout for double clicks in seconds. + * + * This function returns the double clicks in seconds. If + * ecore_win32_double_click_time_set() has not been called, the + * default value is returned. See ecore_win32_double_click_time_set() + * for more informations. + */ +EAPI double +ecore_win32_double_click_time_get(void) +{ + return _ecore_win32_double_click_time; +} + +/** + * @brief Return the last event time. + * + * @return The last envent time. + * + * This function returns the last event time. + */ +EAPI unsigned long +ecore_win32_current_time_get(void) +{ + return _ecore_win32_event_last_time; +} + +/** + * @} + */ diff --git a/src/lib/ecore_win32/ecore_win32_cursor.c b/src/lib/ecore_win32/ecore_win32_cursor.c new file mode 100644 index 0000000000..9b58c95160 --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_cursor.c @@ -0,0 +1,305 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + +#include + +#include "Ecore_Win32.h" +#include "ecore_win32_private.h" + +/*============================================================================* + * Local * + *============================================================================*/ + + +/*============================================================================* + * Global * + *============================================================================*/ + + +/*============================================================================* + * API * + *============================================================================*/ + +/** + * @addtogroup Ecore_Win32_Group Ecore_Win32 library + * + * @{ + */ + +/** + * @brief Create a new cursor. + * + * @param pixels_and The array of bytes containing the bit values for + * the AND mask of the cursor. + * @param pixels_xor The array of bytes containing the bit values for + * the XOR mask of the cursor. + * @param width The width of the cursor. + * @param height The height of the cursor. + * @param hot_x The horizontal position of the cursor's hot spot. + * @param hot_y The vertical position of the cursor's hot spot. + * @return A newly user-defined cursor. + * + * This function creates a new cursor of size @p width and @p + * height. They must be valid size. To determine the valid size of a + * cursor, use ecore_win32_cursor_size_get(). @p pixels_and is an array + * of bytes (unsigned char) containing the bits of the cursor that + * will be visible. @p pixels_xor is similar but will allow the cursor + * to have a shape. Here is the truth table for the masks: + * + * + * + * + * + * + * + *
AND maskXOR maskDisplay
0 0 Black
0 1 White
1 0 Screen
1 1 Reverse screen
+ * + * @p hot_x and @p hot_y are the position of the hot spot of the + * cursor. If @p pixels_and or @p pixels_xor are @c NULL, the function + * returns NULL. If @p width or @p height does not match the valid + * size of a cursor, the function returns @c NULL. On success, the + * function creates a user-defined cursor, otherwise it returns + * @c NULL. + * + * Once the cursor is not used anymore, use ecore_win32_cursor_free() + * to free the ressources. + * + * Example of use: + * + * @code + * unsigned char pixels_and[] ={ + * 0xFF, 0xFC, 0x3F, 0xFF, // line 1 + * 0xFF, 0xC0, 0x1F, 0xFF, // line 2 + * 0xFF, 0x00, 0x3F, 0xFF, // line 3 + * 0xFE, 0x00, 0xFF, 0xFF, // line 4 + * + * 0xF7, 0x01, 0xFF, 0xFF, // line 5 + * 0xF0, 0x03, 0xFF, 0xFF, // line 6 + * 0xF0, 0x03, 0xFF, 0xFF, // line 7 + * 0xE0, 0x07, 0xFF, 0xFF, // line 8 + * + * 0xC0, 0x07, 0xFF, 0xFF, // line 9 + * 0xC0, 0x0F, 0xFF, 0xFF, // line 10 + * 0x80, 0x0F, 0xFF, 0xFF, // line 11 + * 0x80, 0x0F, 0xFF, 0xFF, // line 12 + * + * 0x80, 0x07, 0xFF, 0xFF, // line 13 + * 0x00, 0x07, 0xFF, 0xFF, // line 14 + * 0x00, 0x03, 0xFF, 0xFF, // line 15 + * 0x00, 0x00, 0xFF, 0xFF, // line 16 + * + * 0x00, 0x00, 0x7F, 0xFF, // line 17 + * 0x00, 0x00, 0x1F, 0xFF, // line 18 + * 0x00, 0x00, 0x0F, 0xFF, // line 19 + * 0x80, 0x00, 0x0F, 0xFF, // line 20 + * + * 0x80, 0x00, 0x07, 0xFF, // line 21 + * 0x80, 0x00, 0x07, 0xFF, // line 22 + * 0xC0, 0x00, 0x07, 0xFF, // line 23 + * 0xC0, 0x00, 0x0F, 0xFF, // line 24 + * + * 0xE0, 0x00, 0x0F, 0xFF, // line 25 + * 0xF0, 0x00, 0x1F, 0xFF, // line 26 + * 0xF0, 0x00, 0x1F, 0xFF, // line 27 + * 0xF8, 0x00, 0x3F, 0xFF, // line 28 + * + * 0xFE, 0x00, 0x7F, 0xFF, // line 29 + * 0xFF, 0x00, 0xFF, 0xFF, // line 30 + * 0xFF, 0xC3, 0xFF, 0xFF, // line 31 + * 0xFF, 0xFF, 0xFF, 0xFF // line 32 + * }; + * + * unsigned char pixels_xor[] = { + * 0x00, 0x00, 0x00, 0x00, // line 1 + * 0x00, 0x03, 0xC0, 0x00, // line 2 + * 0x00, 0x3F, 0x00, 0x00, // line 3 + * 0x00, 0xFE, 0x00, 0x00, // line 4 + * + * 0x0E, 0xFC, 0x00, 0x00, // line 5 + * 0x07, 0xF8, 0x00, 0x00, // line 6 + * 0x07, 0xF8, 0x00, 0x00, // line 7 + * 0x0F, 0xF0, 0x00, 0x00, // line 8 + * + * 0x1F, 0xF0, 0x00, 0x00, // line 9 + * 0x1F, 0xE0, 0x00, 0x00, // line 10 + * 0x3F, 0xE0, 0x00, 0x00, // line 11 + * 0x3F, 0xE0, 0x00, 0x00, // line 12 + * + * 0x3F, 0xF0, 0x00, 0x00, // line 13 + * 0x7F, 0xF0, 0x00, 0x00, // line 14 + * 0x7F, 0xF8, 0x00, 0x00, // line 15 + * 0x7F, 0xFC, 0x00, 0x00, // line 16 + * + * 0x7F, 0xFF, 0x00, 0x00, // line 17 + * 0x7F, 0xFF, 0x80, 0x00, // line 18 + * 0x7F, 0xFF, 0xE0, 0x00, // line 19 + * 0x3F, 0xFF, 0xE0, 0x00, // line 20 + * + * 0x3F, 0xC7, 0xF0, 0x00, // line 21 + * 0x3F, 0x83, 0xF0, 0x00, // line 22 + * 0x1F, 0x83, 0xF0, 0x00, // line 23 + * 0x1F, 0x83, 0xE0, 0x00, // line 24 + * + * 0x0F, 0xC7, 0xE0, 0x00, // line 25 + * 0x07, 0xFF, 0xC0, 0x00, // line 26 + * 0x07, 0xFF, 0xC0, 0x00, // line 27 + * 0x01, 0xFF, 0x80, 0x00, // line 28 + * + * 0x00, 0xFF, 0x00, 0x00, // line 29 + * 0x00, 0x3C, 0x00, 0x00, // line 30 + * 0x00, 0x00, 0x00, 0x00, // line 31 + * 0x00, 0x00, 0x00, 0x00 // line 32 + * }; + * + * Ecore_Win32_Cursor *cursor = ecore_win32_cursor_new(pixels_and, pixels_xor, 32, 32, 19, 2); + * @endcode + */ +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) +{ + Ecore_Win32_Cursor *cursor = NULL; + int cursor_width; + int cursor_height; + + INF("creating cursor"); + + if (!pixels_and || !pixels_xor) + return NULL; + + 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; +} + +/** + * @brief Free the given cursor. + * + * @param cursor The cursor to free. + * + * This function free @p cursor. @p cursor must have been obtained + * with ecore_win32_cursor_new(). + */ +EAPI void +ecore_win32_cursor_free(Ecore_Win32_Cursor *cursor) +{ + INF("destroying cursor"); + + DestroyCursor(cursor); +} + +/** + * @brief Create a cursor from a Windows ressource. + * + * @param shape The pre-defined shape of the cursor. + * @return The new cursor. + * + * This function returns a pre-defined cursor with a specified + * @p shape. This cursor does not need to be freed, as it is loaded + * from an existing resource. + */ +EAPI Ecore_Win32_Cursor * +ecore_win32_cursor_shaped_new(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; +} + +/** + * @brief Retrieve the size of a valid cursor. + * + * @param width The width of a valid cursor. + * @param height The height of a valid cursor. + * + * This function returns the size of a cursor that must be passed to + * ecore_win32_cursor_new(). @p width and @p height are buffers that + * will be filled with the correct size. They can be @c NULL. + */ +EAPI void +ecore_win32_cursor_size_get(int *width, int *height) +{ + INF("geting size cursor"); + + if (*width) *width = GetSystemMetrics(SM_CXCURSOR); + if (*height) *height = GetSystemMetrics(SM_CYCURSOR); +} + +/** + * @} + */ diff --git a/src/lib/ecore_win32/ecore_win32_dnd.c b/src/lib/ecore_win32/ecore_win32_dnd.c new file mode 100755 index 0000000000..6c5253ae20 --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd.c @@ -0,0 +1,221 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "Ecore_Win32.h" +#include "ecore_win32_private.h" + +/*============================================================================* + * Local * + *============================================================================*/ + +/** + * @cond LOCAL + */ + + +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; +} + +/** + * @endcond + */ + + +/*============================================================================* + * Global * + *============================================================================*/ + + +/*============================================================================* + * API * + *============================================================================*/ + +/** + * @addtogroup Ecore_Win32_Group Ecore_Win32 library + * + * @{ + */ + +/** + * @brief Initialize the Ecore_Win32 Drag and Drop module. + * + * @return 1 or greater on success, 0 on error. + * + * This function initialize the Drag and Drop module. It returns 0 on + * failure, otherwise it returns the number of times it has already + * been called. + * + * When the Drag and Drop module is not used anymore, call + * ecore_win32_dnd_shutdown() to shut down the module. + */ +EAPI 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; +} + +/** + * @brief Shut down the Ecore_Win32 Drag and Drop module. + * + * @return 0 when the module is completely shut down, 1 or + * greater otherwise. + * + * This function shuts down the Drag and Drop module. It returns 0 when it has + * been called the same number of times than ecore_win32_dnd_init(). In that case + * it shut down the module. + */ +EAPI 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; +} + +/** + * @brief Begin a DnD operation. + * + * @param data The name pf the Drag operation. + * @param size The size of the name. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function start a Drag operation with the name @p data. If + * @p data is @c NULL, @c EINA_FALSE is returned. if @p size is less than + * @c 0, it is set to the length (as strlen()) of @p data. On success the + * function returns @c EINA_TRUE, otherwise it returns @c EINA_FALSE. + */ +EAPI Eina_Bool +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 }; + Eina_Bool res = EINA_FALSE; + + if (!data) + return EINA_FALSE; + + 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 = EINA_TRUE; + } + + _ecore_win32_dnd_data_object_free(pDataObject); + _ecore_win32_dnd_drop_source_free(pDropSource); + + // cleanup + ReleaseStgMedium(&stgmed); + + return res; +} + +/** + * @brief Register a Drop operation. + * + * @param window The destination of the Drop operation. + * @param callback The callback called when the Drop operation + * finishes. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * This function register a Drop operation on @p window. Once the Drop + * operation finishes, @p callback is called. If @p window is @c NULL, + * the function returns @c EINA_FALSE. On success, it returns @c EINA_TRUE, + * otherwise it returns @c EINA_FALSE. + */ +EAPI Eina_Bool +ecore_win32_dnd_register_drop_target(Ecore_Win32_Window *window, + Ecore_Win32_Dnd_DropTarget_Callback callback) +{ + Ecore_Win32_Window *wnd = (Ecore_Win32_Window *)window; + + if (!window) + return EINA_FALSE; + + wnd->dnd_drop_target = _ecore_win32_dnd_register_drop_window(wnd->window, + callback, + (void *)wnd); + return wnd->dnd_drop_target ? EINA_TRUE : EINA_FALSE; +} + +/** + * @brief Unregister a Drop operation. + * + * @param window The destination of the Drop operation. + * + * This function unregister a Drop operation on @p window. If + * @p window is @c NULL, the function does nothing. + */ +EAPI void +ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window) +{ + Ecore_Win32_Window *wnd = (Ecore_Win32_Window *)window; + + if (!window) + return; + + if (wnd->dnd_drop_target) + _ecore_win32_dnd_unregister_drop_window(wnd->window, wnd->dnd_drop_target); +} + +/** + * @} + */ diff --git a/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp b/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp new file mode 100644 index 0000000000..213197780b --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd_data_object.cpp @@ -0,0 +1,209 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include + +#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 EINA_UNUSED, STGMEDIUM *pmedium EINA_UNUSED) +{ + 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 EINA_UNUSED, 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 EINA_UNUSED, STGMEDIUM *pMedium EINA_UNUSED, BOOL fRelease EINA_UNUSED) +{ + 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 EINA_UNUSED, DWORD advf EINA_UNUSED, IAdviseSink *, DWORD *) +{ + return OLE_E_ADVISENOTSUPPORTED; +} + +HRESULT DataObject::DUnadvise(DWORD dwConnection EINA_UNUSED) +{ + return OLE_E_ADVISENOTSUPPORTED; +} + +HRESULT DataObject::EnumDAdvise(IEnumSTATDATA **ppEnumAdvise EINA_UNUSED) +{ + 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(); +} diff --git a/src/lib/ecore_win32/ecore_win32_dnd_data_object.h b/src/lib/ecore_win32/ecore_win32_dnd_data_object.h new file mode 100644 index 0000000000..3d289cf7f5 --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd_data_object.h @@ -0,0 +1,49 @@ +#ifndef __ECORE_WIN32_DND_DATA_OBJECT_H__ +#define __ECORE_WIN32_DND_DATA_OBJECT_H__ + + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include + + +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__ */ diff --git a/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp b/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp new file mode 100644 index 0000000000..a3a8bb1865 --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd_drop_source.cpp @@ -0,0 +1,92 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#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 EINA_UNUSED) +{ + 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(); +} diff --git a/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h b/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h new file mode 100644 index 0000000000..9081f46a15 --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd_drop_source.h @@ -0,0 +1,36 @@ +#ifndef __ECORE_WIN32_DND_DROP_SOURCE_H__ +#define __ECORE_WIN32_DND_DROP_SOURCE_H__ + + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include + +#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__ */ diff --git a/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp b/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp new file mode 100644 index 0000000000..2f2da1af65 --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd_drop_target.cpp @@ -0,0 +1,232 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#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 EINA_UNUSED, 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(); +} diff --git a/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h b/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h new file mode 100644 index 0000000000..24c3de3e1a --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd_drop_target.h @@ -0,0 +1,47 @@ +#ifndef __ECORE_WIN32_DND_DROP_TARGET_H__ +#define __ECORE_WIN32_DND_DROP_TARGET_H__ + + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include + +#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__ */ diff --git a/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp b/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp new file mode 100644 index 0000000000..a3858bcdd8 --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp @@ -0,0 +1,157 @@ + +#include + +#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; +} diff --git a/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h b/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h new file mode 100644 index 0000000000..9f17f5684e --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.h @@ -0,0 +1,50 @@ +#ifndef __ECORE_WIN32_DND_ENUMFORMATETC_H__ +#define __ECORE_WIN32_DND_ENUMFORMATETC_H__ + + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include + + +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__ */ diff --git a/src/lib/ecore_win32/ecore_win32_event.c b/src/lib/ecore_win32/ecore_win32_event.c new file mode 100644 index 0000000000..fc285995fc --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_event.c @@ -0,0 +1,1307 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include /* for printf */ + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include + +#include +#include +#include + +#include "Ecore_Win32.h" +#include "ecore_win32_private.h" + + +typedef enum +{ + ECORE_WIN32_KEY_MASK_LSHIFT = 1 << 0, + ECORE_WIN32_KEY_MASK_RSHIFT = 1 << 1, + ECORE_WIN32_KEY_MASK_LCONTROL = 1 << 2, + ECORE_WIN32_KEY_MASK_RCONTROL = 1 << 3, + ECORE_WIN32_KEY_MASK_LMENU = 1 << 4, + ECORE_WIN32_KEY_MASK_RMENU = 1 << 5 +} Ecore_Win32_Key_Mask; + +/***** 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 Ecore_Win32_Key_Mask _ecore_win32_key_mask = 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(Ecore_Win32_Callback_Data *msg, + Eina_Bool is_down, + char **keyname, + char **keysymbol, + char **keycompose, + unsigned int *modifiers); + +static int _ecore_win32_event_char_get(int key, + char **keyname, + char **keysymbol, + char **keycompose, + unsigned int *modifiers); + + +/***** 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 *)calloc(1, sizeof(Ecore_Event_Key)); + if (!e) return; + + if (is_keystroke) + { + if (!_ecore_win32_event_keystroke_get(msg, + EINA_TRUE, + (char **)&e->keyname, + (char **)&e->key, + (char **)&e->string, + &e->modifiers)) + { + free(e); + return; + } + } + else + { + if (!_ecore_win32_event_char_get(LOWORD(msg->window_param), + (char **)&e->keyname, + (char **)&e->key, + (char **)&e->string, + &e->modifiers)) + { + free(e); + return; + } + } + + e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA); + if (!e->window) + { + free(e); + return; + } + e->event_window = e->window; + e->timestamp = msg->timestamp; + + _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) +{ + Ecore_Event_Key *e; + + INF("key released"); + + e = (Ecore_Event_Key *)calloc(1, sizeof(Ecore_Event_Key)); + if (!e) return; + + if (!_ecore_win32_event_keystroke_get(msg, + EINA_FALSE, + (char **)&e->keyname, + (char **)&e->key, + (char **)&e->string, + &e->modifiers)) + { + if (msg->discard_ctrl || + !_ecore_win32_event_char_get(LOWORD(msg->window_param), + (char **)&e->keyname, + (char **)&e->key, + (char **)&e->string, + &e->modifiers)) + { + free(e); + return; + } + } + + e->window = (Ecore_Window)GetWindowLongPtr(msg->window, GWLP_USERDATA); + if (!e->window) + { + free(e); + return; + } + e->event_window = e->window; + e->timestamp = msg->timestamp; + + _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 *)GetWindowLongPtr(msg->window, GWLP_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->event_window = e->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->timestamp; + + _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->event_window = e->window; + e->x = GET_X_LPARAM(msg->data_param); + e->y = GET_Y_LPARAM(msg->data_param); + e->timestamp = msg->timestamp; + + _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->event_window = e->window; + e->buttons = button; + e->x = GET_X_LPARAM(msg->data_param); + e->y = GET_Y_LPARAM(msg->data_param); + e->timestamp = msg->timestamp; + + if (((e->timestamp - _ecore_win32_mouse_down_last_time) <= (unsigned 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) <= (unsigned 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 *)GetWindowLongPtr(msg->window, GWLP_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->event_window = e->window; + e->x = GET_X_LPARAM(msg->data_param); + e->y = GET_Y_LPARAM(msg->data_param); + e->timestamp = msg->timestamp; + + _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->event_window = e->window; + e->buttons = button; + e->x = GET_X_LPARAM(msg->data_param); + e->y = GET_Y_LPARAM(msg->data_param); + e->timestamp = msg->timestamp; + + _ecore_win32_mouse_up_count++; + + if ((_ecore_win32_mouse_up_count >= 2) && + ((e->timestamp - _ecore_win32_mouse_down_last_time) <= (unsigned 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) <= (unsigned 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)GetWindowLongPtr(msg->window, GWLP_USERDATA); + e->event_window = e->window; + e->x = GET_X_LPARAM(msg->data_param); + e->y = GET_Y_LPARAM(msg->data_param); + e->timestamp = msg->timestamp; + + 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)GetWindowLongPtr(msg->window, GWLP_USERDATA); + e->event_window = e->window; + e->x = msg->x; + e->y = msg->y; + e->timestamp = msg->timestamp; + + _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + e->x = msg->x; + e->y = msg->y; + e->timestamp = msg->timestamp ; + + _ecore_win32_event_last_time = e->timestamp; + + 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)GetWindowLongPtr(msg->window, GWLP_USERDATA); + e->event_window = e->window; + e->x = msg->x; + e->y = msg->y; + e->timestamp = msg->timestamp; + + _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + e->x = msg->x; + e->y = msg->y; + e->timestamp = msg->timestamp; + + _ecore_win32_event_last_time = e->timestamp; + + 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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + + e->timestamp = _ecore_win32_event_last_time; + _ecore_win32_event_last_time = e->timestamp; + + 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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + + e->timestamp = _ecore_win32_event_last_time; + _ecore_win32_event_last_time = e->timestamp; + + 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 *)GetWindowLongPtr(msg->window, GWLP_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->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + + e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + + e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + + e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + + e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + e->abovewin = (void *)GetWindowLongPtr(window_pos->hwndInsertAfter, GWLP_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->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + e->width = rect.right - rect.left; + e->height = rect.bottom - rect.top; + e->timestamp = _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 *)GetWindowLongPtr(msg->window, GWLP_USERDATA); + e->timestamp = _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 EINA_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 EINA_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(Ecore_Win32_Callback_Data *msg, + Eina_Bool is_down, + char **keyname, + char **keysymbol, + char **keycompose, + unsigned int *modifiers) +{ + WCHAR buf[3]; + char delete_string[2] = { 0x7f, 0 }; + char *kn = NULL; + char *ks = NULL; + char *kc = NULL; + int key; + int is_extended; + int previous_key_state; + + key = msg->window_param; + is_extended = msg->data_param & 0x01000000; + previous_key_state = msg->data_param & 0x40000000; + + *keyname = NULL; + *keysymbol = NULL; + *keycompose = NULL; + + switch (key) + { + /* Keystroke */ + case VK_PRIOR: + if (is_extended) + { + kn = "Prior"; + ks = "Prior"; + kc = NULL; + } + else + { + kn = "KP_Prior"; + ks = "KP_9"; + kc = "KP_Prior"; + } + break; + case VK_NEXT: + if (is_extended) + { + kn = "Next"; + ks = "Next"; + kc = NULL; + } + else + { + kn = "KP_Next"; + ks = "KP_3"; + kc = "KP_Next"; + } + break; + case VK_END: + if (is_extended) + { + kn = "End"; + ks = "End"; + kc = NULL; + } + else + { + kn = "KP_End"; + ks = "KP_1"; + kc = "KP_End"; + } + break; + case VK_HOME: + if (is_extended) + { + kn = "Home"; + ks = "Home"; + kc = NULL; + } + else + { + kn = "KP_Home"; + ks = "KP_7"; + kc = "KP_Home"; + } + break; + case VK_LEFT: + if (is_extended) + { + kn = "Left"; + ks = "Left"; + kc = NULL; + } + else + { + kn = "KP_Left"; + ks = "KP_4"; + kc = "KP_Left"; + } + break; + case VK_UP: + if (is_extended) + { + kn = "Up"; + ks = "Up"; + kc = NULL; + } + else + { + kn = "KP_Up"; + ks = "KP_8"; + kc = "KP_Up"; + } + break; + case VK_RIGHT: + if (is_extended) + { + kn = "Right"; + ks = "Right"; + kc = NULL; + } + else + { + kn = "KP_Right"; + ks = "KP_6"; + kc = "KP_Right"; + } + break; + case VK_DOWN: + if (is_extended) + { + kn = "Down"; + ks = "Down"; + kc = NULL; + } + else + { + kn = "KP_Down"; + ks = "KP_2"; + kc = "KP_Down"; + } + break; + case VK_INSERT: + if (is_extended) + { + kn = "Insert"; + ks = "Insert"; + kc = NULL; + } + else + { + kn = "KP_Insert"; + ks = "KP_0"; + kc = "KP_Insert"; + } + break; + case VK_DELETE: + if (is_extended) + { + kn = "Delete"; + ks = "Delete"; + kc = delete_string; + } + else + { + kn = "KP_Delete"; + ks = "KP_Decimal"; + kc = "KP_Delete"; + } + break; + case VK_SHIFT: + { + SHORT res; + + if (is_down) + { + if (previous_key_state) return 0; + res = GetKeyState(VK_LSHIFT); + if (res & 0x8000) + { + _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LSHIFT; + kn = "Shift_L"; + ks = "Shift_L"; + kc = ""; + } + res = GetKeyState(VK_RSHIFT); + if (res & 0x8000) + { + _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RSHIFT; + kn = "Shift_R"; + ks = "Shift_R"; + kc = ""; + } + *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT; + } + else /* is_up */ + { + res = GetKeyState(VK_LSHIFT); + if (!(res & 0x8000) && + (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LSHIFT)) + { + kn = "Shift_L"; + ks = "Shift_L"; + kc = ""; + _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LSHIFT; + } + res = GetKeyState(VK_RSHIFT); + if (!(res & 0x8000) && + (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RSHIFT)) + { + kn = "Shift_R"; + ks = "Shift_R"; + kc = ""; + _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RSHIFT; + } + *modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + } + break; + } + case VK_CONTROL: + { + SHORT res; + + if (msg->discard_ctrl) + return 0; + + if (is_down) + { + if (previous_key_state) return 0; + res = GetKeyState(VK_LCONTROL); + if (res & 0x8000) + { + _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LCONTROL; + kn = "Control_L"; + ks = "Control_L"; + kc = ""; + break; + } + res = GetKeyState(VK_RCONTROL); + if (res & 0x8000) + { + _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RCONTROL; + kn = "Control_R"; + ks = "Control_R"; + kc = ""; + break; + } + *modifiers |= ECORE_EVENT_MODIFIER_CTRL; + } + else /* is_up */ + { + res = GetKeyState(VK_LCONTROL); + if (!(res & 0x8000) && + (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LCONTROL)) + { + kn = "Control_L"; + ks = "Control_L"; + kc = ""; + _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LCONTROL; + break; + } + res = GetKeyState(VK_RCONTROL); + if (!(res & 0x8000) && + (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RCONTROL)) + { + kn = "Control_R"; + ks = "Control_R"; + kc = ""; + _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RCONTROL; + break; + } + *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL; + } + break; + } + case VK_MENU: + { + SHORT res; + + if (is_down) + { + if (previous_key_state) return 0; + res = GetKeyState(VK_LMENU); + if (res & 0x8000) + { + _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_LMENU; + kn = "Alt_L"; + ks = "Alt_L"; + kc = ""; + } + res = GetKeyState(VK_RMENU); + if (res & 0x8000) + { + _ecore_win32_key_mask |= ECORE_WIN32_KEY_MASK_RMENU; + kn = "Alt_R"; + ks = "Alt_R"; + kc = ""; + } + *modifiers |= ECORE_EVENT_MODIFIER_ALT; + } + else /* is_up */ + { + res = GetKeyState(VK_LMENU); + if (!(res & 0x8000) && + (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_LMENU)) + { + kn = "Alt_L"; + ks = "Alt_L"; + kc = ""; + _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_LMENU; + } + res = GetKeyState(VK_RMENU); + if (!(res & 0x8000) && + (_ecore_win32_key_mask & ECORE_WIN32_KEY_MASK_RMENU)) + { + kn = "Alt_R"; + ks = "Alt_R"; + kc = ""; + _ecore_win32_key_mask &= ~ECORE_WIN32_KEY_MASK_RMENU; + } + *modifiers &= ~ECORE_EVENT_MODIFIER_ALT; + } + break; + } + case VK_LWIN: + { + if (is_down) + { + if (previous_key_state) return 0; + kn = "Super_L"; + ks = "Super_L"; + kc = ""; + *modifiers |= ECORE_EVENT_MODIFIER_WIN; + } + else /* is_up */ + { + kn = "Super_L"; + ks = "Super_L"; + kc = ""; + *modifiers &= ~ECORE_EVENT_MODIFIER_WIN; + } + break; + } + case VK_RWIN: + { + if (is_down) + { + if (previous_key_state) return 0; + kn = "Super_R"; + ks = "Super_R"; + kc = ""; + *modifiers |= ECORE_EVENT_MODIFIER_WIN; + } + else /* is_up */ + { + kn = "Super_R"; + ks = "Super_R"; + kc = ""; + *modifiers &= ~ECORE_EVENT_MODIFIER_WIN; + } + 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 */ + BYTE kbd_state[256]; + int res; + + if (is_down) + return 0; + + if (!GetKeyboardState(kbd_state)) + return 0; + + res = ToUnicode(msg->window_param, + MapVirtualKey(msg->window_param, 2), + kbd_state, buf, 3, 0); + if (res == 1) + { + /* FIXME: might be troublesome for non european languages */ + /* in that case, UNICODE should be used, I guess */ + buf[1] = '\0'; + kn = (char *)buf; + ks = (char *)buf; + kc = (char *)buf; + + res = GetAsyncKeyState(VK_SHIFT); + if (res & 0x8000) + *modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + else + *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT; + + res = GetKeyState(VK_CONTROL); + if (res & 0x8000) + *modifiers |= ECORE_EVENT_MODIFIER_CTRL; + else + *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL; + + res = GetKeyState(VK_MENU); + if (res & 0x8000) + *modifiers |= ECORE_EVENT_MODIFIER_ALT; + else + *modifiers &= ~ECORE_EVENT_MODIFIER_ALT; + + break; + } + return 0; + } + } + + *keyname = strdup(kn); + if (!*keyname) return 0; + *keysymbol = strdup(ks); + if (!*keysymbol) + { + free(*keyname); + *keyname = NULL; + return 0; + } + if (!kc) + *keycompose = NULL; + else + { + *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, + unsigned int *modifiers) +{ + char *kn = NULL; + char *ks = NULL; + char *kc = NULL; + char buf[2]; + SHORT res; + + *keyname = NULL; + *keysymbol = NULL; + *keycompose = NULL; + + /* check control charaters such as ^a(key:1), ^z(key:26) */ + if ((key > 0) && (key < 27) && + ((GetKeyState(VK_CONTROL) & 0x8000) || + (GetKeyState(VK_CONTROL) & 0x8000))) key += 96; + + switch (key) + { + case VK_PROCESSKEY: + break; + case VK_BACK: + kn = "BackSpace"; + ks = "BackSpace"; + kc = "\b"; + break; + case VK_TAB: + kn = "Tab"; + ks = "Tab"; + kc = "\t"; + break; + case 0x0a: + /* Line feed (Shift + Enter) */ + kn = "LineFeed"; + ks = "LineFeed"; + kc = "LineFeed"; + break; + case VK_RETURN: + kn = "Return"; + ks = "Return"; + kc = "\n"; + break; + case VK_ESCAPE: + kn = "Escape"; + ks = "Escape"; + kc = "\e"; + break; + case VK_SPACE: + kn = "space"; + ks = "space"; + kc = " "; + break; + default: + /* displayable characters */ + buf[0] = key; + buf[1] = '\0'; + kn = buf; + ks = buf; + kc = buf; + 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; + } + + res = GetAsyncKeyState(VK_SHIFT); + if (res & 0x8000) + *modifiers |= ECORE_EVENT_MODIFIER_SHIFT; + else + *modifiers &= ~ECORE_EVENT_MODIFIER_SHIFT; + + res = GetKeyState(VK_CONTROL); + if (res & 0x8000) + *modifiers |= ECORE_EVENT_MODIFIER_CTRL; + else + *modifiers &= ~ECORE_EVENT_MODIFIER_CTRL; + + res = GetKeyState(VK_MENU); + if (res & 0x8000) + *modifiers |= ECORE_EVENT_MODIFIER_ALT; + else + *modifiers &= ~ECORE_EVENT_MODIFIER_ALT; + + return 1; +} diff --git a/src/lib/ecore_win32/ecore_win32_private.h b/src/lib/ecore_win32/ecore_win32_private.h new file mode 100644 index 0000000000..e3e44264cc --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_private.h @@ -0,0 +1,170 @@ +#ifndef __ECORE_WIN32_PRIVATE_H__ +#define __ECORE_WIN32_PRIVATE_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef MIN +# undef MIN +#endif +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#ifdef MAX +# undef MAX +#endif +#define MAX(a,b) (((a) < (b)) ? (b) : (a)) + +/* 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__) + +#ifdef WRN +# undef WRN +#endif +#define WRN(...) EINA_LOG_DOM_WARN(_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; + unsigned long timestamp; + int x; + int y; + Eina_Bool discard_ctrl; +}; + +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; + int base_width; + 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; + + struct { + DWORD type; + int x; + int y; + int w; + int h; + int px; + int py; + unsigned int dragging : 1; + } drag; + + void *dnd_drop_target; +}; + + +extern HINSTANCE _ecore_win32_instance; +extern double _ecore_win32_double_click_time; +extern unsigned 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); +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__ */ diff --git a/src/lib/ecore_win32/ecore_win32_window.c b/src/lib/ecore_win32/ecore_win32_window.c new file mode 100644 index 0000000000..36f8a86047 --- /dev/null +++ b/src/lib/ecore_win32/ecore_win32_window.c @@ -0,0 +1,1418 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include /* for printf */ + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + +#include + +#include "Ecore_Win32.h" +#include "ecore_win32_private.h" + +/*============================================================================* + * Local * + *============================================================================*/ + +/** + * @cond LOCAL + */ + + +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) +{ + RECT rect; + Ecore_Win32_Window *w; + int minimal_width; + int minimal_height; + + w = (Ecore_Win32_Window *)calloc(1, sizeof(Ecore_Win32_Window)); + if (!w) + { + ERR("malloc() failed"); + return NULL; + } + + rect.left = 0; + rect.top = 0; + rect.right = width; + rect.bottom = height; + if (!AdjustWindowRectEx(&rect, style, FALSE, 0)) + { + 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 ? parent->window : NULL, + NULL, _ecore_win32_instance, NULL); + if (!w->window) + { + ERR("CreateWindowEx() failed"); + free(w); + return NULL; + } + + SetLastError(0); + if (!SetWindowLongPtr(w->window, GWLP_USERDATA, (LONG_PTR)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; +} + +/** + * @endcond + */ + + +/*============================================================================* + * Global * + *============================================================================*/ + +/*============================================================================* + * API * + *============================================================================*/ + +/** + * @addtogroup Ecore_Win32_Group Ecore_Win32 library + * + * @{ + */ + +/** + * @brief Creates a new window. + * + * @param parent The parent window. + * @param x The x coordinate of the top-left corner of the window. + * @param y The y coordinate of the top-left corner of the window. + * @param width The width of the window. + * @param height The height of hte window. + * @return A newly allocated window. + * + * This function creates a new window which parent is @p parent. @p width and + * @p height are the size of the window content (the client part), + * without the border and title bar. @p x and @p y are the system + * coordinates of the top left cerner of the window (that is, of the + * title bar). This function returns a newly created window on + * success, and @c NULL on failure. + */ +EAPI 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); +} + +/** + * @brief Creates a new borderless window. + * + * @param parent The parent window. + * @param x The x coordinate of the top-left corner of the window. + * @param y The y coordinate of the top-left corner of the window. + * @param width The width of the window. + * @param height The height of hte window. + * @return A newly allocated window. + * + * This function is the same than ecore_win32_window_override_new() + * but the returned window is borderless. + */ +EAPI 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 & ~(WS_CAPTION | WS_THICKFRAME)); +} + +/** + * @brief Free the given window. + * + * @param window The window to free. + * + * This function frees @p window. If @p window is @c NULL, this + * function does nothing. + */ +EAPI void +ecore_win32_window_free(Ecore_Win32_Window *window) +{ + if (!window) return; + + INF("destroying window"); + + if (window->shape.mask) + free(window->shape.mask); + + DestroyWindow(window->window); + free(window); +} + +/** + * @brief Return the window HANDLE associated to the given window. + * + * @param window The window to retrieve the HANDLE from. + * + * This function returns the window HANDLE associated to @p window. If + * @p window is @c NULL, this function returns @c NULL. + * + * @note The returned value is of type HWND. + */ +EAPI void * +ecore_win32_window_hwnd_get(Ecore_Win32_Window *window) +{ + if (!window) return NULL; + + return 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((Ecore_Win32_Window *)window->window, w, x, y, width, height, ???); +} +*/ + +/** + * @brief Move the given window to a given position. + * + * @param window The window to move. + * @param x The x coordinate of the destination position. + * @param y The y coordinate of the destination position. + * + * This function move @p window to the new position of coordinates @p x + * and @p y. If @p window is @c NULL, or if it is fullscreen, or on + * error, this function does nothing. + */ +EAPI void +ecore_win32_window_move(Ecore_Win32_Window *window, + int x, + int y) +{ + RECT rect; + + /* FIXME: on fullscreen, should not move it */ + if (!window) return; + + INF("moving window (%dx%d)", x, y); + + if (!GetWindowRect(window->window, &rect)) + { + ERR("GetWindowRect() failed"); + return; + } + + if (!MoveWindow(window->window, x, y, + rect.right - rect.left, + rect.bottom - rect.top, + TRUE)) + { + ERR("MoveWindow() failed"); + } +} + +/** + * @brief Resize the given window to a given size. + * + * @param window The window to resize. + * @param width The new width. + * @param height The new height. + * + * This function resize @p window to the new @p width and @p height. + * If @p window is @c NULL, or if it is fullscreen, or on error, this + * function does nothing. + */ +EAPI void +ecore_win32_window_resize(Ecore_Win32_Window *window, + int width, + int height) +{ + RECT rect; + DWORD style; + int x; + int y; + int minimal_width; + int minimal_height; + + /* FIXME: on fullscreen, should not resize it */ + if (!window) return; + + INF("resizing window (%dx%d)", width, height); + + minimal_width = MAX(GetSystemMetrics(SM_CXMIN), (int)window->min_width); + minimal_height = MAX(GetSystemMetrics(SM_CYMIN), (int)window->min_height); + + if (!GetWindowRect(window->window, &rect)) + { + ERR("GetWindowRect() failed"); + return; + } + + x = rect.left; + y = rect.top; + rect.left = 0; + rect.top = 0; + if (width < minimal_width) width = minimal_width; + if (width > (int)window->max_width) width = window->max_width; + if (height < minimal_height) height = minimal_height; + if (height > (int)window->max_height) height = window->max_height; + rect.right = width; + rect.bottom = height; + if (!(style = GetWindowLong(window->window, GWL_STYLE))) + { + ERR("GetWindowLong() failed"); + return; + } + if (!AdjustWindowRect(&rect, style, FALSE)) + { + ERR("AdjustWindowRect() failed"); + return; + } + + if (!MoveWindow(window->window, x, y, + rect.right - rect.left, + rect.bottom - rect.top, + TRUE)) + { + ERR("MoveWindow() failed"); + } +} + +/** + * @brief Move and resize the given window to a given position and size. + * + * @param window The window to move and resize. + * @param x The x coordinate of the destination position. + * @param y The x coordinate of the destination position. + * @param width The new width. + * @param height The new height. + * + * This function resize @p window to the new position of coordinates @p x + * and @p y and the new @p width and @p height. If @p window is @c NULL, + * or if it is fullscreen, or on error, this function does nothing. + */ +EAPI void +ecore_win32_window_move_resize(Ecore_Win32_Window *window, + int x, + int y, + int width, + int height) +{ + RECT rect; + DWORD style; + int minimal_width; + int minimal_height; + + /* FIXME: on fullscreen, should not move/resize it */ + if (!window) return; + + INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height); + + minimal_width = MAX(GetSystemMetrics(SM_CXMIN), (int)window->min_width); + minimal_height = MAX(GetSystemMetrics(SM_CYMIN), (int)window->min_height); + + rect.left = 0; + rect.top = 0; + if (width < minimal_width) width = minimal_width; + if (width > (int)window->max_width) width = window->max_width; + if (height < minimal_height) height = minimal_height; + if (height > (int)window->max_height) height = window->max_height; + rect.right = width; + rect.bottom = height; + if (!(style = GetWindowLong(window->window, GWL_STYLE))) + { + ERR("GetWindowLong() failed"); + return; + } + if (!AdjustWindowRect(&rect, style, FALSE)) + { + ERR("AdjustWindowRect() failed"); + return; + } + + if (!MoveWindow(window->window, x, y, + rect.right - rect.left, + rect.bottom - rect.top, + TRUE)) + { + ERR("MoveWindow() failed"); + } +} + +/** + * @brief Get the geometry of the given window. + * + * @param window The window to retrieve the geometry from. + * @param x The x coordinate of the position. + * @param y The x coordinate of the position. + * @param width The width. + * @param height The height. + * + * This function retrieves the position and size of @p window. @p x, + * @p y, @p width and @p height can be buffers that will be filled with + * the corresponding values. If one of them is @c NULL, nothing will + * be done for that parameter. If @p window is @c NULL, and if the + * buffers are not @c NULL, they will be filled with respectively 0, + * 0, the size of the screen and the height of the screen. + */ +EAPI 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(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(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; +} + +/** + * @brief Get the size of the given window. + * + * @param window The window to retrieve the size from. + * @param width The width. + * @param height The height. + * + * This function retrieves the size of @p window. @p width and + * @p height can be buffers that will be filled with the corresponding + * values. If one of them is @c NULL, nothing will be done for that + * parameter. If @p window is @c NULL, and if the buffers are not + * @c NULL, they will be filled with respectively the size of the screen + * and the height of the screen. + */ +EAPI 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(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; +} + +/** + * @brief Set the minimum size of the given window. + * + * @param window The window. + * @param min_width The minimal width. + * @param min_height The minimal height. + * + * This function sets the minimum size of @p window to @p min_width + * and *p min_height. If @p window is @c NULL, this functions does + * nothing. + */ +EAPI void +ecore_win32_window_size_min_set(Ecore_Win32_Window *window, + unsigned int min_width, + unsigned int min_height) +{ + if (!window) return; + + printf ("ecore_win32_window_size_min_set : %p %d %d\n", window, min_width, min_height); + window->min_width = min_width; + window->min_height = min_height; +} + +/** + * @brief Get the minimum size of the given window. + * + * @param window The window. + * @param min_width The minimal width. + * @param min_height The minimal height. + * + * This function fills the minimum size of @p window in the buffers + * @p min_width and *p min_height. They both can be @c NULL. If + * @p window is @c NULL, this functions does nothing. + */ +EAPI void +ecore_win32_window_size_min_get(Ecore_Win32_Window *window, + unsigned int *min_width, + unsigned int *min_height) +{ + if (!window) return; + + printf ("ecore_win32_window_size_min_get : %p %d %d\n", window, window->min_width, window->min_height); + if (min_width) *min_width = window->min_width; + if (min_height) *min_height = window->min_height; +} + +/** + * @brief Set the maximum size of the given window. + * + * @param window The window. + * @param max_width The maximal width. + * @param max_height The maximal height. + * + * This function sets the maximum size of @p window to @p max_width + * and *p max_height. If @p window is @c NULL, this functions does + * nothing. + */ +EAPI void +ecore_win32_window_size_max_set(Ecore_Win32_Window *window, + unsigned int max_width, + unsigned int max_height) +{ + if (!window) return; + + printf ("ecore_win32_window_size_max_set : %p %d %d\n", window, max_width, max_height); + window->max_width = max_width; + window->max_height = max_height; +} + +/** + * @brief Get the maximum size of the given window. + * + * @param window The window. + * @param max_width The maximal width. + * @param max_height The maximal height. + * + * This function fills the maximum size of @p window in the buffers + * @p max_width and *p max_height. They both can be @c NULL. If + * @p window is @c NULL, this functions does nothing. + */ +EAPI void +ecore_win32_window_size_max_get(Ecore_Win32_Window *window, + unsigned int *max_width, + unsigned int *max_height) +{ + if (!window) return; + + printf ("ecore_win32_window_size_max_get : %p %d %d\n", window, window->max_width, window->max_height); + if (max_width) *max_width = window->max_width; + if (max_height) *max_height = window->max_height; +} + +/** + * @brief Set the base size of the given window. + * + * @param window The window. + * @param base_width The base width. + * @param base_height The base height. + * + * This function sets the base size of @p window to @p base_width + * and *p base_height. If @p window is @c NULL, this functions does + * nothing. + */ +EAPI void +ecore_win32_window_size_base_set(Ecore_Win32_Window *window, + unsigned int base_width, + unsigned int base_height) +{ + printf ("ecore_win32_window_size_base_set : %p %d %d\n", window, base_width, base_height); + if (!window) return; + + window->base_width = base_width; + window->base_height = base_height; +} + +/** + * @brief Get the base size of the given window. + * + * @param window The window. + * @param base_width The base width. + * @param base_height The bas height. + * + * This function fills the base size of @p window in the buffers + * @p base_width and *p base_height. They both can be @c NULL. If + * @p window is @c NULL, this functions does nothing. + */ +EAPI void +ecore_win32_window_size_base_get(Ecore_Win32_Window *window, + unsigned int *base_width, + unsigned int *base_height) +{ + if (!window) return; + + printf ("ecore_win32_window_size_base_get : %p %d %d\n", window, window->base_width, window->base_height); + if (base_width) *base_width = window->base_width; + if (base_height) *base_height = window->base_height; +} + +/** + * @brief Set the step size of the given window. + * + * @param window The window. + * @param step_width The step width. + * @param step_height The step height. + * + * This function sets the step size of @p window to @p step_width + * and *p step_height. If @p window is @c NULL, this functions does + * nothing. + */ +EAPI void +ecore_win32_window_size_step_set(Ecore_Win32_Window *window, + unsigned int step_width, + unsigned int step_height) +{ + printf ("ecore_win32_window_size_step_set : %p %d %d\n", window, step_width, step_height); + if (!window) return; + + window->step_width = step_width; + window->step_height = step_height; +} + +/** + * @brief Get the step size of the given window. + * + * @param window The window. + * @param step_width The step width. + * @param step_height The bas height. + * + * This function fills the step size of @p window in the buffers + * @p step_width and *p step_height. They both can be @c NULL. If + * @p window is @c NULL, this functions does nothing. + */ +EAPI void +ecore_win32_window_size_step_get(Ecore_Win32_Window *window, + unsigned int *step_width, + unsigned int *step_height) +{ + if (!window) return; + + printf ("ecore_win32_window_size_step_get : %p %d %d\n", window, window->step_width, window->step_height); + if (step_width) *step_width = window->step_width; + if (step_height) *step_height = window->step_height; +} + +/** + * @brief Show the given window. + * + * @param window The window to show. + * + * This function shows @p window. If @p window is @c NULL, or on + * error, this function does nothing. + */ +EAPI void +ecore_win32_window_show(Ecore_Win32_Window *window) +{ + if (!window) return; + + INF("showing window"); + + ShowWindow(window->window, SW_SHOWNORMAL); + if (!UpdateWindow(window->window)) + { + ERR("UpdateWindow() failed"); + } +} + +/* FIXME: seems to block the taskbar */ +/** + * @brief Hide the given window. + * + * @param window The window to show. + * + * This function hides @p window. If @p window is @c NULL, or on + * error, this function does nothing. + */ +EAPI void +ecore_win32_window_hide(Ecore_Win32_Window *window) +{ + if (!window) return; + + INF("hiding window"); + + ShowWindow(window->window, SW_HIDE); +} + +/** + * @brief Place the given window at the top of the Z order. + * + * @param window The window to place at the top. + * + * This function places @p window at the top of the Z order. If + * @p window is @c NULL, this function does nothing. + */ +EAPI void +ecore_win32_window_raise(Ecore_Win32_Window *window) +{ + if (!window) return; + + INF("raising window"); + + if (!SetWindowPos(window->window, + HWND_TOP, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE)) + { + ERR("SetWindowPos() failed"); + } +} + +/** + * @brief Place the given window at the bottom of the Z order. + * + * @param window The window to place at the bottom. + * + * This function places @p window at the bottom of the Z order. If + * @p window is @c NULL, this function does nothing. + */ +EAPI void +ecore_win32_window_lower(Ecore_Win32_Window *window) +{ + if (!window) return; + + INF("lowering window"); + + if (!SetWindowPos(window->window, + HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE)) + { + ERR("SetWindowPos() failed"); + } +} + +/** + * @brief Set the title of the given window. + * + * @param window The window to set the title. + * @param title The new title. + * + * This function sets the title of @p window to @p title. If @p window + * is @c NULL, or if @p title is @c NULL or empty, or on error, this + * function does nothing. + */ +EAPI 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(window->window, title)) + { + ERR("SetWindowText() failed"); + } +} + +/** + * @brief Set the focus to the given window. + * + * @param window The window to give focus to. + * + * This function gives the focus to @p window. If @p window is + * @c NULL, this function does nothing. + */ +EAPI void +ecore_win32_window_focus(Ecore_Win32_Window *window) +{ + if (!window) return; + + INF("focusing window"); + + if (!SetFocus(window->window)) + { + ERR("SetFocus() failed"); + } +} + +/** + * @brief Get the current focused window. + * + * @return The window that has focus. + * + * This function returns the window that has focus. If the calling + * thread's message queue does not have an associated window with the + * keyboard focus, the return value is @c NULL. + * + * @note Even if the returned value is @c NULL, another thread's queue + * may be associated with a window that has the keyboard focus. + * + * @note The returned value is of type HWND. + */ +EAPI void * +ecore_win32_window_focus_get(void) +{ + HWND focused; + + INF("getting focused window"); + + focused = GetFocus(); + if (!focused) + { + ERR("GetFocus() failed"); + return NULL; + } + + return focused; +} + +/** + * @brief Iconify or restore the given window. + * + * @param window The window. + * @param on @c EINA_TRUE to iconify the window, @c EINA_FALSE to restore it. + * + * This function iconify or restore @p window. If @p on is set to @c EINA_TRUE, + * the window will be iconified, if it is set to @c EINA_FALSE, it will be + * restored. If @p window is @c NULL or if the state does not change (like + * iconifying the window while it is already iconified), this function does + * nothing. + */ +EAPI void +ecore_win32_window_iconified_set(Ecore_Win32_Window *window, + Eina_Bool on) +{ + if (!window) return; + + if (((window->iconified) && (on)) || + ((!window->iconified) && (!on))) + return; + + INF("iconifying window: %s", on ? "yes" : "no"); + + ShowWindow(window->window, on ? SW_MINIMIZE : SW_RESTORE); + window->iconified = on; +} + +/** + * @brief Remove or restore the border of the given window. + * + * @param window The window. + * @param on @c EINA_TRUE to remove the border, @c EINA_FALSE to restore it. + * + * This function remove or restore the border of @p window. If @p on is set to + * @c EINA_TRUE, the window will have no border, if it is set to @c EINA_FALSE, + * it will have a border. If @p window is @c NULL or if the state does not + * change (like setting to borderless while the window has no border), this + * function does nothing. + */ +EAPI void +ecore_win32_window_borderless_set(Ecore_Win32_Window *window, + Eina_Bool on) +{ + RECT rect; + DWORD style; + + if (!window) return; + + if (((window->borderless) && (on)) || + ((!window->borderless) && (!on))) + return; + + INF("setting window without border: %s", on ? "yes" : "no"); + + style = GetWindowLong(window->window, GWL_STYLE); + if (on) + { + if (!GetClientRect(window->window, &rect)) + { + ERR("GetClientRect() failed"); + return; + } + SetLastError(0); + if (!SetWindowLongPtr(window->window, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME)) && + (GetLastError() != 0)) + { + ERR("SetWindowLongPtr() failed"); + return; + } + } + else + { + if (!GetWindowRect(window->window, &rect)) + { + ERR("GetWindowRect() failed"); + return; + } + style |= WS_CAPTION | WS_THICKFRAME; + if (!AdjustWindowRect (&rect, style, FALSE)) + { + ERR("AdjustWindowRect() failed"); + return; + } + SetLastError(0); + if (!SetWindowLongPtr(window->window, GWL_STYLE, style) && + (GetLastError() != 0)) + { + ERR("SetWindowLongPtr() failed"); + return; + } + } + if (!SetWindowPos(window->window, HWND_TOPMOST, + rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_NOMOVE | SWP_FRAMECHANGED)) + { + ERR("SetWindowPos() failed"); + return; + } + + window->borderless = on; +} + +/** + * @brief Set the given window to fullscreen. + * + * @param window The window. + * @param on @c EINA_TRUE for fullscreen mode, @c EINA_FALSE for windowed mode. + * + * This function set @p window to fullscreen or windowed mode. If @p on is set + * to @c EINA_TRUE, the window will be fullscreen, if it is set to + * @c EINA_FALSE, it will be windowed. If @p window is @c NULL or if the state + * does not change (like setting to fullscreen while the window is already + * fullscreen), this function does nothing. + */ +EAPI void +ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window, + Eina_Bool on) +{ + if (!window) return; + + if (((window->fullscreen) && (on)) || + ((!window->fullscreen) && (!on))) + return; + + INF("setting fullscreen: %s", on ? "yes" : "no"); + + window->fullscreen = !!on; + + if (on) + { + DWORD style; + + if (!GetWindowRect(window->window, &window->rect)) + { + ERR("GetWindowRect() failed"); + return; + } + if (!(window->style = GetWindowLong(window->window, GWL_STYLE))) + { + ERR("GetWindowLong() failed"); + return; + } + style = window->style & ~WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX; + style |= WS_VISIBLE | WS_POPUP; + SetLastError(0); + if (!SetWindowLongPtr(window->window, GWL_STYLE, style) && + (GetLastError() != 0)) + { + ERR("SetWindowLongPtr() failed"); + return; + } + SetLastError(0); + if (!SetWindowLongPtr(window->window, GWL_EXSTYLE, WS_EX_TOPMOST) && + (GetLastError() != 0)) + { + ERR("SetWindowLongPtr() failed"); + return; + } + if (!SetWindowPos(window->window, HWND_TOPMOST, 0, 0, + GetSystemMetrics (SM_CXSCREEN), + GetSystemMetrics (SM_CYSCREEN), + SWP_NOCOPYBITS | SWP_SHOWWINDOW)) + { + ERR("SetWindowPos() failed"); + return; + } + } + else + { + SetLastError(0); + if (!SetWindowLongPtr(window->window, GWL_STYLE, window->style) && + (GetLastError() != 0)) + { + ERR("SetWindowLongPtr() failed"); + return; + } + SetLastError(0); + if (!SetWindowLongPtr(window->window, GWL_EXSTYLE, 0) && + (GetLastError() != 0)) + { + ERR("SetWindowLongPtr() failed"); + return; + } + if (!SetWindowPos(window->window, HWND_NOTOPMOST, + window->rect.left, + window->rect.top, + window->rect.right - window->rect.left, + window->rect.bottom - window->rect.top, + SWP_NOCOPYBITS | SWP_SHOWWINDOW)) + { + ERR("SetWindowPos() failed"); + return; + } + } +} + +/** + * @brief Set the given cursor to the given window. + * + * @param window The window to modify the cursor. + * @param cursor The new cursor. + * + * This function sets @p cursor to @p window. @p cursor must have been + * obtained by ecore_win32_cursor_new() or + * ecore_win32_cursor_shaped_new(). If @p window or @p cursor is + * @c NULL, the function does nothing. + */ +EAPI void +ecore_win32_window_cursor_set(Ecore_Win32_Window *window, + Ecore_Win32_Cursor *cursor) +{ + INF("setting cursor"); + + if (!window || !cursor) + return; + + if (!SetClassLongPtr(window->window, + GCLP_HCURSOR, (LONG_PTR)cursor)) + { + ERR("SetClassLong() failed"); + } +} + +/** + * @brief Set the state of the given window. + * + * @param window The window to modify the state. + * @param state An array of the new states. + * @param num The number of states in the array. + * + * This function set the state of @p window. @p state is an array of + * states of size @p num. If @p window or @p state are @c NULL, or if + * @p num is less or equal than 0, the function does nothing. + */ +EAPI 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 <= 0)) + return; + + INF("setting cursor state"); + + for (i = 0; i < num; i++) + { + switch (state[i]) + { + case ECORE_WIN32_WINDOW_STATE_ICONIFIED: + window->state.iconified = 1; + break; + case ECORE_WIN32_WINDOW_STATE_MODAL: + window->state.modal = 1; + break; + case ECORE_WIN32_WINDOW_STATE_STICKY: + window->state.sticky = 1; + break; + case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT: + window->state.maximized_vert = 1; + break; + case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ: + window->state.maximized_horz = 1; + break; + case ECORE_WIN32_WINDOW_STATE_MAXIMIZED: + window->state.maximized_horz = 1; + window->state.maximized_vert = 1; + break; + case ECORE_WIN32_WINDOW_STATE_SHADED: + window->state.shaded = 1; + break; + case ECORE_WIN32_WINDOW_STATE_HIDDEN: + window->state.hidden = 1; + break; + case ECORE_WIN32_WINDOW_STATE_FULLSCREEN: + window->state.fullscreen = 1; + break; + case ECORE_WIN32_WINDOW_STATE_ABOVE: + window->state.above = 1; + break; + case ECORE_WIN32_WINDOW_STATE_BELOW: + window->state.below = 1; + break; + case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION: + window->state.demands_attention = 1; + break; + case ECORE_WIN32_WINDOW_STATE_UNKNOWN: + /* nothing to be done */ + break; + } + } +} + +/** + * @brief Apply the modification of the state to the given window. + * + * @param window The window. + * @param state The state to apply changes. + * @param set The value of the state change. + * + * This function applies the modification of the state @p state of + * @p window. @p set is used only for + * #ECORE_WIN32_WINDOW_STATE_ICONIFIED and + * #ECORE_WIN32_WINDOW_STATE_FULLSCREEN. If @p window is @c NULL, the + * function does nothing. + */ +EAPI void +ecore_win32_window_state_request_send(Ecore_Win32_Window *window, + Ecore_Win32_Window_State state, + unsigned int set) +{ + if (!window) return; + + INF("sending cursor state"); + + switch (state) + { + case ECORE_WIN32_WINDOW_STATE_ICONIFIED: + if (window->state.iconified) + ecore_win32_window_iconified_set(window, set); + break; + case ECORE_WIN32_WINDOW_STATE_MODAL: + window->state.modal = 1; + break; + case ECORE_WIN32_WINDOW_STATE_STICKY: + window->state.sticky = 1; + break; + case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT: + if (window->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(window->window, &rect)) + { + ERR("GetClientRect() failed"); + break; + } + + if (!MoveWindow(window->window, rect.left, y, + rect.right - rect.left, + height, + TRUE)) + { + ERR("MoveWindow() failed"); + } + } + break; + case ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ: + if (window->state.maximized_horz) + { + RECT rect; + + if (!GetClientRect(window->window, &rect)) + { + ERR("GetClientRect() failed"); + break; + } + + if (!MoveWindow(window->window, 0, rect.top, + GetSystemMetrics(SM_CXSCREEN), + rect.bottom - rect.top, + TRUE)) + { + ERR("MoveWindow() failed"); + } + } + break; + case ECORE_WIN32_WINDOW_STATE_MAXIMIZED: + if (window->state.maximized_vert && window->state.maximized_horz) + { + RECT rect; + + if (!SystemParametersInfo(SPI_GETWORKAREA, 0, + &rect, 0)) + { + ERR("SystemParametersInfo() failed"); + break; + } + + if (!MoveWindow(window->window, 0, 0, + GetSystemMetrics(SM_CXSCREEN), + rect.bottom - rect.top, + TRUE)) + { + ERR("MoveWindow() failed"); + } + } + break; + case ECORE_WIN32_WINDOW_STATE_SHADED: + window->state.shaded = 1; + break; + case ECORE_WIN32_WINDOW_STATE_HIDDEN: + window->state.hidden = 1; + break; + case ECORE_WIN32_WINDOW_STATE_FULLSCREEN: + if (window->state.fullscreen) + ecore_win32_window_fullscreen_set(window, set); + break; + case ECORE_WIN32_WINDOW_STATE_ABOVE: + if (window->state.above) + if (!SetWindowPos(window->window, HWND_TOP, + 0, 0, + 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW)) + { + ERR("SetWindowPos() failed"); + } + break; + case ECORE_WIN32_WINDOW_STATE_BELOW: + if (window->state.below) + if (!SetWindowPos(window->window, HWND_BOTTOM, + 0, 0, + 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW)) + { + ERR("SetWindowPos() failed"); + } + break; + case ECORE_WIN32_WINDOW_STATE_DEMANDS_ATTENTION: + window->state.demands_attention = 1; + break; + case ECORE_WIN32_WINDOW_STATE_UNKNOWN: + /* nothing to be done */ + break; + } +} + +/** + * @brief Set the type of the given window. + * + * @param window The window to modify the type. + * @param type The nwindow types. + * + * This function set the type of @p window to @p type. If + * @p window is @c NULL, the function does nothing. + */ +EAPI 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: + window->type.desktop = 1; + break; + case ECORE_WIN32_WINDOW_TYPE_DOCK: + window->type.dock = 1; + break; + case ECORE_WIN32_WINDOW_TYPE_TOOLBAR: + window->type.toolbar = 1; + break; + case ECORE_WIN32_WINDOW_TYPE_MENU: + window->type.menu = 1; + break; + case ECORE_WIN32_WINDOW_TYPE_UTILITY: + window->type.utility = 1; + break; + case ECORE_WIN32_WINDOW_TYPE_SPLASH: + window->type.splash = 1; + break; + case ECORE_WIN32_WINDOW_TYPE_DIALOG: + window->type.dialog = 1; + break; + case ECORE_WIN32_WINDOW_TYPE_NORMAL: + window->type.normal = 1; + break; + case ECORE_WIN32_WINDOW_TYPE_UNKNOWN: + window->type.normal = 1; + break; + } +} + +/** + * @} + */ diff --git a/src/lib/ecore_wince/Ecore_WinCE.h b/src/lib/ecore_wince/Ecore_WinCE.h new file mode 100644 index 0000000000..20c197575a --- /dev/null +++ b/src/lib/ecore_wince/Ecore_WinCE.h @@ -0,0 +1,314 @@ +#ifndef __ECORE_WINCE_H__ +#define __ECORE_WINCE_H__ + +/* + * DO NOT USE THIS HEADER. IT IS WORK IN PROGRESS. IT IS NOT FINAL AND + * THE API MAY CHANGE. + */ + +#ifndef ECORE_WINCE_WIP_OSXCKQSD +# warning "You are using a work in progress API. This API is not stable" +# warning "and is subject to change. You use this at your own risk." +#endif + +#include + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# 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 + +/** + * @defgroup Ecore_WinCE_Group Ecore_WinCE library + * + * @{ + */ + + +/** + * @typedef Ecore_WinCE_Window + * Abstract type for a window. + */ +typedef struct _Ecore_WinCE_Window Ecore_WinCE_Window; + + +/** + * @typedef Ecore_WinCE_Event_Mouse_In + * Event sent when the mouse enters the window. + */ +typedef struct _Ecore_WinCE_Event_Mouse_In Ecore_WinCE_Event_Mouse_In; + +/** + * @typedef Ecore_WinCE_Event_Mouse_Out + * Event sent when the mouse leaves the window. + */ +typedef struct _Ecore_WinCE_Event_Mouse_Out Ecore_WinCE_Event_Mouse_Out; + +/** + * @typedef Ecore_WinCE_Event_Window_Focus_In + * Event sent when the window gets the focus. + */ +typedef struct _Ecore_WinCE_Event_Window_Focus_In Ecore_WinCE_Event_Window_Focus_In; + +/** + * @typedef Ecore_WinCE_Event_Window_Focus_Out + * Event sent when the window looses the focus. + */ +typedef struct _Ecore_WinCE_Event_Window_Focus_Out Ecore_WinCE_Event_Window_Focus_Out; + +/** + * @typedef Ecore_WinCE_Event_Window_Damage + * Event sent when the window is damaged. + */ +typedef struct _Ecore_WinCE_Event_Window_Damage Ecore_WinCE_Event_Window_Damage; + +/** + * @typedef Ecore_WinCE_Event_Window_Create + * Event sent when the window is created. + */ +typedef struct _Ecore_WinCE_Event_Window_Create Ecore_WinCE_Event_Window_Create; + +/** + * @typedef Ecore_WinCE_Event_Window_Destroy + * Event sent when the window is destroyed. + */ +typedef struct _Ecore_WinCE_Event_Window_Destroy Ecore_WinCE_Event_Window_Destroy; + +/** + * @typedef Ecore_WinCE_Event_Window_Hide + * Event sent when the window is hidden. + */ +typedef struct _Ecore_WinCE_Event_Window_Hide Ecore_WinCE_Event_Window_Hide; + +/** + * @typedef Ecore_WinCE_Event_Window_Show + * Event sent when the window is shown. + */ +typedef struct _Ecore_WinCE_Event_Window_Show Ecore_WinCE_Event_Window_Show; + +/** + * @typedef Ecore_WinCE_Event_Window_Delete_Request + * Event sent when the window is deleted. + */ +typedef struct _Ecore_WinCE_Event_Window_Delete_Request Ecore_WinCE_Event_Window_Delete_Request; + + +/** + * @struct _Ecore_WinCE_Event_Mouse_In + * Event sent when the mouse enters the window. + */ +struct _Ecore_WinCE_Event_Mouse_In +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + int x; /**< The x coordinate where the mouse entered */ + int y; /**< The y coordinate where the mouse entered */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Mouse_Out + * Event sent when the mouse leaves the window. + */ +struct _Ecore_WinCE_Event_Mouse_Out +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + int x; /**< The x coordinate where the mouse leaved */ + int y; /**< The y coordinate where the mouse leaved */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Window_Focus_In + * Event sent when the window gets the focus. + */ +struct _Ecore_WinCE_Event_Window_Focus_In +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Window_Focus_Out + * Event sent when the window looses the focus. + */ +struct _Ecore_WinCE_Event_Window_Focus_Out +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Window_Damage + * Event sent when the window is damaged. + */ +struct _Ecore_WinCE_Event_Window_Damage +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + int x; /**< The x coordinate of the top left corner of the damaged region */ + int y; /**< The y coordinate of the top left corner of the damaged region */ + int width; /**< The width of the damaged region */ + int height; /**< The height of the damaged region */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Window_Create + * Event sent when the window is created. + */ +struct _Ecore_WinCE_Event_Window_Create +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Window_Destroy + * Event sent when the window is destroyed. + */ +struct _Ecore_WinCE_Event_Window_Destroy +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Window_Hide + * Event sent when the window is hidden. + */ +struct _Ecore_WinCE_Event_Window_Hide +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Window_Show + * Event sent when the window is shown. + */ +struct _Ecore_WinCE_Event_Window_Show +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + long time; /**< The time the event occurred */ +}; + +/** + * @struct _Ecore_WinCE_Event_Window_Delete_Request + * Event sent when the window is deleted. + */ +struct _Ecore_WinCE_Event_Window_Delete_Request +{ + Ecore_WinCE_Window *window; /**< The window that received the event */ + long time; /**< The time the event occurred */ +}; + + +EAPI extern int ECORE_WINCE_EVENT_MOUSE_IN; /**< Ecore_Event for the #Ecore_WinCE_Event_Mouse_In event */ +EAPI extern int ECORE_WINCE_EVENT_MOUSE_OUT; /**< Ecore_Event for the #Ecore_WinCE_Event_Mouse_Out event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_FOCUS_IN; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Focus_In event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_FOCUS_OUT; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Focus_Out event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_DAMAGE; /**< Ecore_Event for the Ecore_WinCE_Event_Damage event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_CREATE; /**< Ecore_Event for the Ecore_WinCE_Event_Create event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_DESTROY; /**< Ecore_Event for the Ecore_WinCE_Event_Destroy event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_HIDE; /**< Ecore_Event for the Ecore_WinCE_Event_Hide event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_SHOW; /**< Ecore_Event for the Ecore_WinCE_Event_Show event */ +EAPI extern int ECORE_WINCE_EVENT_WINDOW_DELETE_REQUEST; /**< Ecore_Event for the #Ecore_WinCE_Event_Window_Delete_Request event */ + + +/* Core */ + +EAPI int ecore_wince_init(); +EAPI int ecore_wince_shutdown(); +EAPI void ecore_wince_double_click_time_set(double t); +EAPI double ecore_wince_double_click_time_get(void); +EAPI long ecore_wince_current_time_get(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_focus(Ecore_WinCE_Window *window); + +EAPI void *ecore_wince_window_focus_get(void); + +EAPI void ecore_wince_window_backend_set(Ecore_WinCE_Window *window, int backend); + +EAPI void ecore_wince_window_suspend_cb_set(Ecore_WinCE_Window *window, int (*suspend_cb)(int)); + +EAPI void ecore_wince_window_resume_cb_set(Ecore_WinCE_Window *window, int (*resume_cb)(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, + Eina_Bool on); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ECORE_WINCE_H__ */ diff --git a/src/lib/ecore_wince/ecore_wince.c b/src/lib/ecore_wince/ecore_wince.c new file mode 100644 index 0000000000..15da44c5e3 --- /dev/null +++ b/src/lib/ecore_wince/ecore_wince.c @@ -0,0 +1,400 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include /* for printf */ + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + +#include +#include +#include + +#include "Ecore_WinCE.h" +#include "ecore_wince_private.h" + +/*============================================================================* + * Local * + *============================================================================*/ + +/** + * @cond LOCAL + */ + +static int _ecore_wince_init_count = 0; + +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; + Ecore_WinCE_Window *w = NULL; + + w = (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_OTHERZOOM)) + 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_ERASEBKGND: + return 1; + 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 EINA_UNUSED, + Eina_Log_Level level EINA_UNUSED, + const char *file EINA_UNUSED, + const char *fnc, + int line, + const char *fmt, + void *data EINA_UNUSED, + va_list args) +{ + fprintf(stderr, "[%s:%d] ", fnc, line); + vfprintf(stderr, fmt, args); +} + +/** + * @endcond + */ + + +/*============================================================================* + * Global * + *============================================================================*/ + + +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; + +/*============================================================================* + * API * + *============================================================================*/ + +/** + * @addtogroup Ecore_WinCE_Group Ecore_WinCE library + * + * Ecore_WinCE is a library that wraps Windows CE graphic functions + * and integrate them nicely into the Ecore main loop. + * + * @{ + */ + +/** + * @brief Initialize the Ecore_WinCE library. + * + * @return 1 or greater on success, 0 on error. + * + * This function sets up the Windows CE graphic system. It returns 0 on + * failure, otherwise it returns the number of times it has already been + * called. + * + * When Ecore_WinCE is not used anymore, call ecore_wince_shutdown() + * to shut down the Ecore_WinCE library. + */ +EAPI 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; +} + +/** + * @brief Shut down the Ecore_WinCE library. + * + * @return 0 when the library is completely shut down, 1 or + * greater otherwise. + * + * This function shuts down the Ecore_WinCE library. It returns 0 when it has + * been called the same number of times than ecore_wince_init(). In that case + * it shuts down all the Windows CE graphic system. + */ +EAPI 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; +} + +/** + * @brief Set the timeout for a double and triple clicks to be flagged. + * + * @param t The time in seconds. + * + * This function sets the time @p t 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. + */ +EAPI void +ecore_wince_double_click_time_set(double t) +{ + if (t < 0.0) t = 0.0; + _ecore_wince_double_click_time = t; +} + +/** + * @brief Retrieve the double and triple click flag timeout. + * + * @return The timeout for double clicks in seconds. + * + * This function returns the double clicks in seconds. If + * ecore_wince_double_click_time_set() has not been called, the + * default value is returned. See ecore_wince_double_click_time_set() + * for more informations. + */ +EAPI double +ecore_wince_double_click_time_get(void) +{ + return _ecore_wince_double_click_time; +} + +/** + * @brief Return the last event time. + * + * @return The last envent time. + * + * This function returns the last event time. + */ +EAPI long +ecore_wince_current_time_get(void) +{ + return _ecore_wince_event_last_time; +} + +/** + * @} + */ diff --git a/src/lib/ecore_wince/ecore_wince_event.c b/src/lib/ecore_wince/ecore_wince_event.c new file mode 100644 index 0000000000..39430343e3 --- /dev/null +++ b/src/lib/ecore_wince/ecore_wince_event.c @@ -0,0 +1,1123 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + +#include +#include +#include + +#include "Ecore_WinCE.h" +#include "ecore_wince_private.h" + +/*============================================================================* + * Local * + *============================================================================*/ + +/** + * @cond LOCAL + */ + +typedef enum +{ + ECORE_WINCE_KEY_MASK_LSHIFT = 1 << 0, + ECORE_WINCE_KEY_MASK_RSHIFT = 1 << 1, + ECORE_WINCE_KEY_MASK_LCONTROL = 1 << 2, + ECORE_WINCE_KEY_MASK_RCONTROL = 1 << 3, + ECORE_WINCE_KEY_MASK_LMENU = 1 << 4, + ECORE_WINCE_KEY_MASK_RMENU = 1 << 5 +} Ecore_Wince_Key_Mask; + +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 Ecore_Wince_Key_Mask _ecore_wince_key_mask = 0; + +static void +_ecore_wince_event_free_key_down(void *data EINA_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 EINA_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, + Eina_Bool is_down, + char **keyname, + char **keysymbol, + char **keycompose) +{ + char *kn; + char *ks; + char *kc; + int previous_key_state; + + previous_key_state = msg->data_param & 0x40000000; + + *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_SHIFT: + { + SHORT res; + + if (is_down) + { + if (previous_key_state) return 0; + res = GetKeyState(VK_LSHIFT); + if (res & 0x8000) + { + _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_LSHIFT; + kn = "Shift_L"; + ks = "Shift_L"; + kc = ""; + } + res = GetKeyState(VK_RSHIFT); + if (res & 0x8000) + { + _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_RSHIFT; + kn = "Shift_R"; + ks = "Shift_R"; + kc = ""; + } + } + else /* is_up */ + { + res = GetKeyState(VK_LSHIFT); + if (!(res & 0x8000) && + (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_LSHIFT)) + { + kn = "Shift_L"; + ks = "Shift_L"; + kc = ""; + _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_LSHIFT; + } + res = GetKeyState(VK_RSHIFT); + if (!(res & 0x8000) && + (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_RSHIFT)) + { + kn = "Shift_R"; + ks = "Shift_R"; + kc = ""; + _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_RSHIFT; + } + } + break; + } + case VK_CONTROL: + { + SHORT res; + + if (is_down) + { + if (previous_key_state) return 0; + res = GetKeyState(VK_LCONTROL); + if (res & 0x8000) + { + _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_LCONTROL; + kn = "Control_L"; + ks = "Control_L"; + kc = ""; + break; + } + res = GetKeyState(VK_RCONTROL); + if (res & 0x8000) + { + _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_RCONTROL; + kn = "Control_R"; + ks = "Control_R"; + kc = ""; + break; + } + } + else /* is_up */ + { + res = GetKeyState(VK_LCONTROL); + if (!(res & 0x8000) && + (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_LCONTROL)) + { + kn = "Control_L"; + ks = "Control_L"; + kc = ""; + _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_LCONTROL; + break; + } + res = GetKeyState(VK_RCONTROL); + if (!(res & 0x8000) && + (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_RCONTROL)) + { + kn = "Control_R"; + ks = "Control_R"; + kc = ""; + _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_RCONTROL; + break; + } + } + break; + } + case VK_MENU: + { + SHORT res; + + if (is_down) + { + if (previous_key_state) return 0; + res = GetKeyState(VK_LMENU); + if (res & 0x8000) + { + _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_LMENU; + kn = "Alt_L"; + ks = "Alt_L"; + kc = ""; + } + res = GetKeyState(VK_RMENU); + if (res & 0x8000) + { + _ecore_wince_key_mask |= ECORE_WINCE_KEY_MASK_RMENU; + kn = "Alt_R"; + ks = "Alt_R"; + kc = ""; + } + } + else /* is_up */ + { + res = GetKeyState(VK_LMENU); + if (!(res & 0x8000) && + (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_LMENU)) + { + kn = "Alt_L"; + ks = "Alt_L"; + kc = ""; + _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_LMENU; + } + res = GetKeyState(VK_RMENU); + if (!(res & 0x8000) && + (_ecore_wince_key_mask & ECORE_WINCE_KEY_MASK_RMENU)) + { + kn = "Alt_R"; + ks = "Alt_R"; + kc = ""; + _ecore_wince_key_mask &= ~ECORE_WINCE_KEY_MASK_RMENU; + } + } + break; + } + case VK_LWIN: + { + if (is_down) + { + if (previous_key_state) return 0; + kn = "Super_L"; + ks = "Super_L"; + kc = ""; + *modifiers |= ECORE_EVENT_MODIFIER_WIN; + } + else /* is_up */ + { + kn = "Super_L"; + ks = "Super_L"; + kc = ""; + *modifiers &= ~ECORE_EVENT_MODIFIER_WIN; + } + break; + } + case VK_RWIN: + { + if (is_down) + { + if (previous_key_state) return 0; + kn = "Super_R"; + ks = "Super_R"; + kc = ""; + *modifiers |= ECORE_EVENT_MODIFIER_WIN; + } + else /* is_up */ + { + kn = "Super_R"; + ks = "Super_R"; + kc = ""; + *modifiers &= ~ECORE_EVENT_MODIFIER_WIN; + } + 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; + + /* check control charaters such as ^a(key:1), ^z(key:26) */ + if ((key > 0) && (key < 27) && + ((GetKeyState(VK_CONTROL) & 0x8000) || + (GetKeyState(VK_CONTROL) & 0x8000))) key += 96; + + 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; + case VK_SPACE: + strncpy(kn, "space", 32); + strncpy(ks, "space", 32); + strncpy(kc, " ", 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; +} + +/** + * @endcond + */ + + +/*============================================================================* + * Global * + *============================================================================*/ + +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), + EINA_TRUE, + (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); + e->event_window = e->window; + 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), + EINA_FALSE, + (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); + e->event_window = e->window; + 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->event_window = e->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->event_window = e->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->event_window = e->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->event_window = e->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->event_window = e->window; + 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->event_window = e->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->event_window = e->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; + 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_cb) + window->resume_cb(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; + 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_cb) + window->suspend_cb(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); +} + +/*============================================================================* + * API * + *============================================================================*/ + diff --git a/src/lib/ecore_wince/ecore_wince_private.h b/src/lib/ecore_wince/ecore_wince_private.h new file mode 100644 index 0000000000..b506312f99 --- /dev/null +++ b/src/lib/ecore_wince/ecore_wince_private.h @@ -0,0 +1,85 @@ +#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_cb) (int); +typedef int (*ecore_wince_resume_cb) (int); + + +struct _Ecore_WinCE_Window +{ + HWND window; + + int backend; + ecore_wince_suspend_cb suspend_cb; + ecore_wince_resume_cb resume_cb; + + 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__ */ diff --git a/src/lib/ecore_wince/ecore_wince_window.c b/src/lib/ecore_wince/ecore_wince_window.c new file mode 100644 index 0000000000..49a6312da3 --- /dev/null +++ b/src/lib/ecore_wince/ecore_wince_window.c @@ -0,0 +1,827 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN + +#include +#include + +#include "Ecore_WinCE.h" +#include "ecore_wince_private.h" + +/*============================================================================* + * Local * + *============================================================================*/ + +/** + * @cond LOCAL + */ + + +typedef BOOL (__stdcall *UnregisterFunc1Proc)(UINT, UINT); + +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; +} + +/** + * @endcond + */ + + +/*============================================================================* + * Global * + *============================================================================*/ + +/*============================================================================* + * API * + *============================================================================*/ + +/** + * @addtogroup Ecore_WinCE_Group Ecore_WinCE library + * + * @{ + */ + +/** + * @brief Creates a new window. + * + * @param parent The parent window. + * @param x The x coordinate of the top-left corner of the window. + * @param y The y coordinate of the top-left corner of the window. + * @param width The width of the window. + * @param height The height of hte window. + * @return A newly allocated window. + * + * This function creates a new window which parent is @p parent. @p width and + * @p height are the size of the window content (the client part), + * without the border and title bar. @p x and @p y are the system + * coordinates of the top left cerner of the window (that is, of the + * title bar). This function returns a newly created window on + * success, and @c NULL on failure. + */ +EAPI Ecore_WinCE_Window * +ecore_wince_window_new(Ecore_WinCE_Window *parent, + int x, + int y, + int width, + int height) +{ + Ecore_WinCE_Window *w; + HWND window; + RECT rect; + + INF("creating window"); + + w = (Ecore_WinCE_Window *)calloc(1, sizeof(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 ? ((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; +} + +/** + * @brief Free the given window. + * + * @param window The window to free. + * + * This function frees @p window. If @p window is @c NULL, this + * function does nothing. + */ +EAPI void +ecore_wince_window_free(Ecore_WinCE_Window *window) +{ + if (!window) return; + + INF("destroying window"); + + DestroyWindow(window->window); + free(window); +} + +/** + * @brief Return the window HANDLE associated to the given window. + * + * @param window The window to retrieve the HANDLE from. + * + * This function returns the window HANDLE associated to @p window. If + * @p window is @c NULL, this function returns @c NULL. + */ +EAPI void * +ecore_wince_window_hwnd_get(Ecore_WinCE_Window *window) +{ + if (!window) + return NULL; + + return window->window; +} + +/** + * @brief Move the given window to a given position. + * + * @param window The window to move. + * @param x The x coordinate of the destination position. + * @param y The y coordinate of the destination position. + * + * This function move @p window to the new position of coordinates @p x + * and @p y. If @p window is @c NULL, or if it is fullscreen, or on + * error, this function does nothing. + */ +EAPI void +ecore_wince_window_move(Ecore_WinCE_Window *window, + int x, + int y) +{ + RECT rect; + + if (!window || window->fullscreen) + return; + + INF("moving window (%dx%d)", x, y); + + if (!GetWindowRect(window->window, &rect)) + { + ERR("GetWindowRect() failed"); + return; + } + + if (!MoveWindow(window->window, x, y, + rect.right - rect.left, + rect.bottom - rect.top, + TRUE)) + { + ERR("MoveWindow() failed"); + } +} + +/** + * @brief Resize the given window to a given size. + * + * @param window The window to resize. + * @param width The new width. + * @param height The new height. + * + * This function resize @p window to the new @p width and @p height. + * If @p window is @c NULL, or if it is fullscreen, or on error, this + * function does nothing. + */ +EAPI void +ecore_wince_window_resize(Ecore_WinCE_Window *window, + int width, + int height) +{ + RECT rect; + DWORD style; + DWORD exstyle; + int x; + int y; + + if (!window || window->fullscreen) + return; + + INF("resizing window (%dx%d)", width, height); + + if (!GetWindowRect(window->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(window->window, GWL_STYLE))) + { + ERR("GetWindowLong() failed"); + return; + } + if (!(exstyle = GetWindowLong(window->window, GWL_EXSTYLE))) + { + ERR("GetWindowLong() failed"); + return; + } + if (!AdjustWindowRectEx(&rect, style, FALSE, exstyle)) + { + ERR("AdjustWindowRectEx() failed"); + return; + } + + if (!MoveWindow(window->window, x, y, + rect.right - rect.left, + rect.bottom - rect.top, + FALSE)) + { + ERR("MoveWindow() failed"); + } +} + +/** + * @brief Move and resize the given window to a given position and size. + * + * @param window The window to move and resize. + * @param x The x coordinate of the destination position. + * @param y The x coordinate of the destination position. + * @param width The new width. + * @param height The new height. + * + * This function resize @p window to the new position of coordinates @p x + * and @p y and the new @p width and @p height. If @p window is @c NULL, + * or if it is fullscreen, or on error, this function does nothing. + */ +EAPI void +ecore_wince_window_move_resize(Ecore_WinCE_Window *window, + int x, + int y, + int width, + int height) +{ + RECT rect; + DWORD style; + DWORD exstyle; + + if (!window || window->fullscreen) + return; + + INF("moving and resizing window (%dx%d %dx%d)", x, y, width, height); + + rect.left = 0; + rect.top = 0; + rect.right = width; + rect.bottom = height; + if (!(style = GetWindowLong(window->window, GWL_STYLE))) + { + ERR("GetWindowLong() failed"); + return; + } + if (!(exstyle = GetWindowLong(window->window, GWL_EXSTYLE))) + { + ERR("GetWindowLong() failed"); + return; + } + if (!AdjustWindowRectEx(&rect, style, FALSE, exstyle)) + { + ERR("AdjustWindowRectEx() failed"); + return; + } + + if (!MoveWindow(window->window, x, y, + rect.right - rect.left, + rect.bottom - rect.top, + TRUE)) + { + ERR("MoveWindow() failed"); + } +} + +/** + * @brief Show the given window. + * + * @param window The window to show. + * + * This function shows @p window. If @p window is @c NULL, or on + * error, this function does nothing. + */ +EAPI void +ecore_wince_window_show(Ecore_WinCE_Window *window) +{ + if (!window) return; + + INF("showing window"); + + if (!ShowWindow(window->window, SW_SHOWNORMAL)) + { + ERR("ShowWindow() failed"); + return; + } + if (!UpdateWindow(window->window)) + { + ERR("UpdateWindow() failed"); + } + if (!SendMessage(window->window, WM_SHOWWINDOW, 1, 0)) + { + ERR("SendMessage() failed"); + } +} + +/** + * @brief Hide the given window. + * + * @param window The window to show. + * + * This function hides @p window. If @p window is @c NULL, or on + * error, this function does nothing. + */ +EAPI void +ecore_wince_window_hide(Ecore_WinCE_Window *window) +{ + if (!window) return; + + INF("hiding window"); + + if (!ShowWindow(window->window, SW_HIDE)) + { + ERR("ShowWindow() failed"); + return; + } + if (!SendMessage(window->window, WM_SHOWWINDOW, 0, 0)) + { + ERR("SendMessage() failed"); + } +} + +/** + * @brief Set the title of the given window. + * + * @param window The window to set the title. + * @param title The new title. + * + * This function sets the title of @p window to @p title. If @p window + * is @c NULL, or if @p title is @c NULL or empty, or on error, this + * function does nothing. + */ +EAPI 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(window->window, wtitle)) + { + ERR("SetWindowText() failed"); + } + free(wtitle); +} + +/** + * @brief Set the focus to the given window. + * + * @param window The window to give focus to. + * + * This function gives the focus to @p window. If @p window is + * @c NULL, this function does nothing. + */ +EAPI void +ecore_wince_window_focus(Ecore_WinCE_Window *window) +{ + if (!window) return; + + INF("focusing window"); + + if (!SetFocus(window->window)) + { + ERR("SetFocus() failed"); + } +} + +/** + * @brief Get the current focused window. + * + * @return The window that has focus. + * + * This function returns the window that has focus. If the calling + * thread's message queue does not have an associated window with the + * keyboard focus, the return value is @c NULL. + * + * @note Even if the returned value is @c NULL, another thread's queue + * may be associated with a window that has the keyboard focus. + * + * @note The returned value is of type HWND. + */ +EAPI void * +ecore_wince_window_focus_get(void) +{ + HWND focused; + + INF("getting focused window"); + + focused = GetFocus(); + if (!focused) + { + ERR("GetFocus() failed"); + return NULL; + } + + return focused; +} + +/** + * @brief Set the graphic backend used for the given window. + * + * @param window The window. + * @param backend The backend. + * + * This function sets the graphic backend to use with @p window to + * @p backend. If @p window if @c NULL, this function does nothing. + * + * The valid values for @p backend are + * + * @li 0: automatic choice of the backend. + * @li 1: the framebuffer (fast but could be not well suported). + * @li 2: GAPI (less fast but almost always supported). + * @li 3: DirectDraw (less fast than GAPI but almost always + * supported). + * @li 4: GDI (the slowest but always supported). + * + * The @p backend is used only in Evas and Ecore_Evas. So this + * function should not be called if Ecore_Evas is used. + */ +EAPI void +ecore_wince_window_backend_set(Ecore_WinCE_Window *window, + int backend) +{ + if (!window) + return; + + INF("setting backend"); + + window->backend = backend; +} + +/** + * @brief Set the suspend callback used for the given window. + * + * @param window The window. + * @param suspend_cb The suspend callback. + * + * This function sets the suspend callback to use with @p window to + * @p suspend_cb. If @p window if @c NULL, this function does nothing. + * + * The @p suspend_cb is used only in Evas and Ecore_Evas. So this + * function should not be called if Ecore_Evas is used. + */ +EAPI void +ecore_wince_window_suspend_cb_set(Ecore_WinCE_Window *window, int (*suspend_cb)(int)) +{ + if (!window) + return; + + INF("setting suspend callback"); + + window->suspend_cb = suspend_cb; +} + +/** + * @brief Set the resume callback used for the given window. + * + * @param window The window. + * @param resume_cb The resume callback. + * + * This function sets the resume callback to use with @p window to + * @p resume_cb. If @p window if @c NULL, this function does nothing. + * + * The @p resume_cb is used only in Evas and Ecore_Evas. So this + * function should not be called if Ecore_Evas is used. + */ +EAPI void +ecore_wince_window_resume_cb_set(Ecore_WinCE_Window *window, int (*resume_cb)(int)) +{ + if (!window) + return; + + INF("setting resume callback"); + + window->resume_cb = resume_cb; +} + +/** + * @brief Get the geometry of the given window. + * + * @param window The window to retrieve the geometry from. + * @param x The x coordinate of the position. + * @param y The x coordinate of the position. + * @param width The width. + * @param height The height. + * + * This function retrieves the position and size of @p window. @p x, + * @p y, @p width and @p height can be buffers that will be filled with + * the corresponding values. If one of them is @c NULL, nothing will + * be done for that parameter. If @p window is @c NULL, and if the + * buffers are not @c NULL, they will be filled with respectively 0, + * 0, the size of the screen and the height of the screen. + */ +EAPI 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(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(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; +} + +/** + * @brief Get the size of the given window. + * + * @param window The window to retrieve the size from. + * @param width The width. + * @param height The height. + * + * This function retrieves the size of @p window. @p width and + * @p height can be buffers that will be filled with the corresponding + * values. If one of them is @c NULL, nothing will be done for that + * parameter. If @p window is @c NULL, and if the buffers are not + * @c NULL, they will be filled with respectively the size of the screen + * and the height of the screen. + */ +EAPI 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(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; +} + +/** + * @brief Set the given window to fullscreen. + * + * @param window The window. + * @param on @c EINA_TRUE for fullscreen mode, @c EINA_FALSE for windowed mode. + * + * This function set @p window to fullscreen or windowed mode. If @p on is set + * to @c EINA_TRUE, the window will be fullscreen, if it is set to + * @c EINA_FALSE, it will be windowed. If @p window is @c NULL or if the state + * does not change (like setting to fullscreen while the window is already + * fullscreen), this function does nothing. + */ +EAPI void +ecore_wince_window_fullscreen_set(Ecore_WinCE_Window *window, + Eina_Bool on) +{ + HWND task_bar; + + if (!window) return; + + if (((window->fullscreen) && (on)) || + ((!window->fullscreen) && (!on))) + return; + + INF("setting fullscreen: %s", on ? "yes" : "no"); + + window->fullscreen = !!on; + + if (on) + { + /* save the position and size of the window */ + if (!GetWindowRect(window->window, &window->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(window->window, GWL_STYLE, WS_POPUP | WS_VISIBLE)) + { + INF("SetWindowLong() failed"); + } + + /* resize window to fit the entire screen */ + if (!SetWindowPos(window->window, 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(window->window, + 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(window->window, GWL_STYLE, WS_CAPTION | WS_SYSMENU | WS_VISIBLE)) + { + INF("SetWindowLong() failed"); + } + /* restaure the position and size of the window */ + if (!SetWindowPos(window->window, HWND_TOPMOST, + window->rect.left, + window->rect.top, + window->rect.right - window->rect.left, + window->rect.bottom - window->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(window->window, + window->rect.left, + window->rect.top, + window->rect.right - window->rect.left, + window->rect.bottom - window->rect.top, + TRUE)) + { + INF("MoveWindow() failed"); + } + } +} + +/** + * @} + */ diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h new file mode 100644 index 0000000000..b3fc0fabab --- /dev/null +++ b/src/lib/ecore_x/Ecore_X.h @@ -0,0 +1,2407 @@ +#ifndef _ECORE_X_H +#define _ECORE_X_H + +#include + +#ifdef EAPI +# undef EAPI +#endif // ifdef EAPI + +#ifdef _MSC_VER +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else // ifdef BUILDING_DLL +# define EAPI __declspec(dllimport) +# endif // ifdef BUILDING_DLL +#else // ifdef _MSC_VER +# ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else // if __GNUC__ >= 4 +# define EAPI +# endif // if __GNUC__ >= 4 +# else // ifdef __GNUC__ +# define EAPI +# endif // ifdef __GNUC__ +#endif // ifdef _MSC_VER + +#include + +/** + * @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 // ifndef _ECORE_X_WINDOW_PREDEF +typedef void *Ecore_X_Visual; +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 // ifdef HAVE_ECORE_X_XCB +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 int Ecore_X_Randr_Screen; + +typedef Ecore_X_ID Ecore_X_Device; + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +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 _Ecore_X_Window_State + * Defines the different states of the window of Ecore_X. + */ +typedef enum _Ecore_X_Window_State +{ + ECORE_X_WINDOW_STATE_UNKNOWN = 0, + ECORE_X_WINDOW_STATE_ICONIFIED, /** The window is iconified. */ + ECORE_X_WINDOW_STATE_MODAL, /** The window is a modal dialog box. */ + ECORE_X_WINDOW_STATE_STICKY, /** The window manager should keep the window's position fixed + * even if the virtual desktop scrolls. */ + ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, /** The window has the maximum vertical size. */ + ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, /** The window has the maximum horizontal size. */ + ECORE_X_WINDOW_STATE_SHADED, /** The window is shaded. */ + ECORE_X_WINDOW_STATE_SKIP_TASKBAR, /** The window should not be included in the taskbar. */ + ECORE_X_WINDOW_STATE_SKIP_PAGER, /** The window should not be included in the pager. */ + ECORE_X_WINDOW_STATE_HIDDEN, /** The window is invisible (i.e. minimized/iconified) */ + ECORE_X_WINDOW_STATE_FULLSCREEN, /** The window should fill the entire screen and have no + * window border/decorations */ + ECORE_X_WINDOW_STATE_ABOVE, + ECORE_X_WINDOW_STATE_BELOW, + 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_Orientation +{ + ECORE_X_RANDR_ORIENTATION_ROT_0 = (1 << 0), + ECORE_X_RANDR_ORIENTATION_ROT_90 = (1 << 1), + ECORE_X_RANDR_ORIENTATION_ROT_180 = (1 << 2), + ECORE_X_RANDR_ORIENTATION_ROT_270 = (1 << 3), + ECORE_X_RANDR_ORIENTATION_FLIP_X = (1 << 4), + ECORE_X_RANDR_ORIENTATION_FLIP_Y = (1 << 5) +} Ecore_X_Randr_Orientation; + +typedef enum _Ecore_X_Randr_Connection_Status +{ + ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED = 0, + ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED = 1, + ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN = 2 +} Ecore_X_Randr_Connection_Status; + +typedef enum _Ecore_X_Randr_Output_Policy +{ + ECORE_X_RANDR_OUTPUT_POLICY_ABOVE = 1, + ECORE_X_RANDR_OUTPUT_POLICY_RIGHT = 2, + ECORE_X_RANDR_OUTPUT_POLICY_BELOW = 3, + ECORE_X_RANDR_OUTPUT_POLICY_LEFT = 4, + ECORE_X_RANDR_OUTPUT_POLICY_CLONE = 5, + ECORE_X_RANDR_OUTPUT_POLICY_NONE = 6, + ECORE_X_RANDR_OUTPUT_POLICY_ASK = 7 +} Ecore_X_Randr_Output_Policy; + +typedef enum _Ecore_X_Randr_Relative_Alignment +{ + ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE = 0, + ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL = 1, + ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR = 2 +} Ecore_X_Randr_Relative_Alignment; + +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; + +typedef enum _Ecore_X_Randr_Edid_Display_Interface_Type +{ + ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_UNDEFINED, + ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DVI, + ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_HDMI_A, + ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_HDMI_B, + ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_MDDI, + ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT +} Ecore_X_Randr_Edid_Display_Interface_Type; + +typedef enum _Ecore_X_Randr_Edid_Display_Colorscheme +{ + ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_MONOCHROME_GRAYSCALE = 0x00, + ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB = 0x08, + ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_NON_RGB = 0x10, + ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_UNDEFINED = 0x18, + ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4 = 0x444000, + ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4 = 0x444, + ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2 = 0x422 +} Ecore_X_Randr_Edid_Display_Colorscheme; + +typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio +{ + ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3 = 0x0, + ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9 = 0x1, + ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10 = 0x2, + ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4 = 0x4, + ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9 = 0x8 +} Ecore_X_Randr_Edid_Aspect_Ratio; + +#define ECORE_X_RANDR_EDID_UNKNOWN_VALUE -1 + +#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 + +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_INPUT +} Ecore_X_Shape_Type; + +typedef enum _Ecore_X_Mapping_Type +{ + ECORE_X_MAPPING_MODIFIER, + ECORE_X_MAPPING_KEYBOARD, + ECORE_X_MAPPING_MOUSE +} Ecore_X_Mapping_Type; + +typedef enum _Ecore_X_Randr_Property_Change +{ + ECORE_X_RANDR_PROPERTY_CHANGE_ADD, + ECORE_X_RANDR_PROPERTY_CHANGE_DEL +} Ecore_X_Randr_Property_Change; + +typedef enum _Ecore_X_Netwm_Direction +{ + ECORE_X_NETWM_DIRECTION_SIZE_TL = 0, + ECORE_X_NETWM_DIRECTION_SIZE_T = 1, + ECORE_X_NETWM_DIRECTION_SIZE_TR = 2, + ECORE_X_NETWM_DIRECTION_SIZE_R = 3, + ECORE_X_NETWM_DIRECTION_SIZE_BR = 4, + ECORE_X_NETWM_DIRECTION_SIZE_B = 5, + ECORE_X_NETWM_DIRECTION_SIZE_BL = 6, + ECORE_X_NETWM_DIRECTION_SIZE_L = 7, + ECORE_X_NETWM_DIRECTION_MOVE = 8, + ECORE_X_NETWM_DIRECTION_CANCEL = 11, +} Ecore_X_Netwm_Direction; + +/** + * @typedef _Ecore_X_Error_Code + * Defines the error codes of Ecore_X which wraps the X Window Systems + * protocol's errors. + * + * @since 1.7.0 + */ +typedef enum _Ecore_X_Error_Code +{ + /** Everything is okay. */ + ECORE_X_ERROR_CODE_SUCCESS = 0, /** Bad request code */ + ECORE_X_ERROR_CODE_BAD_REQUEST = 1, /** Int parameter out of range */ + ECORE_X_ERROR_CODE_BAD_VALUE = 2, /** Parameter not a Window */ + ECORE_X_ERROR_CODE_BAD_WINDOW = 3, /** Parameter not a Pixmap */ + ECORE_X_ERROR_CODE_BAD_PIXMAP = 4, /** Parameter not an Atom */ + ECORE_X_ERROR_CODE_BAD_ATOM = 5, /** Parameter not a Cursor */ + ECORE_X_ERROR_CODE_BAD_CURSOR = 6, /** Parameter not a Font */ + ECORE_X_ERROR_CODE_BAD_FONT = 7, /** Parameter mismatch */ + ECORE_X_ERROR_CODE_BAD_MATCH = 8, /** Parameter not a Pixmap or Window */ + ECORE_X_ERROR_CODE_BAD_DRAWABLE = 9, /** Bad access */ + ECORE_X_ERROR_CODE_BAD_ACCESS = 10, /** Insufficient resources */ + ECORE_X_ERROR_CODE_BAD_ALLOC = 11, /** No such colormap */ + ECORE_X_ERROR_CODE_BAD_COLOR = 12, /** Parameter not a GC */ + ECORE_X_ERROR_CODE_BAD_GC = 13, /** Choice not in range or already used */ + ECORE_X_ERROR_CODE_BAD_ID_CHOICE = 14, /** Font or color name doesn't exist */ + ECORE_X_ERROR_CODE_BAD_NAME = 15, /** Request length incorrect */ + ECORE_X_ERROR_CODE_BAD_LENGTH = 16, /** Server is defective */ + ECORE_X_ERROR_CODE_BAD_IMPLEMENTATION = 17, +} Ecore_X_Error_Code; + +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_Mapping_Change Ecore_X_Event_Mapping_Change; +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_Event_Fixes_Selection_Notify Ecore_X_Event_Fixes_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_Gesture_Notify_Flick Ecore_X_Event_Gesture_Notify_Flick; +typedef struct _Ecore_X_Event_Gesture_Notify_Pan Ecore_X_Event_Gesture_Notify_Pan; +typedef struct _Ecore_X_Event_Gesture_Notify_PinchRotation Ecore_X_Event_Gesture_Notify_PinchRotation; +typedef struct _Ecore_X_Event_Gesture_Notify_Tap Ecore_X_Event_Gesture_Notify_Tap; +typedef struct _Ecore_X_Event_Gesture_Notify_TapNHold Ecore_X_Event_Gesture_Notify_TapNHold; +typedef struct _Ecore_X_Event_Gesture_Notify_Hold Ecore_X_Event_Gesture_Notify_Hold; +typedef struct _Ecore_X_Event_Gesture_Notify_Group Ecore_X_Event_Gesture_Notify_Group; +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_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; + +typedef struct _Ecore_X_Randr_Screen_Size Ecore_X_Randr_Screen_Size; +typedef struct _Ecore_X_Randr_Screen_Size_MM Ecore_X_Randr_Screen_Size_MM; + +typedef struct _Ecore_X_Xdnd_Position Ecore_X_Xdnd_Position; + +struct _Ecore_X_Event_Mouse_In +{ + int modifiers; + int x, y; + Eina_Bool same_screen : 1; + 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; + Eina_Bool override : 1; + Eina_Bool 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; + Eina_Bool installed : 1; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Mapping_Change +{ + Ecore_X_Mapping_Type type; + int keycode; + int num; +}; + +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; +}; + +typedef enum +{ + ECORE_X_OWNER_CHANGE_REASON_NEW_OWNER, + ECORE_X_OWNER_CHANGE_REASON_DESTROY, + ECORE_X_OWNER_CHANGE_REASON_CLOSE +} Ecore_X_Owner_Change_Reason; + +struct _Ecore_X_Event_Fixes_Selection_Notify +{ + Ecore_X_Window win; + Ecore_X_Window owner; + Ecore_X_Time time; + Ecore_X_Time selection_time; + Ecore_X_Selection selection; + Ecore_X_Atom atom; + Ecore_X_Owner_Change_Reason reason; +}; + +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_Xdnd_Position +{ + Ecore_X_Window win, prev; + struct + { + int x, y; + } position; +}; + +struct _Ecore_X_Event_Xdnd_Status +{ + Ecore_X_Window win, target; + Eina_Bool will_accept : 1; + 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; + Eina_Bool completed : 1; + 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; + Ecore_X_Shape_Type type; + int x, y, w, h; + Eina_Bool shaped : 1; +}; + +struct _Ecore_X_Event_Screensaver_Notify +{ + Ecore_X_Window win; + Eina_Bool on : 1; + 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_Randr_Screen_Size +{ + int width, height; +}; + +struct _Ecore_X_Randr_Screen_Size_MM +{ + int width, height, width_mm, height_mm; +}; + +struct _Ecore_X_Event_Screen_Change +{ + Ecore_X_Window win; + Ecore_X_Window root; + Ecore_X_Randr_Screen_Size_MM size; /* in pixel and millimeters */ + Ecore_X_Time time; + Ecore_X_Time config_time; + Ecore_X_Randr_Orientation orientation; + 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_Orientation orientation; + Eina_Rectangle geo; +}; + +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_Orientation orientation; + Ecore_X_Randr_Connection_Status 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; + Ecore_X_Randr_Property_Change state; +}; + +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_MAPPING_CHANGE; +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_FIXES_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_GESTURE_NOTIFY_FLICK; +EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_PAN; +EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION; +EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_TAP; +EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD; +EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD; +EAPI extern int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP; +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_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_XKB_STATE_NOTIFY; /** @since 1.7 */ +EAPI extern int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY; /** @since 1.7 */ + +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_MODIFIER_SHIFT; /**< @since 1.7 */ +EAPI extern int ECORE_X_MODIFIER_CTRL; /**< @since 1.7 */ +EAPI extern int ECORE_X_MODIFIER_ALT; /**< @since 1.7 */ +EAPI extern int ECORE_X_MODIFIER_WIN; /**< @since 1.7 */ +EAPI extern int ECORE_X_MODIFIER_ALTGR; /**< @since 1.7 */ + +EAPI extern int ECORE_X_LOCK_SCROLL; +EAPI extern int ECORE_X_LOCK_NUM; +EAPI extern int ECORE_X_LOCK_CAPS; +EAPI extern int ECORE_X_LOCK_SHIFT; + +EAPI extern int ECORE_X_RAW_BUTTON_PRESS; /**< @since 1.8 */ +EAPI extern int ECORE_X_RAW_BUTTON_RELEASE; /**< @since 1.8 */ +EAPI extern int ECORE_X_RAW_MOTION; /**< @since 1.8 */ + +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 _Ecore_X_Window_State_Hint + * Defines the different state hint of the window of Ecore_X. + */ +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; + +typedef enum _Ecore_X_Illume_Indicator_State +{ + ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN = 0, + ECORE_X_ILLUME_INDICATOR_STATE_OFF, + ECORE_X_ILLUME_INDICATOR_STATE_ON +} Ecore_X_Illume_Indicator_State; + +typedef enum _Ecore_X_Illume_Clipboard_State +{ + ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN = 0, + ECORE_X_ILLUME_CLIPBOARD_STATE_OFF, + ECORE_X_ILLUME_CLIPBOARD_STATE_ON +} Ecore_X_Illume_Clipboard_State; + +typedef enum _Ecore_X_Illume_Indicator_Opacity_Mode +{ + ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN = 0, + ECORE_X_ILLUME_INDICATOR_OPAQUE, + ECORE_X_ILLUME_INDICATOR_TRANSLUCENT, + ECORE_X_ILLUME_INDICATOR_TRANSPARENT +} Ecore_X_Illume_Indicator_Opacity_Mode; + +typedef enum _Ecore_X_Illume_Window_State +{ + ECORE_X_ILLUME_WINDOW_STATE_NORMAL = 0, + ECORE_X_ILLUME_WINDOW_STATE_FLOATING +} Ecore_X_Illume_Window_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_screen_size_get(const Ecore_X_Screen *screen, int *w, int *h); +EAPI int ecore_x_screen_count_get(void); +EAPI int ecore_x_screen_index_get(const Ecore_X_Screen *screen); +EAPI Ecore_X_Screen *ecore_x_screen_get(int index); + +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 Eina_Bool ecore_x_bell(int percent); +EAPI unsigned int ecore_x_visual_id_get(Ecore_X_Visual visual); + +EAPI Ecore_X_Visual ecore_x_default_visual_get(Ecore_X_Display *disp, Ecore_X_Screen *screen); +EAPI Ecore_X_Colormap ecore_x_default_colormap_get(Ecore_X_Display *disp, Ecore_X_Screen *screen); +EAPI int ecore_x_default_depth_get(Ecore_X_Display *disp, Ecore_X_Screen *screen); + +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 Ecore_X_ID ecore_x_error_resource_id_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 Eina_Bool 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 Eina_Bool ecore_x_selection_primary_set(Ecore_X_Window w, const void *data, int size); +EAPI Eina_Bool ecore_x_selection_primary_clear(void); +EAPI Eina_Bool ecore_x_selection_secondary_set(Ecore_X_Window w, const void *data, int size); +EAPI Eina_Bool ecore_x_selection_secondary_clear(void); +EAPI Eina_Bool ecore_x_selection_xdnd_set(Ecore_X_Window w, const void *data, int size); +EAPI Eina_Bool ecore_x_selection_xdnd_clear(void); +EAPI Eina_Bool ecore_x_selection_clipboard_set(Ecore_X_Window w, const void *data, int size); +EAPI Eina_Bool 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 Eina_Bool ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret, int *len, Ecore_X_Atom *targprop, int *targsize); +EAPI void ecore_x_selection_converter_add(char *target, Eina_Bool (*func)(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *, int *)); +EAPI void ecore_x_selection_converter_atom_add(Ecore_X_Atom target, Eina_Bool (*func)(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *tprop, int *tsize)); +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_selection_owner_set(Ecore_X_Window win, Ecore_X_Atom atom, Ecore_X_Time tm); +EAPI Ecore_X_Window ecore_x_selection_owner_get(Ecore_X_Atom atom); +EAPI Eina_Bool ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *targprop, int *s); /** @since 1.8 */ + +EAPI void ecore_x_dnd_aware_set(Ecore_X_Window win, Eina_Bool on); +EAPI int ecore_x_dnd_version_get(Ecore_X_Window win); +EAPI Eina_Bool 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, Eina_Bool 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 Eina_Bool ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size); +EAPI Eina_Bool ecore_x_dnd_drop(void); +EAPI void ecore_x_dnd_send_status(Eina_Bool will_accept, Eina_Bool 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 void ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *data), const void *data); + +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 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, Eina_Bool 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 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, Eina_Bool override); + +EAPI void ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom, unsigned int *val, unsigned int num); +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 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 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 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 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 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 char *ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type); +EAPI Eina_Bool 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_input_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num); +EAPI void ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y); +EAPI void ecore_x_window_shape_input_window_set(Ecore_X_Window win, Ecore_X_Window shape_win); +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_input_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_input_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_input_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num); +EAPI Ecore_X_Rectangle *ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret); +EAPI Ecore_X_Rectangle *ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win, int *num_ret); +EAPI void ecore_x_window_shape_events_select(Ecore_X_Window win, Eina_Bool 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 void ecore_x_gc_foreground_set(Ecore_X_GC gc, unsigned long foreground); +EAPI void ecore_x_gc_background_set(Ecore_X_GC gc, unsigned long background); + +EAPI Eina_Bool 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 Eina_Bool ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, const void *data, int len); +EAPI Eina_Bool ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y); +EAPI Eina_Bool ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b); +EAPI Eina_Bool ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b); +EAPI Eina_Bool ecore_x_mouse_in_send(Ecore_X_Window win, int x, int y); +EAPI Eina_Bool ecore_x_mouse_out_send(Ecore_X_Window win, int x, int y); + +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 Eina_Bool 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 Eina_Bool 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 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 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, Eina_Bool 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, Eina_Bool is_urgent); +EAPI Eina_Bool ecore_x_icccm_hints_get(Ecore_X_Window win, Eina_Bool *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, Eina_Bool *is_urgent); +EAPI void ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, Eina_Bool 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 Eina_Bool ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, Eina_Bool *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, Eina_Bool on); +EAPI Eina_Bool 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 Eina_Bool 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, Eina_Bool 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 Eina_Bool 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 unsigned int *ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, 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, Eina_Bool 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 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 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 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 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 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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_set(Ecore_X_Window win, Ecore_X_Icon *icon, int num); + +EAPI Eina_Bool 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 Eina_Bool 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 Eina_Bool ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid); +EAPI void ecore_x_netwm_handled_icons_set(Ecore_X_Window win); +EAPI Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb); +EAPI Eina_Bool 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, Eina_Bool set); +EAPI void ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop); +EAPI void ecore_x_netwm_moveresize_request_send(Ecore_X_Window win, int x, int y, Ecore_X_Netwm_Direction direction, unsigned int button); + +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 Eina_Bool 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 Eina_Bool 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_access_action_next_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_read_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_up_send(Ecore_X_Window win); +EAPI void ecore_x_e_illume_access_action_down_send(Ecore_X_Window win); + +EAPI void ecore_x_e_illume_drag_set(Ecore_X_Window win, unsigned int drag); +EAPI Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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 Eina_Bool 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_illume_clipboard_state_set(Ecore_X_Window win, Ecore_X_Illume_Clipboard_State state); + +EAPI Ecore_X_Illume_Clipboard_State ecore_x_e_illume_clipboard_state_get(Ecore_X_Window win); + +EAPI void ecore_x_e_illume_clipboard_geometry_set(Ecore_X_Window win, int x, int y, int w, int h); +EAPI Eina_Bool ecore_x_e_illume_clipboard_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h); +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_draw_size_done_send(Ecore_X_Window root, Ecore_X_Window win, int w, int h); +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 void ecore_x_e_comp_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pixmap); +EAPI Ecore_X_Pixmap ecore_x_e_comp_pixmap_get(Ecore_X_Window win); + +EAPI char *ecore_x_e_window_profile_get(Ecore_X_Window win); +EAPI void ecore_x_e_window_profile_set(Ecore_X_Window win, const char *profile); +EAPI void ecore_x_e_window_profile_list_set(Ecore_X_Window win, const char **profiles, unsigned int num_profiles); +EAPI Eina_Bool ecore_x_e_window_profile_list_get(Ecore_X_Window win, const char ***profiles, int *ret_num); + +EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter); +EAPI Eina_Bool ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm); +EAPI Eina_Bool 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_sync_counter_set(Ecore_X_Sync_Counter counter, int val); +EAPI void ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter, int val_hi, unsigned int val_lo); +EAPI Eina_Bool ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter, int *val_hi, unsigned int *val_lo); + +EAPI int ecore_x_xinerama_screen_count_get(void); +EAPI Eina_Bool ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h); + +EAPI Eina_Bool ecore_x_screensaver_event_available_get(void); +EAPI int ecore_x_screensaver_idle_time_get(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(Eina_Bool on); +EAPI Eina_Bool ecore_x_screensaver_custom_blanking_enable(void); /** @since 1.7 */ +EAPI Eina_Bool ecore_x_screensaver_custom_blanking_disable(void); /** @since 1.7 */ + +/* FIXME: these funcs need categorising */ + +typedef struct _Ecore_X_Window_Attributes +{ + Ecore_X_Window root; + int x, y, w, h; + int border; + int depth; + Eina_Bool visible : 1; + Eina_Bool viewable : 1; + Eina_Bool override : 1; + Eina_Bool input_only : 1; + Eina_Bool 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 Eina_Bool 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 Eina_Bool ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold); +EAPI Eina_Bool ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold); +EAPI Eina_Bool ecore_x_pointer_mapping_set(unsigned char *map, int nmap); +EAPI Eina_Bool ecore_x_pointer_mapping_get(unsigned char *map, int nmap); +EAPI Eina_Bool ecore_x_pointer_grab(Ecore_X_Window win); +EAPI Eina_Bool ecore_x_pointer_confine_grab(Ecore_X_Window win); +EAPI void ecore_x_pointer_ungrab(void); +EAPI Eina_Bool ecore_x_pointer_warp(Ecore_X_Window win, int x, int y); +EAPI Eina_Bool 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(Eina_Bool (*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(Ecore_X_Window win, int *x, int *y); + +/* ecore_x_region.c */ +EAPI Ecore_X_XRegion *ecore_x_xregion_new(void); +EAPI void ecore_x_xregion_free(Ecore_X_XRegion *region); +EAPI Eina_Bool 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 Eina_Bool ecore_x_xregion_intersect(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); +EAPI Eina_Bool ecore_x_xregion_union(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); +EAPI Eina_Bool ecore_x_xregion_union_rect(Ecore_X_XRegion *dst, Ecore_X_XRegion *src, Ecore_X_Rectangle *rect); +EAPI Eina_Bool ecore_x_xregion_subtract(Ecore_X_XRegion *dst, Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); +EAPI Eina_Bool ecore_x_xregion_is_empty(Ecore_X_XRegion *region); +EAPI Eina_Bool ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, Ecore_X_XRegion *r2); +EAPI Eina_Bool ecore_x_xregion_point_contain(Ecore_X_XRegion *region, int x, int y); +EAPI Eina_Bool ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, Ecore_X_Rectangle *rect); + +/* ecore_x_randr.c */ + +/* The usage of 'Ecore_X_Randr_None' or 'Ecore_X_Randr_Unset' + * depends on the context. In most cases 'Ecore_X_Randr_Unset' + * can be used, but in some cases -1 is a special value to + * functions, thus 'Ecore_X_Randr_None' (=0) must be used. + */ + +typedef short Ecore_X_Randr_Refresh_Rate; +typedef int Ecore_X_Randr_Crtc_Gamma; +typedef int Ecore_X_Randr_Signal_Format; +typedef int Ecore_X_Randr_Signal_Property; +typedef int Ecore_X_Randr_Connector_Type; + +typedef struct _Ecore_X_Randr_Mode_Info +{ + Ecore_X_ID xid; + unsigned int width; + unsigned int height; + unsigned long dotClock; + unsigned int hSyncStart; + unsigned int hSyncEnd; + unsigned int hTotal; + unsigned int hSkew; + unsigned int vSyncStart; + unsigned int vSyncEnd; + unsigned int vTotal; + char *name; + unsigned int nameLength; + unsigned long modeFlags; +} Ecore_X_Randr_Mode_Info; + +EAPI int ecore_x_randr_version_get(void); +EAPI Eina_Bool ecore_x_randr_query(void); + +/* ecore_x_randr_11.c */ +EAPI Ecore_X_Randr_Orientation ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root); +EAPI Ecore_X_Randr_Orientation ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root); +EAPI Eina_Bool ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Orientation orientation); +EAPI Ecore_X_Randr_Screen_Size_MM *ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, int *num); + +/** + * @brief get the current set size of a given screen's primary output + * @param root window which's primary output will be queried + * @param w the current size's width + * @param h the current size's height + * @param w_mm the current size's width in mm + * @param h_mm the current size's height in mm + * @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set() + */ +EAPI void ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm, int *size_index); +EAPI Eina_Bool ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, int size_index); +EAPI Ecore_X_Randr_Refresh_Rate ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root); +EAPI Ecore_X_Randr_Refresh_Rate *ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, int size_index, int *num); +EAPI Eina_Bool ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root, int size_index, Ecore_X_Randr_Refresh_Rate rate); + +/* ecore_x_randr_12.c */ +EAPI void ecore_x_randr_events_select(Ecore_X_Window win, Eina_Bool on); + +EAPI void ecore_x_randr_screen_current_size_get(Ecore_X_Window root, int *w, int *h, int *w_mm, int *h_mm); +EAPI void ecore_x_randr_screen_size_range_get(Ecore_X_Window root, int *wmin, int *hmin, int *wmax, int *hmax); +EAPI void ecore_x_randr_screen_reset(Ecore_X_Window root); +EAPI Eina_Bool ecore_x_randr_screen_current_size_set(Ecore_X_Window root, int w, int h, int w_mm, int h_mm); +EAPI Ecore_X_Randr_Mode_Info **ecore_x_randr_modes_info_get(Ecore_X_Window root, int *num); +EAPI Ecore_X_Randr_Mode ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info); +EAPI void ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode); +EAPI Ecore_X_Randr_Mode_Info *ecore_x_randr_mode_info_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode); +EAPI void ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info); +EAPI Ecore_X_Randr_Crtc *ecore_x_randr_crtcs_get(Ecore_X_Window root, int *num); +EAPI Ecore_X_Randr_Output *ecore_x_randr_outputs_get(Ecore_X_Window root, int *num); +EAPI Ecore_X_Randr_Output *ecore_x_randr_window_outputs_get(Ecore_X_Window window, int *num); +EAPI Ecore_X_Randr_Output *ecore_x_randr_current_output_get(Ecore_X_Window window, int *num); +EAPI Ecore_X_Randr_Crtc *ecore_x_randr_window_crtcs_get(Ecore_X_Window window, int *num); +EAPI Ecore_X_Randr_Crtc *ecore_x_randr_current_crtc_get(Ecore_X_Window window, int *num); +EAPI Ecore_X_Randr_Output *ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num); +EAPI Ecore_X_Randr_Output *ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *num); +EAPI void ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h); +EAPI void ecore_x_randr_crtc_pos_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y); +EAPI Eina_Bool ecore_x_randr_crtc_pos_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, int y); +EAPI Ecore_X_Randr_Mode ecore_x_randr_crtc_mode_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); +EAPI Eina_Bool ecore_x_randr_crtc_mode_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int noutputs, Ecore_X_Randr_Mode mode); +EAPI void ecore_x_randr_crtc_size_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *w, int *h); +EAPI Ecore_X_Randr_Refresh_Rate ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Mode mode); +EAPI Ecore_X_Randr_Orientation ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); +EAPI Ecore_X_Randr_Orientation ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); +EAPI Eina_Bool ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Orientation orientation); +EAPI Eina_Bool ecore_x_randr_crtc_clone_set(Ecore_X_Window root, Ecore_X_Randr_Crtc original, Ecore_X_Randr_Crtc clone); +EAPI Eina_Bool ecore_x_randr_crtc_settings_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, Ecore_X_Randr_Output *outputs, int noutputs, int x, int y, Ecore_X_Randr_Mode mode, Ecore_X_Randr_Orientation orientation); +EAPI Eina_Bool ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc_r1, Ecore_X_Randr_Crtc crtc_r2, Ecore_X_Randr_Output_Policy policy, Ecore_X_Randr_Relative_Alignment alignment); +EAPI Eina_Bool ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode); +EAPI void ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode); +EAPI Ecore_X_Randr_Mode *ecore_x_randr_output_modes_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num, int *npreferred); +EAPI Ecore_X_Randr_Output *ecore_x_randr_output_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); +EAPI Ecore_X_Randr_Crtc *ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); +EAPI Ecore_X_Randr_Crtc ecore_x_randr_output_crtc_get(Ecore_X_Window root, Ecore_X_Randr_Output output); +EAPI char *ecore_x_randr_output_name_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *len); +EAPI int ecore_x_randr_crtc_gamma_ramp_size_get(Ecore_X_Randr_Crtc crtc); +EAPI Ecore_X_Randr_Crtc_Gamma **ecore_x_randr_crtc_gamma_ramps_get(Ecore_X_Randr_Crtc crtc); +EAPI Eina_Bool ecore_x_randr_crtc_gamma_ramps_set(Ecore_X_Randr_Crtc crtc, const Ecore_X_Randr_Crtc_Gamma *red, const Ecore_X_Randr_Crtc_Gamma *green, const Ecore_X_Randr_Crtc_Gamma *blue); +EAPI Eina_Bool ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, const Ecore_X_Randr_Crtc *not_moved, int nnot_moved, int dx, int dy); +EAPI Eina_Bool ecore_x_randr_move_crtcs(Ecore_X_Window root, const Ecore_X_Randr_Crtc *crtcs, int ncrtc, int dx, int dy); +EAPI void ecore_x_randr_mode_size_get(Ecore_X_Window root, Ecore_X_Randr_Mode mode, int *w, int *h); +EAPI Ecore_X_Randr_Connection_Status ecore_x_randr_output_connection_status_get(Ecore_X_Window root, Ecore_X_Randr_Output output); +EAPI void ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w, int *h); +EAPI Eina_Bool ecore_x_randr_output_crtc_set(Ecore_X_Window root, Ecore_X_Randr_Output output, const Ecore_X_Randr_Crtc crtc); + +/* ecore_x_randr_12_edid.c */ + +/** + * @brief Validates the header from raw EDID data. + * + * @param edid The edid structure. + * @param edid_length Length of the edid structure. + * @return @c EINA_TRUE, if the header is valid, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Checks whether a display's EDID has a valid checksum. + * + * @param edid The edid structure. + * @param edid_length Length of the edid structure. + * @return @c EINA_TRUE, if the checksum is valid, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the encoded version from raw EDID data. + * + * The return value has the minor version in the lowest 8 bits, and the major + * version in all the rest of the bits. i.e. + * + * minor = (version & 0x000000ff); + * major = (version & 0xffffff00) >> 8; + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The encoded major and minor version encasuplated an int. + */ +EAPI int ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the encoded manufacturer from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The encoded manufacturer identifier. + */ +EAPI char *ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the encoded name from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The encoded manufacturer identifier. + */ +EAPI char *ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the encoded ASCII from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The encoded ASCII display identifier. + */ +EAPI char *ecore_x_randr_edid_display_ascii_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the encoded serial identifier from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The encoded serial identifier. + */ +EAPI char *ecore_x_randr_edid_display_serial_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the encoded model number from raw EDID data. + * + * The manufacturer ID table is necessary for a useful description. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The encoded model number. + */ +EAPI int ecore_x_randr_edid_model_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the manufacturer serial number from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The encoded serial manufacturer serial number. + */ +EAPI int ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the manufacturer model number from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The manufacturer's model number. + */ +EAPI int ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Looks up the DPMS support from raw EDID data. + * + * @param edid The edid structure. + * @param edid_length Length of the edid structure. + * @return @c EINA_TRUE, if DPMS is supported in some way, @c EINA_FALSE + * otherwise. + */ +EAPI Eina_Bool ecore_x_randr_edid_dpms_available_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Looks up the DPMS Standby support from raw EDID data. + * + * @param edid The edid structure. + * @param edid_length Length of the edid structure. + * @return @c EINA_TRUE, if DPMS Standby is supported, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Looks up the DPMS Suspend support from raw EDID data. + * + * @param edid The edid structure. + * @param edid_length Length of the edid structure. + * @return @c EINA_TRUE, if DPMS Suspend is supported, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Looks up the DPMS Off support from raw EDID data. + * + * @param edid The edid structure. + * @param edid_length Length of the edid structure. + * @return @c EINA_TRUE, if DPMS Off is supported, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the preferred aspect ratio from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The preferred aspect ratio. + */ +EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the supported aspect ratios from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The supported aspect ratios. + */ +EAPI Ecore_X_Randr_Edid_Aspect_Ratio ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the supported colorschemes from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The supported colorschemes. + */ +EAPI Ecore_X_Randr_Edid_Display_Colorscheme ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the display type from raw EDID data. + * + * @param edid The edid structure. + * @param edid_length Length of the edid structure. + * @return @c EINA_TRUE, if the display is a digital one, @c EINA_FALSE + * otherwise. + */ +EAPI Eina_Bool ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, unsigned long edid_length); + +/** + * @brief Get the display interface type from raw EDID data. + * + * @param edid the edid structure + * @param edid_length length of the edid structure + * @return The interface type. + */ +EAPI Ecore_X_Randr_Edid_Display_Interface_Type ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, unsigned long edid_length); + +/* ecore_x_randr_12.c */ + +EAPI Eina_Bool ecore_x_randr_output_backlight_available(void); +EAPI void ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, double level); +EAPI double ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, Ecore_X_Randr_Output output); +EAPI Eina_Bool ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, Ecore_X_Randr_Output output, double level); +EAPI Ecore_X_Randr_Output ecore_x_randr_primary_output_get(Ecore_X_Window root); +EAPI void ecore_x_randr_primary_output_set(Ecore_X_Window root, Ecore_X_Randr_Output output); +EAPI Ecore_X_Render_Subpixel_Order ecore_x_randr_output_subpixel_order_get(Ecore_X_Window root, Ecore_X_Randr_Output output); +EAPI unsigned char *ecore_x_randr_output_edid_get(Ecore_X_Window root, Ecore_X_Randr_Output output, unsigned long *length); +EAPI Ecore_X_Randr_Output *ecore_x_randr_output_wired_clones_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); +EAPI Ecore_X_Randr_Output **ecore_x_randr_output_compatibility_list_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); +EAPI Ecore_X_Randr_Signal_Format *ecore_x_randr_output_signal_formats_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); +EAPI Eina_Bool ecore_x_randr_output_signal_format_set(Ecore_X_Window root, Ecore_X_Randr_Output output, Ecore_X_Randr_Signal_Format *signal); +EAPI Ecore_X_Randr_Signal_Property *ecore_x_randr_output_signal_properties_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *num); +EAPI int ecore_x_randr_output_connector_number_get(Ecore_X_Window root, Ecore_X_Randr_Output output); +EAPI Ecore_X_Randr_Connector_Type ecore_x_randr_output_connector_type_get(Ecore_X_Window root, Ecore_X_Randr_Output output); +/* WTF - these dont exist in ecore-x!!!! +EAPI Eina_Rectangle *ecore_x_randr_crtc_panning_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h); +EAPI Eina_Bool ecore_x_randr_crtc_panning_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, const int y, const int w, const int h); +EAPI Eina_Rectangle *ecore_x_randr_crtc_tracking_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int *x, int *y, int *w, int *h); +EAPI Eina_Bool ecore_x_randr_crtc_tracking_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int x, const int y, const int w, const int h); +EAPI Eina_Rectangle *ecore_x_randr_crtc_border_area_get(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc); +EAPI Eina_Bool ecore_x_randr_crtc_border_area_set(Ecore_X_Window root, Ecore_X_Randr_Crtc crtc, int left, const int top, const int right, const int bottom); +*/ + +/* 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 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); + +/** + * xfixes selection notification request. + * + * This lets you choose which selections you want to get notifications for. + * @param selection The selection atom. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * @since 1.1.0 + */ +EAPI Eina_Bool ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection); + +/* XComposite Extension Support */ +EAPI Eina_Bool 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 void ecore_x_composite_window_events_disable(Ecore_X_Window win); +EAPI void ecore_x_composite_window_events_enable(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; + +struct _Ecore_X_Event_Xkb +{ + int group; +}; +typedef struct _Ecore_X_Event_Xkb Ecore_X_Event_Xkb; /** @since 1.7 */ + +EAPI Eina_Bool 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 Eina_Bool ecore_x_screen_is_composited(int screen); +EAPI void ecore_x_screen_is_composited_set(int screen, Ecore_X_Window win); + +EAPI Eina_Bool ecore_x_dpms_query(void); +EAPI Eina_Bool ecore_x_dpms_capable_get(void); +EAPI Eina_Bool ecore_x_dpms_enabled_get(void); +EAPI void ecore_x_dpms_enabled_set(int enabled); +EAPI void ecore_x_dpms_timeouts_get(unsigned int *standby, unsigned int *suspend, unsigned int *off); +EAPI Eina_Bool 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 Eina_Bool ecore_x_test_fake_key_down(const char *key); +EAPI Eina_Bool ecore_x_test_fake_key_up(const char *key); +EAPI Eina_Bool ecore_x_test_fake_key_press(const char *key); +EAPI const char *ecore_x_keysym_string_get(int keysym); + +/** + * Given a keyname, return the keycode representing that key + * @param keyname The key from which to get the keycode. + * @return The keycode of the key. + * + * @since 1.2.0 + */ +EAPI int ecore_x_keysym_keycode_get(const char *keyname); + +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, Ecore_X_GC gc, 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_image_is_argb32_get(Ecore_X_Image *im); + +EAPI Eina_Bool ecore_x_image_to_argb_convert(void *src, int sbpp, int sbpl, Ecore_X_Colormap c, Ecore_X_Visual v, int x, int y, int w, int h, unsigned int *dst, int dbpl, int dx, int dy); + +EAPI Eina_Bool ecore_x_input_multi_select(Ecore_X_Window win); +EAPI Eina_Bool ecore_x_input_raw_select(Ecore_X_Window win); /**< @since 1.8 */ + +EAPI Eina_Bool ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win); + +typedef enum _Ecore_X_Gesture_Event_Mask +{ + ECORE_X_GESTURE_EVENT_MASK_NONE = 0L, + ECORE_X_GESTURE_EVENT_MASK_FLICK = (1L << 0), + ECORE_X_GESTURE_EVENT_MASK_PAN = (1L << 1), + ECORE_X_GESTURE_EVENT_MASK_PINCHROTATION = (1L << 2), + ECORE_X_GESTURE_EVENT_MASK_TAP = (1L << 3), + ECORE_X_GESTURE_EVENT_MASK_TAPNHOLD = (1L << 4), + ECORE_X_GESTURE_EVENT_MASK_HOLD = (1L << 5), + ECORE_X_GESTURE_EVENT_MASK_GROUP = (1L << 6) +} Ecore_X_Gesture_Event_Mask; + +typedef enum _Ecore_X_Gesture_Event_Type +{ + ECORE_X_GESTURE_EVENT_FLICK, + ECORE_X_GESTURE_EVENT_PAN, + ECORE_X_GESTURE_EVENT_PINCHROTATION, + ECORE_X_GESTURE_EVENT_TAP, + ECORE_X_GESTURE_EVENT_TAPNHOLD, + ECORE_X_GESTURE_EVENT_HOLD, + ECORE_X_GESTURE_EVENT_GROUP +} Ecore_X_Gesture_Event_Type; + +typedef enum _Ecore_X_Gesture_Event_Subtype +{ + ECORE_X_GESTURE_END, + ECORE_X_GESTURE_BEGIN, + ECORE_X_GESTURE_UPDATE, + ECORE_X_GESTURE_DONE +} Ecore_X_Gesture_Event_Subtype; + +typedef enum _Ecore_X_Gesture_Group_Subtype +{ + ECORE_X_GESTURE_GROUP_REMOVED, + ECORE_X_GESTURE_GROUP_ADDED, + ECORE_X_GESTURE_GROUP_CURRENT +} Ecore_X_Gesture_Group_Subtype; + +typedef enum _Ecore_X_Gesture_Direction +{ + ECORE_X_GESTURE_NORTHWARD, + ECORE_X_GESTURE_NORTHEASTWARD, + ECORE_X_GESTURE_EASTWARD, + ECORE_X_GESTURE_SOUTHEASTWARD, + ECORE_X_GESTURE_SOUTHWARD, + ECORE_X_GESTURE_SOUTHWESTWARD, + ECORE_X_GESTURE_WESTWARD, + ECORE_X_GESTURE_NORTHWESTWARD +} Ecore_X_Gesture_Direction; + +struct _Ecore_X_Event_Gesture_Notify_Flick +{ + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Gesture_Event_Subtype subtype; + int num_fingers; + int distance; + Ecore_X_Time duration; + Ecore_X_Gesture_Direction direction; + double angle; +}; + +struct _Ecore_X_Event_Gesture_Notify_Pan +{ + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Gesture_Event_Subtype subtype; + int num_fingers; + int dx; + int dy; + int distance; + Ecore_X_Time duration; + Ecore_X_Gesture_Direction direction; +}; + +struct _Ecore_X_Event_Gesture_Notify_PinchRotation +{ + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Gesture_Event_Subtype subtype; + int num_fingers; + int distance; + int cx; + int cy; + double zoom; + double angle; +}; + +struct _Ecore_X_Event_Gesture_Notify_Tap +{ + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Gesture_Event_Subtype subtype; + int num_fingers; + int cx; + int cy; + int tap_repeat; + Ecore_X_Time interval; +}; + +struct _Ecore_X_Event_Gesture_Notify_TapNHold +{ + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Gesture_Event_Subtype subtype; + int num_fingers; + int cx; + int cy; + Ecore_X_Time interval; + Ecore_X_Time hold_time; +}; + +struct _Ecore_X_Event_Gesture_Notify_Hold +{ + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Gesture_Event_Subtype subtype; + int num_fingers; + int cx; + int cy; + Ecore_X_Time hold_time; +}; + +struct _Ecore_X_Event_Gesture_Notify_Group +{ + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Gesture_Group_Subtype subtype; + int num_groups; + int group_id; +}; + +EAPI Eina_Bool ecore_x_gesture_supported(void); + +EAPI Eina_Bool ecore_x_gesture_events_select(Ecore_X_Window win, Ecore_X_Gesture_Event_Mask mask); + +EAPI Ecore_X_Gesture_Event_Mask ecore_x_gesture_events_selected_get(Ecore_X_Window win); + +EAPI Eina_Bool ecore_x_gesture_event_grab(Ecore_X_Window win, Ecore_X_Gesture_Event_Type type, int num_fingers); + +EAPI Eina_Bool ecore_x_gesture_event_ungrab(Ecore_X_Window win, Ecore_X_Gesture_Event_Type type, int num_fingers); + +EAPI void ecore_x_e_illume_indicator_state_set(Ecore_X_Window win, Ecore_X_Illume_Indicator_State state); +EAPI Ecore_X_Illume_Indicator_State ecore_x_e_illume_indicator_state_get(Ecore_X_Window win); +EAPI void ecore_x_e_illume_indicator_state_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_State state); + +EAPI void ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win, Ecore_X_Illume_Indicator_Opacity_Mode mode); + +EAPI Ecore_X_Illume_Indicator_Opacity_Mode ecore_x_e_illume_indicator_opacity_get(Ecore_X_Window win); + +EAPI void ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, Ecore_X_Illume_Indicator_Opacity_Mode mode); + +EAPI void +ecore_x_e_illume_window_state_set(Ecore_X_Window win, + Ecore_X_Illume_Window_State state); + +EAPI Ecore_X_Illume_Window_State ecore_x_e_illume_window_state_get(Ecore_X_Window win); +EAPI void ecore_x_xkb_select_group(int group); /* @since 1.7 */ + +#ifdef __cplusplus +} +#endif // ifdef __cplusplus + +#include +#include + +#endif // ifndef _ECORE_X_H diff --git a/src/lib/ecore_x/Ecore_X_Atoms.h b/src/lib/ecore_x/Ecore_X_Atoms.h new file mode 100644 index 0000000000..ca6351d839 --- /dev/null +++ b/src/lib/ecore_x/Ecore_X_Atoms.h @@ -0,0 +1,292 @@ +#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; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_PIXMAP; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_VISUALID; + +/* 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; + +/* currently 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_ILLUME_INDICATOR_STATE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_ON; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN; + +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; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_COMP_PIXMAP; + +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION; + +/* currently elementary and E specific extension */ +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST; + +/* for sliding window */ +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY; + +/* for SDB(Samsung Debug Bridge) */ +EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT; +#endif /* _ECORE_X_ATOMS_H */ diff --git a/src/lib/ecore_x/Ecore_X_Cursor.h b/src/lib/ecore_x/Ecore_X_Cursor.h new file mode 100644 index 0000000000..807541e596 --- /dev/null +++ b/src/lib/ecore_x/Ecore_X_Cursor.h @@ -0,0 +1,87 @@ +#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_BOGOSITY 10 +#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 // ifndef _ECORE_X_CURSOR_H diff --git a/src/lib/ecore_x/ecore_x_atoms_decl.h b/src/lib/ecore_x/ecore_x_atoms_decl.h new file mode 100644 index 0000000000..155283efe6 --- /dev/null +++ b/src/lib/ecore_x/ecore_x_atoms_decl.h @@ -0,0 +1,602 @@ +/* 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; +EAPI Ecore_X_Atom ECORE_X_ATOM_PIXMAP = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_VISUALID = 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_ILLUME_INDICATOR_STATE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_ON = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE= 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN = 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; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_COMP_PIXMAP = 0; + +/* currently Emotion and E17 specific extension */ +EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_PARENT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_VIDEO_POSITION = 0; + +/* for sliding window */ +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY = 0; + +/* for SDB(Samsung Debug Bridge) */ +EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_CONNECT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_SDB_SERVER_DISCONNECT = 0; + +/* currently elementary and E specific extension */ +EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_E_PROFILE_LIST = 0; + +typedef struct _Atom_Item Atom_Item; + +struct _Atom_Item +{ + const char *name; + Ecore_X_Atom *atom; +}; + +const Atom_Item atom_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 }, + { "PIXMAP", &ECORE_X_ATOM_PIXMAP }, + { "VISUALID", &ECORE_X_ATOM_VISUALID }, + + { "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_ILLUME_INDICATOR_STATE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE }, + { "_E_ILLUME_INDICATOR_ON", &ECORE_X_ATOM_E_ILLUME_INDICATOR_ON }, + { "_E_ILLUME_INDICATOR_OFF", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF }, + { "_E_ILLUME_INDICATOR_OPACITY_MODE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE }, + { "_E_ILLUME_INDICATOR_OPAQUE", &ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE }, + { "_E_ILLUME_INDICATOR_TRANSLUCENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT }, + { "_E_ILLUME_INDICATOR_TRANSPARENT", &ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT }, + { "_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLES", &ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_AVAILABLE_ANGLE }, + { "_E_ILLUME_ROTATE_WINDOW_ANGLE", &ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE }, + { "_E_ILLUME_ROTATE_ROOT_ANGLE", &ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE }, + { "_E_ILLUME_CLIPBOARD_STATE", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE }, + { "_E_ILLUME_CLIPBOARD_ON", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON }, + { "_E_ILLUME_CLIPBOARD_OFF", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF }, + { "_E_ILLUME_CLIPBOARD_GEOMETRY", &ECORE_X_ATOM_E_ILLUME_CLIPBOARD_GEOMETRY }, + { "_E_ILLUME_WINDOW_STATE", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE }, + { "_E_ILLUME_WINDOW_STATE_NORMAL", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL }, + { "_E_ILLUME_WINDOW_STATE_FLOATING", &ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING }, + { "_E_ILLUME_ACCESS_CONTROL", &ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL }, + { "_E_ILLUME_ACCESS_ACTION_NEXT", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT }, + { "_E_ILLUME_ACCESS_ACTION_PREV", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV }, + { "_E_ILLUME_ACCESS_ACTION_ACTIVATE", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE }, + { "_E_ILLUME_ACCESS_ACTION_READ", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ }, + { "_E_ILLUME_ACCESS_ACTION_READ_NEXT", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT }, + { "_E_ILLUME_ACCESS_ACTION_READ_PREV", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV }, + { "_E_ILLUME_ACCESS_ACTION_UP", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP }, + { "_E_ILLUME_ACCESS_ACTION_DOWN", &ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN }, + { "_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 }, + { "_E_COMP_PIXMAP", &ECORE_X_ATOM_E_COMP_PIXMAP }, + { "_E_VIDEO_PARENT", &ECORE_X_ATOM_E_VIDEO_PARENT }, + { "_E_VIDEO_POSITION", &ECORE_X_ATOM_E_VIDEO_POSITION } +}; + diff --git a/src/lib/ecore_x/xcb/ecore_xcb.c b/src/lib/ecore_x/xcb/ecore_xcb.c new file mode 100644 index 0000000000..2f1e1a2601 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb.c @@ -0,0 +1,1583 @@ +#include "ecore_xcb_private.h" +#include +#include + +/* local function prototypes */ +static int _ecore_xcb_shutdown(Eina_Bool close_display); +static Eina_Bool _ecore_xcb_fd_handle(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED); +static Eina_Bool _ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED); +static Eina_Bool _ecore_xcb_idle_enter(void *data EINA_UNUSED); + +/* local variables */ +static int _ecore_xcb_init_count = 0; +static int _ecore_xcb_grab_count = 0; +static Ecore_Fd_Handler *_ecore_xcb_fd_handler = NULL; +static xcb_generic_event_t *_ecore_xcb_event_buffered = NULL; +static Ecore_Idle_Enterer *_ecore_xcb_idle_enterer = NULL; + +/* external variables */ +int _ecore_xcb_log_dom = -1; +Ecore_X_Display *_ecore_xcb_display = NULL; +Ecore_X_Connection *_ecore_xcb_conn = NULL; +Ecore_X_Screen *_ecore_xcb_screen = NULL; +Ecore_X_Atom _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_NUM]; +double _ecore_xcb_double_click_time = 0.25; + +/** + * @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) +{ + char *gl = NULL; + uint32_t mask, list[1]; + + /* check if we have initialized already */ + if (++_ecore_xcb_init_count != 1) + return _ecore_xcb_init_count; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* try to initialize eina */ + if (!eina_init()) return --_ecore_xcb_init_count; + + /* setup ecore_xcb log domain */ + _ecore_xcb_log_dom = + eina_log_domain_register("ecore_x", ECORE_XCB_DEFAULT_LOG_COLOR); + if (_ecore_xcb_log_dom < 0) + { + EINA_LOG_ERR("Cannot create Ecore Xcb log domain"); + eina_shutdown(); + return --_ecore_xcb_init_count; + } + + /* try to initialize ecore */ + if (!ecore_init()) + { + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + eina_shutdown(); + return --_ecore_xcb_init_count; + } + + /* try to initialize ecore_event */ + if (!ecore_event_init()) + { + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_shutdown(); + eina_shutdown(); + return --_ecore_xcb_init_count; + } + + /* NB: XLib has XInitThreads */ + + /* check for env var which says we are not going to use GL @ all + * + * NB: This is done because if someone wants a 'pure' xcb implementation + * of ecore_x, all they need do is export this variable in the environment + * and ecore_x will not use xlib stuff at all. + * + * The upside is you can get pure xcb-based ecore_x (w/ all the speed), but + * there is a down-side here in that you cannot get OpenGL without XLib :( + */ + if ((gl = getenv("ECORE_X_NO_XLIB"))) + { + /* we found the env var that says 'Yes, we are not ever gonna try + * OpenGL so it is safe to not use XLib at all' */ + + /* try to connect to the display server */ + _ecore_xcb_conn = xcb_connect(name, NULL); + } + else + { + /* env var was not specified, so we will assume that the user + * may want opengl @ some point. connect this way for opengl to work */ + void *libxcb, *libxlib; + Display *(*_real_display)(const char *display); + xcb_connection_t *(*_real_connection)(Display * dpy); + void (*_real_queue)(Display *dpy, enum XEventQueueOwner owner); + int (*_real_close)(Display *dpy); +#ifdef EVAS_FRAME_QUEUING + Status (*_real_threads)(void); +#endif + + /* want to dlopen here to avoid actual library linkage */ + libxlib = dlopen("libX11.so", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxlib) + libxlib = dlopen("libX11.so.6", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxlib) + libxlib = dlopen("libX11.so.6.3.0", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxlib) + { + ERR("Could not dlsym to libX11"); + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return --_ecore_xcb_init_count; + } + + libxcb = dlopen("libX11-xcb.so", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxcb) + libxcb = dlopen("libX11-xcb.so.1", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxcb) + libxcb = dlopen("libX11-xcb.so.1.0.0", (RTLD_LAZY | RTLD_GLOBAL)); + if (!libxcb) + { + ERR("Could not dlsym to libX11-xcb"); + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return --_ecore_xcb_init_count; + } + + _real_display = dlsym(libxlib, "XOpenDisplay"); + _real_close = dlsym(libxlib, "XCloseDisplay"); + _real_connection = dlsym(libxcb, "XGetXCBConnection"); + _real_queue = dlsym(libxcb, "XSetEventQueueOwner"); +#ifdef EVAS_FRAME_QUEUING + _real_threads = dlsym(libxlib, "XInitThreads"); +#endif + + if (_real_display) + { +#ifdef EVAS_FRAME_QUEUING + if (_real_threads) _real_threads(); +#endif + _ecore_xcb_display = _real_display(name); + if (!_ecore_xcb_display) + { + ERR("Could not open Display via XLib"); + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return --_ecore_xcb_init_count; + } + if (_real_connection) + _ecore_xcb_conn = _real_connection(_ecore_xcb_display); + if (!_ecore_xcb_conn) + { + ERR("Could not get XCB Connection from XLib"); + + if (_real_close) _real_close(_ecore_xcb_display); + + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return --_ecore_xcb_init_count; + } + if (_real_queue) + _real_queue(_ecore_xcb_display, XCBOwnsEventQueue); + } + } + + if (xcb_connection_has_error(_ecore_xcb_conn)) + { + CRIT("XCB Connection has error"); + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + ecore_event_shutdown(); + ecore_shutdown(); + eina_shutdown(); + return --_ecore_xcb_init_count; + } + + /* grab the default screen */ + _ecore_xcb_screen = + xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; + + /* NB: This method of init/finalize extensions first, then atoms + * Does end up being 2 round trips to X, BUT if we do extensions init then + * atoms init first, and call the 'finalize' functions later, we end up + * being slower, so it's a trade-off. This current method clocks in + * around 0.003 for fetching atoms VS 0.010 for init both then finalize */ + + /* prefetch extension data */ + _ecore_xcb_extensions_init(); + + /* finalize extensions */ + _ecore_xcb_extensions_finalize(); + + /* set keyboard autorepeat */ + mask = XCB_KB_AUTO_REPEAT_MODE; + list[0] = XCB_AUTO_REPEAT_MODE_ON; + xcb_change_keyboard_control(_ecore_xcb_conn, mask, list); + + /* setup xcb events */ + _ecore_xcb_events_init(); + + /* setup xcb keymasks */ + _ecore_xcb_keymap_init(); + + /* finalize xcb keymasks */ + _ecore_xcb_keymap_finalize(); + + /* setup ecore fd handler */ + _ecore_xcb_fd_handler = + ecore_main_fd_handler_add(xcb_get_file_descriptor(_ecore_xcb_conn), + ECORE_FD_READ, _ecore_xcb_fd_handle, + _ecore_xcb_conn, _ecore_xcb_fd_handle_buff, + _ecore_xcb_conn); + + if (!_ecore_xcb_fd_handler) + return _ecore_xcb_shutdown(EINA_TRUE); + + /* prefetch atoms */ + _ecore_xcb_atoms_init(); + + /* finalize atoms */ + _ecore_xcb_atoms_finalize(); + + /* icccm_init: dummy function */ + ecore_x_icccm_init(); + + /* setup netwm */ + ecore_x_netwm_init(); + + /* old e hints init: dummy function */ + ecore_x_e_init(); + + _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = + ECORE_X_ATOM_WM_DELETE_WINDOW; + _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = + ECORE_X_ATOM_WM_TAKE_FOCUS; + _ecore_xcb_atoms_wm_protocol[ECORE_X_NET_WM_PROTOCOL_PING] = + ECORE_X_ATOM_NET_WM_PING; + _ecore_xcb_atoms_wm_protocol[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = + ECORE_X_ATOM_NET_WM_SYNC_REQUEST; + + /* setup selection */ + _ecore_xcb_selection_init(); + + /* setup dnd */ + _ecore_xcb_dnd_init(); + + _ecore_xcb_idle_enterer = + ecore_idle_enterer_add(_ecore_xcb_idle_enter, NULL); + + 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_X_Init_Group + */ +EAPI int +ecore_x_shutdown(void) +{ + return _ecore_xcb_shutdown(EINA_TRUE); +} + +/** + * Shuts down the Ecore X library. + * + * As ecore_x_shutdown, except do not close Display, only connection. + * + * @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_disconnect(void) +{ + return _ecore_xcb_shutdown(EINA_FALSE); +} + +/** + * @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__); + + CHECK_XCB_CONN; + xcb_flush(_ecore_xcb_conn); +} + +/** + * Retrieves the Ecore_X_Screen handle used for the current X connection. + * @return The current default screen. + * @ingroup Ecore_X_Display_Attr_Group + */ +EAPI Ecore_X_Screen * +ecore_x_default_screen_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return (Ecore_X_Screen *)_ecore_xcb_screen; +} + +EAPI Ecore_X_Connection * +ecore_x_connection_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + CHECK_XCB_CONN; + return (Ecore_X_Connection *)_ecore_xcb_conn; +} + +/** + * Return the last event time + */ +EAPI Ecore_X_Time +ecore_x_current_time_get(void) +{ + return _ecore_xcb_events_last_time_get(); +} + +/** + * 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__); + + CHECK_XCB_CONN; + free(xcb_get_input_focus_reply(_ecore_xcb_conn, + xcb_get_input_focus_unchecked(_ecore_xcb_conn), + NULL)); +} + +EAPI void +ecore_x_grab(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + CHECK_XCB_CONN; + _ecore_xcb_grab_count++; + if (_ecore_xcb_grab_count == 1) + xcb_grab_server(_ecore_xcb_conn); +} + +EAPI void +ecore_x_ungrab(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + CHECK_XCB_CONN; + _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); +} + +/** + * 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 mask The mask of the message to be sent. + * @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 @c EINA_TRUE on success @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +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) +{ + xcb_client_message_event_t ev; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = type; + ev.data.data32[0] = (uint32_t)d0; + ev.data.data32[1] = (uint32_t)d1; + ev.data.data32[2] = (uint32_t)d2; + ev.data.data32[3] = (uint32_t)d3; + ev.data.data32[4] = (uint32_t)d4; + + cookie = xcb_send_event(_ecore_xcb_conn, 0, win, mask, (const char *)&ev); + + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + DBG("Problem Sending Event"); + DBG("\tType: %d", type); + DBG("\tWin: %d", win); + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +/** + * 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 @c 20. + * + * @return @c EINA_TRUE on success @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, + const void *data, int len) +{ + xcb_client_message_event_t ev; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 8; + ev.window = win; + ev.type = type; + if (len > 20) len = 20; + memcpy(ev.data.data8, data, len); + memset(ev.data.data8 + len, 0, 20 - len); + + cookie = xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); + + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + DBG("Problem Sending Event"); + DBG("\tType: %d", type); + DBG("\tWin: %d", win); + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_mouse_down_send(Ecore_X_Window win, int x, int y, int b) +{ + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *reply; + xcb_button_press_event_t ev; + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + Ecore_X_Window root = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + root = ecore_x_window_root_get(win); + cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); + reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + memset(&ev, 0, sizeof(xcb_button_press_event_t)); + + ev.response_type = XCB_BUTTON_PRESS; + ev.event = win; + ev.child = win; + ev.root = root; + ev.event_x = x; + ev.event_y = y; + ev.same_screen = 1; + ev.state = 1 << b; + ev.detail = b; // xcb uses detail for button + ev.root_x = reply->dst_x; + ev.root_y = reply->dst_y; + ev.time = ecore_x_current_time_get(); + free(reply); + + vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, + XCB_EVENT_MASK_BUTTON_PRESS, (const char *)&ev); + + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_mouse_up_send(Ecore_X_Window win, int x, int y, int b) +{ + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *reply; + xcb_button_release_event_t ev; + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + Ecore_X_Window root = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + root = ecore_x_window_root_get(win); + cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); + reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + memset(&ev, 0, sizeof(xcb_button_release_event_t)); + + ev.response_type = XCB_BUTTON_RELEASE; + ev.event = win; + ev.child = win; + ev.root = root; + ev.event_x = x; + ev.event_y = y; + ev.same_screen = 1; + ev.state = 0; + ev.root_x = reply->dst_x; + ev.root_y = reply->dst_y; + ev.detail = b; // xcb uses detail for button + ev.time = ecore_x_current_time_get(); + free(reply); + + vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, + XCB_EVENT_MASK_BUTTON_RELEASE, (const char *)&ev); + + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_mouse_move_send(Ecore_X_Window win, int x, int y) +{ + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *reply; + xcb_motion_notify_event_t ev; + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + Ecore_X_Window root = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + root = ecore_x_window_root_get(win); + cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); + reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + memset(&ev, 0, sizeof(xcb_motion_notify_event_t)); + + ev.response_type = XCB_MOTION_NOTIFY; + ev.event = win; + ev.child = win; + ev.root = root; + ev.event_x = x; + ev.event_y = y; + ev.same_screen = 1; + ev.state = 0; + ev.detail = 0; // xcb uses 'detail' for is_hint + ev.root_x = reply->dst_x; + ev.root_y = reply->dst_y; + ev.time = ecore_x_current_time_get(); + free(reply); + + vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, + XCB_EVENT_MASK_POINTER_MOTION, (const char *)&ev); + + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_mouse_in_send(Ecore_X_Window win, int x, int y) +{ + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *reply; + xcb_enter_notify_event_t ev; + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + Ecore_X_Window root = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + root = ecore_x_window_root_get(win); + cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); + reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + memset(&ev, 0, sizeof(xcb_enter_notify_event_t)); + + ev.response_type = XCB_ENTER_NOTIFY; + ev.event = win; + ev.child = win; + ev.root = root; + ev.event_x = x; + ev.event_y = y; + ev.same_screen_focus = 1; + ev.mode = XCB_NOTIFY_MODE_NORMAL; + ev.detail = XCB_NOTIFY_DETAIL_NONLINEAR; + /* ev.focus = 0; */ + ev.state = 0; + ev.root_x = reply->dst_x; + ev.root_y = reply->dst_y; + ev.time = ecore_x_current_time_get(); + free(reply); + + vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, + XCB_EVENT_MASK_ENTER_WINDOW, (const char *)&ev); + + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_mouse_out_send(Ecore_X_Window win, int x, int y) +{ + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *reply; + xcb_leave_notify_event_t ev; + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + Ecore_X_Window root = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + root = ecore_x_window_root_get(win); + cookie = xcb_translate_coordinates(_ecore_xcb_conn, win, root, x, y); + reply = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + memset(&ev, 0, sizeof(xcb_leave_notify_event_t)); + + ev.response_type = XCB_LEAVE_NOTIFY; + ev.event = win; + ev.child = win; + ev.root = root; + ev.event_x = x; + ev.event_y = y; + ev.same_screen_focus = 1; + ev.mode = XCB_NOTIFY_MODE_NORMAL; + ev.detail = XCB_NOTIFY_DETAIL_NONLINEAR; + /* ev.focus = 0; */ + ev.state = 0; + ev.root_x = reply->dst_x; + ev.root_y = reply->dst_y; + ev.time = ecore_x_current_time_get(); + free(reply); + + vcookie = xcb_send_event(_ecore_xcb_conn, 1, win, + XCB_EVENT_MASK_LEAVE_WINDOW, (const char *)&ev); + + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_keyboard_grab(Ecore_X_Window win) +{ + xcb_grab_keyboard_cookie_t cookie; + xcb_grab_keyboard_reply_t *reply; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = + xcb_grab_keyboard_unchecked(_ecore_xcb_conn, 0, win, XCB_CURRENT_TIME, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); + reply = xcb_grab_keyboard_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + free(reply); + return EINA_TRUE; +} + +EAPI void +ecore_x_keyboard_ungrab(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_ungrab_keyboard(_ecore_xcb_conn, XCB_CURRENT_TIME); +} + +EAPI void +ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y) +{ + xcb_query_pointer_cookie_t cookie; + xcb_query_pointer_reply_t *reply; + +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +// if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (x) *x = -1; + if (y) *y = -1; + + cookie = xcb_query_pointer_unchecked(_ecore_xcb_conn, win); + reply = xcb_query_pointer_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + if (x) *x = reply->win_x; + if (y) *y = reply->win_y; + free(reply); +} + +EAPI Eina_Bool +ecore_x_pointer_control_set(int accel_num, int accel_denom, int threshold) +{ + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + vcookie = + xcb_change_pointer_control_checked(_ecore_xcb_conn, + accel_num, accel_denom, threshold, + 1, 1); + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_pointer_control_get(int *accel_num, int *accel_denom, int *threshold) +{ + xcb_get_pointer_control_cookie_t cookie; + xcb_get_pointer_control_reply_t *reply; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (accel_num) *accel_num = 0; + if (accel_denom) *accel_denom = 0; + if (threshold) *threshold = 0; + + cookie = xcb_get_pointer_control_unchecked(_ecore_xcb_conn); + reply = xcb_get_pointer_control_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + if (accel_num) *accel_num = reply->acceleration_numerator; + if (accel_denom) *accel_denom = reply->acceleration_denominator; + if (threshold) *threshold = reply->threshold; + free(reply); + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_pointer_mapping_set(unsigned char *map, int nmap) +{ + xcb_set_pointer_mapping_cookie_t cookie; + xcb_set_pointer_mapping_reply_t *reply; + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_set_pointer_mapping_unchecked(_ecore_xcb_conn, nmap, map); + reply = xcb_set_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + if (reply->status == XCB_MAPPING_STATUS_SUCCESS) + ret = EINA_TRUE; + + free(reply); + return ret; +} + +EAPI Eina_Bool +ecore_x_pointer_mapping_get(unsigned char *map, int nmap) +{ + xcb_get_pointer_mapping_cookie_t cookie; + xcb_get_pointer_mapping_reply_t *reply; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (map) *map = 0; + nmap = 0; + + cookie = xcb_get_pointer_mapping_unchecked(_ecore_xcb_conn); + reply = xcb_get_pointer_mapping_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + nmap = xcb_get_pointer_mapping_map_length(reply); + if (nmap <= 0) + { + free(reply); + return EINA_FALSE; + } + + if (map) + { + uint8_t *tmp; + int i = 0; + + tmp = xcb_get_pointer_mapping_map(reply); + for (i = 0; i < nmap; i++) + map[i] = tmp[i]; + } + + free(reply); + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_pointer_grab(Ecore_X_Window win) +{ + xcb_grab_pointer_cookie_t cookie; + xcb_grab_pointer_reply_t *reply; + uint16_t mask; + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + mask = (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); + + cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, win, mask, + 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 EINA_FALSE; + + ret = (reply->status == XCB_GRAB_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE; + + free(reply); + return ret; +} + +EAPI Eina_Bool +ecore_x_pointer_confine_grab(Ecore_X_Window win) +{ + xcb_grab_pointer_cookie_t cookie; + xcb_grab_pointer_reply_t *reply; + uint16_t mask; + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + mask = (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); + + cookie = xcb_grab_pointer_unchecked(_ecore_xcb_conn, 0, win, mask, + XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_ASYNC, + win, XCB_NONE, XCB_CURRENT_TIME); + reply = xcb_grab_pointer_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + ret = (reply->status == XCB_GRAB_STATUS_SUCCESS) ? EINA_TRUE : EINA_FALSE; + + free(reply); + return ret; +} + +EAPI void +ecore_x_pointer_ungrab(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_ungrab_pointer(_ecore_xcb_conn, XCB_CURRENT_TIME); +} + +EAPI Eina_Bool +ecore_x_pointer_warp(Ecore_X_Window win, int x, int y) +{ + xcb_void_cookie_t vcookie; + xcb_generic_error_t *err; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + vcookie = + xcb_warp_pointer_checked(_ecore_xcb_conn, XCB_NONE, win, 0, 0, 0, 0, x, y); + err = xcb_request_check(_ecore_xcb_conn, vcookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +/** + * Invoke the standard system beep to alert users + * + * @param percent The volume at which the bell rings. Must be in the range + * [-100,+100]. If percent >= 0, the final volume will be: + * base - [(base * percent) / 100] + percent + * Otherwise, it's calculated as: + * base + [(base * percent) / 100] + * where @c base is the bell's base volume as set by XChangeKeyboardControl(3). + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_bell(int percent) +{ + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; + + CHECK_XCB_CONN; + + // FIXME: Use unchecked version after development is ironed out + cookie = xcb_bell_checked(_ecore_xcb_conn, percent); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI void +ecore_x_display_size_get(Ecore_X_Display *dsp EINA_UNUSED, int *w, int *h) +{ + xcb_screen_t *screen; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + /* grab the default screen */ + screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; + if (w) *w = screen->width_in_pixels; + if (h) *h = screen->height_in_pixels; +} + +EAPI unsigned long +ecore_x_display_black_pixel_get(Ecore_X_Display *dsp EINA_UNUSED) +{ + xcb_screen_t *screen; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + /* grab the default screen */ + screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; + return screen->black_pixel; +} + +EAPI unsigned long +ecore_x_display_white_pixel_get(Ecore_X_Display *dsp EINA_UNUSED) +{ + xcb_screen_t *screen; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + /* grab the default screen */ + screen = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).data; + return screen->white_pixel; +} + +EAPI void +ecore_x_pointer_last_xy_get(int *x, int *y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (x) *x = _ecore_xcb_event_last_root_x; + if (y) *y = _ecore_xcb_event_last_root_y; +} + +EAPI void +ecore_x_focus_reset(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_POINTER_ROOT, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + XCB_CURRENT_TIME); +// ecore_x_flush(); +} + +EAPI void +ecore_x_events_allow_all(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_allow_events(_ecore_xcb_conn, XCB_ALLOW_ASYNC_BOTH, XCB_CURRENT_TIME); +// ecore_x_flush(); +} + +/** + * 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__); + CHECK_XCB_CONN; + + xcb_kill_client(_ecore_xcb_conn, win); +// ecore_x_flush(); +} + +/** + * 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 = 0, i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + ecore_x_grab(); + + screens = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem; + + /* Traverse 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_t *wins = NULL; + int tree_c_len, j = 0; + + wins = xcb_query_tree_children(reply); + tree_c_len = xcb_query_tree_children_length(reply); + for (j = 0; j < tree_c_len; j++) + xcb_kill_client(_ecore_xcb_conn, wins[j]); + free(reply); + } + } + + ecore_x_ungrab(); + ecore_x_sync(); // needed +} + +/** + * 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 account 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) +{ + uint16_t mw = 0, w = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + mw = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_millimeters; + if (mw <= 0) return 75; + w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; + return (((w * 254) / mw) + 5) / 10; +} + +/** + * @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) +{ + char *gl = NULL; + + CHECK_XCB_CONN; + + /* if we have the 'dont use xlib' env var, then we are not using + * XLib and thus cannot return a real XDisplay. + * + * NB: This may break EFL in some places and needs lots of testing !!! */ + if ((gl = getenv("ECORE_X_NO_XLIB"))) + return (Ecore_X_Display *)_ecore_xcb_conn; + else /* we can safely return an XDisplay var */ + return (Ecore_X_Display *)_ecore_xcb_display; +} + +/** + * 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__); + CHECK_XCB_CONN; + return xcb_get_file_descriptor(_ecore_xcb_conn); +} + +EAPI void +ecore_x_passive_grab_replay_func_set(Eina_Bool (*func)(void *data, int type, void *event), + void *data) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_window_grab_replay_func = func; + _ecore_xcb_window_grab_replay_data = data; +} + +/** + * Retrieves the size of an Ecore_X_Screen. + * @param screen the handle to the screen to query. + * @param w where to return the width. May be NULL. Returns 0 on errors. + * @param h where to return the height. May be NULL. Returns 0 on errors. + * @ingroup Ecore_X_Display_Attr_Group + * @see ecore_x_default_screen_get() + * + * @since 1.1 + */ +EAPI void +ecore_x_screen_size_get(const Ecore_X_Screen *screen, int *w, int *h) +{ + xcb_screen_t *s; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (w) *w = 0; + if (h) *h = 0; + if (!(s = (xcb_screen_t *)screen)) return; + if (w) *w = s->width_in_pixels; + if (h) *h = s->height_in_pixels; +} + +/** + * Retrieves the count of screens. + * + * @return The count of screens. + * @ingroup Ecore_X_Display_Attr_Group + * + * @since 1.1 + */ +EAPI int +ecore_x_screen_count_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + return xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); +} + +/** + * Retrieves the index number of the given screen. + * + * @param screen The screen for which index will be gotten. + * @return The index number of the screen. + * @ingroup Ecore_X_Display_Attr_Group + * + * @since 1.1 + */ +EAPI int +ecore_x_screen_index_get(const Ecore_X_Screen *screen) +{ + xcb_screen_iterator_t iter; + int i = 0; + + CHECK_XCB_CONN; + + iter = + xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); + for (; iter.rem; xcb_screen_next(&iter)) + { + if (iter.data == (xcb_screen_t *)screen) + return i; + i++; + } + + return 0; +} + +/** + * Retrieves the screen based on index number. + * + * @param idx The index that will be used to retrieve the screen. + * @return The Ecore_X_Screen at this index. + * @ingroup Ecore_X_Display_Attr_Group + * + * @since 1.1 + */ +EAPI Ecore_X_Screen * +ecore_x_screen_get(int idx) +{ + xcb_screen_iterator_t iter; + int i = 0; + + CHECK_XCB_CONN; + + iter = + xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); + for (i = 0; iter.rem; xcb_screen_next(&iter), i++) + if (i == idx) return iter.data; + + return NULL; +} + +EAPI unsigned int +ecore_x_visual_id_get(Ecore_X_Visual visual) +{ + return ((xcb_visualtype_t *)visual)->visual_id; +} + +/** + * Retrieve the default Visual. + * + * @param disp The Display to get the Default Visual from + * @param screen The Screen. + * + * @return The default visual. + * @since 1.1.0 + */ +EAPI Ecore_X_Visual +ecore_x_default_visual_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen) +{ + xcb_screen_t *s; + xcb_depth_iterator_t diter; + xcb_visualtype_iterator_t viter; + + CHECK_XCB_CONN; + + s = (xcb_screen_t *)screen; + diter = xcb_screen_allowed_depths_iterator(s); + for (; diter.rem; xcb_depth_next(&diter)) + { + viter = xcb_depth_visuals_iterator(diter.data); + for (; viter.rem; xcb_visualtype_next(&viter)) + { + if (viter.data->visual_id == s->root_visual) + return viter.data; + } + } + return 0; +} + +/** + * Retrieve the default Colormap. + * + * @param disp The Display to get the Default Colormap from + * @param screen The Screen. + * + * @return The default colormap. + * @since 1.1.0 + */ +EAPI Ecore_X_Colormap +ecore_x_default_colormap_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen) +{ + xcb_screen_t *s; + + s = (xcb_screen_t *)screen; + return s->default_colormap; +} + +/** + * Retrieve the default depth. + * + * @param disp The Display to get the Default Depth from + * @param screen The Screen. + * + * @return The default depth. + * @since 1.1.0 + */ +EAPI int +ecore_x_default_depth_get(Ecore_X_Display *disp EINA_UNUSED, Ecore_X_Screen *screen) +{ + xcb_screen_t *s; + + s = (xcb_screen_t *)screen; + return s->root_depth; +} + +EAPI void +ecore_x_xkb_select_group(int group) +{ + // XXX: implement me */ +} + +/** + * 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_xcb_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_xcb_double_click_time; +} + +/* local function prototypes */ +static int +_ecore_xcb_shutdown(Eina_Bool close_display) +{ + if (--_ecore_xcb_init_count != 0) + return _ecore_xcb_init_count; + + if (!_ecore_xcb_conn) + return _ecore_xcb_init_count; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + ecore_idle_enterer_del(_ecore_xcb_idle_enterer); + _ecore_xcb_idle_enterer = NULL; + + if (_ecore_xcb_fd_handler) + ecore_main_fd_handler_del(_ecore_xcb_fd_handler); + + /* disconnect from display server */ + if (close_display) + xcb_disconnect(_ecore_xcb_conn); + else + { + close(xcb_get_file_descriptor(_ecore_xcb_conn)); + _ecore_xcb_conn = NULL; + } + + /* shutdown events */ + _ecore_xcb_events_shutdown(); + + /* shutdown input extension */ + _ecore_xcb_input_shutdown(); + + /* shutdown gesture extension */ + _ecore_xcb_gesture_shutdown(); + + /* shutdown selection */ + _ecore_xcb_selection_shutdown(); + + /* shutdown dnd */ + _ecore_xcb_dnd_shutdown(); + + /* shutdown netwm */ + ecore_x_netwm_shutdown(); + + /* shutdown keymap */ + _ecore_xcb_keymap_shutdown(); + + /* shutdown ecore_event */ + ecore_event_shutdown(); + + /* shutdown ecore */ + ecore_shutdown(); + + /* unregister log domain */ + eina_log_domain_unregister(_ecore_xcb_log_dom); + _ecore_xcb_log_dom = -1; + + /* shutdown eina */ + eina_shutdown(); + + return _ecore_xcb_init_count; +} + +static Eina_Bool +_ecore_xcb_fd_handle(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) +{ + xcb_connection_t *conn; + xcb_generic_event_t *ev = NULL; + + conn = (xcb_connection_t *)data; + + if (_ecore_xcb_event_buffered) + { + _ecore_xcb_events_handle(_ecore_xcb_event_buffered); + free(_ecore_xcb_event_buffered); + _ecore_xcb_event_buffered = NULL; + } + +// xcb_flush(conn); + + while ((ev = xcb_poll_for_event(conn))) + { + /* NB: Ecore Xlib uses filterevent for xim, but xcb does not support + * xim, so no need for it here */ + + /* check for errors first */ + if (xcb_connection_has_error(conn)) + { + xcb_generic_error_t *err; + + err = (xcb_generic_error_t *)ev; + _ecore_xcb_io_error_handle(err); + } + else + { + /* FIXME: Filter event for XIM */ + _ecore_xcb_events_handle(ev); + free(ev); + } + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_ecore_xcb_fd_handle_buff(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) +{ + xcb_connection_t *conn; + xcb_generic_event_t *ev = NULL; + + conn = (xcb_connection_t *)data; + ev = xcb_poll_for_event(conn); + if (ev) + { + /* check for errors first */ + if (xcb_connection_has_error(conn)) + { + xcb_generic_error_t *err; + + err = (xcb_generic_error_t *)ev; + _ecore_xcb_io_error_handle(err); + return ECORE_CALLBACK_CANCEL; + } + _ecore_xcb_event_buffered = ev; + return ECORE_CALLBACK_RENEW; + } + return ECORE_CALLBACK_CANCEL; +} + +static Eina_Bool +_ecore_xcb_idle_enter(void *data EINA_UNUSED) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_flush(_ecore_xcb_conn); + return ECORE_CALLBACK_RENEW; +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_atoms.c b/src/lib/ecore_x/xcb/ecore_xcb_atoms.c new file mode 100644 index 0000000000..c8c217eec7 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_atoms.c @@ -0,0 +1,149 @@ +#include "ecore_xcb_private.h" +#include "ecore_x_atoms_decl.h" + +/* NB: Increment if you add new atoms */ +#define ECORE_X_ATOMS_COUNT 199 + +/* local function prototypes */ + +/* local variables */ +static xcb_intern_atom_cookie_t cookies[ECORE_X_ATOMS_COUNT]; + +void +_ecore_xcb_atoms_init(void) +{ + int i = 0, num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + num = (sizeof(atom_items) / sizeof(Atom_Item)); + for (i = 0; i < num; i++) + { + cookies[i] = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, + strlen(atom_items[i].name), atom_items[i].name); + } +} + +void +_ecore_xcb_atoms_finalize(void) +{ + int i = 0, num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + num = (sizeof(atom_items) / sizeof(Atom_Item)); + for (i = 0; i < num; i++) + { + xcb_intern_atom_reply_t *reply = NULL; + + if (!(reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], 0))) + continue; + *(atom_items[i].atom) = reply->atom; + free(reply); + } +} + +/** + * @defgroup Ecore_X_Atom_Group XCB Atom Functions + * + * Functions that operate on atoms + */ + +/** + * 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. + * + * @ingroup Ecore_X_Atom_Group + */ +EAPI Ecore_X_Atom +ecore_x_atom_get(const char *name) +{ + xcb_intern_atom_cookie_t cookie; + xcb_intern_atom_reply_t *reply; + Ecore_X_Atom a; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(name), name); + reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return XCB_ATOM_NONE; + a = reply->atom; + free(reply); + return a; +} + +/** + * Retrieves the name of the given atom. + * + * @param atom + * @return The name of the atom. + * + * @ingroup Ecore_X_Atom_Group + */ +EAPI char * +ecore_x_atom_name_get(Ecore_X_Atom atom) +{ + xcb_get_atom_name_cookie_t cookie; + xcb_get_atom_name_reply_t *reply; + char *name; + int len = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, atom); + reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + len = xcb_get_atom_name_name_length(reply); + name = (char *)malloc(sizeof(char) * (len + 1)); + if (!name) + { + free(reply); + return NULL; + } + memcpy(name, xcb_get_atom_name_name(reply), len); + name[len] = '\0'; + + free(reply); + return name; +} + +EAPI void +ecore_x_atoms_get(const char **names, + int num, + Ecore_X_Atom *atoms) +{ + xcb_intern_atom_cookie_t cookies[num]; + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + for (i = 0; i < num; i++) + { + cookies[i] = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, + strlen(names[i]), names[i]); + } + for (i = 0; i < num; i++) + { + xcb_intern_atom_reply_t *reply = NULL; + + if (!(reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookies[i], 0))) + continue; + atoms[i] = reply->atom; + free(reply); + } +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_composite.c b/src/lib/ecore_x/xcb/ecore_xcb_composite.c new file mode 100644 index 0000000000..0d3b44e4aa --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_composite.c @@ -0,0 +1,290 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_COMPOSITE +# include +#endif + +/* local variables */ +static Eina_Bool _composite_avail = EINA_FALSE; + +void +_ecore_xcb_composite_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_COMPOSITE + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_composite_id); +#endif +} + +void +_ecore_xcb_composite_finalize(void) +{ +#ifdef ECORE_XCB_COMPOSITE + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_COMPOSITE + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_composite_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_composite_query_version_cookie_t cookie; + xcb_composite_query_version_reply_t *reply; + + cookie = + xcb_composite_query_version_unchecked(_ecore_xcb_conn, + XCB_COMPOSITE_MAJOR_VERSION, + XCB_COMPOSITE_MINOR_VERSION); + reply = + xcb_composite_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { +// if ((reply->major_version >= XCB_COMPOSITE_MAJOR_VERSION) && + if (reply->minor_version >= XCB_COMPOSITE_MINOR_VERSION) + { +# ifdef ECORE_XCB_RENDER + if (_ecore_xcb_render_avail_get()) + { +# ifdef ECORE_XCB_XFIXES + if (_ecore_xcb_xfixes_avail_get()) + _composite_avail = EINA_TRUE; +# endif + } +# endif + } + + free(reply); + } + } +#endif +} + +/** + * @defgroup Ecore_X_Composite_Group X Composite Extension Functions + * + * Functions related to the X Composite Extension + */ + +/** + * Return whether the Composite Extension is available + * + * @return @c EINA_TRUE is the Composite Extension is available, @c EINA_FALSE + * if not. + * + * @ingroup Ecore_X_Composite_Group + */ +EAPI Eina_Bool +ecore_x_composite_query(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return _composite_avail; +} + +EAPI void +ecore_x_composite_redirect_window(Ecore_X_Window win, + Ecore_X_Composite_Update_Type type) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return; + +#ifdef ECORE_XCB_COMPOSITE + uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + + switch (type) + { + case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: + update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + break; + + case ECORE_X_COMPOSITE_UPDATE_MANUAL: + update = XCB_COMPOSITE_REDIRECT_MANUAL; + break; + } + xcb_composite_redirect_window(_ecore_xcb_conn, win, update); +// ecore_x_flush(); +#endif +} + +EAPI void +ecore_x_composite_redirect_subwindows(Ecore_X_Window win, + Ecore_X_Composite_Update_Type type) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return; + +#ifdef ECORE_XCB_COMPOSITE + uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + + switch (type) + { + case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: + update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + break; + + case ECORE_X_COMPOSITE_UPDATE_MANUAL: + update = XCB_COMPOSITE_REDIRECT_MANUAL; + break; + } + xcb_composite_redirect_subwindows(_ecore_xcb_conn, win, update); +// ecore_x_flush(); +#endif +} + +EAPI void +ecore_x_composite_unredirect_window(Ecore_X_Window win, + Ecore_X_Composite_Update_Type type) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return; + +#ifdef ECORE_XCB_COMPOSITE + uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + + switch (type) + { + case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: + update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + break; + + case ECORE_X_COMPOSITE_UPDATE_MANUAL: + update = XCB_COMPOSITE_REDIRECT_MANUAL; + break; + } + xcb_composite_unredirect_window(_ecore_xcb_conn, win, update); +// ecore_x_flush(); +#endif +} + +EAPI void +ecore_x_composite_unredirect_subwindows(Ecore_X_Window win, + Ecore_X_Composite_Update_Type type) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return; + +#ifdef ECORE_XCB_COMPOSITE + uint8_t update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + + switch (type) + { + case ECORE_X_COMPOSITE_UPDATE_AUTOMATIC: + update = XCB_COMPOSITE_REDIRECT_AUTOMATIC; + break; + + case ECORE_X_COMPOSITE_UPDATE_MANUAL: + update = XCB_COMPOSITE_REDIRECT_MANUAL; + break; + } + xcb_composite_unredirect_subwindows(_ecore_xcb_conn, win, update); +// ecore_x_flush(); +#endif +} + +EAPI Ecore_X_Pixmap +ecore_x_composite_name_window_pixmap_get(Ecore_X_Window win) +{ +#ifdef ECORE_XCB_COMPOSITE + Ecore_X_Pixmap pmap = XCB_NONE; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return XCB_NONE; + +#ifdef ECORE_XCB_COMPOSITE + pmap = xcb_generate_id(_ecore_xcb_conn); + xcb_composite_name_window_pixmap(_ecore_xcb_conn, win, pmap); +// ecore_x_flush(); +#endif + + return pmap; +} + +EAPI void +ecore_x_composite_window_events_disable(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return; + +#ifdef ECORE_XCB_SHAPE + ecore_x_window_shape_input_rectangle_set(win, -1, -1, 1, 1); +// ecore_x_flush(); +#else + return; + win = 0; +#endif +} + +EAPI void +ecore_x_composite_window_events_enable(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return; + +#ifdef ECORE_XCB_SHAPE + ecore_x_window_shape_input_rectangle_set(win, 0, 0, 65535, 65535); +// ecore_x_flush(); +#else + return; + win = 0; +#endif +} + +EAPI Ecore_X_Window +ecore_x_composite_render_window_enable(Ecore_X_Window root) +{ + Ecore_X_Window win = 0; +#ifdef ECORE_XCB_COMPOSITE + xcb_composite_get_overlay_window_cookie_t cookie; + xcb_composite_get_overlay_window_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return 0; + +#ifdef ECORE_XCB_COMPOSITE + cookie = xcb_composite_get_overlay_window_unchecked(_ecore_xcb_conn, root); + reply = + xcb_composite_get_overlay_window_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return win; + + win = reply->overlay_win; + free(reply); + + ecore_x_composite_window_events_disable(win); +// ecore_x_flush(); +#endif + + return win; +} + +EAPI void +ecore_x_composite_render_window_disable(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_composite_avail) return; + +#ifdef ECORE_XCB_COMPOSITE + xcb_composite_release_overlay_window(_ecore_xcb_conn, win); +// ecore_x_flush(); +#endif +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_cursor.c b/src/lib/ecore_x/xcb/ecore_xcb_cursor.c new file mode 100644 index 0000000000..755df04e4f --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_cursor.c @@ -0,0 +1,400 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_CURSOR +# include +# include +#endif + +/* local function prototypes */ +#ifdef ECORE_XCB_CURSOR +static xcb_render_pictforminfo_t *_ecore_xcb_cursor_format_get(void); +#endif +static void _ecore_xcb_cursor_default_size_get(void); +static void _ecore_xcb_cursor_dpi_size_get(void); +static void _ecore_xcb_cursor_guess_size(void); +#ifdef ECORE_XCB_CURSOR +static Ecore_X_Cursor _ecore_xcb_cursor_image_load_cursor(xcb_image_t *img, + int hot_x, + int hot_y); +#endif +static void _ecore_xcb_cursor_image_destroy(xcb_image_t *img); + +/* local variables */ +static int _ecore_xcb_cursor_size = 0; +static Eina_Bool _ecore_xcb_cursor = EINA_FALSE; +#ifdef ECORE_XCB_CURSOR +static uint32_t _ecore_xcb_cursor_format_id = 0; +// static xcb_render_pictforminfo_t *_ecore_xcb_cursor_format = NULL; +#endif + +void +_ecore_xcb_cursor_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + /* NB: No-op */ +} + +void +_ecore_xcb_cursor_finalize(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_CURSOR + _ecore_xcb_cursor = _ecore_xcb_render_argb_get(); + + /* find render pict format */ + if (_ecore_xcb_cursor_format_id <= 0) + _ecore_xcb_cursor_format_id = _ecore_xcb_cursor_format_get()->id; +#endif + + /* try to grab cursor size from XDefaults */ + _ecore_xcb_cursor_default_size_get(); + + /* if that failed, try to get it from Xft Dpi setting */ + if (_ecore_xcb_cursor_size == 0) + _ecore_xcb_cursor_dpi_size_get(); + + /* if that failed, try to guess from display size */ + if (_ecore_xcb_cursor_size == 0) + _ecore_xcb_cursor_guess_size(); + + /* NB: Would normally add theme stuff here, but E cursor does not support + * xcursor themes. Delay parsing that stuff out until such time if/when the + * user selects to use X Cursor, rather than E cursor */ +} + +EAPI Eina_Bool +ecore_x_cursor_color_supported_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_cursor; +} + +EAPI Ecore_X_Cursor +ecore_x_cursor_new(Ecore_X_Window win, + int *pixels, + int w, + int h, + int hot_x, + int hot_y) +{ + Ecore_X_Cursor cursor = 0; + xcb_image_t *img; + +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_CURSOR + if (_ecore_xcb_cursor) + { + img = _ecore_xcb_image_create_native(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, + 32, NULL, (w * h * sizeof(int)), + (uint8_t *)pixels); + cursor = _ecore_xcb_cursor_image_load_cursor(img, hot_x, hot_y); + _ecore_xcb_cursor_image_destroy(img); + return cursor; + } + else +#endif + { + Ecore_X_GC gc; + xcb_pixmap_t pmap, mask; + uint32_t *pix; + uint8_t fr = 0x00, fg = 0x00, fb = 0x00; + uint8_t br = 0xff, bg = 0xff, bb = 0xff; + uint32_t brightest = 0, darkest = 255 * 3; + uint16_t x, y; + const uint32_t dither[2][2] = + { + {0, 2}, + {3, 1} + }; + + img = _ecore_xcb_image_create_native(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP, + 1, NULL, ~0, NULL); + if (img->data) free(img->data); + img->data = malloc(img->size); + + pmap = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 1, pmap, win, w, h); + mask = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 1, mask, win, w, h); + + 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(img, x, y, v); + pix++; + } + } + + gc = ecore_x_gc_new(pmap, 0, NULL); + xcb_put_image(_ecore_xcb_conn, img->format, pmap, gc, w, h, + 0, 0, 0, img->depth, img->size, img->data); + ecore_x_gc_free(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(img, x, y, v); + pix++; + } + } + + gc = ecore_x_gc_new(mask, 0, NULL); + xcb_put_image(_ecore_xcb_conn, img->format, mask, gc, w, h, + 0, 0, 0, img->depth, img->size, img->data); + ecore_x_gc_free(gc); + + if (img->data) free(img->data); + _ecore_xcb_cursor_image_destroy(img); + + cursor = xcb_generate_id(_ecore_xcb_conn); + xcb_create_cursor(_ecore_xcb_conn, cursor, pmap, 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, pmap); + xcb_free_pixmap(_ecore_xcb_conn, mask); + + return cursor; + } + + return 0; +} + +EAPI void +ecore_x_cursor_free(Ecore_X_Cursor c) +{ +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_free_cursor(_ecore_xcb_conn, 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) +{ + Ecore_X_Cursor cursor = 0; + xcb_font_t font; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + font = xcb_generate_id(_ecore_xcb_conn); + xcb_open_font(_ecore_xcb_conn, font, strlen("cursor"), "cursor"); + + cursor = xcb_generate_id(_ecore_xcb_conn); + /* FIXME: Add request check ?? */ + 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_cursor_size = size; + /* NB: May need to adjust size of current cursors here */ +} + +EAPI int +ecore_x_cursor_size_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_cursor_size; +} + +/* local functions */ +#ifdef ECORE_XCB_CURSOR +static xcb_render_pictforminfo_t * +_ecore_xcb_cursor_format_get(void) +{ + const xcb_render_query_pict_formats_reply_t *reply; + xcb_render_pictforminfo_t *ret = NULL; + + CHECK_XCB_CONN; + + reply = xcb_render_util_query_formats(_ecore_xcb_conn); + if (reply) + ret = xcb_render_util_find_standard_format(reply, + XCB_PICT_STANDARD_ARGB_32); + + return ret; +} + +#endif + +static void +_ecore_xcb_cursor_default_size_get(void) +{ + char *s = NULL; + int v = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + s = getenv("XCURSOR_SIZE"); + if (!s) + { + _ecore_xcb_xdefaults_init(); + v = _ecore_xcb_xdefaults_int_get("Xcursor", "size"); + _ecore_xcb_xdefaults_shutdown(); + } + else + v = atoi(s); + if (v) _ecore_xcb_cursor_size = ((v * 16) / 72); +} + +static void +_ecore_xcb_cursor_dpi_size_get(void) +{ + int v = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_xdefaults_init(); + v = _ecore_xcb_xdefaults_int_get("Xft", "dpi"); + if (v) _ecore_xcb_cursor_size = ((v * 16) / 72); + _ecore_xcb_xdefaults_shutdown(); +} + +static void +_ecore_xcb_cursor_guess_size(void) +{ + int w = 0, h = 0, s = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_screen_size_get(_ecore_xcb_screen, &w, &h); + if (h < w) s = h; + else s = w; + _ecore_xcb_cursor_size = (s / 48); +} + +#ifdef ECORE_XCB_CURSOR +static Ecore_X_Cursor +_ecore_xcb_cursor_image_load_cursor(xcb_image_t *img, + int hot_x, + int hot_y) +{ + Ecore_X_Cursor cursor = 0; + Ecore_X_GC gc; + xcb_pixmap_t pmap; + xcb_render_picture_t pict; + + CHECK_XCB_CONN; + + pmap = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, img->depth, pmap, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + img->width, img->height); + + gc = ecore_x_gc_new(pmap, 0, NULL); + xcb_put_image(_ecore_xcb_conn, img->format, pmap, gc, + img->width, img->height, 0, 0, 0, img->depth, + img->size, img->data); + ecore_x_gc_free(gc); + + pict = xcb_generate_id(_ecore_xcb_conn); + xcb_render_create_picture(_ecore_xcb_conn, pict, pmap, + _ecore_xcb_cursor_format_id, 0, NULL); + xcb_free_pixmap(_ecore_xcb_conn, pmap); + + cursor = xcb_generate_id(_ecore_xcb_conn); + xcb_render_create_cursor(_ecore_xcb_conn, cursor, pict, hot_x, hot_y); + xcb_render_free_picture(_ecore_xcb_conn, pict); + + return cursor; +} + +#endif + +static void +_ecore_xcb_cursor_image_destroy(xcb_image_t *img) +{ + CHECK_XCB_CONN; + if (img) xcb_image_destroy(img); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_damage.c b/src/lib/ecore_x/xcb/ecore_xcb_damage.c new file mode 100644 index 0000000000..deb3b9cb49 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_damage.c @@ -0,0 +1,155 @@ +#include "ecore_xcb_private.h" +# ifdef ECORE_XCB_DAMAGE +# include +# endif + +/* local variables */ +static Eina_Bool _damage_avail = EINA_FALSE; + +/* external variables */ +int _ecore_xcb_event_damage = -1; + +void +_ecore_xcb_damage_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_DAMAGE + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_damage_id); +#endif +} + +void +_ecore_xcb_damage_finalize(void) +{ +#ifdef ECORE_XCB_DAMAGE + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_DAMAGE + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_damage_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_damage_query_version_cookie_t cookie; + xcb_damage_query_version_reply_t *reply; + + cookie = + xcb_damage_query_version_unchecked(_ecore_xcb_conn, + XCB_DAMAGE_MAJOR_VERSION, + XCB_DAMAGE_MINOR_VERSION); + reply = xcb_damage_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + _damage_avail = EINA_TRUE; + free(reply); + } + + if (_damage_avail) + _ecore_xcb_event_damage = ext_reply->first_event; + } +#endif +} + +/** + * @defgroup Ecore_X_Damage_Group X Damage Extension Functions + * + * Functions related to the X Damage Extension. + */ + +EAPI Eina_Bool +ecore_x_damage_query(void) +{ + return _damage_avail; +} + +/** + * Create a damage object + * + * @param drawable The drawable to monitor + * @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; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_damage_avail) return 0; + +#ifdef ECORE_XCB_DAMAGE + damage = xcb_generate_id(_ecore_xcb_conn); + xcb_damage_create(_ecore_xcb_conn, damage, drawable, level); +// ecore_x_flush(); +#endif + + return damage; +} + +/** + * Destroy 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_damage_avail) return; + +#ifdef ECORE_XCB_DAMAGE + xcb_damage_destroy(_ecore_xcb_conn, damage); +// ecore_x_flush(); +#endif +} + +/** + * 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 = \ + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_damage_avail) return; + +#ifdef ECORE_XCB_DAMAGE + xcb_damage_subtract(_ecore_xcb_conn, damage, repair, parts); +// ecore_x_flush(); +#endif +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_dnd.c b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c new file mode 100644 index 0000000000..80ae6b4c5d --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c @@ -0,0 +1,688 @@ +#include "ecore_xcb_private.h" + +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +/* local structures */ +typedef struct _Version_Cache_Item +{ + Ecore_X_Window win; + int ver; +} Version_Cache_Item; + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_dnd_converter_copy(char *target EINA_UNUSED, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *tprop EINA_UNUSED, + int *count EINA_UNUSED); + +/* local variables */ +static int _ecore_xcb_dnd_init_count = 0; +static Ecore_X_DND_Source *_source = NULL; +static Ecore_X_DND_Target *_target = NULL; +static Version_Cache_Item *_version_cache = NULL; +static int _version_cache_num = 0, _version_cache_alloc = 0; +static void (*_posupdatecb)(void *, + Ecore_X_Xdnd_Position *); +static void *_posupdatedata; + +/* external variables */ +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; + +void +_ecore_xcb_dnd_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_ecore_xcb_dnd_init_count) + { + _source = calloc(1, sizeof(Ecore_X_DND_Source)); + if (!_source) return; + _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)); + if (!_target) + { + free(_source); + _source = NULL; + return; + } + _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_xcb_dnd_init_count++; +} + +void +_ecore_xcb_dnd_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_dnd_init_count--; + if (_ecore_xcb_dnd_init_count > 0) return; + if (_source) free(_source); + _source = NULL; + if (_target) free(_target); + _target = NULL; + _ecore_xcb_dnd_init_count = 0; +} + +EAPI void +ecore_x_dnd_send_status(Eina_Bool will_accept, + Eina_Bool suppress, + Ecore_X_Rectangle rect, + Ecore_X_Atom action) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (_target->state == ECORE_X_DND_TARGET_IDLE) return; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + _target->will_accept = will_accept; + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.type = ECORE_X_ATOM_XDND_STATUS; + ev.format = 32; + ev.window = _target->source; + 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; + + ev.data.data32[2] = rect.x; + ev.data.data32[2] <<= 16; + ev.data.data32[2] |= rect.y; + ev.data.data32[3] = rect.width; + ev.data.data32[3] <<= 16; + ev.data.data32[3] |= rect.height; + + if (will_accept) + ev.data.data32[4] = action; + else + ev.data.data32[4] = XCB_NONE; + _target->accepted_action = action; + + xcb_send_event(_ecore_xcb_conn, 0, _target->source, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); +} + +EAPI Eina_Bool +ecore_x_dnd_drop(void) +{ + xcb_client_message_event_t ev; + Eina_Bool status = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + if (_source->dest) + { + 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, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + _source->state = ECORE_X_DND_SOURCE_DROPPED; + status = EINA_TRUE; + } + 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, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + _source->state = ECORE_X_DND_SOURCE_IDLE; + } + } + else + { + 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_aware_set(Ecore_X_Window win, + Eina_Bool 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, + ECORE_X_ATOM_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 *data; + int num = 0; + Version_Cache_Item *t; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (_source->state == ECORE_X_DND_SOURCE_DRAGGING) + { + if (_version_cache) + { + int i = 0; + + 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, + ECORE_X_ATOM_ATOM, 32, &data, &num)) + { + int version = 0; + + version = (int)*data; + free(data); + if (_source->state == ECORE_X_DND_SOURCE_DRAGGING) + { + _version_cache_num++; + if (_version_cache_num > _version_cache_alloc) + _version_cache_alloc += 16; + t = realloc(_version_cache, + _version_cache_alloc * sizeof(Version_Cache_Item)); + if (!t) return 0; + _version_cache = t; + _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; + t = realloc(_version_cache, + _version_cache_alloc * sizeof(Version_Cache_Item)); + if (!t) return 0; + _version_cache = t; + _version_cache[_version_cache_num - 1].win = win; + _version_cache[_version_cache_num - 1].ver = 0; + } + + return 0; +} + +EAPI Eina_Bool +ecore_x_dnd_type_isset(Ecore_X_Window win, + const char *type) +{ + int num = 0, i = 0; + Eina_Bool ret = EINA_FALSE; + unsigned char *data; + Ecore_X_Atom *atoms, atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_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 = EINA_TRUE; + break; + } + } + + free(data); + return ret; +} + +EAPI void +ecore_x_dnd_type_set(Ecore_X_Window win, + const char *type, + Eina_Bool on) +{ + Ecore_X_Atom atom, *oldset = NULL, *newset = NULL; + int i = 0, j = 0, num = 0; + unsigned char *data = NULL, *old_data = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + atom = ecore_x_atom_get(type); + ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, &old_data, &num); + oldset = (Ecore_X_Atom *)old_data; + if (on) + { + if (ecore_x_dnd_type_isset(win, type)) + { + free(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]; + newset[0] = atom; + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, data, num + 1); + } + else + { + if (!ecore_x_dnd_type_isset(win, 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(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, data, num - 1); + } + free(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__); + CHECK_XCB_CONN; + + 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_xcb_dnd_converter_copy); + } + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_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__); + CHECK_XCB_CONN; + + 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_xcb_dnd_converter_copy); + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_ACTION_LIST, + ECORE_X_ATOM_ATOM, 32, data, + num_actions); + } +} + +/** + * The DND position update cb is called Ecore_X sends a DND position to a + * client. + * + * It essentially mirrors some of the data sent in the position message. + * Generally this cb should be set just before position update is called. + * Please note well you need to look after your own data pointer if someone + * trashes you position update cb set. + * + * It is considered good form to clear this when the dnd event finishes. + * + * @param cb Callback to updated each time ecore_x sends a position update. + * @param data User data. + */ +EAPI void +ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *data), + const void *data) +{ + _posupdatecb = cb; + _posupdatedata = (void *)data; +} + +EAPI Eina_Bool +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 EINA_FALSE; + + /* Take ownership of XdndSelection */ + if (!ecore_x_selection_xdnd_set(source, data, size)) return EINA_FALSE; + + 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_xcb_events_last_time_get(); + _source->prev.window = 0; + + /* Default Accepted Action: move */ + _source->action = ECORE_X_ATOM_XDND_ACTION_MOVE; + _source->accepted_action = XCB_NONE; + _source->dest = XCB_NONE; + + return EINA_TRUE; +} + +EAPI void +ecore_x_dnd_send_finished(void) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (_target->state == ECORE_X_DND_TARGET_IDLE) return; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.type = ECORE_X_ATOM_XDND_FINISHED; + ev.window = _target->source; + 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, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + _target->state = ECORE_X_DND_TARGET_IDLE; +} + +EAPI void +ecore_x_dnd_source_action_set(Ecore_X_Atom action) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _source->action = action; + if (_source->prev.window) + _ecore_xcb_dnd_drag(_source->prev.window, + _source->prev.x, _source->prev.y); +} + +Ecore_X_DND_Source * +_ecore_xcb_dnd_source_get(void) +{ + return _source; +} + +Ecore_X_DND_Target * +_ecore_xcb_dnd_target_get(void) +{ + return _target; +} + +void +_ecore_xcb_dnd_drag(Ecore_X_Window root, + int x, + int y) +{ + xcb_client_message_event_t ev; + Ecore_X_Window win, *skip; + Ecore_X_Xdnd_Position pos; + int num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) return; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + + skip = ecore_x_window_ignore_list(&num); + win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num); + while ((win) && !(ecore_x_dnd_version_get(win))) + win = ecore_x_window_shadow_parent_get(root, win); + + 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, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + _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 = 0; + unsigned char *data; + Ecore_X_Atom *types; + + ecore_x_window_prop_property_get(_source->win, + ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, + &data, &num); + types = (Ecore_X_Atom *)data; + 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, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + _source->await_status = 0; + _source->will_accept = 0; + } + + 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; + ev.data.data32[2] = ((x << 16) & 0xffff0000) | (y & 0xffff); + ev.data.data32[3] = _source->time; + ev.data.data32[4] = _source->action; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + _source->await_status = 1; + } + } + + if (_posupdatecb) + { + pos.position.x = x; + pos.position.y = y; + pos.win = win; + pos.prev = _source->dest; + _posupdatecb(_posupdatedata, &pos); + } + + _source->prev.x = x; + _source->prev.y = y; + _source->prev.window = root; + _source->dest = win; +} + +EAPI Ecore_X_Atom +ecore_x_dnd_source_action_get(void) +{ + return _source->action; +} + +/* local functions */ +static Eina_Bool +_ecore_xcb_dnd_converter_copy(char *target EINA_UNUSED, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *tprop EINA_UNUSED, + int *count EINA_UNUSED) +{ + Ecore_Xcb_Textproperty text_prop; + Ecore_Xcb_Encoding_Style style = XcbTextStyle; + char *mystr; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!data) || (!size)) return EINA_FALSE; + + mystr = calloc(1, size + 1); + if (!mystr) return EINA_FALSE; + + memcpy(mystr, data, size); + if (_ecore_xcb_mb_textlist_to_textproperty(&mystr, 1, style, &text_prop)) + { + int len; + + len = strlen((char *)text_prop.value) + 1; + if (!(*data_ret = malloc(len))) + { + free(mystr); + return EINA_FALSE; + } + memcpy(*data_ret, text_prop.value, len); + *size_ret = len; + free(text_prop.value); + free(mystr); + return EINA_TRUE; + } + else + { + free(mystr); + return EINA_FALSE; + } +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_dpms.c b/src/lib/ecore_x/xcb/ecore_xcb_dpms.c new file mode 100644 index 0000000000..39ef589dd1 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_dpms.c @@ -0,0 +1,320 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_DAMAGE +# include +#endif + +/* local variables */ +static Eina_Bool _dpms_avail = EINA_FALSE; + +void +_ecore_xcb_dpms_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_DPMS + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_dpms_id); +#endif +} + +void +_ecore_xcb_dpms_finalize(void) +{ +#ifdef ECORE_XCB_DPMS + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_DPMS + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_dpms_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_dpms_get_version_cookie_t cookie; + xcb_dpms_get_version_reply_t *reply; + + cookie = + xcb_dpms_get_version_unchecked(_ecore_xcb_conn, + XCB_DPMS_MAJOR_VERSION, + XCB_DPMS_MINOR_VERSION); + reply = xcb_dpms_get_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (reply->server_major_version >= 1) + _dpms_avail = EINA_TRUE; + free(reply); + } + } +#endif +} + +/** + * @defgroup Ecore_X_DPMS_Group X DPMS Extension Functions + * + * Functions related to the X DPMS Extension + */ + +/** + * Checks if the DPMS extension is available or not. + * + * @return @c EINA_TRUE if the DPMS extension is available, + * @c EINA_FALSE otherwise. + * + * Return @c EINA_TRUE if the X server supports the DPMS Extension version 1.0, + * @c EINA_FALSE otherwise. + * + * @ingroup Ecore_X_DPMS_Group + */ +EAPI Eina_Bool +ecore_x_dpms_query(void) +{ +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _dpms_avail; +} + +/** + * 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 Eina_Bool +ecore_x_dpms_capable_get(void) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_DPMS + xcb_dpms_capable_cookie_t cookie; + xcb_dpms_capable_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_dpms_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_DPMS + cookie = xcb_dpms_capable_unchecked(_ecore_xcb_conn); + reply = xcb_dpms_capable_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->capable; + free(reply); + } +#endif + + return ret; +} + +/** + * Checks the DPMS state of the display. + * @return @c EINA_TRUE if DPMS is enabled, @c EINA_FALSE otherwise. + * @ingroup Ecore_X_DPMS_Group + */ +EAPI Eina_Bool +ecore_x_dpms_enabled_get(void) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_DPMS + xcb_dpms_info_cookie_t cookie; + xcb_dpms_info_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_dpms_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_DPMS + cookie = xcb_dpms_info_unchecked(_ecore_xcb_conn); + reply = xcb_dpms_info_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + if (reply->state) ret = EINA_TRUE; + free(reply); +#endif + + return ret; +} + +/** + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_dpms_avail) return; + +#ifdef ECORE_XCB_DPMS + if (enabled) + xcb_dpms_enable(_ecore_xcb_conn); + else + xcb_dpms_disable(_ecore_xcb_conn); +#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_XCB_DPMS + xcb_dpms_get_timeouts_cookie_t cookie; + xcb_dpms_get_timeouts_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (standby) *standby = 0; + if (suspend) *suspend = 0; + if (off) *off = 0; + + if (!_dpms_avail) return; + +#ifdef ECORE_XCB_DPMS + cookie = xcb_dpms_get_timeouts_unchecked(_ecore_xcb_conn); + reply = xcb_dpms_get_timeouts_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + if (standby) *standby = reply->standby_timeout; + if (suspend) *suspend = reply->suspend_timeout; + if (off) *off = reply->off_timeout; + free(reply); +#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. + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + * @ingroup Ecore_X_DPMS_Group + */ +EAPI Eina_Bool +ecore_x_dpms_timeouts_set(unsigned int standby, + unsigned int suspend, + unsigned int off) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_dpms_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_DPMS + // FIXME: Add request check + xcb_dpms_set_timeouts(_ecore_xcb_conn, standby, suspend, off); + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + +/** + * 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(void) +{ + unsigned int standby = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_dpms_timeouts_get(&standby, NULL, NULL); + return standby; +} + +/** + * 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(void) +{ + unsigned int suspend = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_dpms_timeouts_get(NULL, &suspend, NULL); + 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. + * @ingroup Ecore_X_DPMS_Group + */ +EAPI unsigned int +ecore_x_dpms_timeout_off_get(void) +{ + unsigned int off = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_dpms_timeouts_get(NULL, NULL, &off); + return off; +} + +/** + * Sets the standby timeout (in unit of seconds). + * @param new_timeout 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) +{ + unsigned int standby = 0, suspend = 0, off = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_dpms_timeouts_get(&standby, &suspend, &off); + ecore_x_dpms_timeouts_set(new_timeout, suspend, off); +} + +/** + * Sets the suspend timeout (in unit of seconds). + * @param new_timeout 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) +{ + unsigned int standby = 0, suspend = 0, off = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_dpms_timeouts_get(&standby, &suspend, &off); + ecore_x_dpms_timeouts_set(standby, new_timeout, off); +} + +/** + * Sets the off timeout (in unit of seconds). + * @param new_timeout 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) +{ + unsigned int standby = 0, suspend = 0, off = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_dpms_timeouts_get(&standby, &suspend, &off); + ecore_x_dpms_timeouts_set(standby, suspend, new_timeout); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_drawable.c b/src/lib/ecore_x/xcb/ecore_xcb_drawable.c new file mode 100644 index 0000000000..4e9a3564ce --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_drawable.c @@ -0,0 +1,123 @@ +#include "ecore_xcb_private.h" + +/** + * @defgroup Ecore_X_Drawable_Group X Drawable Functions + * + * Functions that operate on drawables. + */ + +/** + * 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 draw, + Ecore_X_GC gc, + int x, + int y, + int w, + int h) +{ + xcb_rectangle_t rect; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_poly_fill_rectangle(_ecore_xcb_conn, draw, gc, 1, + (const xcb_rectangle_t *)&rect); +// ecore_x_flush(); +} + +/** + * 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 draw, + int *x, + int *y, + int *w, + int *h) +{ + xcb_get_geometry_cookie_t cookie; + xcb_get_geometry_reply_t *reply; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, draw); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + if (x) *x = reply->x; + if (y) *y = reply->y; + if (w) *w = (int)reply->width; + if (h) *h = (int)reply->height; + free(reply); +} + +/** + * 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) +{ + xcb_get_geometry_cookie_t cookie; + xcb_get_geometry_reply_t *reply; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, d); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + ret = (int)reply->border_width; + free(reply); + return 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) +{ + xcb_get_geometry_cookie_t cookie; + xcb_get_geometry_reply_t *reply; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, d); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + ret = (int)reply->depth; + free(reply); + return ret; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_e.c b/src/lib/ecore_x/xcb/ecore_xcb_e.c new file mode 100644 index 0000000000..82d94b634f --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_e.c @@ -0,0 +1,1576 @@ +#include "ecore_xcb_private.h" + +/* local function prototypes */ +static Ecore_X_Atom _ecore_xcb_e_vkbd_atom_get(Ecore_X_Virtual_Keyboard_State state); +static Ecore_X_Virtual_Keyboard_State _ecore_xcb_e_vkbd_state_get(Ecore_X_Atom atom); +static Ecore_X_Atom _ecore_xcb_e_quickpanel_atom_get(Ecore_X_Illume_Quickpanel_State state); +static Ecore_X_Illume_Quickpanel_State _ecore_xcb_e_quickpanel_state_get(Ecore_X_Atom atom); +static Ecore_X_Atom _ecore_xcb_e_illume_atom_get(Ecore_X_Illume_Mode mode); +static Ecore_X_Illume_Mode _ecore_xcb_e_illume_mode_get(Ecore_X_Atom atom); +static Ecore_X_Atom _ecore_xcb_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state); +static Ecore_X_Illume_Indicator_State _ecore_xcb_e_indicator_state_get(Ecore_X_Atom atom); + +EAPI void +ecore_x_e_init(void) +{ +} + +EAPI void +ecore_x_e_comp_sync_draw_done_send(Ecore_X_Window root, + Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE; + ev.data.data32[0] = win; + ev.data.data32[1] = 0; + ev.data.data32[2] = 0; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +// ecore_x_flush(); +} + +EAPI void +ecore_x_e_comp_sync_draw_size_done_send(Ecore_X_Window root, + Ecore_X_Window win, + int w, + int h) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_SYNC_DRAW_DONE; + ev.data.data32[0] = win; + ev.data.data32[1] = 1; + ev.data.data32[2] = w; + ev.data.data32[3] = h; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +// ecore_x_flush(); +} + +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) +{ + Ecore_X_Sync_Counter counter = 0; + int ret = 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 Eina_Bool +ecore_x_e_comp_sync_supported_get(Ecore_X_Window root) +{ + Ecore_X_Window win, win2; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + 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 EINA_TRUE; + } + return EINA_FALSE; +} + +EAPI void +ecore_x_e_window_profile_list_set(Ecore_X_Window win, + const char **profiles, + unsigned int num_profiles) +{ + Ecore_X_Atom *atoms; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!win) + return; + + if (!num_profiles) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE_LIST); + else + { + atoms = alloca(num_profiles * sizeof(Ecore_X_Atom)); + ecore_x_atoms_get(profiles, num_profiles, atoms); + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_E_PROFILE_LIST, + ECORE_X_ATOM_ATOM, 32, (void *)atoms, + num_profiles); + } +} + +EAPI Eina_Bool +ecore_x_e_window_profile_list_get(Ecore_X_Window win, + const char ***profiles, + int *ret_num) +{ + unsigned char *data = NULL; + Ecore_X_Atom *atoms; + int num, i; + + if (ret_num) + *ret_num = 0; + + if (profiles) + *profiles = NULL; + + if (!win) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_E_PROFILE_LIST, + ECORE_X_ATOM_ATOM, 32, &data, &num)) + return EINA_FALSE; + + if (ret_num) + *ret_num = num; + + if (profiles) + { + (*profiles) = calloc(num, sizeof(char *)); + if (!(*profiles)) + { + if (ret_num) + *ret_num = 0; + + if (data) + free(data); + + return EINA_FALSE; + } + + atoms = (Ecore_X_Atom *)data; + for (i = 0; i < num; i++) + (*profiles)[i] = ecore_x_atom_name_get(atoms[i]); + } + + if (data) + free(data); + + return EINA_TRUE; +} + +EAPI void +ecore_x_e_window_profile_set(Ecore_X_Window win, + const char *profile) +{ + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!win) + return; + + if (!profile) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE); + else + { + atom = ecore_x_atom_get(profile); + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_PROFILE, + ECORE_X_ATOM_ATOM, 32, (void *)&atom, 1); + } +} + +EAPI char * +ecore_x_e_window_profile_get(Ecore_X_Window win) +{ + Ecore_X_Atom *atom = NULL; + unsigned char *data; + char *profile = NULL; + int num; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_PROFILE, + ECORE_X_ATOM_ATOM, 32, &data, &num)) + return NULL; + + if (data) + atom = (Ecore_X_Atom *)data; + + if (atom) + profile = ecore_x_atom_name_get(atom[0]); + + return profile; +} + +EAPI void +ecore_x_e_comp_sync_supported_set(Ecore_X_Window root, + Eina_Bool enabled) +{ + Ecore_X_Window win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + 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 = 0; + + 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 void +ecore_x_e_comp_sync_begin_send(Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_SYNC_BEGIN; + ev.data.data32[0] = win; + ev.data.data32[1] = 0; + ev.data.data32[2] = 0; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); +} + +EAPI void +ecore_x_e_comp_sync_end_send(Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_SYNC_END; + ev.data.data32[0] = win; + ev.data.data32[1] = 0; + ev.data.data32[2] = 0; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); +} + +EAPI void +ecore_x_e_comp_sync_cancel_send(Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_SYNC_CANCEL; + ev.data.data32[0] = win; + ev.data.data32[1] = 0; + ev.data.data32[2] = 0; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); +} + +EAPI void +ecore_x_e_comp_flush_send(Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_FLUSH; + ev.data.data32[0] = win; + ev.data.data32[1] = 0; + ev.data.data32[2] = 0; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); +} + +EAPI void +ecore_x_e_comp_dump_send(Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_E_COMP_DUMP; + ev.data.data32[0] = win; + ev.data.data32[1] = 0; + ev.data.data32[2] = 0; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); +} + +EAPI void +ecore_x_e_comp_pixmap_set(Ecore_X_Window win, + Ecore_X_Pixmap pixmap) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (pixmap) + ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_PIXMAP, + ECORE_X_ATOM_PIXMAP, &pixmap, 1); + else + ecore_x_window_prop_property_del(win, pixmap); +} + +EAPI Ecore_X_Pixmap +ecore_x_e_comp_pixmap_get(Ecore_X_Window win) +{ + Ecore_X_Pixmap pixmap = 0; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ret = ecore_x_window_prop_xid_get(win, ECORE_X_ATOM_E_COMP_PIXMAP, + ECORE_X_ATOM_PIXMAP, &pixmap, 1); + if (ret != 1) return 0; + return pixmap; +} + +EAPI void +ecore_x_e_frame_size_set(Ecore_X_Window win, + int fl, + int fr, + int ft, + int fb) +{ + uint32_t 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 Ecore_X_Virtual_Keyboard_State +ecore_x_e_virtual_keyboard_state_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_VIRTUAL_KEYBOARD_STATE, + &atom, 1)) + return ECORE_X_VIRTUAL_KEYBOARD_STATE_UNKNOWN; + + return _ecore_xcb_e_vkbd_state_get(atom); +} + +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_xcb_e_vkbd_atom_get(state); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE, + &atom, 1); +} + +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_xcb_e_vkbd_atom_get(state), + 0, 0, 0, 0); +} + +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 Eina_Bool +ecore_x_e_virtual_keyboard_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_VIRTUAL_KEYBOARD, + &val, 1)) + return EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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_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_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_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 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 Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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 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 Eina_Bool +ecore_x_e_illume_softkey_geometry_get(Ecore_X_Window win, + int *x, + int *y, + int *w, + int *h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + + if (ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY, + geom, 4) != 4) + return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +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 Eina_Bool +ecore_x_e_illume_indicator_geometry_get(Ecore_X_Window win, + int *x, + int *y, + int *w, + int *h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + + if (ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY, + geom, 4) != 4) + return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +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 Eina_Bool +ecore_x_e_illume_keyboard_geometry_get(Ecore_X_Window win, + int *x, + int *y, + int *w, + int *h) +{ + unsigned int geom[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + + if (ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY, + geom, 4) != 4) + return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +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 Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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_xcb_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 = 0; + + 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_xcb_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_xcb_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); +} + +static Ecore_X_Atom +_ecore_xcb_e_clipboard_atom_get(Ecore_X_Illume_Clipboard_State state) +{ + switch (state) + { + case ECORE_X_ILLUME_CLIPBOARD_STATE_ON: + return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON; + case ECORE_X_ILLUME_CLIPBOARD_STATE_OFF: + return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF; + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Clipboard_State +_ecore_xcb_e_clipboard_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON) + return ECORE_X_ILLUME_CLIPBOARD_STATE_ON; + + if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF) + return ECORE_X_ILLUME_CLIPBOARD_STATE_OFF; + + return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; +} + +EAPI void +ecore_x_e_illume_clipboard_state_set(Ecore_X_Window win, + Ecore_X_Illume_Clipboard_State state) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_xcb_e_clipboard_atom_get(state); + + ecore_x_window_prop_atom_set(win, + ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Clipboard_State +ecore_x_e_illume_clipboard_state_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_CLIPBOARD_STATE, + &atom, 1)) + return ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN; + return _ecore_xcb_e_clipboard_state_get(atom); +} + +EAPI void +ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY, + geom, 4); +} + +EAPI Eina_Bool +ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY, + geom, 4); + if (ret != 4) return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +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_xcb_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_xcb_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_xcb_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_access_action_next_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_read_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_up_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_down_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN, + 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 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 Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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_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 num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_window_set(win, ECORE_X_ATOM_E_ILLUME_ZONE_LIST, + zones, num); +} + +/* local functions */ +static Ecore_X_Atom +_ecore_xcb_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: + break; + } + return 0; +} + +static Ecore_X_Virtual_Keyboard_State +_ecore_xcb_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_xcb_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: + break; + } + return 0; +} + +static Ecore_X_Illume_Quickpanel_State +_ecore_xcb_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; +} + +static Ecore_X_Atom +_ecore_xcb_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: + break; + } + return ECORE_X_ILLUME_MODE_UNKNOWN; +} + +static Ecore_X_Illume_Mode +_ecore_xcb_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; +} + +static Ecore_X_Atom +_ecore_xcb_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state) +{ + switch (state) + { + case ECORE_X_ILLUME_INDICATOR_STATE_ON: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_ON; + + case ECORE_X_ILLUME_INDICATOR_STATE_OFF: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF; + + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Indicator_State +_ecore_xcb_e_indicator_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_ON) + return ECORE_X_ILLUME_INDICATOR_STATE_ON; + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF) + return ECORE_X_ILLUME_INDICATOR_STATE_OFF; + + return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; +} + +EAPI void +ecore_x_e_illume_indicator_state_set(Ecore_X_Window win, + Ecore_X_Illume_Indicator_State state) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + atom = _ecore_xcb_e_indicator_atom_get(state); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Indicator_State +ecore_x_e_illume_indicator_state_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_INDICATOR_STATE, + &atom, 1)) + return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; + + return _ecore_xcb_e_indicator_state_get(atom); +} + +EAPI void +ecore_x_e_illume_indicator_state_send(Ecore_X_Window win, + Ecore_X_Illume_Indicator_State state) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_xcb_e_indicator_atom_get(state), + 0, 0, 0, 0); +} + +static Ecore_X_Atom +_ecore_x_e_indicator_opacity_atom_get(Ecore_X_Illume_Indicator_Opacity_Mode mode) +{ + switch (mode) + { + case ECORE_X_ILLUME_INDICATOR_OPAQUE: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE; + + case ECORE_X_ILLUME_INDICATOR_TRANSLUCENT: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT; + + case ECORE_X_ILLUME_INDICATOR_TRANSPARENT: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; + + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Indicator_Opacity_Mode +_ecore_x_e_indicator_opacity_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE) + return ECORE_X_ILLUME_INDICATOR_OPAQUE; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT) + return ECORE_X_ILLUME_INDICATOR_TRANSLUCENT; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT) + return ECORE_X_ILLUME_INDICATOR_TRANSPARENT; + + return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; +} + +EAPI void +ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win, + Ecore_X_Illume_Indicator_Opacity_Mode mode) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_x_e_indicator_opacity_atom_get(mode); + ecore_x_window_prop_atom_set(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Indicator_Opacity_Mode +ecore_x_e_illume_indicator_opacity_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_INDICATOR_OPACITY_MODE, + &atom, 1)) + return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; + + return _ecore_x_e_indicator_opacity_get(atom); +} + +EAPI void +ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, + Ecore_X_Illume_Indicator_Opacity_Mode mode) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_x_e_indicator_opacity_atom_get(mode), + 0, 0, 0, 0); +} + +static Ecore_X_Atom +_ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state) +{ + switch (state) + { + case ECORE_X_ILLUME_WINDOW_STATE_NORMAL: + return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL; + + case ECORE_X_ILLUME_WINDOW_STATE_FLOATING: + return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; + + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Window_State +_ecore_x_e_illume_window_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL) + return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; + + if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING) + return ECORE_X_ILLUME_WINDOW_STATE_FLOATING; + + return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; +} + +EAPI void +ecore_x_e_illume_window_state_set(Ecore_X_Window win, + Ecore_X_Illume_Window_State state) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_x_e_illume_window_state_atom_get(state); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_WINDOW_STATE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Window_State +ecore_x_e_illume_window_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_WINDOW_STATE, + &atom, 1)) + return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; + + return _ecore_x_e_illume_window_state_get(atom); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_error.c b/src/lib/ecore_x/xcb/ecore_xcb_error.c new file mode 100644 index 0000000000..fc329265d5 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_error.c @@ -0,0 +1,123 @@ +#include "ecore_xcb_private.h" +#include + +/* local variables */ +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; +static Ecore_X_ID _error_resource_id = 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; +} + +/** + * Get the resource id that caused the error. + * @return The resource id causing the X error + * + * Return the X resource id that caused the last X error + */ +EAPI Ecore_X_ID +ecore_x_error_resource_id_get(void) +{ + return _error_resource_id; +} + +int +_ecore_xcb_error_handle(xcb_generic_error_t *err) +{ + WRN("Got Error:"); + WRN("\tEvent: %s", xcb_event_get_request_label(err->major_code)); + WRN("\tError: %s", xcb_event_get_error_label(err->error_code)); + +#ifdef OLD_XCB_VERSION + if (err->error_code == XCB_EVENT_ERROR_BAD_VALUE) + WRN("\tBad Value: %d", ((xcb_value_error_t *)err)->bad_value); + else if (err->error_code == XCB_EVENT_ERROR_BAD_WINDOW) + WRN("\tBad Window: %d", ((xcb_window_error_t *)err)->bad_value); +#else + if (err->error_code == XCB_VALUE) + WRN("\tBad Value: %d", ((xcb_value_error_t *)err)->bad_value); + else if (err->error_code == XCB_WINDOW) + WRN("\tBad Window: %d", ((xcb_window_error_t *)err)->bad_value); +#endif + + _error_request_code = err->sequence; + _error_code = err->error_code; + _error_resource_id = err->resource_id; + if (_error_func) + _error_func(_error_data); + + return 0; +} + +int +_ecore_xcb_io_error_handle(xcb_generic_error_t *err) +{ + CRIT("IO Error:"); + if (err) + { + CRIT("\tRequest: %d", err->sequence); + CRIT("\tCode: %d", err->error_code); + } + if (_io_error_func) + _io_error_func(_io_error_data); + else + exit(-1); + + return 0; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_events.c b/src/lib/ecore_x/xcb/ecore_xcb_events.c new file mode 100644 index 0000000000..9cc86f62a8 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_events.c @@ -0,0 +1,2824 @@ +#include "ecore_xcb_private.h" +//#include "Ecore_X_Atoms.h" +#include +#include +#include +# ifdef ECORE_XCB_DAMAGE +# include +# endif +# ifdef ECORE_XCB_RANDR +# include +# endif +# ifdef ECORE_XCB_SCREENSAVER +# include +# endif +# ifdef ECORE_XCB_SYNC +# include +# endif +# ifdef ECORE_XCB_XFIXES +# include +# endif +# ifdef ECORE_XCB_XGESTURE +# include +# endif + +#ifndef CODESET +# define CODESET "INVALID" +#endif + +typedef struct _Ecore_X_Mouse_Down_Info +{ + EINA_INLIST; + int dev; + Ecore_X_Time last_time; + Ecore_X_Time last_last_time; + Ecore_X_Window last_win; + Ecore_X_Window last_last_win; + Ecore_X_Window last_event_win; + Ecore_X_Window last_last_event_win; + Eina_Bool did_double : 1; + Eina_Bool did_triple : 1; +} Ecore_X_Mouse_Down_Info; + +/* local function prototypes */ +static void _ecore_xcb_event_handle_any_event(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_key_press(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_key_release(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_button_press(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_button_release(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_motion_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_expose(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_map_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_client_message(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event); +#ifdef ECORE_XCB_XGESTURE +static void _ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event); +#endif +#ifdef ECORE_XCB_SHAPE +static void _ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event); +#endif +static void _ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event EINA_UNUSED); +static void _ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event); +static void _ecore_xcb_event_handle_input_event(xcb_generic_event_t *event); + +static void _ecore_xcb_event_key_press(xcb_generic_event_t *event); +static void _ecore_xcb_event_key_release(xcb_generic_event_t *event); +static void _ecore_xcb_event_mouse_move_free(void *data EINA_UNUSED, + void *event); +static Ecore_X_Event_Mode _ecore_xcb_event_mode_get(uint8_t mode); +static Ecore_X_Event_Detail _ecore_xcb_event_detail_get(uint8_t detail); +static void _ecore_xcb_event_xdnd_enter_free(void *data EINA_UNUSED, + void *event); +static void _ecore_xcb_event_selection_notify_free(void *data EINA_UNUSED, + void *event); +static void _ecore_xcb_event_generic_event_free(void *data, + void *event); +static void _ecore_xcb_event_mouse_down_info_clear(void); +static Ecore_X_Mouse_Down_Info *_ecore_xcb_event_mouse_down_info_get(int dev); + +/* local variables */ +static Eina_Bool _ecore_xcb_event_last_mouse_move = EINA_FALSE; +//static Ecore_Event *_ecore_xcb_event_last_mouse_move_event = NULL; +static Eina_Inlist *_ecore_xcb_mouse_down_info_list = NULL; +static Ecore_X_Time _ecore_xcb_event_last_time; +static Ecore_X_Window _ecore_xcb_event_last_window = 0; + +/* public variables */ +int16_t _ecore_xcb_event_last_root_x = 0; +int16_t _ecore_xcb_event_last_root_y = 0; + +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_MAPPING_CHANGE = 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_FIXES_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_GESTURE_NOTIFY_FLICK = 0; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN = 0; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = 0; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP = 0; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = 0; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = 0; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_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_XKB_STATE_NOTIFY = 0; +EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0; +EAPI int ECORE_X_EVENT_GENERIC = 0; + +EAPI int ECORE_X_RAW_BUTTON_PRESS = 0; +EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0; +EAPI int ECORE_X_RAW_MOTION = 0; + +void +_ecore_xcb_events_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + 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_MAPPING_CHANGE = 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_FIXES_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_GESTURE_NOTIFY_FLICK = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_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_XKB_STATE_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_GENERIC = ecore_event_type_new(); + + ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new(); + ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new(); + ECORE_X_RAW_MOTION = ecore_event_type_new(); + } +} + +void +_ecore_xcb_events_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_mouse_down_info_clear(); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +// if (_ecore_xcb_event_last_mouse_move_event) +// { +// ecore_event_del(_ecore_xcb_event_last_mouse_move_event); +// _ecore_xcb_event_last_mouse_move_event = NULL; +// } +} + +void +_ecore_xcb_events_handle(xcb_generic_event_t *ev) +{ + uint8_t response = 0; + +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + /* strip highest bit (set if event is generated) */ + response = (ev->response_type & ~0x80); + if (response == 0) + { + xcb_generic_error_t *err; + + err = (xcb_generic_error_t *)ev; + + /* NB: There is no way to check access of destroyed windows, + * so trap those cases and ignore. We also ignore BadValue from + * xcb_grab/ungrab_button (happens when we are using any_mod) + * and a few others */ +#ifdef OLD_XCB_VERSION + if (err->error_code == XCB_EVENT_ERROR_BAD_WINDOW) return; + else if (err->error_code == XCB_EVENT_ERROR_BAD_MATCH) + { + if ((err->major_code == XCB_SET_INPUT_FOCUS) || + (err->major_code == XCB_CONFIGURE_WINDOW)) + return; + } + else if (err->error_code == XCB_EVENT_ERROR_BAD_VALUE) + { + if ((err->major_code == XCB_KILL_CLIENT) || + (err->major_code == XCB_GRAB_BUTTON) || + (err->major_code == XCB_UNGRAB_BUTTON)) + return; + } +#else + if (err->error_code == XCB_WINDOW) return; + else if (err->error_code == XCB_MATCH) + { + if ((err->major_code == XCB_SET_INPUT_FOCUS) || + (err->major_code == XCB_CONFIGURE_WINDOW)) + return; + } + else if (err->error_code == XCB_VALUE) + { + if ((err->major_code == XCB_KILL_CLIENT) || + (err->major_code == XCB_GRAB_BUTTON) || + (err->major_code == XCB_UNGRAB_BUTTON)) + return; + } +#endif + WRN("Got Event Error:"); + WRN("\tMajor Code: %d", err->major_code); + WRN("\tMinor Code: %d", err->minor_code); + WRN("\tRequest: %s", xcb_event_get_request_label(err->major_code)); + WRN("\tError: %s", xcb_event_get_error_label(err->error_code)); + if (err->error_code == 2) // bad value + WRN("\tValue: %d", ((xcb_value_error_t *)err)->bad_value); + else if (err->error_code == 8) // bad match + WRN("\tMatch: %d", ((xcb_match_error_t *)err)->bad_value); + + if (err->major_code == XCB_SEND_EVENT) + { + WRN("\tSend Event Error"); + WRN("\t\tSeq: %d", ev->sequence); + WRN("\t\tFull Seq: %d", ev->full_sequence); + WRN("\t\tType: %d", ev->response_type); + } + /* if (err->major_code == 148) */ + /* { */ + /* printf("GOT 148 Error\n"); */ + /* } */ + return; + } + + /* FIXME: Filter event for xim when xcb supports xim */ + + _ecore_xcb_event_handle_any_event(ev); + + if (response == XCB_KEY_PRESS) + _ecore_xcb_event_handle_key_press(ev); + else if (response == XCB_KEY_RELEASE) + _ecore_xcb_event_handle_key_release(ev); + else if (response == XCB_BUTTON_PRESS) + _ecore_xcb_event_handle_button_press(ev); + else if (response == XCB_BUTTON_RELEASE) + _ecore_xcb_event_handle_button_release(ev); + else if (response == XCB_MOTION_NOTIFY) + _ecore_xcb_event_handle_motion_notify(ev); + else if (response == XCB_ENTER_NOTIFY) + _ecore_xcb_event_handle_enter_notify(ev); + else if (response == XCB_LEAVE_NOTIFY) + _ecore_xcb_event_handle_leave_notify(ev); + else if (response == XCB_KEYMAP_NOTIFY) + _ecore_xcb_event_handle_keymap_notify(ev); + else if (response == XCB_FOCUS_IN) + _ecore_xcb_event_handle_focus_in(ev); + else if (response == XCB_FOCUS_OUT) + _ecore_xcb_event_handle_focus_out(ev); + else if (response == XCB_EXPOSE) + _ecore_xcb_event_handle_expose(ev); + else if (response == XCB_GRAPHICS_EXPOSURE) + _ecore_xcb_event_handle_graphics_exposure(ev); + else if (response == XCB_VISIBILITY_NOTIFY) + _ecore_xcb_event_handle_visibility_notify(ev); + else if (response == XCB_CREATE_NOTIFY) + _ecore_xcb_event_handle_create_notify(ev); + else if (response == XCB_DESTROY_NOTIFY) + _ecore_xcb_event_handle_destroy_notify(ev); + else if (response == XCB_MAP_NOTIFY) + _ecore_xcb_event_handle_map_notify(ev); + else if (response == XCB_UNMAP_NOTIFY) + _ecore_xcb_event_handle_unmap_notify(ev); + else if (response == XCB_MAP_REQUEST) + _ecore_xcb_event_handle_map_request(ev); + else if (response == XCB_REPARENT_NOTIFY) + _ecore_xcb_event_handle_reparent_notify(ev); + else if (response == XCB_CONFIGURE_NOTIFY) + _ecore_xcb_event_handle_configure_notify(ev); + else if (response == XCB_CONFIGURE_REQUEST) + _ecore_xcb_event_handle_configure_request(ev); + else if (response == XCB_GRAVITY_NOTIFY) + _ecore_xcb_event_handle_gravity_notify(ev); + else if (response == XCB_RESIZE_REQUEST) + _ecore_xcb_event_handle_resize_request(ev); + else if (response == XCB_CIRCULATE_NOTIFY) + _ecore_xcb_event_handle_circulate_notify(ev); + else if (response == XCB_CIRCULATE_REQUEST) + _ecore_xcb_event_handle_circulate_request(ev); + else if (response == XCB_PROPERTY_NOTIFY) + _ecore_xcb_event_handle_property_notify(ev); + else if (response == XCB_SELECTION_CLEAR) + _ecore_xcb_event_handle_selection_clear(ev); + else if (response == XCB_SELECTION_REQUEST) + _ecore_xcb_event_handle_selection_request(ev); + else if (response == XCB_SELECTION_NOTIFY) + _ecore_xcb_event_handle_selection_notify(ev); + else if (response == XCB_COLORMAP_NOTIFY) + _ecore_xcb_event_handle_colormap_notify(ev); + else if (response == XCB_CLIENT_MESSAGE) + _ecore_xcb_event_handle_client_message(ev); + else if (response == XCB_MAPPING_NOTIFY) + _ecore_xcb_event_handle_mapping_notify(ev); + else if (response == 35) /* GenericEvent == 35 */ + _ecore_xcb_event_handle_generic_event(ev); +#ifdef ECORE_XCB_DAMAGE + else if ((_ecore_xcb_event_damage >= 0) && + (response == (_ecore_xcb_event_damage + XCB_DAMAGE_NOTIFY))) + _ecore_xcb_event_handle_damage_notify(ev); +#endif +#ifdef ECORE_XCB_RANDR + else if ((_ecore_xcb_event_randr >= 0) && + (response == + _ecore_xcb_event_randr + XCB_RANDR_SCREEN_CHANGE_NOTIFY)) + _ecore_xcb_event_handle_randr_change(ev); + else if ((_ecore_xcb_event_randr >= 0) && + (response == (_ecore_xcb_event_randr + XCB_RANDR_NOTIFY))) + _ecore_xcb_event_handle_randr_notify(ev); +#endif +#ifdef ECORE_XCB_SCREENSAVER + else if ((_ecore_xcb_event_screensaver >= 0) && + (response == + _ecore_xcb_event_screensaver + XCB_SCREENSAVER_NOTIFY)) + _ecore_xcb_event_handle_screensaver_notify(ev); +#endif +#ifdef ECORE_XCB_XGESTURE + else if ((_ecore_xcb_event_gesture >= 0) && + (response == + _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_FLICK)) + _ecore_xcb_event_handle_gesture_notify_flick(ev); + else if ((_ecore_xcb_event_gesture >= 0) && + (response == + _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_PAN)) + _ecore_xcb_event_handle_gesture_notify_pan(ev); + else if ((_ecore_xcb_event_gesture >= 0) && + (response == + _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_PINCH_ROTATION)) + _ecore_xcb_event_handle_gesture_notify_pinchrotation(ev); + else if ((_ecore_xcb_event_gesture >= 0) && + (response == + _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_TAP)) + _ecore_xcb_event_handle_gesture_notify_tap(ev); + else if ((_ecore_xcb_event_gesture >= 0) && + (response == + _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_TAP_N_HOLD)) + _ecore_xcb_event_handle_gesture_notify_tapnhold(ev); + else if ((_ecore_xcb_event_gesture >= 0) && + (response == + _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_HOLD)) + _ecore_xcb_event_handle_gesture_notify_hold(ev); + else if ((_ecore_xcb_event_gesture >= 0) && + (response == + _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_GROUP)) + _ecore_xcb_event_handle_gesture_notify_group(ev); +#endif +#ifdef ECORE_XCB_SHAPE + else if ((_ecore_xcb_event_shape >= 0) && + (response == (_ecore_xcb_event_shape + XCB_SHAPE_NOTIFY))) + _ecore_xcb_event_handle_shape_change(ev); +#endif +#ifdef ECORE_XCB_SYNC + else if ((_ecore_xcb_event_sync >= 0) && + (response == (_ecore_xcb_event_sync + XCB_SYNC_COUNTER_NOTIFY))) + _ecore_xcb_event_handle_sync_counter(ev); + else if ((_ecore_xcb_event_sync >= 0) && + (response == (_ecore_xcb_event_sync + XCB_SYNC_ALARM_NOTIFY))) + _ecore_xcb_event_handle_sync_alarm(ev); +#endif +#ifdef ECORE_XCB_XFIXES + else if ((_ecore_xcb_event_xfixes >= 0) && + (response == + _ecore_xcb_event_xfixes + XCB_XFIXES_SELECTION_NOTIFY)) + _ecore_xcb_event_handle_xfixes_selection_notify(ev); + else if ((_ecore_xcb_event_xfixes >= 0) && + (response == (_ecore_xcb_event_xfixes + XCB_XFIXES_CURSOR_NOTIFY))) + _ecore_xcb_event_handle_xfixes_cursor_notify(ev); +#endif +} + +Ecore_X_Time +_ecore_xcb_events_last_time_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_event_last_time; +} + +EAPI void +ecore_x_event_mask_set(Ecore_X_Window win, + Ecore_X_Event_Mask mask) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + + list = (mask | reply->your_event_mask); + free(reply); + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +// ecore_x_flush(); +} + +EAPI void +ecore_x_event_mask_unset(Ecore_X_Window win, + Ecore_X_Event_Mask mask) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + + list = (reply->your_event_mask & ~mask); + free(reply); + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +// ecore_x_flush(); +} + +unsigned int +_ecore_xcb_events_modifiers_get(unsigned int state) +{ + unsigned int modifiers = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + 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_MODIFIER_ALTGR) + modifiers |= ECORE_EVENT_MODIFIER_ALTGR; + if (state & ECORE_X_LOCK_SCROLL) + modifiers |= ECORE_EVENT_LOCK_SCROLL; + if (state & ECORE_X_LOCK_CAPS) + modifiers |= ECORE_EVENT_LOCK_CAPS; + if (state & ECORE_X_LOCK_NUM) + modifiers |= ECORE_EVENT_LOCK_NUM; + if (state & ECORE_X_LOCK_SHIFT) + modifiers |= ECORE_EVENT_LOCK_SHIFT; + + return modifiers; +} + +/* local functions */ +static void +_ecore_xcb_event_handle_any_event(xcb_generic_event_t *event) +{ + xcb_generic_event_t *ev; + +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ev = malloc(sizeof(xcb_generic_event_t)); + if (!ev) return; + + memcpy(ev, event, sizeof(xcb_generic_event_t)); + ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_key_press(xcb_generic_event_t *event) +{ + _ecore_xcb_event_key_press(event); +} + +static void +_ecore_xcb_event_handle_key_release(xcb_generic_event_t *event) +{ + _ecore_xcb_event_key_release(event); +} + +static void +_ecore_xcb_event_handle_button_press(xcb_generic_event_t *event) +{ + xcb_button_press_event_t *ev; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + + ev = (xcb_button_press_event_t *)event; + if ((ev->detail > 3) && (ev->detail < 8)) + { + Ecore_Event_Mouse_Wheel *e; + + if (!(e = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return; + + e->timestamp = ev->time; + e->modifiers = _ecore_xcb_events_modifiers_get(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); + + _ecore_xcb_window_grab_allow_events(ev->event, ev->child, + ECORE_EVENT_MOUSE_WHEEL, + e, ev->time); + } + else + { + Ecore_Event_Mouse_Button *e; + unsigned int child_win = 0; + + child_win = (ev->child ? ev->child : ev->event); + + _ecore_xcb_event_mouse_move(ev->time, ev->state, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y, + ev->event, child_win, + ev->root, ev->same_screen, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + + e = _ecore_xcb_event_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, ev->event, + child_win, + ev->root, ev->same_screen, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + if (e) + _ecore_xcb_window_grab_allow_events(ev->event, ev->child, + ECORE_EVENT_MOUSE_BUTTON_DOWN, + e, ev->time); + } +} + +static void +_ecore_xcb_event_handle_button_release(xcb_generic_event_t *event) +{ + xcb_button_release_event_t *ev; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_button_release_event_t *)event; + if ((ev->detail <= 3) || (ev->detail > 7)) + { + _ecore_xcb_event_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, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + + _ecore_xcb_event_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, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + } +} + +static void +_ecore_xcb_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_event_last_mouse_move_event) */ + /* { */ + /* ecore_event_del(_ecore_xcb_event_last_mouse_move_event); */ + /* _ecore_xcb_event_last_mouse_move = EINA_FALSE; */ + /* _ecore_xcb_event_last_mouse_move_event = NULL; */ + /* } */ + + _ecore_xcb_event_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, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + _ecore_xcb_event_last_mouse_move = EINA_TRUE; + + _ecore_xcb_dnd_drag(ev->root, ev->root_x, ev->root_y); +} + +static void +_ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event) +{ + xcb_enter_notify_event_t *ev; + Ecore_X_Event_Mouse_In *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_enter_notify_event_t *)event; + + _ecore_xcb_event_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, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Mouse_In)))) return; + + e->modifiers = _ecore_xcb_events_modifiers_get(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->event_win = ev->event; + e->same_screen = ev->same_screen_focus; + e->root_win = ev->root; + e->mode = _ecore_xcb_event_mode_get(ev->mode); + e->detail = _ecore_xcb_event_detail_get(ev->detail); + e->time = ev->time; + _ecore_xcb_event_last_time = e->time; + + ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event) +{ + xcb_leave_notify_event_t *ev; + Ecore_X_Event_Mouse_Out *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_enter_notify_event_t *)event; + + _ecore_xcb_event_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, + 0, 1, 1, 1.0, 0.0, + ev->event_x, ev->event_y, + ev->root_x, ev->root_y); + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out)))) return; + + e->modifiers = _ecore_xcb_events_modifiers_get(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->event_win = ev->event; + e->same_screen = ev->same_screen_focus; + e->root_win = ev->root; + e->mode = _ecore_xcb_event_mode_get(ev->mode); + e->detail = _ecore_xcb_event_detail_get(ev->detail); + + 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); +} + +static void +_ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event EINA_UNUSED) +{ +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + // FIXME: handle this event type + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +} + +static void +_ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event) +{ + xcb_focus_in_event_t *ev; + Ecore_X_Event_Window_Focus_In *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_focus_in_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In)))) return; + + e->win = ev->event; + e->mode = _ecore_xcb_event_mode_get(ev->mode); + e->detail = _ecore_xcb_event_detail_get(ev->detail); + + 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); +} + +static void +_ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event) +{ + xcb_focus_out_event_t *ev; + Ecore_X_Event_Window_Focus_Out *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_focus_out_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out)))) return; + + e->win = ev->event; + e->mode = _ecore_xcb_event_mode_get(ev->mode); + e->detail = _ecore_xcb_event_detail_get(ev->detail); + + 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); +} + +static void +_ecore_xcb_event_handle_expose(xcb_generic_event_t *event) +{ + xcb_expose_event_t *ev; + Ecore_X_Event_Window_Damage *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_expose_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) 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); +} + +static void +_ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event) +{ + xcb_graphics_exposure_event_t *ev; + Ecore_X_Event_Window_Damage *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_graphics_exposure_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) return; + + e->win = ev->drawable; + e->x = ev->x; + e->y = ev->y; + e->w = ev->width; + e->h = ev->height; + e->count = ev->count; + e->time = _ecore_xcb_event_last_time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event) +{ + xcb_visibility_notify_event_t *ev; + Ecore_X_Event_Window_Visibility_Change *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_visibility_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change)))) + 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); +} + +static void +_ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event) +{ + xcb_create_notify_event_t *ev; + Ecore_X_Event_Window_Create *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_create_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Create)))) return; + + e->win = ev->window; + e->parent = ev->parent; + if (ev->override_redirect) + e->override = 1; + else + e->override = 0; + e->x = ev->x; + e->y = ev->y; + e->w = ev->width; + e->h = ev->height; + e->border = ev->border_width; + e->time = _ecore_xcb_event_last_time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event) +{ + xcb_destroy_notify_event_t *ev; + Ecore_X_Event_Window_Destroy *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_destroy_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy)))) return; + + e->win = ev->window; + e->event_win = ev->event; + if (e->win == _ecore_xcb_event_last_window) + _ecore_xcb_event_last_window = 0; + e->time = _ecore_xcb_event_last_time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event) +{ + xcb_map_notify_event_t *ev; + Ecore_X_Event_Window_Show *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_map_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show)))) return; + + e->win = ev->window; + e->event_win = ev->event; + e->time = _ecore_xcb_event_last_time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event) +{ + xcb_unmap_notify_event_t *ev; + Ecore_X_Event_Window_Hide *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_unmap_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Hide)))) return; + + e->win = ev->window; + e->event_win = ev->event; + e->time = _ecore_xcb_event_last_time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_map_request(xcb_generic_event_t *event) +{ + xcb_map_request_event_t *ev; + Ecore_X_Event_Window_Show_Request *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_map_request_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request)))) 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); +} + +static void +_ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event) +{ + xcb_reparent_notify_event_t *ev; + Ecore_X_Event_Window_Reparent *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_reparent_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent)))) return; + + e->win = ev->window; + e->event_win = ev->event; + e->parent = ev->parent; + e->time = _ecore_xcb_event_last_time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event) +{ + xcb_configure_notify_event_t *ev; + Ecore_X_Event_Window_Configure *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_configure_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure)))) return; + + e->win = ev->window; + e->event_win = ev->event; + 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); +} + +static void +_ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event) +{ + xcb_configure_request_event_t *ev; + Ecore_X_Event_Window_Configure_Request *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_configure_request_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request)))) + return; + + e->win = ev->window; + e->parent_win = ev->parent; + 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); +} + +static void +_ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event EINA_UNUSED) +{ +/* + xcb_gravity_notify_event_t *ev; + Ecore_X_Event_Window_Gravity *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_gravity_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Gravity)))) return; + + e->win = ev->window; + e->event_win = ev->event; + e->time = _ecore_xcb_event_last_time; + + ecore_event_add(ECORE_X_EVENT_WINDOW_GRAVITY, e, NULL, NULL); + */ +} + +static void +_ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event) +{ + xcb_resize_request_event_t *ev; + Ecore_X_Event_Window_Resize_Request *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_resize_request_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request)))) 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); +} + +static void +_ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event) +{ + xcb_circulate_notify_event_t *ev; + Ecore_X_Event_Window_Stack *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_circulate_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack)))) 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); +} + +static void +_ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event) +{ + xcb_circulate_request_event_t *ev; + Ecore_X_Event_Window_Stack_Request *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_circulate_request_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request)))) 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); +} + +static void +_ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event) +{ + xcb_property_notify_event_t *ev; + Ecore_X_Event_Window_Property *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_property_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Property)))) 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); +} + +static void +_ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event) +{ + xcb_selection_clear_event_t *ev; + Ecore_X_Event_Selection_Clear *e; + Ecore_X_Atom sel; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_selection_clear_event_t *)event; + if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Clear)))) return; + + e->win = ev->owner; + 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; + e->time = ev->time; + + ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event) +{ + xcb_selection_request_event_t *ev; + Ecore_X_Event_Selection_Request *e; + Ecore_X_Selection_Intern *sd; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_selection_request_event_t *)event; + if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Request)))) return; + + e->owner = ev->owner; + e->requestor = ev->requestor; + e->selection = ev->selection; + e->target = ev->target; + e->property = ev->property; + e->time = ev->time; + + ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL); + + if ((sd = _ecore_xcb_selection_get(ev->selection)) && + (sd->win == ev->owner)) + { + Ecore_X_Selection_Intern *si; + + si = _ecore_xcb_selection_get(ev->selection); + if (si->data) + { + Ecore_X_Atom property = XCB_NONE, type; + void *data = NULL; + int len = 0, typesize = 0; + + type = ev->target; + typesize = 8; + len = sd->length; + + if (!ecore_x_selection_convert(ev->selection, ev->target, + &data, &len, &type, &typesize)) + property = XCB_NONE; + else if (data) + { + ecore_x_window_prop_property_set(ev->requestor, ev->property, + type, typesize, data, len); + property = ev->property; + free(data); + } + ecore_x_selection_notify_send(ev->requestor, ev->selection, + ev->target, property, ev->time); + } + } +} + +static void +_ecore_xcb_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 = 0, format = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_selection_notify_event_t *)event; + selection = ev->selection; + if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS) + { + format = + ecore_x_window_prop_property_get(ev->requestor, ev->property, + XCB_ATOM_ATOM, 32, &data, &num); + if (!format) + { + /* fallback if targets handling is not working and try get the + * selection directly */ + xcb_convert_selection(_ecore_xcb_conn, ev->requestor, + selection, selection, + ECORE_X_ATOM_UTF8_STRING, XCB_CURRENT_TIME); + return; + } + } + else + format = ecore_x_window_prop_property_get(ev->requestor, ev->property, + XCB_GET_PROPERTY_TYPE_ANY, 8, + &data, &num); + + 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_xcb_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_xcb_selection_parse(e->target, data, num, format); + + ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, + _ecore_xcb_event_selection_notify_free, NULL); +} + +static void +_ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event) +{ + xcb_colormap_notify_event_t *ev; + Ecore_X_Event_Window_Colormap *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_colormap_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap)))) 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); +} + +static void +_ecore_xcb_event_handle_client_message(xcb_generic_event_t *event) +{ + xcb_client_message_event_t *ev; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_client_message_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 */ + + if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) && (ev->format == 32) && + (ev->data.data32[0] == ECORE_X_ATOM_WM_DELETE_WINDOW)) + { + Ecore_X_Event_Window_Delete_Request *e; + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request)))) + 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) && (ev->data.data32[2] < 9)) + { + Ecore_X_Event_Window_Move_Resize_Request *e; + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request)))) + 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); + } + else if (ev->type == ECORE_X_ATOM_XDND_ENTER) + { + Ecore_X_Event_Xdnd_Enter *e; + Ecore_X_DND_Target *target; + + DBG("Got Xdnd Enter Event"); + if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)))) return; + target = _ecore_xcb_dnd_target_get(); + target->state = ECORE_X_DND_TARGET_ENTERED; + target->source = ev->data.data32[0]; + target->win = ev->window; + target->version = (int)(ev->data.data32[1] >> 24); + if (target->version > ECORE_X_DND_VERSION) + { + WRN("DND: Requested version %d but we only support up to %d", + target->version, ECORE_X_DND_VERSION); + free(e); + return; + } + if (ev->data.data32[1] & 0x1UL) + { + unsigned char *data; + Ecore_X_Atom *types; + int num_ret = 0; + + if (!ecore_x_window_prop_property_get(target->source, + ECORE_X_ATOM_XDND_TYPE_LIST, + ECORE_X_ATOM_ATOM, 32, + &data, &num_ret)) + { + WRN("DND: Could not fetch data type list from source window"); + free(e); + return; + } + types = (Ecore_X_Atom *)data; + e->types = calloc(num_ret, sizeof(char *)); + if (e->types) + { + int i = 0; + + for (i = 0; i < num_ret; i++) + e->types[i] = ecore_x_atom_name_get(types[i]); + } + e->num_types = num_ret; + } + else + { + int i = 0; + + e->types = calloc(3, sizeof(char *)); + if (e->types) + { + while ((i < 3) && (ev->data.data32[i + 2])) + { + e->types[i] = + ecore_x_atom_name_get(ev->data.data32[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_xcb_event_xdnd_enter_free, NULL); + } + else if (ev->type == ECORE_X_ATOM_XDND_POSITION) + { + Ecore_X_Event_Xdnd_Position *e; + Ecore_X_DND_Target *target; + + DBG("Got Xdnd Position Event"); + target = _ecore_xcb_dnd_target_get(); + if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || + (target->win != ev->window)) return; + target->pos.x = ev->data.data32[2] >> 16; + target->pos.y = ev->data.data32[2] & 0xFFFFUL; + target->action = ev->data.data32[4]; + target->time = (target->version >= 1) ? + (Ecore_X_Time)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); + } + else if (ev->type == ECORE_X_ATOM_XDND_STATUS) + { + Ecore_X_Event_Xdnd_Status *e; + Ecore_X_DND_Source *source; + + DBG("Got Xdnd Status Event"); + source = _ecore_xcb_dnd_source_get(); + if ((source->win != ev->window) || + (source->dest != (Ecore_X_Window)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 = ev->data.data32[2] >> 16; + source->rectangle.y = ev->data.data32[2] & 0xFFFFUL; + source->rectangle.width = ev->data.data32[3] >> 16; + source->rectangle.height = 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); + } + else if (ev->type == ECORE_X_ATOM_XDND_LEAVE) + { + Ecore_X_Event_Xdnd_Leave *e; + Ecore_X_DND_Target *target; + + DBG("Got Xdnd Leave Event"); + target = _ecore_xcb_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 = (Ecore_X_Window)ev->data.data32[0]; + ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL); + } + else if (ev->type == ECORE_X_ATOM_XDND_DROP) + { + Ecore_X_Event_Xdnd_Drop *e; + Ecore_X_DND_Target *target; + + DBG("Got Xdnd Drop Event"); + target = _ecore_xcb_dnd_target_get(); + if ((target->source != (Ecore_X_Window)ev->data.data32[0]) || + (target->win != ev->window)) + return; + target->time = (target->version >= 1) ? + (Ecore_X_Time)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); + } + else if (ev->type == ECORE_X_ATOM_XDND_FINISHED) + { + Ecore_X_Event_Xdnd_Finished *e; + Ecore_X_DND_Source *source; + Eina_Bool completed = EINA_TRUE; + + DBG("Got Xdnd Finished Event"); + source = _ecore_xcb_dnd_source_get(); + if ((source->win != ev->window) || + (source->dest != (Ecore_X_Window)ev->data.data32[0])) + return; + if ((source->version < 5) || (ev->data.data32[1] & 0x1UL)) + { + ecore_x_selection_xdnd_clear(); + source->state = ECORE_X_DND_SOURCE_IDLE; + } + else if (source->version >= 5) + { + completed = EINA_FALSE; + source->state = ECORE_X_DND_SOURCE_CONVERTING; + /* FIXME: Probably need to add a timer to switch back to idle + * and discard the selection data */ + } + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished)))) + 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; + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)))) + 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_xcb_netwm_window_state_get(ev->data.data32[1]); + if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN) + { + /* FIXME */ + } + e->state[1] = _ecore_xcb_netwm_window_state_get(ev->data.data32[2]); + if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN) + { + /* FIXME */ + } + e->source = ev->data.data32[3]; + ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL); + } +#ifdef OLD_XCB_VERSION + else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) && + (ev->format == 32) && (ev->data.data32[0] == XCB_WM_STATE_ICONIC)) +#else + else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) && (ev->format == 32) && + (ev->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC)) +#endif + { + Ecore_X_Event_Window_State_Request *e; + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)))) + 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; + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change)))) + 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; + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request)))) + 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; + Ecore_X_Window root = 0; + int count = 0; + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Ping)))) 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); + + CHECK_XCB_CONN; + + count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); + if (count > 1) + root = ecore_x_window_root_get(e->win); + else + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (ev->window != root) + { + ev->window = root; + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), + (const char *)&ev); +// ecore_x_flush(); + } + } + else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) && + (ev->format == 8)) + { + _ecore_xcb_netwm_startup_info_begin(ev->window, ev->data.data8[0]); + } + else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) && (ev->format == 8)) + { + _ecore_xcb_netwm_startup_info(ev->window, ev->data.data8[0]); + } + else if ((ev->type == 27777) && (ev->data.data32[0] == 0x7162534) && + (ev->format == 32)) // && (ev->window = _private_window)) + { + if (ev->data.data32[1] == 0x10000001) + _ecore_xcb_window_button_grab_remove(ev->data.data32[2]); + else if (ev->data.data32[1] == 0x10000002) + _ecore_xcb_window_key_grab_remove(ev->data.data32[2]); + } + else + { + Ecore_X_Event_Client_Message *e; + int i = 0; + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Client_Message)))) + 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); + } +} + +static void +_ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event) +{ + xcb_mapping_notify_event_t *ev; + Ecore_X_Event_Mapping_Change *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + + ev = (xcb_mapping_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change)))) return; + + _ecore_xcb_keymap_refresh(ev); + _ecore_xcb_modifiers_get(); + + switch (ev->request) + { + case XCB_MAPPING_MODIFIER: + e->type = ECORE_X_MAPPING_MODIFIER; + break; + + case XCB_MAPPING_KEYBOARD: + e->type = ECORE_X_MAPPING_KEYBOARD; + break; + + case XCB_MAPPING_POINTER: + default: + e->type = ECORE_X_MAPPING_MOUSE; + break; + } + e->keycode = ev->first_keycode; + e->num = ev->count; + + ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_DAMAGE + xcb_damage_notify_event_t *ev; + Ecore_X_Event_Damage *e; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +#ifdef ECORE_XCB_DAMAGE + ev = (xcb_damage_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Damage)))) return; + + e->level = ev->level; + e->drawable = ev->drawable; + e->damage = ev->damage; + 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 +} + +static void +_ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_screen_change_notify_event_t *ev; + Ecore_X_Event_Screen_Change *e; +#endif + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + ev = (xcb_randr_screen_change_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Screen_Change)))) return; + + e->win = ev->request_window; + e->root = ev->root; + e->size.width = ev->width; + e->size.height = ev->height; + e->time = ev->timestamp; + e->config_time = ev->config_timestamp; + e->size.width_mm = ev->mwidth; + e->size.height_mm = ev->mheight; + e->orientation = ev->rotation; + e->subpixel_order = ev->subpixel_order; + + ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_notify_event_t *ev; +#endif + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + ev = (xcb_randr_notify_event_t *)event; + switch (ev->subCode) + { + case XCB_RANDR_NOTIFY_CRTC_CHANGE: + _ecore_xcb_event_handle_randr_crtc_change(event); + break; + + case XCB_RANDR_NOTIFY_OUTPUT_CHANGE: + _ecore_xcb_event_handle_randr_output_change(event); + break; + + case XCB_RANDR_NOTIFY_OUTPUT_PROPERTY: + _ecore_xcb_event_handle_randr_output_property_change(event); + break; + + default: + break; + } +#endif +} + +static void +_ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_notify_event_t *ev; + Ecore_X_Event_Randr_Crtc_Change *e; +#endif + +#ifdef ECORE_XCB_RANDR + ev = (xcb_randr_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change)))) + return; + + e->win = ev->u.cc.window; + e->crtc = ev->u.cc.crtc; + e->mode = ev->u.cc.mode; + e->orientation = ev->u.cc.rotation; + e->geo.x = ev->u.cc.x; + e->geo.y = ev->u.cc.y; + e->geo.w = ev->u.cc.width; + e->geo.h = ev->u.cc.height; + + ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_notify_event_t *ev; + Ecore_X_Event_Randr_Output_Change *e; +#endif + +#ifdef ECORE_XCB_RANDR + ev = (xcb_randr_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change)))) + return; + + e->win = ev->u.oc.window; + e->output = ev->u.oc.output; + e->crtc = ev->u.oc.crtc; + e->mode = ev->u.oc.mode; + e->orientation = ev->u.oc.rotation; + e->connection = ev->u.oc.connection; + e->subpixel_order = ev->u.oc.subpixel_order; + + ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_notify_event_t *ev; + Ecore_X_Event_Randr_Output_Property_Notify *e; +#endif + +#ifdef ECORE_XCB_RANDR + ev = (xcb_randr_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify)))) + return; + + e->win = ev->u.op.window; + e->output = ev->u.op.output; + e->property = ev->u.op.atom; + e->time = ev->u.op.timestamp; + if (ev->u.op.status == XCB_PROPERTY_NEW_VALUE) + e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD; + else + e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL; + + ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_SCREENSAVER + xcb_screensaver_notify_event_t *ev; + Ecore_X_Event_Screensaver_Notify *e; +#endif + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +#ifdef ECORE_XCB_SCREENSAVER + ev = (xcb_screensaver_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify)))) return; + + e->win = ev->window; + e->on = EINA_FALSE; + if ((ev->state == XCB_SCREENSAVER_STATE_ON) || + (ev->state == XCB_SCREENSAVER_STATE_CYCLE)) e->on = EINA_TRUE; + e->time = ev->time; + + ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL); +#endif +} + +#ifdef ECORE_XCB_XGESTURE +static void +_ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event) +{ + xcb_gesture_notify_flick_event_t *ev; + Ecore_X_Event_Gesture_Notify_Flick *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); + + ev = (xcb_gesture_notify_flick_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick)))) return; + + e->win = ev->window; + e->time = ev->time; + e->subtype = ev->kind; + e->num_fingers = ev->num_finger; + e->distance = ev->distance; + e->duration = ev->duration; + e->direction = ev->direction; + e->angle = XFixedToDouble(ev->angle); + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event) +{ + xcb_gesture_notify_pan_event_t *ev; + Ecore_X_Event_Gesture_Notify_Pan *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); + + ev = (xcb_gesture_notify_pan_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan)))) return; + + e->win = ev->window; + e->time = ev->time; + e->subtype = ev->kind; + e->num_fingers = ev->num_finger; + e->dx = ev->dx; + e->dy = ev->dy; + e->distance = ev->distance; + e->duration = ev->duration; + e->direction = ev->direction; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event) +{ + xcb_gesture_notify_pinch_rotation_event_t *ev; + Ecore_X_Event_Gesture_Notify_PinchRotation *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); + + ev = (xcb_gesture_notify_pinch_rotation_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation)))) return; + + e->win = ev->window; + e->time = ev->time; + e->subtype = ev->kind; + e->num_fingers = ev->num_finger; + e->distance = ev->distance; + e->cx = ev->cx; + e->cy = ev->cy; + e->zoom = XFixedToDouble(ev->zoom); + e->angle = XFixedToDouble(ev->angle); + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event) +{ + xcb_gesture_notify_tap_event_t *ev; + Ecore_X_Event_Gesture_Notify_Tap *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); + + ev = (xcb_gesture_notify_tap_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap)))) return; + + e->win = ev->window; + e->time = ev->time; + e->subtype = ev->kind; + e->num_fingers = ev->num_finger; + e->cx = ev->cx; + e->cy = ev->cy; + e->tap_repeat = ev->tap_repeat; + e->interval = ev->interval; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL); +} + +static void +_ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event) +{ + xcb_gesture_notify_tap_n_hold_event_t *ev; + Ecore_X_Event_Gesture_Notify_TapNHold *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); + + ev = (xcb_gesture_notify_tap_n_hold_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold)))) return; + + e->win = ev->window; + e->time = ev->time; + e->subtype = ev->kind; + e->num_fingers = ev->num_finger; + e->cx = ev->cx; + e->cy = ev->cy; + e->interval = ev->interval; + e->hold_time = ev->holdtime; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL); +} + +static void + _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event) +{ + xcb_gesture_notify_hold_event_t *ev; + Ecore_X_Event_Gesture_Notify_Hold *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); + + ev = (xcb_gesture_notify_hold_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold)))) return; + + e->win = ev->window; + e->time = ev->time; + e->subtype = ev->kind; + e->num_fingers = ev->num_finger; + e->cx = ev->cx; + e->cy = ev->cy; + e->hold_time = ev->holdtime; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL); +} + +static void + _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event) +{ + xcb_gesture_notify_group_event_t *ev; + Ecore_X_Event_Gesture_Notify_Group *e; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__); + + ev = (xcb_gesture_notify_group_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group)))) return; + + e->win = ev->window; + e->time = ev->time; + e->subtype = ev->kind; + e->num_groups = ev->num_group; + e->group_id = ev->groupid; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL); +} +#endif + +#ifdef ECORE_XCB_SHAPE +static void +_ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event) +{ + xcb_shape_notify_event_t *ev; + Ecore_X_Event_Window_Shape *e; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + ev = (xcb_shape_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Shape)))) return; + + e->win = ev->affected_window; + e->time = ev->server_time; + switch (ev->shape_kind) + { + case XCB_SHAPE_SK_BOUNDING: + e->type = ECORE_X_SHAPE_BOUNDING; + break; + + case XCB_SHAPE_SK_CLIP: + e->type = ECORE_X_SHAPE_CLIP; + break; + + case XCB_SHAPE_SK_INPUT: + e->type = ECORE_X_SHAPE_INPUT; + break; + + default: + break; + } + e->x = ev->extents_x; + e->y = ev->extents_y; + e->w = ev->extents_width; + e->h = ev->extents_height; + e->shaped = ev->shaped; + + ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL); +} + +#endif + +static void +_ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_counter_notify_event_t *ev; + Ecore_X_Event_Sync_Counter *e; +#endif + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + +#ifdef ECORE_XCB_SYNC + ev = (xcb_sync_counter_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter)))) return; + + e->time = ev->timestamp; + + ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_alarm_notify_event_t *ev; + Ecore_X_Event_Sync_Alarm *e; +#endif + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +#ifdef ECORE_XCB_SYNC + ev = (xcb_sync_alarm_notify_event_t *)event; + if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm)))) return; + + e->time = ev->timestamp; + e->alarm = ev->alarm; + + ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event) +{ +#ifdef ECORE_XCB_XFIXES + Ecore_X_Event_Fixes_Selection_Notify *e; + Ecore_X_Atom sel; + xcb_xfixes_selection_notify_event_t *ev; +#endif + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; +#ifdef ECORE_XCB_XFIXES + ev = (xcb_xfixes_selection_notify_event_t *)event; + + if (!(e = calloc(1, sizeof(*e)))) return; + + e->win = ev->window; + e->owner = ev->owner; + e->time = ev->timestamp; + e->selection_time = ev->selection_timestamp; + 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; + e->reason = ev->subtype; + + ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL); +#endif +} + +static void +_ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event EINA_UNUSED) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +// FIXME: TBD +} + +static void +_ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event) +{ + xcb_ge_event_t *ev; + Ecore_X_Event_Generic *e; + + ev = (xcb_ge_event_t *)event; + + /* pad0 *IS* extension - bug in xcb */ + if (ev->pad0 == _ecore_xcb_event_input) + { + _ecore_xcb_event_handle_input_event(event); +// FIXME: should we generate generic events as WELL as input events? +// return; + } + + if (!(e = calloc(1, sizeof(Ecore_X_Event_Generic)))) + return; + + DBG("Handle Generic Event: %d", ev->event_type); + + e->cookie = ev->sequence; + /* NB: These are bugs in xcb ge_event structure. The struct should have a + * field for extension & data, but does not. + * + * XCB people have been notified of this issue */ + e->extension = ev->pad0; + /* e->data = ev->pad1; */ + if (ev->length > 0) + { + int len = ev->length * sizeof(int); + e->data = malloc(len); + if (e->data) memcpy(e->data, &(event[1]), len); + } + + e->evtype = ev->event_type; + + ecore_event_add(ECORE_X_EVENT_GENERIC, e, + _ecore_xcb_event_generic_event_free, e->data); +} + +static void +_ecore_xcb_event_handle_input_event(xcb_generic_event_t *event) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_input_handle_event(event); +} + +static void +_ecore_xcb_event_key_press(xcb_generic_event_t *event) +{ + Ecore_Event_Key *e; + xcb_keysym_t sym = XCB_NO_SYMBOL; + xcb_keycode_t keycode = 0; + xcb_key_press_event_t *xevent; + char *keyname = NULL, *key = NULL; + char *compose = NULL; + char compose_buffer[256]; + int val = 0; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + + xevent = (xcb_key_press_event_t *)event; + keycode = xevent->detail; + + sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state); + keyname = _ecore_xcb_keymap_keysym_to_string(sym); + if (!keyname) + { + char buff[256]; + + snprintf(buff, sizeof(buff), "Keycode-%i", keycode); + keyname = buff; + } + + val = + _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer, + sizeof(compose_buffer), &sym); + if (val > 0) + { + compose_buffer[val] = 0; + compose = + eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); + if (!compose) + ERR("Ecore_X cannot convert input key string '%s' to UTF-8. " + "Is Eina built with iconv support?", compose_buffer); + } + + key = _ecore_xcb_keymap_keysym_to_string(sym); + if (!key) key = keyname; + + e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + + (compose ? strlen(compose) : 0) + 3); + if (e) + { + e->keyname = (char *)(e + 1); + e->key = e->keyname + strlen(keyname) + 1; + + e->compose = NULL; + if (compose) e->compose = (e->key + strlen(key) + 1); + e->string = e->compose; + + strcpy((char *)e->keyname, keyname); + strcpy((char *)e->key, key); + if (compose) strcpy((char *)e->compose, compose); + + e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state); + e->timestamp = xevent->time; + e->window = xevent->child ? xevent->child : xevent->event; + e->event_window = xevent->event; + e->same_screen = xevent->same_screen; + e->root_window = xevent->root; + + DBG("Sending Key Down Event: %s", e->keyname); + ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL); + } + _ecore_xcb_event_last_time = xevent->time; +} + +static void +_ecore_xcb_event_key_release(xcb_generic_event_t *event) +{ + Ecore_Event_Key *e; + xcb_keysym_t sym = XCB_NO_SYMBOL; + xcb_keycode_t keycode = 0; + xcb_key_release_event_t *xevent; + char *keyname = NULL, *key = NULL; + char *compose = NULL; + char compose_buffer[256]; + int val = 0; + + _ecore_xcb_event_last_mouse_move = EINA_FALSE; + + xevent = (xcb_key_release_event_t *)event; + keycode = xevent->detail; + + sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state); + keyname = _ecore_xcb_keymap_keysym_to_string(sym); + if (!keyname) + { + char buff[256]; + + snprintf(buff, sizeof(buff), "Keycode-%i", keycode); + keyname = buff; + } + + val = + _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer, + sizeof(compose_buffer), &sym); + if (val > 0) + { + compose_buffer[val] = 0; + compose = + eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); +// tmp = compose; + } + + key = _ecore_xcb_keymap_keysym_to_string(sym); + if (!key) key = keyname; + + e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + + (compose ? strlen(compose) : 0) + 3); + if (e) + { + e->keyname = (char *)(e + 1); + e->key = e->keyname + strlen(keyname) + 1; + + e->compose = NULL; + if (compose) e->compose = (e->key + strlen(key) + 1); + e->string = e->compose; + + strcpy((char *)e->keyname, keyname); + strcpy((char *)e->key, key); + if (compose) strcpy((char *)e->compose, compose); + + e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state); + e->timestamp = xevent->time; + e->window = xevent->child ? xevent->child : xevent->event; + e->event_window = xevent->event; + e->same_screen = xevent->same_screen; + e->root_window = xevent->root; + + ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL); + } + _ecore_xcb_event_last_time = xevent->time; +} + +void +_ecore_xcb_event_mouse_move(uint16_t timestamp, + uint16_t modifiers, + int16_t x, + int16_t y, + int16_t root_x, + int16_t root_y, + xcb_window_t event_win, + xcb_window_t win, + xcb_window_t root_win, + uint8_t same_screen, + int dev, + double radx, + double rady, + double pressure, + double angle, + int16_t mx, + int16_t my, + int16_t mrx, + int16_t mry) +{ + Ecore_Event_Mouse_Move *e; + Ecore_Event *event; + + if (!(e = malloc(sizeof(Ecore_Event_Mouse_Move)))) return; + + e->window = win; + e->root_window = root_win; + e->timestamp = timestamp; + e->same_screen = same_screen; + e->event_window = event_win; + e->modifiers = _ecore_xcb_events_modifiers_get(modifiers); + e->x = x; + e->y = y; + e->root.x = root_x; + e->root.y = root_y; + 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_xcb_event_mouse_move_free, NULL); + + _ecore_xcb_event_last_time = e->timestamp; + _ecore_xcb_event_last_window = e->window; + _ecore_xcb_event_last_root_x = root_x; + _ecore_xcb_event_last_root_y = root_y; +// _ecore_xcb_event_last_mouse_move_event = event; +} + +static void +_ecore_xcb_event_mouse_move_free(void *data EINA_UNUSED, + void *event) +{ + Ecore_Event_Mouse_Move *ev; + + ev = event; +// if (_ecore_xcb_event_last_mouse_move_event) +// { +// _ecore_xcb_event_last_mouse_move = EINA_FALSE; +// _ecore_xcb_event_last_mouse_move_event = NULL; +// } + if (ev) free(ev); +} + +Ecore_Event_Mouse_Button * +_ecore_xcb_event_mouse_button(int event, + uint16_t timestamp, + uint16_t modifiers, + xcb_button_t buttons, + int16_t x, + int16_t y, + int16_t root_x, + int16_t root_y, + xcb_window_t event_win, + xcb_window_t win, + xcb_window_t root_win, + uint8_t same_screen, + int dev, + double radx, + double rady, + double pressure, + double angle, + int16_t mx, + int16_t my, + int16_t mrx, + int16_t mry) +{ + Ecore_Event_Mouse_Button *e; + Ecore_X_Mouse_Down_Info *info = NULL; + + if (!(e = malloc(sizeof(Ecore_Event_Mouse_Button)))) return NULL; + + e->window = win; + e->root_window = root_win; + e->timestamp = timestamp; + e->same_screen = same_screen; + e->event_window = event_win; + e->buttons = buttons; + e->modifiers = _ecore_xcb_events_modifiers_get(modifiers); + e->double_click = 0; + e->triple_click = 0; + e->x = x; + e->y = y; + e->root.x = root_x; + e->root.y = root_y; + + if ((info = _ecore_xcb_event_mouse_down_info_get(dev))) + { + if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && + (info->did_triple)) + { + info->last_win = 0; + info->last_last_win = 0; + info->last_event_win = 0; + info->last_time = 0; + info->last_last_time = 0; + } + if (event_win == win) + { + if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) + { + if (((int)(timestamp - info->last_time) <= + (int)(1000 * _ecore_xcb_double_click_time)) && + (win == info->last_win) && + (event_win == info->last_event_win)) + { + e->double_click = 1; + info->did_double = EINA_TRUE; + } + else + { + info->did_double = EINA_FALSE; + info->did_triple = EINA_FALSE; + } + if (((int)(timestamp - info->last_last_time) <= + (int)(2 * 1000 * _ecore_xcb_double_click_time)) && + (win == info->last_win) && + (win == info->last_last_win) && + (event_win == info->last_event_win) && + (event_win == info->last_last_event_win)) + { + e->triple_click = 1; + info->did_triple = EINA_TRUE; + } + else + info->did_triple = EINA_FALSE; + } + else + { + if (info->did_double) e->double_click = 1; + if (info->did_triple) e->triple_click = 1; + } + } + } + + /* NB: Comment out right now because _ecore_xcb_mouse_up_count is + * only used here...nowhere else in the code */ + + /* if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && */ + /* (!e->double_click) && (!e->triple_click)) */ + /* _ecore_xcb_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_xcb_event_last_time = e->timestamp; + _ecore_xcb_event_last_window = e->window; + _ecore_xcb_event_last_root_x = root_x; + _ecore_xcb_event_last_root_y = root_y; + + ecore_event_add(event, e, NULL, NULL); + + if ((info) && (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && + (win == event_win) && (!info->did_triple)) + { + info->last_last_win = info->last_win; + info->last_win = win; + info->last_last_event_win = info->last_event_win; + info->last_event_win = event_win; + info->last_last_time = info->last_time; + info->last_time = timestamp; + } + + return e; +} + +static Ecore_X_Event_Mode +_ecore_xcb_event_mode_get(uint8_t mode) +{ + switch (mode) + { + case XCB_NOTIFY_MODE_NORMAL: + return ECORE_X_EVENT_MODE_NORMAL; + + case XCB_NOTIFY_MODE_WHILE_GRABBED: + return ECORE_X_EVENT_MODE_WHILE_GRABBED; + + case XCB_NOTIFY_MODE_GRAB: + return ECORE_X_EVENT_MODE_GRAB; + + case XCB_NOTIFY_MODE_UNGRAB: + return ECORE_X_EVENT_MODE_UNGRAB; + + default: + return ECORE_X_EVENT_MODE_NORMAL; + } +} + +static Ecore_X_Event_Detail +_ecore_xcb_event_detail_get(uint8_t detail) +{ + switch (detail) + { + case XCB_NOTIFY_DETAIL_ANCESTOR: + return ECORE_X_EVENT_DETAIL_ANCESTOR; + + case XCB_NOTIFY_DETAIL_VIRTUAL: + return ECORE_X_EVENT_DETAIL_VIRTUAL; + + case XCB_NOTIFY_DETAIL_INFERIOR: + return ECORE_X_EVENT_DETAIL_INFERIOR; + + case XCB_NOTIFY_DETAIL_NONLINEAR: + return ECORE_X_EVENT_DETAIL_NON_LINEAR; + + case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: + return ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; + + case XCB_NOTIFY_DETAIL_POINTER: + return ECORE_X_EVENT_DETAIL_POINTER; + + case XCB_NOTIFY_DETAIL_POINTER_ROOT: + return ECORE_X_EVENT_DETAIL_POINTER_ROOT; + + case XCB_NOTIFY_DETAIL_NONE: + default: + return ECORE_X_EVENT_DETAIL_ANCESTOR; + } +} + +static void +_ecore_xcb_event_xdnd_enter_free(void *data EINA_UNUSED, + void *event) +{ + Ecore_X_Event_Xdnd_Enter *e; + int i = 0; + + e = event; + for (i = 0; i < e->num_types; i++) + free(e->types[i]); + free(e->types); + free(e); +} + +static void +_ecore_xcb_event_selection_notify_free(void *data EINA_UNUSED, + void *event) +{ + Ecore_X_Event_Selection_Notify *e; + Ecore_X_Selection_Data *sel; + + e = event; + if (!(sel = e->data)) return; + if (sel->free) sel->free(sel); + free(e->target); + free(e); +} + +static void +_ecore_xcb_event_generic_event_free(void *data, + void *event) +{ + Ecore_X_Event_Generic *e; + + e = (Ecore_X_Event_Generic *)event; + if (e->data) free(data); + free(e); +} + +static void +_ecore_xcb_event_mouse_down_info_clear(void) +{ + Eina_Inlist *l; + Ecore_X_Mouse_Down_Info *info = NULL; + + l = _ecore_xcb_mouse_down_info_list; + while (l) + { + info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info); + l = eina_inlist_remove(l, l); + free(info); + } + _ecore_xcb_mouse_down_info_list = NULL; +} + +static Ecore_X_Mouse_Down_Info * +_ecore_xcb_event_mouse_down_info_get(int dev) +{ + Eina_Inlist *l; + Ecore_X_Mouse_Down_Info *info = NULL; + + l = _ecore_xcb_mouse_down_info_list; + EINA_INLIST_FOREACH(l, info) + if (info->dev == dev) return info; + + if (!(info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info)))) return NULL; + + info->dev = dev; + l = eina_inlist_append(l, (Eina_Inlist *)info); + _ecore_xcb_mouse_down_info_list = l; + + return info; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_extensions.c b/src/lib/ecore_x/xcb/ecore_xcb_extensions.c new file mode 100644 index 0000000000..40c10ac05b --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_extensions.c @@ -0,0 +1,148 @@ +#include "ecore_xcb_private.h" + +void +_ecore_xcb_extensions_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shm_id); + +#ifdef ECORE_XCB_SHAPE + _ecore_xcb_shape_init(); +#endif + +#ifdef ECORE_XCB_SCREENSAVER + _ecore_xcb_screensaver_init(); +#endif + +#ifdef ECORE_XCB_SYNC + _ecore_xcb_sync_init(); +#endif + +#ifdef ECORE_XCB_RANDR + _ecore_xcb_randr_init(); +#endif + +#ifdef ECORE_XCB_XFIXES + _ecore_xcb_xfixes_init(); +#endif + +#ifdef ECORE_XCB_DAMAGE + _ecore_xcb_damage_init(); +#endif + +#ifdef ECORE_XCB_RENDER + _ecore_xcb_render_init(); +#endif + +#ifdef ECORE_XCB_COMPOSITE + _ecore_xcb_composite_init(); +#endif + +#ifdef ECORE_XCB_DPMS + _ecore_xcb_dpms_init(); +#endif + +#ifdef ECORE_XCB_DPMS + _ecore_xcb_dpms_init(); +#endif + +#ifdef ECORE_XCB_CURSOR + _ecore_xcb_cursor_init(); +#endif + +#ifdef ECORE_XCB_XINERAMA + _ecore_xcb_xinerama_init(); +#endif + +#ifdef ECORE_XCB_XINPUT + _ecore_xcb_input_init(); +#endif + +#ifdef ECORE_XCB_GESTURE + _ecore_xcb_gesture_init(); +#endif + +/* #ifdef ECORE_XCB_DRI */ +/* _ecore_xcb_dri_init(); */ +/* #endif */ + +#ifdef ECORE_XCB_XTEST + _ecore_xcb_xtest_init(); +#endif + + xcb_prefetch_maximum_request_length(_ecore_xcb_conn); +} + +void +_ecore_xcb_extensions_finalize(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xcb_get_extension_data(_ecore_xcb_conn, &xcb_big_requests_id); + xcb_get_extension_data(_ecore_xcb_conn, &xcb_shm_id); + +#ifdef ECORE_XCB_SHAPE + _ecore_xcb_shape_finalize(); +#endif + +#ifdef ECORE_XCB_SCREENSAVER + _ecore_xcb_screensaver_finalize(); +#endif + +#ifdef ECORE_XCB_SYNC + _ecore_xcb_sync_finalize(); +#endif + +#ifdef ECORE_XCB_RANDR + _ecore_xcb_randr_finalize(); +#endif + +#ifdef ECORE_XCB_XFIXES + _ecore_xcb_xfixes_finalize(); +#endif + +#ifdef ECORE_XCB_DAMAGE + _ecore_xcb_damage_finalize(); +#endif + +#ifdef ECORE_XCB_RENDER + _ecore_xcb_render_finalize(); +#endif + +#ifdef ECORE_XCB_COMPOSITE + _ecore_xcb_composite_finalize(); +#endif + +#ifdef ECORE_XCB_DPMS + _ecore_xcb_dpms_finalize(); +#endif + +#ifdef ECORE_XCB_CURSOR + _ecore_xcb_cursor_finalize(); +#endif + +#ifdef ECORE_XCB_XINERAMA + _ecore_xcb_xinerama_finalize(); +#endif + +#ifdef ECORE_XCB_XINPUT + _ecore_xcb_input_finalize(); +#endif + +#ifdef ECORE_XCB_GESTURE + _ecore_xcb_gesture_finalize(); +#endif + +/* #ifdef ECORE_XCB_DRI */ +/* _ecore_xcb_dri_finalize(); */ +/* #endif */ + +#ifdef ECORE_XCB_XTEST + _ecore_xcb_xtest_finalize(); +#endif + + xcb_get_maximum_request_length(_ecore_xcb_conn); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_gc.c b/src/lib/ecore_x/xcb/ecore_xcb_gc.c new file mode 100644 index 0000000000..d811b54594 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_gc.c @@ -0,0 +1,173 @@ +#include "ecore_xcb_private.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 drawable, + Ecore_X_GC_Value_Mask value_mask, + const unsigned int *value_list) +{ + xcb_gcontext_t gc; + uint32_t vmask = 0; + int i = 0, mask = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!drawable) drawable = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + for (i = 0, mask = 1; i <= 22; i++, mask <<= 1) + { + switch (mask & value_mask) + { + case ECORE_X_GC_VALUE_MASK_FUNCTION: + vmask |= XCB_GC_FUNCTION; + break; + + case ECORE_X_GC_VALUE_MASK_PLANE_MASK: + vmask |= XCB_GC_PLANE_MASK; + break; + + case ECORE_X_GC_VALUE_MASK_FOREGROUND: + vmask |= XCB_GC_FOREGROUND; + break; + + case ECORE_X_GC_VALUE_MASK_BACKGROUND: + vmask |= XCB_GC_BACKGROUND; + break; + + case ECORE_X_GC_VALUE_MASK_LINE_WIDTH: + vmask |= XCB_GC_LINE_WIDTH; + break; + + case ECORE_X_GC_VALUE_MASK_LINE_STYLE: + vmask |= XCB_GC_LINE_STYLE; + break; + + case ECORE_X_GC_VALUE_MASK_CAP_STYLE: + vmask |= XCB_GC_CAP_STYLE; + break; + + case ECORE_X_GC_VALUE_MASK_JOIN_STYLE: + vmask |= XCB_GC_JOIN_STYLE; + break; + + case ECORE_X_GC_VALUE_MASK_FILL_STYLE: + vmask |= XCB_GC_FILL_STYLE; + break; + + case ECORE_X_GC_VALUE_MASK_FILL_RULE: + vmask |= XCB_GC_FILL_RULE; + break; + + case ECORE_X_GC_VALUE_MASK_TILE: + vmask |= XCB_GC_TILE; + break; + + case ECORE_X_GC_VALUE_MASK_STIPPLE: + vmask |= XCB_GC_STIPPLE; + break; + + case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X: + vmask |= XCB_GC_TILE_STIPPLE_ORIGIN_X; + break; + + case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y: + vmask |= XCB_GC_TILE_STIPPLE_ORIGIN_Y; + break; + + case ECORE_X_GC_VALUE_MASK_FONT: + vmask |= XCB_GC_FONT; + break; + + case ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE: + vmask |= XCB_GC_SUBWINDOW_MODE; + break; + + case ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES: + vmask |= XCB_GC_GRAPHICS_EXPOSURES; + break; + + case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X: + vmask |= XCB_GC_CLIP_ORIGIN_X; + break; + + case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y: + vmask |= XCB_GC_CLIP_ORIGIN_Y; + break; + + case ECORE_X_GC_VALUE_MASK_CLIP_MASK: + vmask |= XCB_GC_CLIP_MASK; + break; + + case ECORE_X_GC_VALUE_MASK_DASH_OFFSET: + vmask |= XCB_GC_DASH_OFFSET; + break; + + case ECORE_X_GC_VALUE_MASK_DASH_LIST: + vmask |= XCB_GC_DASH_LIST; + break; + + case ECORE_X_GC_VALUE_MASK_ARC_MODE: + vmask |= XCB_GC_ARC_MODE; + break; + } + } + + gc = xcb_generate_id(_ecore_xcb_conn); + xcb_create_gc(_ecore_xcb_conn, gc, drawable, vmask, value_list); + +// ecore_x_flush(); + return gc; +} + +/** + * 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__); + CHECK_XCB_CONN; + + xcb_free_gc(_ecore_xcb_conn, gc); +// ecore_x_flush(); +} + +EAPI void +ecore_x_gc_foreground_set(Ecore_X_GC gc, + unsigned long foreground) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = foreground; + xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list); +// ecore_x_flush(); +} + +EAPI void +ecore_x_gc_background_set(Ecore_X_GC gc, + unsigned long background) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = background; + xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_BACKGROUND, &list); +// ecore_x_flush(); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_gesture.c b/src/lib/ecore_x/xcb/ecore_xcb_gesture.c new file mode 100644 index 0000000000..27c13167af --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_gesture.c @@ -0,0 +1,203 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_XGESTURE +# include +# include +#endif + +/* local variables */ +static Eina_Bool _gesture_available = EINA_FALSE; + +/* external variables */ +int _ecore_xcb_event_gesture = -1; + +void +_ecore_xcb_gesture_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XGESTURE + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_gesture_id); +#endif +} + +void +_ecore_xcb_gesture_finalize(void) +{ +#ifdef ECORE_XCB_XGESTURE + xcb_gesture_query_version_cookie_t cookie; + xcb_gesture_query_version_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XGESTURE + cookie = + xcb_gesture_query_version_unchecked(_ecore_xcb_conn); + reply = + xcb_gesture_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + _gesture_available = EINA_TRUE; + free(reply); + } + + if (_gesture_available) + { + const xcb_query_extension_reply_t *ext_reply; + + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_gesture_id); + if (ext_reply) + _ecore_xcb_event_gesture = ext_reply->first_event; + } +#endif +} + +void +_ecore_xcb_gesture_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +} + +EAPI Eina_Bool +ecore_x_gesture_supported(void) +{ + return _gesture_available; +} + +#ifdef ECORE_XCB_XGESTURE +EAPI Eina_Bool +ecore_x_gesture_events_select(Ecore_X_Window win, + Ecore_X_Gesture_Event_Mask mask) +#else +EAPI Eina_Bool +ecore_x_gesture_events_select(Ecore_X_Window win EINA_UNUSED, + Ecore_X_Gesture_Event_Mask mask EINA_UNUSED) +#endif + +{ +#ifdef ECORE_XCB_XGESTURE + if (!_gesture_available) return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN + + xcb_gesture_select_events(_ecore_xcb_conn, win, mask); + + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +#ifdef ECORE_XCB_XGESTURE +EAPI Ecore_X_Gesture_Event_Mask +ecore_x_gesture_events_selected_get(Ecore_X_Window win) +#else +EAPI Ecore_X_Gesture_Event_Mask +ecore_x_gesture_events_selected_get(Ecore_X_Window win EINA_UNUSED) +#endif +{ +#ifdef ECORE_XCB_XGESTURE + xcb_gesture_get_selected_events_cookie_t ecookie; + xcb_gesture_get_selected_events_reply_t *ereply; + Ecore_X_Gesture_Event_Mask mask = ECORE_X_GESTURE_EVENT_MASK_NONE; + + if (!_gesture_available) return mask; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN + + ecookie = xcb_gesture_get_selected_events(_ecore_xcb_conn, win); + ereply = + xcb_gesture_get_selected_events_reply(_ecore_xcb_conn, ecookie, NULL); + if (ereply) + { + mask = ereply->mask; + free(ereply); + } + + return mask; +#else + return ECORE_X_GESTURE_EVENT_MASK_NONE; +#endif +} + +#ifdef ECORE_XCB_XGESTURE +EAPI Eina_Bool +ecore_x_gesture_event_grab(Ecore_X_Window win, + Ecore_X_Gesture_Event_Type type, + int num_fingers) +#else +EAPI Eina_Bool +ecore_x_gesture_event_grab(Ecore_X_Window win EINA_UNUSED, + Ecore_X_Gesture_Event_Type type EINA_UNUSED, + int num_fingers EINA_UNUSED) +#endif +{ +#ifdef ECORE_XCB_XGESTURE + Eina_Bool status = EINA_TRUE; + xcb_gesture_grab_event_cookie_t ecookie; + xcb_gesture_grab_event_reply_t *ereply; + + if (!_gesture_available) return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN + + ecookie = + xcb_gesture_grab_event(_ecore_xcb_conn, win, type, num_fingers, 0L); + ereply = xcb_gesture_grab_event_reply(_ecore_xcb_conn, ecookie, NULL); + + if (ereply) + { + if (ereply->status) status = EINA_FALSE; + free(ereply); + } + else + status = EINA_FALSE; + + return status; +#else + return EINA_FALSE; +#endif +} + +#ifdef ECORE_XCB_XGESTURE +EAPI Eina_Bool +ecore_x_gesture_event_ungrab(Ecore_X_Window win, + Ecore_X_Gesture_Event_Type type, + int num_fingers) +#else +EAPI Eina_Bool +ecore_x_gesture_event_ungrab(Ecore_X_Window win EINA_UNUSED, + Ecore_X_Gesture_Event_Type type EINA_UNUSED, + int num_fingers EINA_UNUSED) +#endif +{ +#ifdef ECORE_XCB_XGESTURE + Eina_Bool status = EINA_TRUE; + xcb_gesture_ungrab_event_cookie_t ecookie; + xcb_gesture_ungrab_event_reply_t *ereply; + + if (!_gesture_available) return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN + + ecookie = + xcb_gesture_ungrab_event(_ecore_xcb_conn, win, type, num_fingers, 0L); + ereply = xcb_gesture_ungrab_event_reply(_ecore_xcb_conn, ecookie, NULL); + + if (ereply) + { + if (ereply->status) status = EINA_FALSE; + free(ereply); + } + else + status = EINA_FALSE; + + return status; +#else + return EINA_FALSE; +#endif +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_icccm.c b/src/lib/ecore_x/xcb/ecore_xcb_icccm.c new file mode 100644 index 0000000000..8dea8617d1 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_icccm.c @@ -0,0 +1,1569 @@ +#include "ecore_xcb_private.h" +#include + +EAPI void +ecore_x_icccm_init(void) +{ +} + +/** + * 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) +{ + void *buf; + char *b; + int nbytes, i; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + for (i = 0, nbytes = 0; i < argc; i++) + if (argv[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, win, + ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8, + nbytes, buf); + free(buf); +} + +/** + * 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) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + int len = 0; + char **v, *data, *cp, *start; + int c = 0, i = 0, j = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (argc) *argc = 0; + if (argv) *argv = NULL; + + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, + ECORE_X_ATOM_WM_COMMAND, + XCB_GET_PROPERTY_TYPE_ANY, + 0, 1000000L); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + + if ((reply->type != ECORE_X_ATOM_STRING) || (reply->format != 8)) + { + free(reply); + return; + } + + len = reply->value_len; + if (len < 1) + { + free(reply); + return; + } + + data = (char *)xcb_get_property_value(reply); + if (len && (data[len - 1] == '\0')) + len--; + + c = 1; + for (cp = (char *)data, i = len; i > 0; cp++, i--) + if (*cp == '\0') c++; + + v = (char **)malloc((c + 1) * sizeof(char *)); + if (!v) + { + free(reply); + return; + } + + start = (char *)malloc((len + 1) * sizeof(char)); + if (!start) + { + free(reply); + free(v); + return; + } + + memcpy(start, (char *)data, len); + start[len] = '\0'; + for (cp = start, i = len + 1, j = 0; i > 0; cp++, i--) + { + if (*cp == '\0') + { + v[j] = start; + start = (cp + 1); + j++; + } + } + + if (c < 1) + { + free(reply); + free(v); + return; + } + + if (argc) *argc = c; + + if (argv) + { + (*argv) = malloc(c * sizeof(char *)); + if (!*argv) + { + free(reply); + 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(reply); + free(v); +} + +EAPI char * +ecore_x_icccm_title_get(Ecore_X_Window win) +{ + xcb_get_property_cookie_t cookie; +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_t prop; +#else + xcb_icccm_get_text_property_reply_t prop; +#endif + uint8_t ret = 0; + char *title = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return NULL; +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_name_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); +#else + cookie = xcb_icccm_get_wm_name_unchecked(_ecore_xcb_conn, win); + ret = xcb_icccm_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); +#endif + if (ret == 0) return NULL; + if (prop.name_len < 1) + { +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_wipe(&prop); +#else + xcb_icccm_get_text_property_reply_wipe(&prop); +#endif + return NULL; + } + + if (!(title = malloc((prop.name_len + 1) * sizeof(char *)))) + { +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_wipe(&prop); +#else + xcb_icccm_get_text_property_reply_wipe(&prop); +#endif + return NULL; + } + memcpy(title, prop.name, sizeof(char *) * prop.name_len); + title[prop.name_len] = '\0'; + + if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) + { + Ecore_Xcb_Textproperty tp; + int count = 0; + char **list = NULL; + Eina_Bool ret = EINA_FALSE; + + tp.value = strdup(title); + tp.nitems = prop.name_len; + tp.encoding = prop.encoding; +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); +#else + ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); +#endif + if (ret) + { + if (count > 0) + title = strdup(list[0]); + + if (list) free(list); + } + } + +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_wipe(&prop); +#else + xcb_icccm_get_text_property_reply_wipe(&prop); +#endif + return title; +} + +EAPI void +ecore_x_icccm_title_set(Ecore_X_Window win, + const char *title) +{ + Ecore_Xcb_Textproperty prop; + char *list[1]; + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!title) return; + + prop.value = NULL; + list[0] = strdup(title); + +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle, + &prop); +#else + ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle, + &prop); +#endif + + if (ret) + { +#ifdef OLD_XCB_VERSION + xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + strlen(prop.value), prop.value); +#else + xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8, + strlen(prop.value), prop.value); +#endif + if (prop.value) free(prop.value); + } + else +#ifdef OLD_XCB_VERSION + xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + strlen(title), title); +#else + xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8, + strlen(title), title); +#endif + free(list[0]); +} + +/** + * 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 **name, + char **class) +{ + xcb_get_property_cookie_t cookie; +#ifdef OLD_XCB_VERSION + xcb_get_wm_class_reply_t prop; +#else + xcb_icccm_get_wm_class_reply_t prop; +#endif + uint8_t ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (name) *name = NULL; + if (class) *class = NULL; + +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_class_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL); +#else + cookie = xcb_icccm_get_wm_class_unchecked(_ecore_xcb_conn, win); + ret = xcb_icccm_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL); +#endif + if (ret == 0) return; + + if (name) *name = strdup(prop.instance_name); + if (class) *class = strdup(prop.class_name); + +#ifdef OLD_XCB_VERSION + xcb_get_wm_class_reply_wipe(&prop); +#else + xcb_icccm_get_wm_class_reply_wipe(&prop); +#endif +} + +/** + * 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 *name, + const char *class) +{ + char *class_string, *s; + int length_name, length_class; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + 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, win, + ECORE_X_ATOM_WM_CLASS, ECORE_X_ATOM_STRING, 8, + length_name + length_class + 2, (void *)class_string); + free(class_string); +} + +/** + * 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 forwindow) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32, + 1, (void *)&forwindow); +} + +/** + * Remove the transient_for setting from a window. + * @param win The window + */ +EAPI void +ecore_x_icccm_transient_for_unset(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_property_del(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) +{ + Ecore_X_Window forwin = 0; + xcb_get_property_cookie_t cookie; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_transient_for_unchecked(_ecore_xcb_conn, win); + xcb_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL); +#else + cookie = xcb_icccm_get_wm_transient_for_unchecked(_ecore_xcb_conn, win); + xcb_icccm_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL); +#endif + + return forwin; +} + +/** + * 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 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, role); +} + +/** + * 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 leader; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER, + &leader, 1) > 0) + return leader; + + return 0; +} + +/** + * 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 leader) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER, + &leader, 1); +} + +EAPI Ecore_X_Window_State_Hint +ecore_x_icccm_state_get(Ecore_X_Window win) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE; + uint8_t *prop; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = + xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, + ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE, + 0L, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return hint; + if ((reply->type == 0) || (reply->format != 8) || (reply->value_len != 2)) + { + free(reply); + return hint; + } + + prop = (uint8_t *)xcb_get_property_value(reply); +#ifdef OLD_XCB_VERSION + 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: + break; + } +#else + switch (prop[0]) + { + case XCB_ICCCM_WM_STATE_WITHDRAWN: + hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + break; + + case XCB_ICCCM_WM_STATE_NORMAL: + hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; + break; + + case XCB_ICCCM_WM_STATE_ICONIC: + hint = ECORE_X_WINDOW_STATE_HINT_ICONIC; + break; + + default: + break; + } +#endif + + free(reply); + return hint; +} + +EAPI void +ecore_x_icccm_state_set(Ecore_X_Window win, + Ecore_X_Window_State_Hint state) +{ +#ifdef OLD_XCB_VERSION + xcb_wm_hints_t hints; +#else + xcb_icccm_wm_hints_t hints; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef OLD_XCB_VERSION + xcb_wm_hints_set_none(&hints); + + hints.flags = XCB_WM_HINT_STATE; + + if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + xcb_wm_hints_set_withdrawn(&hints); + else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) + xcb_wm_hints_set_normal(&hints); + else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) + xcb_wm_hints_set_iconic(&hints); + + xcb_set_wm_hints(_ecore_xcb_conn, win, &hints); +#else + xcb_icccm_wm_hints_set_none(&hints); + + hints.flags = XCB_ICCCM_WM_HINT_STATE; + + if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + xcb_icccm_wm_hints_set_withdrawn(&hints); + else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) + xcb_icccm_wm_hints_set_normal(&hints); + else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) + xcb_icccm_wm_hints_set_iconic(&hints); + + xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints); +#endif +} + +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_hints_set(Ecore_X_Window win, + Eina_Bool 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, + Eina_Bool is_urgent) +{ +#ifdef OLD_XCB_VERSION + xcb_wm_hints_t hints; +#else + xcb_icccm_wm_hints_t hints; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef OLD_XCB_VERSION + xcb_wm_hints_set_none(&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, win, &hints); +#else + xcb_icccm_wm_hints_set_none(&hints); + xcb_icccm_wm_hints_set_input(&hints, accepts_focus); + + if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + xcb_icccm_wm_hints_set_withdrawn(&hints); + else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL) + xcb_icccm_wm_hints_set_normal(&hints); + else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC) + xcb_icccm_wm_hints_set_iconic(&hints); + + if (icon_pixmap != 0) + xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap); + if (icon_mask != 0) + xcb_icccm_wm_hints_set_icon_mask(&hints, icon_mask); + if (icon_window != 0) + xcb_icccm_wm_hints_set_icon_window(&hints, icon_window); + if (window_group != 0) + xcb_icccm_wm_hints_set_window_group(&hints, window_group); + if (is_urgent) + xcb_icccm_wm_hints_set_urgency(&hints); + + xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints); +#endif +} + +EAPI Eina_Bool +ecore_x_icccm_hints_get(Ecore_X_Window win, + Eina_Bool *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, + Eina_Bool *is_urgent) +{ + xcb_get_property_cookie_t cookie; +#ifdef OLD_XCB_VERSION + xcb_wm_hints_t hints; +#else + xcb_icccm_wm_hints_t hints; +#endif + uint8_t ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (accepts_focus) *accepts_focus = EINA_TRUE; + 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 = EINA_FALSE; + +#ifdef OLD_XCB_VERSION + xcb_wm_hints_set_none(&hints); + cookie = xcb_get_wm_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); +#else + xcb_icccm_wm_hints_set_none(&hints); + cookie = xcb_icccm_get_wm_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_icccm_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); +#endif + if (!ret) return EINA_FALSE; + +#ifdef OLD_XCB_VERSION + if ((hints.flags & XCB_WM_HINT_INPUT) && (accepts_focus)) +#else + if ((hints.flags & XCB_ICCCM_WM_HINT_INPUT) && (accepts_focus)) +#endif + { + if (hints.input) + *accepts_focus = EINA_TRUE; + else + *accepts_focus = EINA_FALSE; + } + +#ifdef OLD_XCB_VERSION + if ((hints.flags & XCB_WM_HINT_STATE) && (initial_state)) + { + if (hints.initial_state == XCB_WM_STATE_WITHDRAWN) + *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + else if (hints.initial_state == XCB_WM_STATE_NORMAL) + *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; + else if (hints.initial_state == XCB_WM_STATE_ICONIC) + *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; + } + + if ((hints.flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap)) + *icon_pixmap = hints.icon_pixmap; + + if ((hints.flags & XCB_WM_HINT_ICON_MASK) && (icon_mask)) + *icon_mask = hints.icon_mask; + + if ((hints.flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window)) + *icon_window = hints.icon_window; + + if ((hints.flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group)) + *window_group = hints.window_group; + + if ((hints.flags & XCB_WM_HINT_X_URGENCY) && (is_urgent)) + *is_urgent = EINA_TRUE; +#else + if ((hints.flags & XCB_ICCCM_WM_HINT_STATE) && (initial_state)) + { + if (hints.initial_state == XCB_ICCCM_WM_STATE_WITHDRAWN) + *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + else if (hints.initial_state == XCB_ICCCM_WM_STATE_NORMAL) + *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; + else if (hints.initial_state == XCB_ICCCM_WM_STATE_ICONIC) + *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; + } + + if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_PIXMAP) && (icon_pixmap)) + *icon_pixmap = hints.icon_pixmap; + + if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_MASK) && (icon_mask)) + *icon_mask = hints.icon_mask; + + if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_WINDOW) && (icon_window)) + *icon_window = hints.icon_window; + + if ((hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) && (window_group)) + *window_group = hints.window_group; + + if ((hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) && (is_urgent)) + *is_urgent = EINA_TRUE; +#endif + + return EINA_TRUE; +} + +/** + * 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) +{ + xcb_get_property_cookie_t cookie; +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_t prop; +#else + xcb_icccm_get_text_property_reply_t prop; +#endif + uint8_t ret = 0; + char *tmp = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return NULL; + +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_icon_name_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); +#else + cookie = xcb_icccm_get_wm_icon_name_unchecked(_ecore_xcb_conn, win); + ret = xcb_icccm_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL); +#endif + if (ret == 0) return NULL; + + if (prop.name_len < 1) + { +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_wipe(&prop); +#else + xcb_icccm_get_text_property_reply_wipe(&prop); +#endif + return NULL; + } + + if (!(tmp = malloc((prop.name_len + 1) * sizeof(char *)))) + { +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_wipe(&prop); +#else + xcb_icccm_get_text_property_reply_wipe(&prop); +#endif + return NULL; + } + memcpy(tmp, prop.name, sizeof(char *) * prop.name_len); + tmp[prop.name_len] = '\0'; + + if (prop.encoding != ECORE_X_ATOM_UTF8_STRING) + { + Ecore_Xcb_Textproperty tp; + int count = 0; + char **list = NULL; + Eina_Bool ret = EINA_FALSE; + + tp.value = strdup(tmp); + tp.nitems = prop.name_len; + tp.encoding = prop.encoding; +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count); +#else + ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count); +#endif + if (ret) + { + if (count > 0) + tmp = strdup(list[0]); + + if (list) free(list); + } + } + +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_wipe(&prop); +#else + xcb_icccm_get_text_property_reply_wipe(&prop); +#endif + return tmp; +} + +/** + * 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 *name) +{ + Ecore_Xcb_Textproperty prop; + char *list[1]; + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!win) || (!name)) return; + + prop.value = NULL; + list[0] = strdup(name); + +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle, + &prop); +#else + ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle, + &prop); +#endif + + if (ret) + { +#ifdef OLD_XCB_VERSION + xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + strlen(prop.value), prop.value); +#else + xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + 8, strlen(prop.value), prop.value); +#endif + if (prop.value) free(prop.value); + } + else +#ifdef OLD_XCB_VERSION + xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + strlen(name), name); +#else + xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, + 8, strlen(name), name); +#endif + + free(list[0]); +} + +EAPI void +ecore_x_icccm_iconic_request_send(Ecore_X_Window win, + Ecore_X_Window root) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_WM_CHANGE_STATE; +#ifdef OLD_XCB_VERSION + ev.data.data32[0] = XCB_WM_STATE_ICONIC; +#else + ev.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC; +#endif + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT), + (const char *)&ev); +// ecore_x_flush(); +} + +/** + * 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, + Eina_Bool on) +{ + Ecore_X_Atom proto; + xcb_get_property_cookie_t cookie; +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_t protos; +#else + xcb_icccm_get_wm_protocols_reply_t protos; +#endif + int i = 0, count = 0, set = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return; + proto = _ecore_xcb_atoms_wm_protocol[protocol]; +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); + if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL)) +#else + cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); + if (!xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL)) +#endif + count = 0; + else + count = protos.atoms_len; + + for (i = 0; i < count; i++) + { + if (protos.atoms[i] == proto) + { + set = 1; + break; + } + } + + if (on) + { + if (!set) + { + Ecore_X_Atom *atoms = NULL; + + atoms = malloc((count + 1) * sizeof(Ecore_X_Atom)); + if (atoms) + { + for (i = 0; i < count; i++) + atoms[i] = protos.atoms[i]; + atoms[count] = proto; +#ifdef OLD_XCB_VERSION + xcb_set_wm_protocols(_ecore_xcb_conn, + ECORE_X_ATOM_WM_PROTOCOLS, + win, count, atoms); +#else + xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS, + count, atoms); +#endif + free(atoms); + } + } + } + else + { + if (set) + { + for (i = 0; i < count; i++) + { + if (protos.atoms[i] == proto) + { + int j = 0; + + for (j = (i + 1); j < count; j++) + protos.atoms[j - 1] = protos.atoms[j]; + if (count > 1) +#ifdef OLD_XCB_VERSION + xcb_set_wm_protocols(_ecore_xcb_conn, + ECORE_X_ATOM_WM_PROTOCOLS, + win, count - 1, protos.atoms); +#else + xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS, + count - 1, protos.atoms); +#endif + else + ecore_x_window_prop_property_del(win, + ECORE_X_ATOM_WM_PROTOCOLS); + break; + } + } + } + } + +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_wipe(&protos); +#else + xcb_icccm_get_wm_protocols_reply_wipe(&protos); +#endif +} + +/** + * 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 Eina_Bool +ecore_x_icccm_protocol_isset(Ecore_X_Window win, + Ecore_X_WM_Protocol protocol) +{ + Ecore_X_Atom proto; + Eina_Bool ret = EINA_FALSE; + xcb_get_property_cookie_t cookie; +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_t reply; +#else + xcb_icccm_get_wm_protocols_reply_t reply; +#endif + uint8_t val = 0; + unsigned int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE; + + proto = _ecore_xcb_atoms_wm_protocol[protocol]; +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); + val = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL); +#else + cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto); + val = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL); +#endif + if (!val) return EINA_FALSE; + + for (i = 0; i < reply.atoms_len; i++) + if (reply.atoms[i] == proto) + { + ret = EINA_TRUE; + break; + } + +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_wipe(&reply); +#else + xcb_icccm_get_wm_protocols_reply_wipe(&reply); +#endif + + return ret; +} + +/** + * 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__); + CHECK_XCB_CONN; + + if (num > 0) +#ifdef OLD_XCB_VERSION + xcb_set_wm_protocols(_ecore_xcb_conn, ECORE_X_ATOM_WM_PROTOCOLS, + win, num, protos); +#else + xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS, num, protos); +#endif + else + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_PROTOCOLS); +} + +EAPI Eina_Bool +ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, + Eina_Bool *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 hints; + xcb_get_property_cookie_t cookie; + uint8_t ret = 0; + int32_t minw = 0, minh = 0; + int32_t maxw = 32767, maxh = 32767; + int32_t basew = -1, baseh = -1; + int32_t stepx = -1, stepy = -1; + double mina = 0.0, maxa = 0.0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (request_pos) *request_pos = EINA_FALSE; + 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; + +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); +#else + cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, + &hints, NULL); +#endif + if (!ret) return EINA_FALSE; + +#ifdef OLD_XCB_VERSION + if ((hints.flags & XCB_SIZE_HINT_US_POSITION) || + (hints.flags & XCB_SIZE_HINT_P_POSITION)) +#else + if ((hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION) || + (hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION)) +#endif + { + if (request_pos) *request_pos = EINA_TRUE; + } + +#ifdef OLD_XCB_VERSION + if (hints.flags & XCB_SIZE_HINT_P_WIN_GRAVITY) +#else + if (hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY) +#endif + { + if (gravity) *gravity = hints.win_gravity; + } + +#ifdef OLD_XCB_VERSION + if (hints.flags & XCB_SIZE_HINT_P_MIN_SIZE) +#else + if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE) +#endif + { + minw = hints.min_width; + minh = hints.min_height; + } + +#ifdef OLD_XCB_VERSION + if (hints.flags & XCB_SIZE_HINT_P_MAX_SIZE) +#else + if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE) +#endif + { + maxw = hints.max_width; + maxh = hints.max_height; + if (maxw < minw) maxw = minw; + if (maxh < minh) maxh = minh; + } + +#ifdef OLD_XCB_VERSION + if (hints.flags & XCB_SIZE_HINT_BASE_SIZE) +#else + if (hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE) +#endif + { + basew = hints.base_width; + baseh = hints.base_height; + if (basew > minw) minw = basew; + if (baseh > minh) minh = baseh; + } + +#ifdef OLD_XCB_VERSION + if (hints.flags & XCB_SIZE_HINT_P_RESIZE_INC) +#else + if (hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC) +#endif + { + stepx = hints.width_inc; + stepy = hints.height_inc; + if (stepx < 1) stepx = 1; + if (stepy < 1) stepy = 1; + } + +#ifdef OLD_XCB_VERSION + if (hints.flags & XCB_SIZE_HINT_P_ASPECT) +#else + if (hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT) +#endif + { + if (hints.min_aspect_den > 0) + mina = ((double)hints.min_aspect_num) / ((double)hints.min_aspect_den); + + if (hints.max_aspect_den > 0) + maxa = ((double)hints.max_aspect_num) / ((double)hints.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 EINA_TRUE; +} + +EAPI void +ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, + Eina_Bool 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_get_property_cookie_t cookie; + xcb_size_hints_t hints; + uint8_t ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL); +#else + cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win); + ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, + &hints, NULL); +#endif + if (!ret) memset(&hints, 0, sizeof(xcb_size_hints_t)); + + hints.flags = 0; + +#ifdef OLD_XCB_VERSION + if (request_pos) + hints.flags |= XCB_SIZE_HINT_US_POSITION; + + if (gravity != ECORE_X_GRAVITY_NW) + xcb_size_hints_set_win_gravity(&hints, gravity); + if ((min_w > 0) || (min_h > 0)) + xcb_size_hints_set_min_size(&hints, min_w, min_h); + if ((max_w > 0) || (max_h > 0)) + xcb_size_hints_set_max_size(&hints, max_w, max_h); + if ((base_w > 0) || (base_h > 0)) + xcb_size_hints_set_base_size(&hints, base_w, base_h); + if ((step_x > 1) || (step_y > 1)) + xcb_size_hints_set_resize_inc(&hints, step_x, step_y); + if ((min_aspect > 0.0) || (max_aspect > 0.0)) + xcb_size_hints_set_aspect(&hints, + (int32_t)(min_aspect * 10000), 10000, + (int32_t)(max_aspect * 10000), 10000); + + xcb_set_wm_normal_hints(_ecore_xcb_conn, win, &hints); +#else + if (request_pos) + hints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION; + + if (gravity != ECORE_X_GRAVITY_NW) + xcb_icccm_size_hints_set_win_gravity(&hints, gravity); + if ((min_w > 0) || (min_h > 0)) + xcb_icccm_size_hints_set_min_size(&hints, min_w, min_h); + if ((max_w > 0) || (max_h > 0)) + xcb_icccm_size_hints_set_max_size(&hints, max_w, max_h); + if ((base_w > 0) || (base_h > 0)) + xcb_icccm_size_hints_set_base_size(&hints, base_w, base_h); + if ((step_x > 1) || (step_y > 1)) + xcb_icccm_size_hints_set_resize_inc(&hints, step_x, step_y); + if ((min_aspect > 0.0) || (max_aspect > 0.0)) + xcb_icccm_size_hints_set_aspect(&hints, + (int32_t)(min_aspect * 10000), 10000, + (int32_t)(max_aspect * 10000), 10000); + + xcb_icccm_set_wm_normal_hints(_ecore_xcb_conn, win, &hints); +#endif +} + +EAPI void +ecore_x_icccm_move_resize_send(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ + xcb_configure_notify_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + + memset(&ev, 0, sizeof(xcb_configure_notify_event_t)); + + ev.response_type = XCB_CONFIGURE_NOTIFY; + ev.event = win; + ev.window = win; + ev.above_sibling = XCB_NONE; + ev.x = x; + ev.y = y; + ev.width = w; + ev.height = h; + ev.border_width = 0; + ev.override_redirect = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev); +// ecore_x_flush(); +} + +/** + * 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) +{ + xcb_get_property_cookie_t cookie; +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_t prop; +#else + xcb_icccm_get_text_property_reply_t prop; +#endif + uint8_t ret = 0; + char *tmp = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_client_machine_unchecked(_ecore_xcb_conn, win); + ret = xcb_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, &prop, NULL); +#else + cookie = xcb_icccm_get_wm_client_machine_unchecked(_ecore_xcb_conn, win); + ret = xcb_icccm_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, + &prop, NULL); +#endif + if (ret == 0) return NULL; + + tmp = malloc((prop.name_len + 1) * sizeof(char *)); + if (!tmp) + { +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_wipe(&prop); +#else + xcb_icccm_get_text_property_reply_wipe(&prop); +#endif + return NULL; + } + memcpy(tmp, prop.name, sizeof(char *) * prop.name_len); + tmp[prop.name_len] = '\0'; + +#ifdef OLD_XCB_VERSION + xcb_get_text_property_reply_wipe(&prop); +#else + xcb_icccm_get_text_property_reply_wipe(&prop); +#endif + + return tmp; +} + +EAPI void +ecore_x_icccm_take_focus_send(Ecore_X_Window win, + Ecore_X_Time t) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + XCB_EVENT_MASK_NO_EVENT, + 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, + XCB_EVENT_MASK_NO_EVENT, + ECORE_X_ATOM_WM_SAVE_YOURSELF, t, 0, 0, 0); +} + +/** + * 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 = 0; + unsigned char *odata = NULL, *data = NULL; + Ecore_X_Window *newset = NULL, *oldset = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + ECORE_X_ATOM_WINDOW, 32, &odata, &num)) + { + if (!(newset = calloc(1, sizeof(Ecore_X_Window)))) return; + newset[0] = subwin; + num = 1; + data = (unsigned char *)newset; + } + else + { + if (!(newset = calloc(num + 1, sizeof(Ecore_X_Window)))) return; + oldset = (Ecore_X_Window *)odata; + for (i = 0; i < num; i++) + { + if (oldset[i] == subwin) + { + if (odata) free(odata); + odata = NULL; + free(newset); + return; + } + newset[i] = oldset[i]; + } + newset[num++] = subwin; + if (odata) free(odata); + data = (unsigned char *)newset; + } + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + ECORE_X_ATOM_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 = 0, j = 0, k = 0; + unsigned char *odata = NULL, *data = NULL; + Ecore_X_Window *newset = NULL, *oldset = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + ECORE_X_ATOM_WINDOW, 32, &odata, &num)) + return; + + oldset = (Ecore_X_Window *)odata; + for (i = 0; i < num; i++) + { + if (oldset[i] == subwin) + { + if (num == 1) + { + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS); + if (odata) free(odata); + odata = NULL; + return; + } + else + { + newset = calloc(num - 1, sizeof(Ecore_X_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, + ECORE_X_ATOM_WINDOW, 32, data, k); + if (odata) free(odata); + odata = NULL; + free(newset); + return; + } + } + } + if (odata) free(odata); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_image.c b/src/lib/ecore_x/xcb/ecore_xcb_image.c new file mode 100644 index 0000000000..8e221101b0 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_image.c @@ -0,0 +1,738 @@ +#include "ecore_xcb_private.h" +#include +#include +#include +#include + +struct _Ecore_X_Image +{ + xcb_shm_segment_info_t shminfo; + xcb_image_t *xim; + Ecore_X_Visual vis; + int depth, w, h; + int bpl, bpp, rows; + unsigned char *data; + Eina_Bool shm : 1; +}; + +/* local function prototypes */ +static void _ecore_xcb_image_shm_check(void); +static void _ecore_xcb_image_shm_create(Ecore_X_Image *im); +static xcb_format_t *_ecore_xcb_image_find_format(const xcb_setup_t *setup, + uint8_t depth); + +/* local variables */ +static int _ecore_xcb_image_shm_can = -1; + +EAPI Ecore_X_Image * +ecore_x_image_new(int w, + int h, + Ecore_X_Visual vis, + int depth) +{ + Ecore_X_Image *im; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(im = calloc(1, sizeof(Ecore_X_Image)))) return NULL; + im->w = w; + im->h = h; + im->vis = vis; + im->depth = depth; + _ecore_xcb_image_shm_check(); + im->shm = _ecore_xcb_image_shm_can; + return im; +} + +EAPI void +ecore_x_image_free(Ecore_X_Image *im) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!im) return; + if (im->shm) + { + if (im->xim) + { + xcb_shm_detach(_ecore_xcb_conn, im->shminfo.shmseg); + xcb_image_destroy(im->xim); + shmdt(im->shminfo.shmaddr); + shmctl(im->shminfo.shmid, IPC_RMID, 0); + } + } + else if (im->xim) + { + if (im->xim->data) free(im->xim->data); + im->xim->data = NULL; + xcb_image_destroy(im->xim); + } + + free(im); +// ecore_x_flush(); +} + +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) +{ + Eina_Bool ret = EINA_TRUE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (im->shm) + { + if (!im->xim) _ecore_xcb_image_shm_create(im); + if (!im->xim) return EINA_FALSE; + + if ((sx == 0) && (w == im->w)) + { + im->xim->data = (uint8_t *)im->data + (im->xim->stride * sy) + + (sx * im->bpp); + im->xim->width = w; + im->xim->height = h; + + ecore_x_grab(); + if (!xcb_image_shm_get(_ecore_xcb_conn, draw, im->xim, + im->shminfo, x, y, 0xffffffff)) + { + DBG("\tImage Shm Get Failed"); + ret = EINA_FALSE; + } + ecore_x_ungrab(); + ecore_x_sync(); // needed + } + else + { + Ecore_X_Image *tim; + + 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) + { + unsigned char *spixels, *pixels; + int sbpp = 0, sbpl = 0, srows = 0; + int bpp = 0, bpl = 0, rows = 0; + + spixels = + ecore_x_image_data_get(tim, &sbpl, &srows, &sbpp); + pixels = ecore_x_image_data_get(im, &bpl, &rows, &bpp); + if ((spixels) && (pixels)) + { + unsigned char *p, *sp; + int r = 0; + + 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); + } + } + } + else + { + ret = EINA_FALSE; + ecore_x_grab(); + im->xim = + xcb_image_get(_ecore_xcb_conn, draw, x, y, w, h, + 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP); + if (!im->xim) ret = EINA_FALSE; + ecore_x_ungrab(); + ecore_x_sync(); // needed + + if (im->xim) + { + im->data = (unsigned char *)im->xim->data; + im->bpl = im->xim->stride; + im->rows = im->xim->height; + if (im->xim->bpp <= 8) + im->bpp = 1; + else if (im->xim->bpp <= 16) + im->bpp = 2; + else + im->bpp = 4; + } + } + + return ret; +} + +EAPI void * +ecore_x_image_data_get(Ecore_X_Image *im, + int *bpl, + int *rows, + int *bpp) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!im) return NULL; + if (!im->xim) _ecore_xcb_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; +} + +EAPI void +ecore_x_image_put(Ecore_X_Image *im, + Ecore_X_Drawable draw, + Ecore_X_GC gc, + int x, + int y, + int sx, + int sy, + int w, + int h) +{ + Ecore_X_GC tgc = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!gc) + { + uint32_t mask, values[1]; + + tgc = xcb_generate_id(_ecore_xcb_conn); + mask = XCB_GC_SUBWINDOW_MODE; + values[0] = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS; + xcb_create_gc(_ecore_xcb_conn, tgc, draw, mask, values); + gc = tgc; + } + if (!im->xim) _ecore_xcb_image_shm_create(im); + if (im->xim) + { + if (im->shm) + xcb_shm_put_image(_ecore_xcb_conn, draw, gc, im->xim->width, + im->xim->height, sx, sy, w, h, x, y, + im->xim->depth, im->xim->format, 0, + im->shminfo.shmseg, + im->xim->data - im->shminfo.shmaddr); +// xcb_image_shm_put(_ecore_xcb_conn, draw, gc, im->xim, +// im->shminfo, sx, sy, x, y, w, h, 0); + else + xcb_image_put(_ecore_xcb_conn, draw, gc, im->xim, sx, sy, 0); + } + if (tgc) ecore_x_gc_free(tgc); + ecore_x_sync(); +} + +EAPI Eina_Bool +ecore_x_image_is_argb32_get(Ecore_X_Image *im) +{ + xcb_visualtype_t *vis; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + vis = (xcb_visualtype_t *)im->vis; + if (!im->xim) _ecore_xcb_image_shm_create(im); + + if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && + (im->depth >= 24) && (vis->red_mask == 0xff0000) && + (vis->green_mask == 0x00ff00) && (vis->blue_mask == 0x0000ff)) + { +#ifdef WORDS_BIGENDIAN + if (im->xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST) return EINA_TRUE; +#else + if (im->xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST) return EINA_TRUE; +#endif + } + + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_image_to_argb_convert(void *src, + int sbpp, + int sbpl, + Ecore_X_Colormap c, + Ecore_X_Visual v, + int x, + int y, + int w, + int h, + unsigned int *dst, + int dbpl, + int dx, + int dy) +{ + xcb_visualtype_t *vis; + uint32_t *cols; + int n = 0, nret = 0, i, row, mode = 0; + unsigned int pal[256], r, g, b; + enum + { + rgbnone = 0, + rgb565, + bgr565, + rgbx555, + argbx888, + abgrx888, + rgba888x, + bgra888x, + argbx666 + }; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + sbpp *= 8; + + vis = (xcb_visualtype_t *)v; + n = vis->colormap_entries; + if ((n <= 256) && + ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || + (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY))) + { + xcb_query_colors_cookie_t cookie; + xcb_query_colors_reply_t *reply; + + if (!c) + { + c = (xcb_colormap_t)((xcb_screen_t *) + _ecore_xcb_screen)->default_colormap; + } + + cols = alloca(n * sizeof(uint32_t)); + for (i = 0; i < n; i++) + cols[i] = i; + + cookie = xcb_query_colors_unchecked(_ecore_xcb_conn, c, n, cols); + reply = xcb_query_colors_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_rgb_iterator_t iter; + xcb_rgb_t *ret; + + iter = xcb_query_colors_colors_iterator(reply); + ret = xcb_query_colors_colors(reply); + if (ret) + { + for (i = 0; iter.rem; xcb_rgb_next(&iter), i++) + { + pal[i] = 0xff000000 | + ((iter.data->red >> 8) << 16) | + ((iter.data->green >> 8) << 8) | + ((iter.data->blue >> 8)); + } + nret = n; + } + free(reply); + } + } + else if ((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || + (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) + { + if ((vis->red_mask == 0x00ff0000) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x000000ff)) + mode = argbx888; + else if ((vis->red_mask == 0x000000ff) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x00ff0000)) + mode = abgrx888; + else if ((vis->red_mask == 0xff000000) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0x0000ff00)) + mode = rgba888x; + else if ((vis->red_mask == 0x0000ff00) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0xff000000)) + mode = bgra888x; + else if ((vis->red_mask == 0x0003f000) && + (vis->green_mask == 0x00000fc0) && + (vis->blue_mask == 0x0000003f)) + mode = argbx666; + else if ((vis->red_mask == 0x0000f800) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgb565; + else if ((vis->red_mask == 0x0000001f) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000f800)) + mode = bgr565; + else if ((vis->red_mask == 0x00007c00) && + (vis->green_mask == 0x000003e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgbx555; + else + return EINA_FALSE; + } + for (row = 0; row < h; row++) + { + unsigned char *s8; + unsigned short *s16; + unsigned int *s32, *dp, *de; + + dp = ((unsigned int *)(((unsigned char *)dst) + + ((dy + row) * dbpl))) + dx; + de = dp + w; + switch (sbpp) + { + case 8: + s8 = ((unsigned char *)(((unsigned char *)src) + + ((y + row) * sbpl))) + x; + if (nret > 0) + { + while (dp < de) + { + *dp = pal[*s8]; + s8++; dp++; + } + } + else + return EINA_FALSE; + break; + + case 16: + s16 = ((unsigned short *)(((unsigned char *)src) + + ((y + row) * sbpl))) + x; + switch (mode) + { + case rgb565: + while (dp < de) + { + r = (*s16 & 0xf800) << 8; + g = (*s16 & 0x07e0) << 5; + b = (*s16 & 0x001f) << 3; + r |= (r >> 5) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + + case bgr565: + while (dp < de) + { + r = (*s16 & 0x001f) << 19; + g = (*s16 & 0x07e0) << 5; + b = (*s16 & 0xf800) >> 8; + r |= (r >> 5) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + + case rgbx555: + while (dp < de) + { + r = (*s16 & 0x7c00) << 9; + g = (*s16 & 0x03e0) << 6; + b = (*s16 & 0x001f) << 3; + r |= (r >> 5) & 0xff0000; + g |= (g >> 5) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + + default: + return EINA_FALSE; + break; + } + break; + + case 24: + case 32: + s32 = ((unsigned int *)(((unsigned char *)src) + + ((y + row) * sbpl))) + x; + switch (mode) + { + case argbx888: + while (dp < de) + { + *dp = 0xff000000 | *s32; + s32++; dp++; + } + break; + + case abgrx888: + while (dp < de) + { + r = *s32 & 0x000000ff; + g = *s32 & 0x0000ff00; + b = *s32 & 0x00ff0000; + *dp = 0xff000000 | (r << 16) | (g) | (b >> 16); + s32++; dp++; + } + break; + + case rgba888x: + while (dp < de) + { + *dp = 0xff000000 | (*s32 >> 8); + s32++; dp++; + } + break; + + case bgra888x: + while (dp < de) + { + r = *s32 & 0x0000ff00; + g = *s32 & 0x00ff0000; + b = *s32 & 0xff000000; + *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24); + s32++; dp++; + } + break; + + case argbx666: + while (dp < de) + { + r = (*s32 & 0x3f000) << 6; + g = (*s32 & 0x00fc0) << 4; + b = (*s32 & 0x0003f) << 2; + r |= (r >> 6) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 6); + *dp = 0xff000000 | r | g | b; + s32++; dp++; + } + break; + + default: + return EINA_FALSE; + break; + } + break; + break; + + default: + return EINA_FALSE; + break; + } + } + return EINA_TRUE; +} + +/* local functions */ +static void +_ecore_xcb_image_shm_check(void) +{ +// xcb_shm_query_version_reply_t *reply; + xcb_shm_segment_info_t shminfo; + xcb_shm_get_image_cookie_t cookie; + xcb_shm_get_image_reply_t *ireply; + xcb_image_t *img = 0; + uint8_t depth = 0; + + if (_ecore_xcb_image_shm_can != -1) return; + CHECK_XCB_CONN; + + /* reply = */ + /* xcb_shm_query_version_reply(_ecore_xcb_conn, */ + /* xcb_shm_query_version(_ecore_xcb_conn), NULL); */ + /* if (!reply) */ + /* { */ + /* _ecore_xcb_image_shm_can = 0; */ + /* return; */ + /* } */ + + /* if ((reply->major_version < 1) || */ + /* ((reply->major_version == 1) && (reply->minor_version == 0))) */ + /* { */ + /* _ecore_xcb_image_shm_can = 0; */ + /* free(reply); */ + /* return; */ + /* } */ + + /* free(reply); */ + + depth = ((xcb_screen_t *)_ecore_xcb_screen)->root_depth; + + ecore_x_sync(); // needed + + img = _ecore_xcb_image_create_native(1, 1, XCB_IMAGE_FORMAT_Z_PIXMAP, + depth, NULL, ~0, NULL); + if (!img) + { + _ecore_xcb_image_shm_can = 0; + return; + } + + shminfo.shmid = + shmget(IPC_PRIVATE, img->stride * img->height, (IPC_CREAT | 0666)); + if (shminfo.shmid == (uint32_t)-1) + { + xcb_image_destroy(img); + _ecore_xcb_image_shm_can = 0; + return; + } + + shminfo.shmaddr = shmat(shminfo.shmid, 0, 0); + img->data = shminfo.shmaddr; + if (img->data == (uint8_t *)-1) + { + xcb_image_destroy(img); + _ecore_xcb_image_shm_can = 0; + return; + } + + shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn); + xcb_shm_attach(_ecore_xcb_conn, shminfo.shmseg, shminfo.shmid, 0); + + cookie = + xcb_shm_get_image(_ecore_xcb_conn, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + 0, 0, img->width, img->height, + 0xffffffff, img->format, + shminfo.shmseg, img->data - shminfo.shmaddr); + + ecore_x_sync(); // needed + + ireply = xcb_shm_get_image_reply(_ecore_xcb_conn, cookie, NULL); + if (ireply) + { + _ecore_xcb_image_shm_can = 1; + free(ireply); + } + else + _ecore_xcb_image_shm_can = 0; + + xcb_shm_detach(_ecore_xcb_conn, shminfo.shmseg); + xcb_image_destroy(img); + shmdt(shminfo.shmaddr); + shmctl(shminfo.shmid, IPC_RMID, 0); +} + +static void +_ecore_xcb_image_shm_create(Ecore_X_Image *im) +{ + CHECK_XCB_CONN; + + im->xim = + _ecore_xcb_image_create_native(im->w, im->h, XCB_IMAGE_FORMAT_Z_PIXMAP, + im->depth, NULL, ~0, NULL); + if (!im->xim) return; + + im->shminfo.shmid = shmget(IPC_PRIVATE, im->xim->size, (IPC_CREAT | 0666)); + if (im->shminfo.shmid == (uint32_t)-1) + { + xcb_image_destroy(im->xim); + return; + } + + im->shminfo.shmaddr = shmat(im->shminfo.shmid, 0, 0); + im->xim->data = im->shminfo.shmaddr; + if ((!im->xim->data) || (im->xim->data == (uint8_t *)-1)) + { + DBG("Shm Create No Image Data"); + xcb_image_destroy(im->xim); + shmdt(im->shminfo.shmaddr); + shmctl(im->shminfo.shmid, IPC_RMID, 0); + return; + } + + im->shminfo.shmseg = xcb_generate_id(_ecore_xcb_conn); + xcb_shm_attach(_ecore_xcb_conn, im->shminfo.shmseg, im->shminfo.shmid, 0); + + im->data = (unsigned char *)im->xim->data; + im->bpl = im->xim->stride; + im->rows = im->xim->height; + if (im->xim->bpp <= 8) + im->bpp = 1; + else if (im->xim->bpp <= 16) + im->bpp = 2; + else + im->bpp = 4; +} + +xcb_image_t * +_ecore_xcb_image_create_native(int w, + int h, + xcb_image_format_t format, + uint8_t depth, + void *base, + uint32_t bytes, + uint8_t *data) +{ + static uint8_t dpth = 0; + static xcb_format_t *fmt = NULL; + const xcb_setup_t *setup; + xcb_image_format_t xif; + + CHECK_XCB_CONN; + + /* NB: We cannot use xcb_image_create_native as it only creates images + * using MSB_FIRST, so this routine recreates that function and uses + * the endian-ness of the server setup */ + setup = xcb_get_setup(_ecore_xcb_conn); + xif = format; + + if ((xif == XCB_IMAGE_FORMAT_Z_PIXMAP) && (depth == 1)) + xif = XCB_IMAGE_FORMAT_XY_PIXMAP; + + if (dpth != depth) + { + dpth = depth; + fmt = _ecore_xcb_image_find_format(setup, depth); + if (!fmt) return 0; + } + + switch (xif) + { + case XCB_IMAGE_FORMAT_XY_BITMAP: + if (depth != 1) return 0; + + case XCB_IMAGE_FORMAT_XY_PIXMAP: + case XCB_IMAGE_FORMAT_Z_PIXMAP: + return xcb_image_create(w, h, xif, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, + setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + base, bytes, data); + + default: + break; + } + + return 0; +} + +static xcb_format_t * +_ecore_xcb_image_find_format(const xcb_setup_t *setup, + uint8_t depth) +{ + xcb_format_t *fmt, *fmtend; + + CHECK_XCB_CONN; + + fmt = xcb_setup_pixmap_formats(setup); + fmtend = fmt + xcb_setup_pixmap_formats_length(setup); + for (; fmt != fmtend; ++fmt) + if (fmt->depth == depth) + return fmt; + + return 0; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_input.c b/src/lib/ecore_x/xcb/ecore_xcb_input.c new file mode 100644 index 0000000000..6cf3ebf6e6 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_input.c @@ -0,0 +1,274 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_XINPUT +# include +# include +#endif + +/* FIXME: this is a guess. can't find defines for touch events in xcb libs + * online */ +/* these are not yet defined in xcb support for xi2 - so manually create */ +#ifndef XCB_INPUT_DEVICE_TOUCH_BEGIN +#define XCB_INPUT_DEVICE_TOUCH_BEGIN 18 +#endif +#ifndef XCB_INPUT_DEVICE_TOUCH_END +#define XCB_INPUT_DEVICE_TOUCH_END 19 +#endif +#ifndef XCB_INPUT_DEVICE_TOUCH_UPDATE +#define XCB_INPUT_DEVICE_TOUCH_UPDATE 21 +#endif + +#ifndef XCB_INPUT_POINTER_EMULATED_MASK +#define XCB_INPUT_POINTER_EMULATED_MASK (1 << 16) +#endif + +/* local variables */ +static Eina_Bool _input_avail = EINA_FALSE; + +/* external variables */ +int _ecore_xcb_event_input = 0; + +void +_ecore_xcb_input_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XINPUT + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_input_id); +#endif +} + +void +_ecore_xcb_input_finalize(void) +{ +#ifdef ECORE_XCB_XINPUT + xcb_input_get_extension_version_cookie_t cookie; + xcb_input_get_extension_version_reply_t *reply; + char buff[128]; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XINPUT + cookie = + xcb_input_get_extension_version_unchecked(_ecore_xcb_conn, 127, buff); + reply = + xcb_input_get_extension_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + _input_avail = EINA_TRUE; + free(reply); + } + + if (_input_avail) + { + const xcb_query_extension_reply_t *ext_reply; + + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_input_id); + if (ext_reply) + _ecore_xcb_event_input = ext_reply->first_event; + } +#endif +} + +void +_ecore_xcb_input_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +} + +void +#ifdef ECORE_XCB_XINPUT +_ecore_xcb_input_handle_event(xcb_generic_event_t *event) +#else +_ecore_xcb_input_handle_event(xcb_generic_event_t * event EINA_UNUSED) +#endif +{ +#ifdef ECORE_XCB_XINPUT + xcb_ge_event_t *ev; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + /* FIXME: look at xlib ecore_x_xi2.c to copy logic in when i can find an + * xcb-input lib to test with */ +#ifdef ECORE_XCB_XINPUT + ev = (xcb_ge_event_t *)event; + switch (ev->event_type) + { + case XCB_INPUT_DEVICE_MOTION_NOTIFY: + { + xcb_input_device_motion_notify_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_motion_notify_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_move(de->time, de->state, de->event_x, + de->event_y, de->root_x, de->root_y, + de->event, child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + + case XCB_INPUT_DEVICE_BUTTON_PRESS: + { + xcb_input_device_button_press_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_button_press_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN, + de->time, de->state, de->detail, + de->event_x, de->event_y, + de->root_x, de->root_y, de->event, + child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + + case XCB_INPUT_DEVICE_BUTTON_RELEASE: + { + xcb_input_device_button_release_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_button_release_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP, + de->time, de->state, de->detail, + de->event_x, de->event_y, + de->root_x, de->root_y, de->event, + child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + + case XCB_INPUT_DEVICE_TOUCH_UPDATE: + { + xcb_input_device_motion_notify_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_motion_notify_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_move(de->time, de->state, de->event_x, + de->event_y, de->root_x, de->root_y, + de->event, child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + + case XCB_INPUT_DEVICE_TOUCH_BEGIN: + { + xcb_input_device_button_press_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_button_press_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN, + de->time, de->state, de->detail, + de->event_x, de->event_y, + de->root_x, de->root_y, de->event, + child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + + case XCB_INPUT_DEVICE_TOUCH_END: + { + xcb_input_device_button_release_event_t *de; + unsigned int child_win = 0; + + de = (xcb_input_device_button_release_event_t *)ev->pad1; + child_win = (de->child ? de->child : de->event); + _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP, + de->time, de->state, de->detail, + de->event_x, de->event_y, + de->root_x, de->root_y, de->event, + child_win, de->root, + de->same_screen, de->device_id, + 1, 1, 1.0, 0.0, + de->event_x, de->event_y, + de->root_x, de->root_y); + } + break; + + default: + break; + } +#endif +} + +EAPI Eina_Bool +ecore_x_input_multi_select(Ecore_X_Window win) +{ + Eina_Bool find = EINA_FALSE; +#ifdef ECORE_XCB_XINPUT + xcb_input_list_input_devices_cookie_t dcookie; + xcb_input_list_input_devices_reply_t *dreply; + xcb_input_device_info_iterator_t diter; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_input_avail) return EINA_FALSE; + + /* FIXME: i can't seemingly test this! no xcb input lib so can't look and + * test and look at types etc. - look at xlib code and copy logic over + * when we can */ +#ifdef ECORE_XCB_XINPUT + dcookie = xcb_input_list_input_devices_unchecked(_ecore_xcb_conn); + dreply = + xcb_input_list_input_devices_reply(_ecore_xcb_conn, dcookie, NULL); + if (!dreply) return EINA_FALSE; + + diter = xcb_input_list_input_devices_devices_iterator(dreply); + while (diter.rem) + { + xcb_input_device_info_t *dev; + const xcb_input_event_class_t iclass[] = + { + XCB_INPUT_DEVICE_BUTTON_PRESS, + XCB_INPUT_DEVICE_BUTTON_RELEASE, + XCB_INPUT_DEVICE_MOTION_NOTIFY, + XCB_INPUT_DEVICE_TOUCH_BEGIN, + XCB_INPUT_DEVICE_TOUCH_END, + XCB_INPUT_DEVICE_TOUCH_UPDATE + }; + + dev = diter.data; + if (dev->device_use == XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_DEVICE) + { + DBG("Device %d", dev->device_id); + DBG("\tType: %d", dev->device_type); + DBG("\tNum Classes: %d", dev->num_class_info); + DBG("\tUse: %d", dev->device_use); + + xcb_input_select_extension_event(_ecore_xcb_conn, win, + sizeof(iclass) / sizeof(xcb_input_event_class_t), + iclass); + find = EINA_TRUE; + } + xcb_input_device_info_next(&diter); + } + free(dreply); +#endif + + return find; + win = 0; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_keymap.c b/src/lib/ecore_x/xcb/ecore_xcb_keymap.c new file mode 100644 index 0000000000..6c112464b0 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_keymap.c @@ -0,0 +1,491 @@ +#include "ecore_xcb_private.h" +#define NEED_KEYSYM_TABLE +#define NEED_VTABLE +#include "ecore_xcb_keysym_table.h" +#include +#include + +/* local function prototypes */ +static int _ecore_xcb_keymap_mask_get(void *reply, + xcb_keysym_t sym); +static xcb_keysym_t _ecore_xcb_keymap_string_to_keysym(const char *str); +static int _ecore_xcb_keymap_translate_key(xcb_keycode_t keycode, + unsigned int modifiers, + unsigned int *modifiers_return, + xcb_keysym_t *keysym_return); +static int _ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym, + unsigned int modifiers, + char *buffer, + int bytes); + +/* local variables */ +static xcb_key_symbols_t *_ecore_xcb_keysyms; +static int _ecore_xcb_mode_switch = 0; + +/* public variables */ +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_MODIFIER_ALTGR = 0; +EAPI int ECORE_X_LOCK_SCROLL = 0; +EAPI int ECORE_X_LOCK_NUM = 0; +EAPI int ECORE_X_LOCK_CAPS = 0; +EAPI int ECORE_X_LOCK_SHIFT = 0; + +void +_ecore_xcb_keymap_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_keysyms = xcb_key_symbols_alloc(_ecore_xcb_conn); +} + +void +_ecore_xcb_keymap_finalize(void) +{ + xcb_get_modifier_mapping_cookie_t cookie; + xcb_get_modifier_mapping_reply_t *reply; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_modifier_mapping_unchecked(_ecore_xcb_conn); + reply = xcb_get_modifier_mapping_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) + { + xcb_key_symbols_free(_ecore_xcb_keysyms); + return; + } + + _ecore_xcb_mode_switch = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch); + + ECORE_X_MODIFIER_SHIFT = _ecore_xcb_keymap_mask_get(reply, XK_Shift_L); + ECORE_X_MODIFIER_CTRL = _ecore_xcb_keymap_mask_get(reply, XK_Control_L); + + ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Alt_L); + if (!ECORE_X_MODIFIER_ALT) + ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Meta_L); + if (!ECORE_X_MODIFIER_ALT) + ECORE_X_MODIFIER_ALT = _ecore_xcb_keymap_mask_get(reply, XK_Super_L); + + ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Super_L); + if (!ECORE_X_MODIFIER_WIN) + ECORE_X_MODIFIER_WIN = _ecore_xcb_keymap_mask_get(reply, XK_Meta_L); + + ECORE_X_MODIFIER_ALTGR = _ecore_xcb_keymap_mask_get(reply, XK_Mode_switch); + + 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_keymap_mask_get(reply, XK_Scroll_Lock); + ECORE_X_LOCK_NUM = _ecore_xcb_keymap_mask_get(reply, XK_Num_Lock); + ECORE_X_LOCK_CAPS = _ecore_xcb_keymap_mask_get(reply, XK_Caps_Lock); + ECORE_X_LOCK_SHIFT = _ecore_xcb_keymap_mask_get(reply, XK_Shift_Lock); +} + +void +_ecore_xcb_modifiers_get(void) +{ + _ecore_xcb_keymap_finalize(); +} + +void +_ecore_xcb_keymap_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (_ecore_xcb_keysyms) xcb_key_symbols_free(_ecore_xcb_keysyms); +} + +void +_ecore_xcb_keymap_refresh(xcb_mapping_notify_event_t *event) +{ + CHECK_XCB_CONN; + xcb_refresh_keyboard_mapping(_ecore_xcb_keysyms, event); +} + +xcb_keysym_t +_ecore_xcb_keymap_keycode_to_keysym(xcb_keycode_t keycode, + int col) +{ + xcb_keysym_t key0, key1; + + CHECK_XCB_CONN; + if (col & _ecore_xcb_mode_switch) + { + key0 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 4); + key1 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 5); + } + else + { + key0 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 0); + key1 = xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, keycode, 1); + } + + if (key1 == XCB_NO_SYMBOL) + key1 = key0; + + if ((col & ECORE_X_LOCK_NUM) && + ((xcb_is_keypad_key(key1)) || (xcb_is_private_keypad_key(key1)))) + { + if ((col & XCB_MOD_MASK_SHIFT) || + ((col & XCB_MOD_MASK_LOCK) && (col & ECORE_X_LOCK_SHIFT))) + return key0; + else + return key1; + } + else if (!(col & XCB_MOD_MASK_SHIFT) && !(col & XCB_MOD_MASK_LOCK)) + return key0; + else if (!(col & XCB_MOD_MASK_SHIFT) && + (col & XCB_MOD_MASK_LOCK && (col & ECORE_X_LOCK_CAPS))) + return key1; + else if ((col & XCB_MOD_MASK_SHIFT) && + (col & XCB_MOD_MASK_LOCK) && (col & ECORE_X_LOCK_CAPS)) + return key0; + else if ((col & XCB_MOD_MASK_SHIFT) || + (col & XCB_MOD_MASK_LOCK && (col & ECORE_X_LOCK_SHIFT))) + return key1; + + return XCB_NO_SYMBOL; +} + +xcb_keycode_t * +_ecore_xcb_keymap_keysym_to_keycode(xcb_keysym_t keysym) +{ + CHECK_XCB_CONN; + return xcb_key_symbols_get_keycode(_ecore_xcb_keysyms, keysym); +} + +char * +_ecore_xcb_keymap_keysym_to_string(xcb_keysym_t keysym) +{ + int i = 0, n = 0, h = 0, idx = 0; + const unsigned char *entry; + unsigned char val1, val2, val3, val4; + + CHECK_XCB_CONN; + if (!keysym) return NULL; + if (keysym == XK_VoidSymbol) keysym = 0; + if (keysym <= 0x1fffffff) + { + val1 = (keysym >> 24); + val2 = ((keysym >> 16) & 0xff); + val3 = ((keysym >> 8) & 0xff); + val4 = (keysym & 0xff); + i = keysym % VTABLESIZE; + h = i + 1; + n = VMAXHASH; + while ((idx = hashKeysym[i])) + { + entry = &_ecore_xcb_keytable[idx]; + if ((entry[0] == val1) && (entry[1] == val2) && + (entry[2] == val3) && (entry[3] == val4)) + return (char *)entry + 4; + if (!--n) break; + i += h; + if (i >= VTABLESIZE) i -= VTABLESIZE; + } + } + + if ((keysym >= 0x01000100) && (keysym <= 0x0110ffff)) + { + xcb_keysym_t val; + char *s = NULL; + int i = 0; + + val = (keysym & 0xffffff); + if (val & 0xff0000) + i = 10; + else + i = 6; + + if (!(s = malloc(i))) return NULL; + i--; + s[i--] = '\0'; + for (; i; i--) + { + val1 = (val & 0xf); + val >>= 4; + if (val1 < 10) + s[i] = '0' + val1; + else + s[i] = 'A' + val1 - 10; + } + s[i] = 'U'; + return s; + } + + return NULL; +} + +xcb_keycode_t +_ecore_xcb_keymap_string_to_keycode(const char *key) +{ + if (!strncmp(key, "Keycode-", 8)) + return atoi(key + 8); + else + { + xcb_keysym_t keysym = XCB_NO_SYMBOL; + xcb_keycode_t *keycodes, keycode = 0; + int i = 0; + + CHECK_XCB_CONN; + + keysym = _ecore_xcb_keymap_string_to_keysym(key); + if (keysym == XCB_NO_SYMBOL) return XCB_NO_SYMBOL; + + keycodes = _ecore_xcb_keymap_keysym_to_keycode(keysym); + if (!keycodes) return XCB_NO_SYMBOL; + + while (keycodes[i] != XCB_NO_SYMBOL) + { + if (keycodes[i] != 0) + { + keycode = keycodes[i]; + break; + } + i++; + } + return keycode; + } +} + +int +_ecore_xcb_keymap_lookup_string(xcb_keycode_t keycode, + int state, + char *buffer, + int bytes, + xcb_keysym_t *sym) +{ + unsigned int modifiers = 0; + xcb_keysym_t keysym; + + CHECK_XCB_CONN; + if (!_ecore_xcb_keymap_translate_key(keycode, state, &modifiers, &keysym)) + return 0; + + if (sym) *sym = keysym; + + return _ecore_xcb_keymap_translate_keysym(keysym, state, buffer, bytes); +} + +EAPI const char * +ecore_x_keysym_string_get(int keysym) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_keymap_keysym_to_string(keysym); +} + +EAPI int +ecore_x_keysym_keycode_get(const char *keyname) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_keymap_string_to_keycode(keyname); +} + +/* local functions */ +static int +_ecore_xcb_keymap_mask_get(void *reply, + xcb_keysym_t sym) +{ + xcb_get_modifier_mapping_reply_t *rep; + xcb_keysym_t sym2; + int mask = 0; + 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 + }; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + rep = (xcb_get_modifier_mapping_reply_t *)reply; + if ((rep) && (rep->keycodes_per_modifier > 0)) + { + int i = 0; + xcb_keycode_t *modmap; + + modmap = xcb_get_modifier_mapping_keycodes(rep); + for (i = 0; i < (8 * rep->keycodes_per_modifier); i++) + { + int j = 0; + + for (j = 0; j < 8; j++) + { + sym2 = + xcb_key_symbols_get_keysym(_ecore_xcb_keysyms, + modmap[i], j); + if (sym2 != 0) break; + } + if (sym2 == sym) + { + mask = masks[i / rep->keycodes_per_modifier]; + break; + } + } + } + + return mask; +} + +static xcb_keysym_t +_ecore_xcb_keymap_string_to_keysym(const char *str) +{ + int i = 0, n = 0, h = 0; + unsigned long sig = 0; + const char *p = NULL; + int c = 0, idx = 0; + const unsigned char *entry; + unsigned char sig1, sig2; + long unsigned int val; + + p = str; + while ((c = *p++)) + sig = (sig << 1) + c; + + i = (sig % KTABLESIZE); + h = i + 1; + sig1 = (sig >> 8) & 0xff; + sig2 = sig & 0xff; + n = KMAXHASH; + + while ((idx = hashString[i])) + { + entry = &_ecore_xcb_keytable[idx]; + if ((entry[0] == sig1) && (entry[1] == sig2) && + !strcmp(str, (char *)entry + 6)) + { + val = ((entry[2] << 24) | (entry[3] << 16) | + (entry[4] << 8) | (entry[5])); + if (!val) val = 0xffffff; + return val; + } + if (!--n) break; + i += h; + if (i >= KTABLESIZE) i -= KTABLESIZE; + } + + if (*str == 'U') + { + val = 0; + for (p = &str[1]; *p; p++) + { + c = *p; + if (('0' <= c) && (c <= '9')) + val = (val << 4) + c - '0'; + else if (('a' <= c) && (c <= 'f')) + val = (val << 4) + c - 'a' + 10; + else if (('A' <= c) && (c <= 'F')) + val = (val << 4) + c - 'A' + 10; + else + return XCB_NO_SYMBOL; + if (val > 0x10ffff) return XCB_NO_SYMBOL; + } + if ((val < 0x20) || ((val > 0x7e) && (val < 0xa0))) + return XCB_NO_SYMBOL; + if (val < 0x100) return val; + return val | 0x01000000; + } + + if ((strlen(str) > 2) && (str[0] == '0') && (str[1] == 'x')) + { + char *tmp = NULL; + + val = strtoul(str, &tmp, 16); + if ((val == ULONG_MAX) || ((tmp) && (*tmp != '\0'))) + return XCB_NO_SYMBOL; + else + return val; + } + + if (!strncmp(str, "XF86_", 5)) + { + long unsigned int ret; + char *tmp; + + tmp = strdup(str); + if (!tmp) return XCB_NO_SYMBOL; + memmove(&tmp[4], &tmp[5], strlen(str) - 5 + 1); + ret = _ecore_xcb_keymap_string_to_keysym(tmp); + free(tmp); + return ret; + } + + return XCB_NO_SYMBOL; +} + +static int +_ecore_xcb_keymap_translate_key(xcb_keycode_t keycode, + unsigned int modifiers, + unsigned int *modifiers_return, + xcb_keysym_t *keysym_return) +{ + xcb_keysym_t sym; + + if (!_ecore_xcb_keysyms) return 0; + + sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, modifiers); + + if (modifiers_return) + *modifiers_return = ((XCB_MOD_MASK_SHIFT | XCB_MOD_MASK_LOCK) | + _ecore_xcb_mode_switch | ECORE_X_LOCK_NUM); + if (keysym_return) + *keysym_return = sym; + + return 1; +} + +static int +_ecore_xcb_keymap_translate_keysym(xcb_keysym_t keysym, + unsigned int modifiers, + char *buffer, + int bytes) +{ + unsigned long hbytes = 0; + unsigned char c; + + if (!keysym) return 0; + hbytes = (keysym >> 8); + + if (!(bytes && + ((hbytes == 0) || + ((hbytes == 0xFF) && + (((keysym >= XK_BackSpace) && (keysym <= XK_Clear)) || + (keysym == XK_Return) || (keysym == XK_Escape) || + (keysym == XK_KP_Space) || (keysym == XK_KP_Tab) || + (keysym == XK_KP_Enter) || + ((keysym >= XK_KP_Multiply) && (keysym <= XK_KP_9)) || + (keysym == XK_KP_Equal) || (keysym == XK_Delete)))))) + return 0; + + if (keysym == XK_KP_Space) + c = (XK_space & 0x7F); + else if (hbytes == 0xFF) + c = (keysym & 0x7F); + else + c = (keysym & 0xFF); + + if (modifiers & ECORE_X_MODIFIER_CTRL) + { + if (((c >= '@') && (c < '\177')) || c == ' ') + c &= 0x1F; + else if (c == '2') + c = '\000'; + else if ((c >= '3') && (c <= '7')) + c -= ('3' - '\033'); + else if (c == '8') + c = '\177'; + else if (c == '/') + c = '_' & 0x1F; + } + buffer[0] = c; + return 1; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_mwm.c b/src/lib/ecore_x/xcb/ecore_xcb_mwm.c new file mode 100644 index 0000000000..6c9533136f --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_mwm.c @@ -0,0 +1,104 @@ +#include "ecore_xcb_private.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 +{ + uint32_t flags; + uint32_t functions; + uint32_t decorations; + int32_t inputmode; + uint32_t status; +} MWMHints; + +/** + * @defgroup Ecore_X_MWM_Group MWM related functions. + * + * Functions related to MWM. + */ + +/** + * Sets the borderless flag of a window using MWM. + * + * @param win The window. + * @param borderless The borderless flag. + * + * @ingroup Ecore_X_MWM_Group + */ +EAPI void +ecore_x_mwm_borderless_set(Ecore_X_Window win, + Eina_Bool borderless) +{ + uint32_t data[5] = { 0, 0, 0, 0, 0 }; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + data[0] = 2; + data[2] = !borderless; + + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_MOTIF_WM_HINTS, + ECORE_X_ATOM_MOTIF_WM_HINTS, 32, + (void *)data, 5); +} + +EAPI Eina_Bool +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) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + MWMHints *mwmhints = NULL; + int ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = + xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, + ECORE_X_ATOM_MOTIF_WM_HINTS, + ECORE_X_ATOM_MOTIF_WM_HINTS, 0, UINT_MAX); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + if ((reply->format != 32) || (reply->value_len == 0)) + { + free(reply); + return EINA_FALSE; + } + + 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 = EINA_TRUE; + } + free(reply); + return ret; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_netwm.c b/src/lib/ecore_x/xcb/ecore_xcb_netwm.c new file mode 100644 index 0000000000..ae801d3407 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_netwm.c @@ -0,0 +1,1604 @@ +#include "ecore_xcb_private.h" + +/* local function prototypes */ +/* static void _ecore_xcb_netwm_startup_info_free(void *data); */ +static Ecore_X_Atom _ecore_xcb_netwm_window_type_atom_get(Ecore_X_Window_Type type); +static Ecore_X_Window_Type _ecore_xcb_netwm_window_type_type_get(Ecore_X_Atom atom); +static Ecore_X_Atom _ecore_xcb_netwm_window_state_atom_get(Ecore_X_Window_State state); +static Ecore_X_Atom _ecore_xcb_netwm_action_atom_get(Ecore_X_Action action); + +/* local variables */ +//static Eina_Hash *_startup_info = NULL; + +/* local structures */ +typedef struct _Ecore_Xcb_Startup_Info Ecore_Xcb_Startup_Info; +struct _Ecore_Xcb_Startup_Info +{ + Ecore_X_Window win; + int init, size; + char *buffer; + int length; + + /* sequence info fields */ + char *id, *name; + int screen; + char *bin, *icon; + int desktop, timestamp; + char *description, *wmclass; + int silent; +}; + +EAPI void +ecore_x_netwm_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +// _startup_info = +// eina_hash_string_superfast_new(_ecore_xcb_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; +} + +EAPI Eina_Bool +ecore_x_netwm_pid_get(Ecore_X_Window win, + int *pid) +{ + uint32_t tmp; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID, &tmp, 1)) + return EINA_FALSE; + + if (pid) *pid = tmp; + + return EINA_TRUE; +} + +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 Eina_Bool +ecore_x_netwm_window_type_get(Ecore_X_Window win, + Ecore_X_Window_Type *type) +{ + Ecore_X_Atom *atoms; + int num = 0; + + 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_xcb_netwm_window_type_type_get(atoms[0]); + + if (atoms) free(atoms); + + if (num >= 1) return EINA_TRUE; + return EINA_FALSE; +} + +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_xcb_netwm_window_type_atom_get(type); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, &atom, 1); +} + +EAPI int +ecore_x_netwm_window_types_get(Ecore_X_Window win, + Ecore_X_Window_Type **types) +{ + int num = 0, i = 0; + 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) + { + if (atoms) free(atoms); + return 0; + } + + for (i = 0; i < num; i++) + atoms2[i] = _ecore_xcb_netwm_window_type_type_get(atoms[i]); + if (atoms) free(atoms); + + if (types) + *types = atoms2; + else + free(atoms2); + + return num; +} + +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_get(win, ECORE_X_ATOM_NET_WM_NAME); + return 1; +} + +EAPI void +ecore_x_netwm_name_set(Ecore_X_Window win, + const char *name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_string_set(win, ECORE_X_ATOM_NET_WM_NAME, name); +} + +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 Eina_Bool +ecore_x_netwm_opacity_get(Ecore_X_Window win, + unsigned int *opacity) +{ + unsigned int tmp = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, + &tmp, 1)) + return EINA_FALSE; + + if (opacity) *opacity = tmp; + + return EINA_TRUE; +} + +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(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, + &check, 1); + ecore_x_window_prop_string_set(check, ECORE_X_ATOM_NET_WM_NAME, wm_name); + ecore_x_window_prop_string_set(root, ECORE_X_ATOM_NET_WM_NAME, wm_name); + ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, + &check, 1); +} + +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 Eina_Bool +ecore_x_netwm_supported_get(Ecore_X_Window root, + Ecore_X_Atom **supported, + int *num) +{ + int num_ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (num) *num = 0; + if (supported) *supported = NULL; + + num_ret = + ecore_x_window_prop_atom_list_get(root, ECORE_X_ATOM_NET_SUPPORTED, + supported); + if (num_ret <= 0) return EINA_FALSE; + if (num) *num = num_ret; + + return EINA_TRUE; +} + +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 = NULL, *t = NULL; + const char *s; + uint32_t len = 0, i, l; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + for (i = 0; i < n_desks; i++) + { + s = ((names) ? names[i] : NULL); + if (!s) + { + /* Default to "Desk-" */ + sprintf(ss, "Desk-%d", i); + s = ss; + } + + l = strlen(s) + 1; + t = realloc(buf, len + 1); + if (t) + { + buf = t; + 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); +// ecore_x_flush(); + free(buf); +} + +EAPI void +ecore_x_netwm_desk_size_set(Ecore_X_Window root, + unsigned int width, + unsigned int height) +{ + uint32_t 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 unsigned int * +ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks) +{ + int ret; + unsigned int *areas = NULL; + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + ret = ecore_x_window_prop_card32_list_get(root, ECORE_X_ATOM_NET_WORKAREA, + &areas); + if (!areas) + { + if (n_desks) *n_desks = 0; + return 0; + } + if (n_desks) *n_desks = ret / 4; + return areas; +} + +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, + Eina_Bool on) +{ + unsigned int val = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + val = ((on) ? 1 : 0); + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, + &val, 1); +} + +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_get(win, ECORE_X_ATOM_NET_STARTUP_ID); + } + + 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_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id); +} + +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, + Eina_Bool set) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_NET_WM_STATE; + ev.data.data32[0] = !!set; + ev.data.data32[1] = _ecore_xcb_netwm_window_state_atom_get(s1); + ev.data.data32[2] = _ecore_xcb_netwm_window_state_atom_get(s2); + /* 1 == normal client, if used 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_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +// ecore_x_flush(); +} + +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 = 0; + + 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_xcb_netwm_window_state_atom_get(state[i]); + + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_STATE, set, num); + free(set); +} + +EAPI Eina_Bool +ecore_x_netwm_window_state_get(Ecore_X_Window win, + Ecore_X_Window_State **state, + unsigned int *num) +{ + Ecore_X_Atom *atoms; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (num) *num = 0; + if (state) *state = NULL; + + ret = + ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE, &atoms); + + if (ret <= 0) return EINA_FALSE; + + if (state) + { + *state = malloc(ret * sizeof(Ecore_X_Window_State)); + if (*state) + { + int i = 0; + + for (i = 0; i < ret; i++) + (*state)[i] = _ecore_xcb_netwm_window_state_get(atoms[i]); + if (num) *num = ret; + } + } + + free(atoms); + + return EINA_TRUE; +} + +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) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_NET_ACTIVE_WINDOW; + ev.data.data32[0] = type; + ev.data.data32[1] = XCB_CURRENT_TIME; + ev.data.data32[2] = current_win; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, root, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +// ecore_x_flush(); +} + +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); +} + +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 Eina_Bool +ecore_x_screen_is_composited(int screen) +{ + char buff[32]; + xcb_get_selection_owner_cookie_t ocookie; + xcb_get_selection_owner_reply_t *oreply; + Ecore_X_Window win; + static Ecore_X_Atom atom = XCB_NONE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + snprintf(buff, sizeof(buff), "_NET_WM_CM_S%i", screen); + + if (atom == XCB_NONE) + { + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(buff), buff); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + if (!areply) return EINA_FALSE; + atom = areply->atom; + free(areply); + } + if (atom == XCB_NONE) return EINA_FALSE; + + ocookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, atom); + oreply = xcb_get_selection_owner_reply(_ecore_xcb_conn, ocookie, NULL); + if (!oreply) return EINA_FALSE; + win = oreply->owner; + free(oreply); + + return (win != XCB_NONE) ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_x_screen_is_composited_set(int screen, + Ecore_X_Window win) +{ + static Ecore_X_Atom atom = XCB_NONE; + char buff[32]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + snprintf(buff, sizeof(buff), "_NET_WM_CM_S%i", screen); + if (atom == XCB_NONE) + { + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 0, strlen(buff), buff); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + if (!areply) return; + atom = areply->atom; + free(areply); + } + if (atom == XCB_NONE) return; + xcb_set_selection_owner(_ecore_xcb_conn, win, atom, + _ecore_xcb_events_last_time_get()); +} + +EAPI void +ecore_x_netwm_ping_send(Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_WM_PROTOCOLS; + ev.data.data32[0] = ECORE_X_ATOM_NET_WM_PING; + ev.data.data32[1] = ecore_x_current_time_get(); + ev.data.data32[2] = win; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); +} + +EAPI void +ecore_x_netwm_frame_size_set(Ecore_X_Window win, + int fl, + int fr, + int ft, + int fb) +{ + uint32_t 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 Eina_Bool +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 EINA_FALSE; + + if (fl) *fl = frames[0]; + if (fr) *fr = frames[1]; + if (ft) *ft = frames[2]; + if (fb) *fb = frames[3]; + + return EINA_TRUE; +} + +EAPI void +ecore_x_netwm_sync_request_send(Ecore_X_Window win, + unsigned int serial) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + + /* FIXME: Maybe need XSyncIntToValue ?? */ + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_WM_PROTOCOLS; + ev.data.data32[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; + ev.data.data32[1] = _ecore_xcb_events_last_time_get(); + ev.data.data32[2] = serial; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(_ecore_xcb_conn, 0, win, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); +} + +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 Eina_Bool +ecore_x_netwm_desktop_get(Ecore_X_Window win, + unsigned int *desk) +{ + unsigned int tmp = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP, + &tmp, 1)) + return EINA_FALSE; + + if (desk) *desk = tmp; + + return EINA_TRUE; +} + +EAPI void +ecore_x_netwm_desktop_request_send(Ecore_X_Window win, + Ecore_X_Window root, + unsigned int desktop) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + 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_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +// ecore_x_flush(); +} + +EAPI void +ecore_x_netwm_moveresize_request_send(Ecore_X_Window win, + int x, + int y, + Ecore_X_Netwm_Direction direction, + unsigned int button) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = ECORE_X_ATOM_NET_WM_MOVERESIZE; + ev.data.data32[0] = x; + ev.data.data32[1] = y; + ev.data.data32[2] = direction; + ev.data.data32[3] = button; + ev.data.data32[4] = 1; + + xcb_send_event(_ecore_xcb_conn, 0, win, + (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY), (const char *)&ev); +} + +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 Eina_Bool +ecore_x_netwm_handled_icons_get(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS, + NULL, 0)) + return EINA_FALSE; + + return EINA_TRUE; +} + +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_get(win, ECORE_X_ATOM_NET_WM_ICON_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_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME, name); +} + +EAPI void +ecore_x_netwm_icons_set(Ecore_X_Window win, + Ecore_X_Icon *icon, + int num) +{ + unsigned int *data, *p, *p2; + unsigned int i, size, x, y; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + size = 0; + for (i = 0; i < (unsigned int)num; i++) + { + size += 2 + (icon[i].width * icon[i].height); + } + data = malloc(size * sizeof(unsigned int)); + if (!data) return; + p = data; + for (i = 0; i < (unsigned int)num; i++) + { + p[0] = icon[i].width; + p[1] = icon[i].height; + p += 2; + p2 = icon[i].data; + for (y = 0; y < icon[i].height; y++) + { + for (x = 0; x < icon[i].width; x++) + { + unsigned int r, g, b, a; + + a = (*p2 >> 24) & 0xff; + r = (*p2 >> 16) & 0xff; + g = (*p2 >> 8 ) & 0xff; + b = (*p2 ) & 0xff; + if ((a > 0) && (a < 255)) + { + r = (r * 255) / a; + g = (g * 255) / a; + b = (b * 255) / a; + } + *p = (a << 24) | (r << 16) | (g << 8) | b; + p++; + p2++; + } + } + } + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON, + data, size); + free(data); +} + +EAPI Eina_Bool +ecore_x_netwm_icons_get(Ecore_X_Window win, + Ecore_X_Icon **icon, + int *num) +{ + int num_ret = 0; + unsigned int i = 0, len = 0, icons = 0; + unsigned int *data, *p, *src; + + 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) || (!data)) + { + if (data) free(data); + return EINA_FALSE; + } + if (num_ret < 2) + { + if (data) free(data); + return EINA_FALSE; + } + + icons = 0; + p = data; + while (p) + { + len = (p[0] * p[1]); + p += (len + 2); + if ((p - data) > num_ret) + { + if (data) free(data); + return EINA_FALSE; + } + icons++; + if ((p - data) == num_ret) p = NULL; + } + if (num) *num = icons; + if (!icon) + { + if (data) free(data); + return EINA_TRUE; + } + + *icon = malloc(icons * sizeof(Ecore_X_Icon)); + if (!(*icon)) + { + if (data) free(data); + return EINA_FALSE; + } + + /* 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 EINA_FALSE; + } + + 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); + } + + if (data) free(data); + return EINA_TRUE; +} + +EAPI void +ecore_x_netwm_icon_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_NET_WM_ICON_GEOMETRY, + geom, 4); +} + +EAPI Eina_Bool +ecore_x_netwm_icon_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_NET_WM_ICON_GEOMETRY, + geom, 4); + if (ret != 4) return EINA_FALSE; + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +EAPI void +ecore_x_netwm_strut_set(Ecore_X_Window win, + int l, + int r, + int t, + int b) +{ + unsigned int strut[4]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + strut[0] = l; + strut[1] = r; + strut[2] = t; + strut[3] = b; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); +} + +EAPI Eina_Bool +ecore_x_netwm_strut_get(Ecore_X_Window win, + int *l, + int *r, + int *t, + int *b) +{ + unsigned int strut[4]; + int ret = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ret = + ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); + if (ret != 4) return EINA_FALSE; + + if (l) *l = strut[0]; + if (r) *r = strut[1]; + if (t) *t = strut[2]; + if (b) *b = strut[3]; + + return EINA_TRUE; +} + +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 Eina_Bool +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) +{ + unsigned int strut[12]; + int ret = 0; + + 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 EINA_FALSE; + + 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 EINA_TRUE; +} + +EAPI void +ecore_x_netwm_user_time_set(Ecore_X_Window win, + unsigned int t) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME, &t, 1); +} + +EAPI Eina_Bool +ecore_x_netwm_user_time_get(Ecore_X_Window win, + unsigned int *t) +{ + unsigned int tmp; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME, + &tmp, 1)) + return EINA_FALSE; + + if (t) *t = tmp; + + return EINA_TRUE; +} + +EAPI void +ecore_x_netwm_visible_name_set(Ecore_X_Window win, + const char *name) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_string_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_get(win, + ECORE_X_ATOM_NET_WM_VISIBLE_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_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_get(win, + ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME); + } + + return 1; +} + +EAPI Eina_Bool +ecore_x_netwm_sync_counter_get(Ecore_X_Window win, + Ecore_X_Sync_Counter *counter) +{ + unsigned int tmp; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, + &tmp, 1)) + return EINA_FALSE; + + if (counter) *counter = tmp; + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, + Ecore_X_Action action) +{ + int num = 0, i = 0; + Ecore_X_Atom *atoms, atom; + Eina_Bool ret = EINA_FALSE; + + 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 EINA_FALSE; + + atom = _ecore_xcb_netwm_action_atom_get(action); + for (i = 0; i < num; i++) + { + if (atoms[i] == atom) + { + ret = EINA_TRUE; + break; + } + } + + if (atoms) free(atoms); + return ret; +} + +EAPI Eina_Bool +ecore_x_netwm_allowed_action_get(Ecore_X_Window win, + Ecore_X_Action **action, + unsigned int *num) +{ + Ecore_X_Atom *atoms; + int num_ret = 0; + + 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 EINA_FALSE; + if (action) + { + *action = malloc(num_ret * sizeof(Ecore_X_Action)); + if (*action) + { + int i = 0; + + for (i = 0; i < num_ret; i++) + (*action)[i] = _ecore_xcb_netwm_action_atom_get(atoms[i]); + } + if (num) *num = num_ret; + } + free(atoms); + return EINA_TRUE; +} + +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 = 0; + + 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_xcb_netwm_action_atom_get(action[i]); + + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, + set, num); + free(set); +} + +/* local functions */ +int +_ecore_xcb_netwm_startup_info_begin(Ecore_X_Window win EINA_UNUSED, + uint8_t data EINA_UNUSED) +{ + // TODO: TBD + return 1; +} + +int +_ecore_xcb_netwm_startup_info(Ecore_X_Window win EINA_UNUSED, + uint8_t data EINA_UNUSED) +{ + // TODO: TBD + return 1; +} + +/* static void */ +/* _ecore_xcb_netwm_startup_info_free(void *data) */ +/* { */ +/* Ecore_Xcb_Startup_Info *info; */ + +/* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ + +/* if (!(info = data)) 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); */ +/* } */ + +static Ecore_X_Atom +_ecore_xcb_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; + } +} + +static Ecore_X_Window_Type +_ecore_xcb_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_xcb_netwm_window_state_atom_get(Ecore_X_Window_State state) +{ + switch (state) + { + 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; + } +} + +Ecore_X_Window_State +_ecore_xcb_netwm_window_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_NET_WM_STATE_MODAL) + return ECORE_X_WINDOW_STATE_MODAL; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_STICKY) + return ECORE_X_WINDOW_STATE_STICKY; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT) + return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ) + return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_SHADED) + return ECORE_X_WINDOW_STATE_SHADED; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR) + return ECORE_X_WINDOW_STATE_SKIP_TASKBAR; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER) + return ECORE_X_WINDOW_STATE_SKIP_PAGER; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_HIDDEN) + return ECORE_X_WINDOW_STATE_HIDDEN; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN) + return ECORE_X_WINDOW_STATE_FULLSCREEN; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_ABOVE) + return ECORE_X_WINDOW_STATE_ABOVE; + else if (atom == ECORE_X_ATOM_NET_WM_STATE_BELOW) + return ECORE_X_WINDOW_STATE_BELOW; + else if (atom == 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_xcb_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; + } +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c b/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c new file mode 100644 index 0000000000..f9bf525f7a --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_pixmap.c @@ -0,0 +1,128 @@ +#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; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + 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); + +// ecore_x_flush(); + 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_free_pixmap(_ecore_xcb_conn, pmap); +// ecore_x_flush(); +} + +/** + * 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__); + CHECK_XCB_CONN; + + xcb_copy_area(_ecore_xcb_conn, pmap, dest, gc, sx, sy, dx, dy, w, h); +// ecore_x_flush(); +} + +/** + * 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); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_private.h b/src/lib/ecore_x/xcb/ecore_xcb_private.h new file mode 100644 index 0000000000..240210ca0d --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_private.h @@ -0,0 +1,468 @@ +#ifndef __ECORE_XCB_PRIVATE_H__ +# define __ECORE_XCB_PRIVATE_H__ + +//# define LOGFNS 1 + +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +# include // included for close & gethostname functions + +/* generic xcb includes */ +# include +# include +# include +# include + +/* EFL includes */ +# include "Ecore.h" +# include "Ecore_Input.h" +# include "Ecore_X.h" + +/* logging */ +extern int _ecore_xcb_log_dom; + +# ifdef ECORE_XCB_DEFAULT_LOG_COLOR +# undef ECORE_XCB_DEFAULT_LOG_COLOR +# endif +# define ECORE_XCB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE + +# ifdef ERR +# undef ERR +# endif +# define ERR(...) EINA_LOG_DOM_ERR(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef DBG +# undef DBG +# endif +# define DBG(...) EINA_LOG_DOM_DBG(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef INF +# undef INF +# endif +# define INF(...) EINA_LOG_DOM_INFO(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef WRN +# undef WRN +# endif +# define WRN(...) EINA_LOG_DOM_WARN(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef CRIT +# undef CRIT +# endif +# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_xcb_log_dom, __VA_ARGS__) + +# ifdef LOGFNS +# include +# define LOGFN(fl, ln, fn) printf("-ECORE-XCB: %25s: %5i - %s\n", fl, ln, fn); +# else +# define LOGFN(fl, ln, fn) +# endif + +# ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +# endif + +# ifndef MIN +# define MIN(x, y) (((x) > (y)) ? (y) : (x)) +# endif + +# ifndef MAX +# define MAX(a, b) ((a < b) ? b : a) +# endif + +#define CHECK_XCB_CONN \ + { \ + if (xcb_connection_has_error(_ecore_xcb_conn)) \ + { \ + DBG("XCB Connection Has Error !!"); \ + _ecore_xcb_io_error_handle(NULL); \ + } \ + } + +/* enums */ +typedef enum _Ecore_Xcb_Encoding_Style Ecore_Xcb_Encoding_Style; + +enum _Ecore_Xcb_Encoding_Style +{ + XcbStringStyle, + XcbCompoundTextStyle, + XcbTextStyle, + XcbStdICCTextStyle, + XcbUTF8StringStyle +}; + +/* structures */ +typedef struct _Ecore_X_DND_Source Ecore_X_DND_Source; +typedef struct _Ecore_X_DND_Target Ecore_X_DND_Target; +typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern; +typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter; +typedef struct _Ecore_X_Selection_Parser Ecore_X_Selection_Parser; +typedef struct _Ecore_Xcb_Textproperty Ecore_Xcb_Textproperty; + +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, suppress; + int await_status; +}; + +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; +}; + +struct _Ecore_X_Selection_Intern +{ + Ecore_X_Window win; + Ecore_X_Atom selection; + unsigned char *data; + int length; + Ecore_X_Time time; +}; + +struct _Ecore_X_Selection_Converter +{ + Ecore_X_Atom target; + Eina_Bool (*convert)(char *target, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *type, + int *size_type); + Ecore_X_Selection_Converter *next; +}; + +struct _Ecore_X_Selection_Parser +{ + char *target; + void *(*parse)(const char *target, void *data, int size, int format); + Ecore_X_Selection_Parser *next; +}; + +struct _Ecore_Xcb_Textproperty +{ + char *value; + Ecore_X_Atom encoding; + unsigned int format, nitems; +}; + +/* external variables */ +extern Ecore_X_Connection *_ecore_xcb_conn; +extern Ecore_X_Screen *_ecore_xcb_screen; +extern double _ecore_xcb_double_click_time; +extern int16_t _ecore_xcb_event_last_root_x; +extern int16_t _ecore_xcb_event_last_root_y; + +/* external variables for extension events */ +extern int _ecore_xcb_event_damage; +extern int _ecore_xcb_event_randr; +extern int _ecore_xcb_event_screensaver; +extern int _ecore_xcb_event_shape; +extern int _ecore_xcb_event_sync; +extern int _ecore_xcb_event_xfixes; +extern int _ecore_xcb_event_input; +extern int _ecore_xcb_event_gesture; + +extern Ecore_X_Atom _ecore_xcb_atoms_wm_protocol[ECORE_X_WM_PROTOCOL_NUM]; + +extern int _ecore_xcb_button_grabs_num; +extern int _ecore_xcb_key_grabs_num; +extern Ecore_X_Window *_ecore_xcb_button_grabs; +extern Ecore_X_Window *_ecore_xcb_key_grabs; +extern Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data, + int type, + void *event); +extern void *_ecore_xcb_window_grab_replay_data; + +/* private function prototypes */ +void _ecore_xcb_error_handler_init(void); +void _ecore_xcb_error_handler_shutdown(void); + +void _ecore_xcb_atoms_init(void); +void _ecore_xcb_atoms_finalize(void); + +void _ecore_xcb_extensions_init(void); +void _ecore_xcb_extensions_finalize(void); + +void _ecore_xcb_shape_init(void); +void _ecore_xcb_shape_finalize(void); + +void _ecore_xcb_screensaver_init(void); +void _ecore_xcb_screensaver_finalize(void); + +void _ecore_xcb_sync_init(void); +void _ecore_xcb_sync_finalize(void); +void _ecore_xcb_sync_magic_send(int val, + Ecore_X_Window win); + +void _ecore_xcb_render_init(void); +void _ecore_xcb_render_finalize(void); +Eina_Bool _ecore_xcb_render_argb_get(void); +Eina_Bool _ecore_xcb_render_anim_get(void); +Eina_Bool _ecore_xcb_render_avail_get(void); + +Eina_Bool _ecore_xcb_render_visual_supports_alpha(Ecore_X_Visual visual); +uint32_t _ecore_xcb_render_find_visual_id(int type, + Eina_Bool check_alpha); +Ecore_X_Visual *_ecore_xcb_render_visual_get(int visual_id); + +void _ecore_xcb_randr_init(void); +void _ecore_xcb_randr_finalize(void); + +void _ecore_xcb_gesture_init(void); +void _ecore_xcb_gesture_finalize(void); +void _ecore_xcb_gesture_shutdown(void); + +void _ecore_xcb_xfixes_init(void); +void _ecore_xcb_xfixes_finalize(void); +Eina_Bool _ecore_xcb_xfixes_avail_get(void); + +void _ecore_xcb_damage_init(void); +void _ecore_xcb_damage_finalize(void); + +void _ecore_xcb_composite_init(void); +void _ecore_xcb_composite_finalize(void); + +void _ecore_xcb_dpms_init(void); +void _ecore_xcb_dpms_finalize(void); + +void _ecore_xcb_cursor_init(void); +void _ecore_xcb_cursor_finalize(void); + +void _ecore_xcb_xinerama_init(void); +void _ecore_xcb_xinerama_finalize(void); + +void _ecore_xcb_dnd_init(void); +void _ecore_xcb_dnd_shutdown(void); +Ecore_X_DND_Source *_ecore_xcb_dnd_source_get(void); +Ecore_X_DND_Target *_ecore_xcb_dnd_target_get(void); +void _ecore_xcb_dnd_drag(Ecore_X_Window root, + int x, + int y); + +void _ecore_xcb_selection_init(void); +void _ecore_xcb_selection_shutdown(void); +void *_ecore_xcb_selection_parse(const char *target, + void *data, + int size, + int format); +char *_ecore_xcb_selection_target_get(Ecore_X_Atom target); +Ecore_X_Selection_Intern *_ecore_xcb_selection_get(Ecore_X_Atom selection); + +# ifdef HAVE_ICONV +Eina_Bool _ecore_xcb_utf8_textlist_to_textproperty(char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret); +# endif +Eina_Bool _ecore_xcb_mb_textlist_to_textproperty(char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret); +Eina_Bool _ecore_xcb_textlist_to_textproperty(const char *type, + char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret); + +# ifdef HAVE_ICONV +Eina_Bool _ecore_xcb_utf8_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + char ***list_ret, + int *count_ret); +# endif +Eina_Bool _ecore_xcb_mb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + char ***list_ret, + int *count_ret); +Eina_Bool _ecore_xcb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + const char *type, + char ***list_ret, + int *count_ret); + +void _ecore_xcb_events_init(void); +void _ecore_xcb_events_shutdown(void); +void _ecore_xcb_events_handle(xcb_generic_event_t *ev); +Ecore_X_Time _ecore_xcb_events_last_time_get(void); +unsigned int _ecore_xcb_events_modifiers_get(unsigned int state); +void _ecore_xcb_event_mouse_move(uint16_t timestamp, + uint16_t modifiers, + int16_t x, + int16_t y, + int16_t root_x, + int16_t root_y, + xcb_window_t event_win, + xcb_window_t win, + xcb_window_t root_win, + uint8_t same_screen, + int dev, + double radx, + double rady, + double pressure, + double angle, + int16_t mx, + int16_t my, + int16_t mrx, + int16_t mry); +Ecore_Event_Mouse_Button *_ecore_xcb_event_mouse_button(int event, + uint16_t timestamp, + uint16_t modifiers, + xcb_button_t buttons, + int16_t x, + int16_t y, + int16_t root_x, + int16_t root_y, + xcb_window_t event_win, + xcb_window_t win, + xcb_window_t root_win, + uint8_t same_screen, + int dev, + double radx, + double rady, + double pressure, + double angle, + int16_t mx, + int16_t my, + int16_t mrx, + int16_t mry); + +void _ecore_xcb_keymap_init(void); +void _ecore_xcb_keymap_finalize(void); +void _ecore_xcb_keymap_shutdown(void); +void _ecore_xcb_keymap_refresh(xcb_mapping_notify_event_t *event); +xcb_keysym_t _ecore_xcb_keymap_keycode_to_keysym(xcb_keycode_t keycode, + int col); +xcb_keycode_t *_ecore_xcb_keymap_keysym_to_keycode(xcb_keysym_t keysym); +char *_ecore_xcb_keymap_keysym_to_string(xcb_keysym_t keysym); +xcb_keycode_t _ecore_xcb_keymap_string_to_keycode(const char *key); +int _ecore_xcb_keymap_lookup_string(xcb_keycode_t keycode, + int state, + char *buffer, + int bytes, + xcb_keysym_t *sym); + +void _ecore_xcb_input_init(void); +void _ecore_xcb_input_finalize(void); +void _ecore_xcb_input_shutdown(void); +# ifdef ECORE_XCB_XINPUT +void _ecore_xcb_input_handle_event(xcb_generic_event_t *event); +# else +void _ecore_xcb_input_handle_event(xcb_generic_event_t *event); +# endif + +void _ecore_xcb_dri_init(void); +void _ecore_xcb_dri_finalize(void); + +void _ecore_xcb_xtest_init(void); +void _ecore_xcb_xtest_finalize(void); + +Ecore_X_Window _ecore_xcb_window_root_of_screen_get(int screen); +void _ecore_xcb_window_prop_string_utf8_set(Ecore_X_Window win, + Ecore_X_Atom atom, + const char *str); +Ecore_X_Visual _ecore_xcb_window_visual_get(Ecore_X_Window win); +void _ecore_xcb_window_button_grab_remove(Ecore_X_Window win); +void _ecore_xcb_window_key_grab_remove(Ecore_X_Window win); +void _ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win, + Ecore_X_Window child_win, + int type, + void *event, + Ecore_X_Time timestamp); + +int _ecore_xcb_netwm_startup_info_begin(Ecore_X_Window win, + uint8_t data); +int _ecore_xcb_netwm_startup_info(Ecore_X_Window win, + uint8_t data); +Ecore_X_Window_State _ecore_xcb_netwm_window_state_get(Ecore_X_Atom atom); + +int _ecore_xcb_error_handle(xcb_generic_error_t *err); +int _ecore_xcb_io_error_handle(xcb_generic_error_t *err); + +xcb_image_t *_ecore_xcb_image_create_native(int w, + int h, + xcb_image_format_t format, + uint8_t depth, + void *base, + uint32_t bytes, + uint8_t *data); + +void _ecore_xcb_xdefaults_init(void); +void _ecore_xcb_xdefaults_shutdown(void); +char *_ecore_xcb_xdefaults_string_get(const char *prog, + const char *param); +int _ecore_xcb_xdefaults_int_get(const char *prog, + const char *param); + +void _ecore_xcb_modifiers_get(void); + +#endif diff --git a/src/lib/ecore_x/xcb/ecore_xcb_randr.c b/src/lib/ecore_x/xcb/ecore_xcb_randr.c new file mode 100644 index 0000000000..a2a4e6271f --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_randr.c @@ -0,0 +1,3807 @@ +/* TODO: List of missing functions + * + * ecore_x_randr_crtc_clone_set + * ecore_x_randr_output_crtc_set + * ecore_x_randr_edid_version_get + * ecore_x_randr_edid_info_has_valid_checksum + * ecore_x_randr_edid_manufacturer_name_get + * ecore_x_randr_edid_display_ascii_get + * ecore_x_randr_edid_display_serial_get + * ecore_x_randr_edid_model_get + * ecore_x_randr_edid_manufacturer_serial_number_get + * ecore_x_randr_edid_manufacturer_model_get + * ecore_x_randr_edid_dpms_available_get + * ecore_x_randr_edid_dpms_standby_available_get + * ecore_x_randr_edid_dpms_suspend_available_get + * ecore_x_randr_edid_dpms_off_available_get + * ecore_x_randr_edid_display_aspect_ratio_preferred_get + * ecore_x_randr_edid_display_aspect_ratios_get + * ecore_x_randr_edid_display_colorscheme_get + * ecore_x_randr_edid_display_type_digital_get + * ecore_x_randr_edid_display_interface_type_get + * ecore_x_randr_screen_backlight_level_set + * ecore_x_randr_output_subpixel_order_get + * ecore_x_randr_output_wired_clones_get + * ecore_x_randr_output_compatibility_list_get + * ecore_x_randr_output_signal_formats_get + * ecore_x_randr_output_signal_format_set + * ecore_x_randr_output_signal_properties_get + * ecore_x_randr_output_connector_number_get + * ecore_x_randr_output_connector_type_get + * ecore_x_randr_crtc_panning_area_get + * ecore_x_randr_crtc_panning_area_set + * ecore_x_randr_crtc_tracking_area_get + * ecore_x_randr_crtc_tracking_area_set + * ecore_x_randr_crtc_border_area_get + * ecore_x_randr_crtc_border_area_set + */ + +#include "ecore_xcb_private.h" +# ifdef ECORE_XCB_RANDR +# include +# endif + +#define Ecore_X_Randr_None 0 +#define Ecore_X_Randr_Unset -1 + +#define RANDR_1_1 ((1 << 16) | 1) +#define RANDR_1_2 ((1 << 16) | 2) +#define RANDR_1_3 ((1 << 16) | 3) + +#define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) return ret +#define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) return ret +#define RANDR_CHECK_1_3_RET(ret) if (_randr_version < RANDR_1_3) return ret + +#define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3) +#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12 +#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13 +#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36 +#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3 +#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5 +#define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13 + +#define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ + for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18) + +#define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \ + _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ + if ((block[0] == 0) && (block[1] == 0)) + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_randr_output_validate(Ecore_X_Window root, + Ecore_X_Randr_Output output); +static Eina_Bool _ecore_xcb_randr_crtc_validate(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc); +static Eina_Bool _ecore_xcb_randr_root_validate(Ecore_X_Window root); +static int _ecore_xcb_randr_root_to_screen(Ecore_X_Window root); +#ifdef ECORE_XCB_RANDR +static xcb_randr_get_screen_resources_reply_t *_ecore_xcb_randr_12_get_resources(Ecore_X_Window win); +static xcb_randr_get_screen_resources_current_reply_t *_ecore_xcb_randr_13_get_resources(Ecore_X_Window win); +#endif +static xcb_timestamp_t _ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win); +static xcb_timestamp_t _ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win); + +static Ecore_X_Randr_Mode *_ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num, + int *npreferred); +static Ecore_X_Randr_Mode *_ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num, + int *npreferred); +static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode); +static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode); +static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root, + int *num); +static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root, + int *num); +static void _ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode, + int *w, + int *h); +static void _ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode, + int *w, + int *h); +static Ecore_X_Randr_Output *_ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num); +static Ecore_X_Randr_Output *_ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num); +static Ecore_X_Randr_Crtc *_ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num); +static Ecore_X_Randr_Crtc *_ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num); +static char *_ecore_xcb_randr_12_output_name_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *len); +static char *_ecore_xcb_randr_13_output_name_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *len); +static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root, + Ecore_X_Randr_Output output); +static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root, + Ecore_X_Randr_Output output); +static Ecore_X_Randr_Output *_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root, + int *num); +static Ecore_X_Randr_Output *_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root, + int *num); +static Ecore_X_Randr_Crtc _ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root, + Ecore_X_Randr_Output output); +static Ecore_X_Randr_Crtc _ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root, + Ecore_X_Randr_Output output); + +/* local variables */ +static Eina_Bool _randr_avail = EINA_FALSE; +static int _randr_version = -1; + +/* external variables */ +int _ecore_xcb_event_randr = -1; + +void +_ecore_xcb_randr_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id); +#endif +} + +void +_ecore_xcb_randr_finalize(void) +{ +#ifdef ECORE_XCB_RANDR + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_randr_query_version_cookie_t cookie; + xcb_randr_query_version_reply_t *reply; + + cookie = + xcb_randr_query_version_unchecked(_ecore_xcb_conn, + XCB_RANDR_MAJOR_VERSION, + XCB_RANDR_MINOR_VERSION); + reply = xcb_randr_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if ((reply->major_version >= XCB_RANDR_MAJOR_VERSION) && + (reply->minor_version >= XCB_RANDR_MINOR_VERSION)) + _randr_avail = EINA_TRUE; + + _randr_version = + ((reply->major_version << 16) | reply->minor_version); + + free(reply); + } + + if (_randr_avail) + _ecore_xcb_event_randr = ext_reply->first_event; + } +#endif +} + +static Eina_Bool +#ifdef ECORE_XCB_RANDR +_ecore_xcb_randr_root_validate(Ecore_X_Window root) +#else +_ecore_xcb_randr_root_validate(Ecore_X_Window root EINA_UNUSED) +#endif +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Randr_Screen scr = -1; +# define RANDR_VALIDATE_ROOT(screen, root) \ + ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RANDR + if ((root) && RANDR_VALIDATE_ROOT(scr, root)) + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + +static int +_ecore_xcb_randr_root_to_screen(Ecore_X_Window root) +{ + int count = 0, num = 0; + + CHECK_XCB_CONN; + + count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn)); + for (num = 0; num < count; num++) + if (_ecore_xcb_window_root_of_screen_get(num) == root) + return num; + + return -1; +} + +/* public functions */ + +/* + * @brief Query whether RandR is available or not. + * + * @return @c EINA_TRUE if extension is available, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_randr_query(void) +{ + return _randr_avail; +} + +/* + * @return version of the RandRR extension supported by the server or, + * in case RandRR extension is not available, Ecore_X_Randr_Unset (=-1). + * bit version information: 31 MAJOR 16 | 15 MINOR 0 + */ +EAPI int +ecore_x_randr_version_get(void) +{ + return _randr_version; +} + +/* + * @param root window which's primary output will be queried + */ +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root) +{ + int ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->rotations; + free(reply); + } +#endif + + return ret; +} + +/* + * @param root window which's primary output will be queried + * @return the current orientation of the root window's screen primary output + */ +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root) +{ + int ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->rotation; + free(reply); + } +#endif + + return ret; +} + +/* + * @brief Sets a given screen's primary output's orientation. + * + * @param root Window which's screen's primary output will be queried. + * @param orientation Orientation which should be set for the root window's + * screen primary output. + * @return @c EINA_TRUE if the primary output's orientation could be + * successfully altered. + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root, + Ecore_X_Randr_Orientation orientation) +{ + int ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_set_screen_config_cookie_t scookie; + xcb_randr_set_screen_config_reply_t *sreply; + + scookie = + xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, + XCB_CURRENT_TIME, + reply->config_timestamp, + reply->sizeID, orientation, + reply->rate); + sreply = + xcb_randr_set_screen_config_reply(_ecore_xcb_conn, scookie, NULL); + if (!sreply) + ret = EINA_FALSE; + else + { + ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? + EINA_TRUE : EINA_FALSE; + free(sreply); + } + free(reply); + } +#endif + + return ret; +} + +/* + * @brief gets a screen's primary output's possible sizes + * @param root window which's primary output will be queried + * @param num number of sizes reported as supported by the screen's primary output + * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL + */ +EAPI Ecore_X_Randr_Screen_Size_MM * +ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, + int *num) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; + Ecore_X_Randr_Screen_Size_MM *ret = NULL; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0, i = 0; + xcb_randr_screen_size_t *sizes; + + len = xcb_randr_get_screen_info_sizes_length(reply); + sizes = xcb_randr_get_screen_info_sizes(reply); + if ((!sizes) || (len <= 0)) + { + free(reply); + return NULL; + } + if (num) *num = len; + ret = calloc(len, sizeof(Ecore_X_Randr_Screen_Size_MM)); + if (!ret) + { + free(reply); + return NULL; + } + for (i = 0; i < len; i++) + { + ret[i].width = sizes[i].width; + ret[i].height = sizes[i].height; + ret[i].width_mm = sizes[i].mwidth; + ret[i].height_mm = sizes[i].mheight; + } + + free(reply); + } + + return ret; +#else + return NULL; +#endif +} + +/* + * @brief get the current set size of a given screen's primary output + * @param root window which's primary output will be queried + * @param w the current size's width + * @param h the current size's height + * @param w_mm the current size's width in mm + * @param h_mm the current size's height in mm + * @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set() + */ +EAPI void +ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, + int *w, + int *h, + int *w_mm, + int *h_mm, + int *size_index) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0, idx = 0; + xcb_randr_screen_size_t *sizes; + + len = xcb_randr_get_screen_info_sizes_length(reply); + sizes = xcb_randr_get_screen_info_sizes(reply); + if ((!sizes) || (len <= 0)) + { + free(reply); + return; + } + idx = reply->sizeID; + if ((idx < len) && (idx >= 0)) + { + if (w) *w = sizes[idx].width; + if (h) *h = sizes[idx].height; + if (w_mm) *w_mm = sizes[idx].mwidth; + if (h_mm) *h_mm = sizes[idx].mheight; + if (size_index) *size_index = idx; + } + + free(reply); + } +#endif +} + +/* + * @brief Sets a given screen's primary output size, but disables all other + * outputs at the same time. + * + * @param root Window which's primary output will be queried. + * @param size_index Within the list of sizes reported as supported by the root + * window's screen primary output. + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure due to e.g. + * invalid times. + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, + int size_index) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + if (!((size_index >= 0) && (_ecore_xcb_randr_root_validate(root)))) + return EINA_FALSE; + + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0; + + len = xcb_randr_get_screen_info_sizes_length(reply); + if (len <= 0) + { + free(reply); + return EINA_FALSE; + } + if ((size_index < len) && (size_index >= 0)) + { + xcb_randr_set_screen_config_cookie_t scookie; + xcb_randr_set_screen_config_reply_t *sreply; + + scookie = + xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, + XCB_CURRENT_TIME, + reply->config_timestamp, + size_index, + reply->rotation, + reply->rate); + sreply = + xcb_randr_set_screen_config_reply(_ecore_xcb_conn, + scookie, NULL); + if (!sreply) + ret = EINA_FALSE; + else + { + ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? + EINA_TRUE : EINA_FALSE; + free(sreply); + } + } + + free(reply); + } +#endif + return ret; +} + +/* + * @param root window which's primary output will be queried + * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0 + */ +EAPI Ecore_X_Randr_Refresh_Rate +ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; + Ecore_X_Randr_Refresh_Rate ret = 0.0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) return ret; + + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->rate; + free(reply); + } + + return ret; +#else + return 0.0; +#endif +} + +/* + * @param root window which's primary output will be queried + * @param size_index referencing the size to query valid refresh rates for + * @return currently used refresh rate or - if request failed or RandRR is not available - NULL + */ +EAPI Ecore_X_Randr_Refresh_Rate * +ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, + int size_index, + int *num) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; + Ecore_X_Randr_Refresh_Rate *ret = NULL; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) return ret; + + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + int len = 0; + + len = xcb_randr_get_screen_info_rates_length(reply); + if (num) *num = len; + + ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * len); + if (ret) + { + xcb_randr_refresh_rates_iterator_t iter; + int i = 0; + + iter = xcb_randr_get_screen_info_rates_iterator(reply); + while (i++ < size_index) + xcb_randr_refresh_rates_next(&iter); + + memcpy(ret, xcb_randr_refresh_rates_rates(iter.data), + sizeof(Ecore_X_Randr_Refresh_Rate) * len); + } + free(reply); + } + + return ret; +#else + return NULL; +#endif +} + +/* + * @brief Sets the current primary output's refresh rate. + * + * @param root Window which's primary output will be queried. + * @param size_index Referencing the size to be set. + * @param rate The refresh rate to be set. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root, + int size_index, + Ecore_X_Randr_Refresh_Rate rate) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_info_cookie_t cookie; + xcb_randr_get_screen_info_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + if (_randr_version < RANDR_1_1) return EINA_FALSE; + + cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_randr_set_screen_config_cookie_t scookie; + xcb_randr_set_screen_config_reply_t *sreply; + + scookie = + xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root, + XCB_CURRENT_TIME, + reply->config_timestamp, + size_index, + reply->rotation, rate); + sreply = + xcb_randr_set_screen_config_reply(_ecore_xcb_conn, + scookie, NULL); + if (!sreply) + ret = EINA_FALSE; + else + { + ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? + EINA_TRUE : EINA_FALSE; + free(sreply); + } + free(reply); + } +#endif + + return ret; +} + +/* + * @brief Free detailed mode information. The pointer handed in will be set to + * @c NULL after freeing the memory. + * + * @param mode_info The mode information that should be freed. + */ +EAPI void +ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + RANDR_CHECK_1_2_RET(); + + if (!mode_info) return; + + if (mode_info->name) free(mode_info->name); + free(mode_info); + mode_info = NULL; +} + +/* + * @param root window which's screen should be queried + * @return Ecore_X_Randr_Ouptut_Id or - if query failed or none is set - Ecore_X_Randr_None + */ +EAPI Ecore_X_Randr_Output +ecore_x_randr_primary_output_get(Ecore_X_Window root) +{ + Ecore_X_Randr_Output ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_output_primary_cookie_t cookie; + xcb_randr_get_output_primary_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_3_RET(Ecore_X_Randr_None); + + if (!_ecore_xcb_randr_root_validate(root)) + return Ecore_X_Randr_None; + + cookie = xcb_randr_get_output_primary_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_output_primary_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + ret = reply->output; + free(reply); + } +#endif + return ret; +} + +/* + * @param root window which's screen should be queried + * @param output that should be set as given root window's screen primary output + */ +EAPI void +ecore_x_randr_primary_output_set(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_3_RET(); + + if ((output) && (_ecore_xcb_randr_root_validate(root))) + xcb_randr_set_output_primary(_ecore_xcb_conn, root, output); +#endif +} + +EAPI Ecore_X_Randr_Mode * +ecore_x_randr_output_modes_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num, + int *npreferred) +{ + Ecore_X_Randr_Mode *modes = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (_randr_version >= RANDR_1_3) + { + modes = + _ecore_xcb_randr_13_output_modes_get(root, output, num, npreferred); + } + else if (_randr_version == RANDR_1_2) + { + modes = + _ecore_xcb_randr_12_output_modes_get(root, output, num, npreferred); + } +#endif + + return modes; +} + +EAPI Eina_Bool +ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None)) + return EINA_FALSE; + + xcb_randr_add_output_mode(_ecore_xcb_conn, output, mode); + return EINA_TRUE; +#endif + return EINA_FALSE; +} + +/* + * @brief get detailed information for a given mode id + * @param root window which's screen's ressources are queried + * @param mode the XID which identifies the mode of interest + * @return mode's detailed information + */ +EAPI Ecore_X_Randr_Mode_Info * +ecore_x_randr_mode_info_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode) +{ + Ecore_X_Randr_Mode_Info *ret = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (!_ecore_xcb_randr_root_validate(root)) return NULL; + + if (_randr_version >= RANDR_1_3) + ret = _ecore_xcb_randr_13_mode_info_get(root, mode); + else if (_randr_version == RANDR_1_2) + ret = _ecore_xcb_randr_12_mode_info_get(root, mode); +#endif + return ret; +} + +/* + * @brief add a mode to a display + * @param root window to which's screen's ressources are added + * @param mode_info + * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode + * adding failed. + * @since 1.2.0 + */ +EAPI Ecore_X_Randr_Mode +ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info) +{ + Ecore_X_Randr_Mode mode = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_create_mode_cookie_t cookie; + xcb_randr_create_mode_reply_t *reply; + xcb_randr_mode_info_t info; + int namelen = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if (!mode_info) return Ecore_X_Randr_None; + if (!_ecore_xcb_randr_root_validate(root)) return Ecore_X_Randr_None; + + namelen = strlen(mode_info->name); + + memset(&info, 0, sizeof(info)); + info.width = mode_info->width; + info.height = mode_info->height; + info.dot_clock = mode_info->dotClock; + info.hsync_start = mode_info->hSyncStart; + info.hsync_end = mode_info->hSyncEnd; + info.htotal = mode_info->hTotal; + info.hskew = mode_info->hSkew; + info.vsync_start = mode_info->vSyncStart; + info.vsync_end = mode_info->vSyncEnd; + info.vtotal = mode_info->vTotal; + info.mode_flags = mode_info->modeFlags; + info.name_len = namelen; + + cookie = + xcb_randr_create_mode_unchecked(_ecore_xcb_conn, root, info, + namelen, mode_info->name); + reply = xcb_randr_create_mode_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + mode = mode_info->xid; + free(reply); + } +#endif + return mode; +} + +/* + * @brief get detailed information for all modes related to a root window's screen + * @param root window which's screen's ressources are queried + * @param num number of modes returned + * @return modes' information + */ +EAPI Ecore_X_Randr_Mode_Info ** +ecore_x_randr_modes_info_get(Ecore_X_Window root, + int *num) +{ + Ecore_X_Randr_Mode_Info **ret = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (num) *num = 0; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (!_ecore_xcb_randr_root_validate(root)) return NULL; + + if (_randr_version >= RANDR_1_3) + ret = _ecore_xcb_randr_13_modes_info_get(root, num); + else if (_randr_version == RANDR_1_2) + ret = _ecore_xcb_randr_12_modes_info_get(root, num); +#endif + return ret; +} + +/** + * @brief Gets the width and hight of a given mode. + * + * @param root Window which's screen's ressources are queried. + * @param mode The mode which's size is to be looked up. + * @param w Width of given mode in px. + * @param h Height of given mode in px. + */ +EAPI void +ecore_x_randr_mode_size_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode, + int *w, + int *h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(); + + if (mode == Ecore_X_Randr_None) return; + + if (_randr_version >= RANDR_1_3) + _ecore_xcb_randr_13_mode_size_get(root, mode, w, h); + else if (_randr_version == RANDR_1_2) + _ecore_xcb_randr_12_mode_size_get(root, mode, w, h); +#endif +} + +/** + * @brief Gets the EDID information of an attached output if available. + * Note that this information is not to be compared using ordinary string + * comparison functions, since it includes 0-bytes. + * + * @param root Window this information should be queried from. + * @param output The XID of the output. + * @param length Length of the byte-array. If @c NULL, request will fail. + * @return EDID information of the output. + */ +EAPI unsigned char * +ecore_x_randr_output_edid_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + unsigned long *length) +{ + unsigned char *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_output_property_cookie_t cookie; + xcb_randr_get_output_property_reply_t *reply; + Ecore_X_Atom atom; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if ((!length) || (!_ecore_xcb_randr_output_validate(root, output))) + return NULL; + + atom = ecore_x_atom_get("EDID"); + cookie = + xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, output, atom, + XCB_GET_PROPERTY_TYPE_ANY, + 0, 100, 0, 0); + reply = + xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if ((reply->type == XCB_ATOM_INTEGER) && (reply->format == 8)) + { + if (length) *length = reply->num_items; + if ((ret = malloc(reply->num_items * sizeof(unsigned char)))) + { + memcpy(ret, xcb_randr_get_output_property_data(reply), + (reply->num_items * sizeof(unsigned char))); + } + } + free(reply); + } +#endif + return ret; +} + +/** + * @brief Gets the outputs which might be used simultaneously on the same CRTC. + * + * @param root Window that this information should be queried for. + * @param output The output which's clones we concern. + * @param num Number of possible clones. + * @return The existing outputs, @c NULL otherwise. + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_output_clones_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num) +{ + Ecore_X_Randr_Output *outputs = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (output == Ecore_X_Randr_None) return NULL; + + if (_randr_version >= RANDR_1_3) + outputs = _ecore_xcb_randr_13_output_clones_get(root, output, num); + else if (_randr_version == RANDR_1_2) + outputs = _ecore_xcb_randr_12_output_clones_get(root, output, num); +#endif + return outputs; +} + +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num) +{ + Ecore_X_Randr_Crtc *crtcs = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (output == Ecore_X_Randr_None) return NULL; + + if (_randr_version >= RANDR_1_3) + crtcs = _ecore_xcb_randr_13_output_possible_crtcs_get(root, output, num); + else if (_randr_version == RANDR_1_2) + crtcs = _ecore_xcb_randr_12_output_possible_crtcs_get(root, output, num); +#endif + return crtcs; +} + +/** + * @brief gets the given output's name as reported by X + * @param root the window which's screen will be queried + * @param output The output name given to be reported. + * @param len length of returned c-string. + * @return name of the output as reported by X + */ +EAPI char * +ecore_x_randr_output_name_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *len) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (output == Ecore_X_Randr_None) return NULL; + + if (_randr_version >= RANDR_1_3) + return _ecore_xcb_randr_13_output_name_get(root, output, len); + else if (_randr_version == RANDR_1_2) + return _ecore_xcb_randr_12_output_name_get(root, output, len); +#endif + + return NULL; +} + +EAPI Ecore_X_Randr_Connection_Status +ecore_x_randr_output_connection_status_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN); + + if (output == Ecore_X_Randr_None) + return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; + + if (_randr_version >= RANDR_1_3) + return _ecore_xcb_randr_13_output_connection_status_get(root, output); + else if (_randr_version == RANDR_1_2) + return _ecore_xcb_randr_12_output_connection_status_get(root, output); +#endif + + return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; +} + +EAPI Ecore_X_Randr_Output * +ecore_x_randr_outputs_get(Ecore_X_Window root, + int *num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (_randr_version >= RANDR_1_3) + return _ecore_xcb_randr_13_outputs_get(root, num); + else if (_randr_version == RANDR_1_2) + return _ecore_xcb_randr_12_outputs_get(root, num); +#endif + + return NULL; +} + +EAPI Ecore_X_Randr_Crtc +ecore_x_randr_output_crtc_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); + + if (output == Ecore_X_Randr_None) return Ecore_X_Randr_None; + + if (_randr_version >= RANDR_1_3) + return _ecore_xcb_randr_13_output_crtc_get(root, output); + else if (_randr_version == RANDR_1_2) + return _ecore_xcb_randr_12_output_crtc_get(root, output); +#endif + + return Ecore_X_Randr_None; +} + +EAPI void +ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w_mm, int *h_mm) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + xcb_timestamp_t timestamp = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (w_mm) *w_mm = 0; + if (h_mm) *h_mm = 0; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(); + + if ((output != Ecore_X_Randr_None) && (_randr_version >= RANDR_1_3)) + { + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + timestamp = reply->config_timestamp; + free(reply); + } + else if ((output != Ecore_X_Randr_None) && (_randr_version == RANDR_1_2)) + { + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + timestamp = reply->config_timestamp; + free(reply); + } + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL); + if (oreply) + { + if (w_mm) *w_mm = oreply->mm_width; + if (h_mm) *h_mm = oreply->mm_height; + free(oreply); + } +#endif +} + +/** + * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is + * auto enabled in it's preferred mode, when it was disabled before. + * + * @param root The root window which's default display will be queried. + * @param crtc The CRTC which's configuration should be altered. + * @param outputs An array of outputs, that should display this CRTC's content. + * @param noutputs Number of outputs in the array of outputs. If set to + * Ecore_X_Randr_Unset, current outputs and number of outputs will be used. If + * set to Ecore_X_Randr_None, CRTC will be disabled. + * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x + * coordinate will be assumed. + * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y + * coordinate will be assumed. + * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the + * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is + * assumed. + * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is + * used, the current mode is assumed. + * @return @c EINA_TRUE if the configuration alteration was successful, + * @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_settings_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + Ecore_X_Randr_Output *outputs, + int noutputs, + int x, + int y, + Ecore_X_Randr_Mode mode, + Ecore_X_Randr_Orientation orientation) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_crtc_info_cookie_t ccookie; + xcb_randr_get_crtc_info_reply_t *creply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + ccookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); + creply = + xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ccookie, NULL); + if (creply) + { + xcb_randr_set_crtc_config_cookie_t scookie; + xcb_randr_set_crtc_config_reply_t *sreply; + + if ((mode == Ecore_X_Randr_None) || + (noutputs == Ecore_X_Randr_None)) + { + outputs = NULL; + noutputs = 0; + } + else if (noutputs == (int)Ecore_X_Randr_Unset) + { + outputs = xcb_randr_get_crtc_info_outputs(creply); + noutputs = creply->num_outputs; + } + if ((int)mode == Ecore_X_Randr_Unset) mode = creply->mode; + if (x < 0) x = creply->x; + if (y < 0) y = creply->y; + if ((int)orientation == Ecore_X_Randr_Unset) + orientation = creply->rotation; + + scookie = + xcb_randr_set_crtc_config_unchecked(_ecore_xcb_conn, + crtc, XCB_CURRENT_TIME, stamp, + x, y, mode, orientation, + noutputs, outputs); + sreply = + xcb_randr_set_crtc_config_reply(_ecore_xcb_conn, scookie, NULL); + if (sreply) + { + ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ? + EINA_TRUE : EINA_FALSE; + free(sreply); + } + free(creply); + } +#endif + + return ret; +} + +/** + * @brief Sets a mode for a CRTC and the outputs attached to it. + * + * @param root The window's screen to be queried + * @param crtc The CRTC which shall be set + * @param outputs Array of outputs which have to be compatible with the mode. If + * @c NULL CRTC will be disabled. + * @param noutputs Number of outputs in array to be used. Use + * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs. + * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be + * disabled. If set to @c -1 the call will fail. + * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE + * otherwise. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_mode_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + Ecore_X_Randr_Output *outputs, + int noutputs, + Ecore_X_Randr_Mode mode) +{ + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if ((int)mode == Ecore_X_Randr_Unset) return ret; + ret = + ecore_x_randr_crtc_settings_set(root, crtc, outputs, noutputs, + Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, + mode, Ecore_X_Randr_Unset); +#endif + + return ret; +} + +/** + * @brief Get the current set mode of a given CRTC + * @param root the window's screen to be queried + * @param crtc the CRTC which's should be queried + * @return currently set mode or - in case parameters are invalid - + * Ecore_X_Randr_Unset + */ +EAPI Ecore_X_Randr_Mode +ecore_x_randr_crtc_mode_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc) +{ + Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset; +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset); + + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); + if (oreply) + { + ret = oreply->mode; + free(oreply); + } +#endif + + return ret; +} + +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc) +{ + Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); + + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); + if (oreply) + { + ret = oreply->rotation; + free(oreply); + } +#endif + + return ret; +} + +EAPI Eina_Bool +ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + Ecore_X_Randr_Orientation orientation) +{ + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if (orientation != Ecore_X_Randr_None) + { + ret = + ecore_x_randr_crtc_settings_set(root, crtc, NULL, + Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, + Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, + orientation); + } +#endif + return ret; +} + +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc) +{ + Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); + + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); + oreply = + xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); + if (oreply) + { + ret = oreply->rotations; + free(oreply); + } +#endif + + return ret; +} + +/* + * @brief get a CRTC's possible outputs. + * @param root the root window which's screen will be queried + * @param num number of possible outputs referenced by given CRTC + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *num) +{ + Ecore_X_Randr_Output *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_possible_outputs; + ret = malloc(sizeof(Ecore_X_Randr_Output) * + oreply->num_possible_outputs); + if (ret) + { + memcpy(ret, xcb_randr_get_crtc_info_possible(oreply), + sizeof(Ecore_X_Randr_Output) * + oreply->num_possible_outputs); + } + free(oreply); + } +#endif + + return ret; +} + +/* + * @brief get all known CRTCs related to a root window's screen + * @param root window which's screen's ressources are queried + * @param num number of CRTCs returned + * @return CRTC IDs + */ +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_crtcs_get(Ecore_X_Window root, + int *num) +{ + Ecore_X_Randr_Crtc *ret = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (_randr_version >= RANDR_1_3) + { + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + if (num) *num = reply->num_crtcs; + ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); + if (ret) + memcpy(ret, xcb_randr_get_screen_resources_current_crtcs(reply), + sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); + free(reply); + } + } + else if (_randr_version == RANDR_1_2) + { + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + if (num) *num = reply->num_crtcs; + ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); + if (ret) + memcpy(ret, xcb_randr_get_screen_resources_crtcs(reply), + sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs); + free(reply); + } + } +#endif + + return ret; +} + +/* + * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead. + * @brief Get the CRTCs, which display a certain window. + * + * @param window Window the displaying CRTCs shall be found for. + * @param num The number of CRTCs displaying the window. + * @return Array of CRTCs that display a certain window. @c NULL if no CRTCs + * was found that displays the specified window. + */ +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_current_crtc_get(Ecore_X_Window window, + int *num) +{ + return ecore_x_randr_window_crtcs_get(window, num); +} + +/* + * @brief Get the CRTCs, which display a certain window. + * + * @param window Window the displaying crtcs shall be found for. + * @param num The number of crtcs displaying the window. + * @return Array of crtcs that display a certain window. @c NULL if no crtcs + * was found that displays the specified window. + * @since 1.2.0 + */ +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_window_crtcs_get(Ecore_X_Window window, + int *num) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Window root; + Eina_Rectangle w_geo, c_geo; + Ecore_X_Randr_Crtc *crtcs, *ret = NULL; + Ecore_X_Randr_Mode mode; + int ncrtcs, i, nret = 0; + xcb_translate_coordinates_cookie_t cookie; + xcb_translate_coordinates_reply_t *trans; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + ecore_x_window_geometry_get(window, &w_geo.x, &w_geo.y, &w_geo.w, &w_geo.h); + + root = ecore_x_window_root_get(window); + crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs); + if (!crtcs) goto _ecore_x_randr_window_crtcs_get_fail; + + /* now get window RELATIVE to root window - thats what matters. */ + cookie = xcb_translate_coordinates(_ecore_xcb_conn, window, root, 0, 0); + trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL); + w_geo.x = trans->dst_x; + w_geo.y = trans->dst_y; + free(trans); + + ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc)); + if (!ret) + { + free(crtcs); + goto _ecore_x_randr_window_crtcs_get_fail; + } + for (i = 0, nret = 0; i < ncrtcs; i++) + { + /* if crtc is not enabled, don't bother about it any further */ + mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]); + if (mode == Ecore_X_Randr_None) continue; + + ecore_x_randr_crtc_geometry_get(root, crtcs[i], &c_geo.x, &c_geo.y, + &c_geo.w, &c_geo.h); + if (eina_rectangles_intersect(&w_geo, &c_geo)) + { + ret[nret] = crtcs[i]; + nret++; + } + } + free(crtcs); + + if (num) *num = nret; + return ret; + +_ecore_x_randr_window_crtcs_get_fail: +#endif + if (num) *num = 0; + return NULL; +} + +/* + * @brief get a CRTC's outputs. + * @param root the root window which's screen will be queried + * @param num number of outputs referenced by given CRTC + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *num) +{ + Ecore_X_Randr_Output *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(NULL); + + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret; + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_outputs; + ret = malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_outputs); + if (ret) + memcpy(ret, xcb_randr_get_crtc_info_outputs(oreply), + sizeof(Ecore_X_Randr_Output) * oreply->num_outputs); + free(oreply); + } +#endif + + return ret; +} + +EAPI void +ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *x, + int *y, + int *w, + int *h) +{ +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(); + + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return; + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL); + if (oreply) + { + if (x) *x = oreply->x; + if (y) *y = oreply->y; + if (w) *w = oreply->width; + if (h) *h = oreply->height; + free(oreply); + } +#endif +} + +/** + * @brief Sets a CRTC relative to another one. + * + * @param root The window on which CRTC's position will be set. + * @param crtc_r1 The CRTC to be positioned. + * @param crtc_r2 The CRTC the position should be relative to. + * @param policy The relation between the crtcs. + * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at + * CRTC2's borders. + * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE + * if repositioning failed or if position of new crtc would be out of given + * screen's min/max bounds. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc_r1, + Ecore_X_Randr_Crtc crtc_r2, + Ecore_X_Randr_Output_Policy policy, + Ecore_X_Randr_Relative_Alignment alignment) +{ +#ifdef ECORE_XCB_RANDR + Eina_Rectangle r1, r2; + int w_max = 0, h_max = 0, cw = 0, ch = 0, xn = -1, yn = -1; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == 0) || + (ecore_x_randr_crtc_mode_get(root, crtc_r2) == 0)) + return EINA_FALSE; + + if ((!_ecore_xcb_randr_crtc_validate(root, crtc_r1) || + (!(crtc_r1 != crtc_r2) && (!_ecore_xcb_randr_crtc_validate(root, crtc_r2))))) + return EINA_FALSE; + + ecore_x_randr_crtc_geometry_get(root, crtc_r1, &r1.x, &r1.y, &r1.w, &r1.h); + ecore_x_randr_crtc_geometry_get(root, crtc_r2, &r2.x, &r2.y, &r2.w, &r2.h); + ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); + ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); + + switch (policy) + { + case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT: + xn = (r2.x + r2.w); + if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) + yn = -1; + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) + yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0))); + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) + yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0)); + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: + xn = (r2.x - r1.w); + if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) + yn = -1; + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) + yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0))); + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) + yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0)); + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_BELOW: + yn = (r2.y + r2.h); + if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) + xn = -1; + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) + xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0))); + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) + xn = ((int)((double)cw / 2.0)); + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: + yn = (r2.y - r1.h); + if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE) + xn = -1; + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL) + xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0))); + else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR) + xn = ((int)((double)cw / 2.0)); + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: + return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2.x, r2.y); + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_NONE: + break; + default: + return EINA_FALSE; + } + + if ((xn == r1.x) && (yn == r1.x)) return EINA_TRUE; + if (((yn + r1.h) > h_max) || ((xn + r1.w) > w_max)) + return EINA_FALSE; + + return ecore_x_randr_crtc_pos_set(root, crtc_r1, xn, yn); +#endif + + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, + const Ecore_X_Randr_Crtc *not_moved, + int num, + int dx, + int dy) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + Ecore_X_Randr_Crtc *crtcs = NULL, *move = NULL; + int i = 0, j = 0, k = 0, n = 0, total = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + if ((num <= 0) || (!not_moved) || (!_ecore_xcb_randr_root_validate(root))) + return EINA_FALSE; + + crtcs = ecore_x_randr_crtcs_get(root, &total); + n = (total - num); + move = malloc(sizeof(Ecore_X_Randr_Crtc) * n); + if (move) + { + for (i = 0, k = 0; (i < total) && (k < n); i++) + { + for (j = 0; j < num; j++) + if (crtcs[i] == not_moved[j]) break; + if (j == num) + move[k++] = crtcs[i]; + } + ret = ecore_x_randr_move_crtcs(root, move, n, dx, dy); + free(move); + free(crtcs); + } +#endif + + return ret; +} + +EAPI void +ecore_x_randr_crtc_pos_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *x, + int *y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(); + + ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL); +#endif +} + +/* + * @brief Sets the position of given CRTC within root window's screen. + * + * @param root The window's screen to be queried. + * @param crtc The CRTC which's position within the mentioned screen is to be + * altered. + * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current + * value will be kept. + * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current + * value will be kept. + * @return @c EINA_TRUE if position could be successfully be altered. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_pos_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int x, + int y) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RANDR + int w = 0, h = 0, nw = 0, nh = 0; + Eina_Rectangle rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + ecore_x_randr_crtc_geometry_get(root, crtc, + &rect.x, &rect.y, &rect.w, &rect.h); + ecore_x_randr_screen_current_size_get(root, &w, &h, NULL, NULL); + if (x < 0) x = rect.x; + if (y < 0) y = rect.y; + if ((x + rect.w) > w) + nw = (x + rect.w); + if ((y + rect.h) > h) + nh = (y + rect.h); + + if ((nw != 0) || (nh != 0)) + { + if (!ecore_x_randr_screen_current_size_set(root, nw, nh, 0, 0)) + return EINA_FALSE; + } + + ret = ecore_x_randr_crtc_settings_set(root, crtc, NULL, -1, x, y, -1, -1); +#endif + + return ret; +} + +EAPI void +ecore_x_randr_crtc_size_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *w, + int *h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(); + ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h); +#endif +} + +EAPI Ecore_X_Randr_Refresh_Rate +ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + Ecore_X_Randr_Mode mode) +{ + Ecore_X_Randr_Refresh_Rate ret = 0.0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(0.0); + + if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return 0.0; + + if (_randr_version >= RANDR_1_3) + { + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + xcb_randr_mode_info_iterator_t miter; + + miter = + xcb_randr_get_screen_resources_current_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + if (minfo->id == mode) + { + if ((minfo->htotal) && (minfo->vtotal)) + { + ret = ((double)minfo->dot_clock / + ((double)minfo->htotal * + (double)minfo->vtotal)); + } + break; + } + xcb_randr_mode_info_next(&miter); + } + free(reply); + } + } + else if (_randr_version == RANDR_1_2) + { + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + xcb_randr_mode_info_iterator_t miter; + + miter = xcb_randr_get_screen_resources_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + if (minfo->id == mode) + { + if ((minfo->htotal) && (minfo->vtotal)) + { + ret = ((double)minfo->dot_clock / + ((double)minfo->htotal * + (double)minfo->vtotal)); + } + break; + } + xcb_randr_mode_info_next(&miter); + } + free(reply); + } + } +#endif + return ret; +} + +/* + * @brief Move given CRTCs belonging to the given root window's screen dx/dy + * pixels relative to their current position. The screen size will be + * automatically adjusted if necessary and possible. + * + * @param root Window which's screen's resources are used. + * @param crtcs List of CRTCs to be moved. + * @param ncrtc Number of CRTCs in array. + * @param dx Amount of pixels the CRTCs should be moved in x direction. + * @param dy Amount of pixels the CRTCs should be moved in y direction. + * @return @c EINA_TRUE if all crtcs could be moved successfully. + */ +EAPI Eina_Bool +ecore_x_randr_move_crtcs(Ecore_X_Window root, + const Ecore_X_Randr_Crtc *crtcs, + int num, + int dx, + int dy) +{ + Eina_Bool ret = EINA_TRUE; +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_crtc_info_reply_t *oreply[num]; + int i = 0, cw = 0, ch = 0; + int mw = 0, mh = 0, nw = 0, nh = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if (!_ecore_xcb_randr_root_validate(root)) return EINA_FALSE; + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh); + ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); + nw = cw; + nh = ch; + + for (i = 0; i < num; i++) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], + stamp); + oreply[i] = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply[i]) + { + if (((oreply[i]->x + dx) < 0) || + ((oreply[i]->y + dy) < 0) || + ((oreply[i]->x + oreply[i]->width + dx) > mw) || + ((oreply[i]->y + oreply[i]->height + dy) > mh)) + { + continue; + } + nw = MAX((int)(oreply[i]->x + oreply[i]->width + dx), nw); + nh = MAX((int)(oreply[i]->y + oreply[i]->height + dy), nh); + } + } + + if ((nw > cw) || (nh > ch)) + { + if (!ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1)) + { + for (i = 0; i < num; i++) + if (oreply[i]) free(oreply[i]); + + return EINA_FALSE; + } + } + + for (i = 0; ((i < num) && (oreply[i])); i++) + { + if (!oreply[i]) continue; + if (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1, + (oreply[i]->x + dx), + (oreply[i]->y + dy), + oreply[i]->mode, + oreply[i]->rotation)) + { + ret = EINA_FALSE; + break; + } + } + + if (i < num) + { + while (i-- >= 0) + { + if (oreply[i]) + ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1, + (oreply[i]->x - dx), + (oreply[i]->y - dy), + oreply[i]->mode, + oreply[i]->rotation); + } + } + + for (i = 0; i < num; i++) + if (oreply[i]) free(oreply[i]); +#endif + + return ret; +} + +/** + * @brief enable event selection. This enables basic interaction with + * output/crtc events and requires RRandR >= 1.2. + * @param win select this window's properties for RandRR events + * @param on enable/disable selecting + */ +EAPI void +ecore_x_randr_events_select(Ecore_X_Window win, + Eina_Bool on) +{ +#ifdef ECORE_XCB_RANDR + uint16_t mask = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + if (on) + { + mask = XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE; + if (_randr_version >= ((1 << 16) | 2)) + { + mask |= (XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE | + XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE | + XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY); + } + } + + xcb_randr_select_input(_ecore_xcb_conn, win, mask); +#endif +} + +/** + * @brief removes unused screen space. The most upper left CRTC is set to 0x0 + * and all other CRTCs dx,dy respectively. + * @param root the window's screen which will be reset. + */ +EAPI void +ecore_x_randr_screen_reset(Ecore_X_Window root) +{ +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + Ecore_X_Randr_Crtc *crtcs = NULL; + int total = 0, i = 0, w = 0, h = 0; + int dx = 100000, dy = 100000, num = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + if (!_ecore_xcb_randr_root_validate(root)) return; + crtcs = ecore_x_randr_crtcs_get(root, &total); + + if (_randr_version >= RANDR_1_3) + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + else if (_randr_version == RANDR_1_2) + stamp = _ecore_xcb_randr_12_get_resource_timestamp(root); + + /* I hate declaring variables inside code like this, but we need the + * value of 'total' before we can */ + Ecore_X_Randr_Crtc enabled[total]; + + for (i = 0; i < total; i++) + { + xcb_randr_get_crtc_info_cookie_t ocookie; + xcb_randr_get_crtc_info_reply_t *oreply; + + ocookie = + xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], stamp); + oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (!oreply) continue; + if ((oreply->mode <= 0) || (oreply->num_outputs == 0)) + { + free(oreply); + continue; + } + + enabled[num++] = crtcs[i]; + if ((int)(oreply->x + oreply->width) > w) + w = (oreply->x + oreply->width); + if ((int)(oreply->y + oreply->height) > h) + h = (oreply->y + oreply->height); + + if (oreply->x < dx) dx = oreply->x; + if (oreply->y < dy) dy = oreply->y; + + free(oreply); + } + free(crtcs); + + if ((dx > 0) || (dy > 0)) + { + if (ecore_x_randr_move_crtcs(root, enabled, num, -dx, -dy)) + { + w -= dx; + h -= dy; + } + } + + ecore_x_randr_screen_current_size_set(root, w, h, -1, -1); +#endif +} + +/* + * @param root window which's screen will be queried + * @param wmin minimum width the screen can be set to + * @param hmin minimum height the screen can be set to + * @param wmax maximum width the screen can be set to + * @param hmax maximum height the screen can be set to + */ +EAPI void +ecore_x_randr_screen_size_range_get(Ecore_X_Window root, + int *minw, + int *minh, + int *maxw, + int *maxh) +{ +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_size_range_cookie_t cookie; + xcb_randr_get_screen_size_range_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(); + + cookie = xcb_randr_get_screen_size_range_unchecked(_ecore_xcb_conn, root); + reply = xcb_randr_get_screen_size_range_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (minw) *minw = reply->min_width; + if (minh) *minh = reply->min_height; + if (maxw) *maxw = reply->max_width; + if (maxh) *maxh = reply->max_height; + free(reply); + } +#endif +} + +/* + * @param w width of screen in px + * @param h height of screen in px + */ +EAPI void +ecore_x_randr_screen_current_size_get(Ecore_X_Window root, + int *w, + int *h, + int *w_mm, + int *h_mm) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Randr_Screen scr = 0; + xcb_screen_t *s; +# define RANDR_VALIDATE_ROOT(screen, root) \ + ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(); + + if (!RANDR_VALIDATE_ROOT(scr, root)) return; + + s = ecore_x_screen_get(scr); + if (w) *w = s->width_in_pixels; + if (h) *h = s->height_in_pixels; + if (w_mm) *w_mm = s->width_in_millimeters; + if (h_mm) *h_mm = s->height_in_millimeters; +#endif +} + +/* + * @param root Window which's screen's size should be set. If invalid (e.g. + * @c NULL) no action is taken. + * @param w Width in px the screen should be set to. If out of valid + * boundaries, current value is assumed. + * @param h Height in px the screen should be set to. If out of valid + * boundaries, current value is assumed. + * @param w_mm Width in mm the screen should be set to. If @c 0, current + * aspect is assumed. + * @param h_mm Height in mm the screen should be set to. If @c 0, current + * aspect is assumed. + * @return @c EINA_TRUE if request was successfully sent or screen is already + * in requested size, @c EINA_FALSE if parameters are invalid. + */ +EAPI Eina_Bool +ecore_x_randr_screen_current_size_set(Ecore_X_Window root, + int w, + int h, + int w_mm, + int h_mm) +{ + Eina_Bool ret = EINA_TRUE; +#ifdef ECORE_XCB_RANDR + Ecore_X_Randr_Screen scr; + int wc = 0, hc = 0, w_mm_c = 0, h_mm_c = 0; + int mw = 0, mh = 0, xw = 0, xh = 0; +# define RANDR_VALIDATE_ROOT(screen, root) \ + ((screen == _ecore_xcb_randr_root_to_screen(root)) != -1) +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if (!RANDR_VALIDATE_ROOT(scr, root)) return EINA_FALSE; + ecore_x_randr_screen_current_size_get(root, &wc, &hc, &w_mm_c, &h_mm_c); + if ((w == wc) && (h == hc) && (w_mm == w_mm_c) && (h_mm == h_mm_c)) + return EINA_TRUE; + ecore_x_randr_screen_size_range_get(root, &mw, &mh, &xw, &xh); + if (((w != 1) && ((w < mw) || (w > xw))) || + ((h != -1) && ((h < mh) || (h > xh)))) return EINA_FALSE; + + if (w <= 0) + w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; + if (h <= 0) + h = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; + + /* NB: Hmmmm, xlib version divides w_mm by width ... that seems wrong */ + if (w_mm <= 0) + w_mm = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_millimeters; + if (h_mm <= 0) + h_mm = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_millimeters; + + xcb_randr_set_screen_size(_ecore_xcb_conn, root, w, h, w_mm, h_mm); +#endif + + return ret; +} + +/* + * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead. + * @brief Get the outputs, which display a certain window. + * + * @param window Window the displaying outputs shall be found for. + * @param num The number of outputs displaying the window. + * @return Array of outputs that display a certain window. @c NULL if no + * outputs was found that displays the specified window. + */ + +Ecore_X_Randr_Output * +ecore_x_randr_current_output_get(Ecore_X_Window window, + int *num) +{ + return ecore_x_randr_window_outputs_get(window, num); +} + +/* + * @brief Get the outputs, which display a certain window. + * + * @param window Window the displaying outputs shall be found for. + * @param num The number of outputs displaying the window. + * @return Array of outputs that display a certain window. @c NULL if no + * outputs was found that displays the specified window. + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_window_outputs_get(Ecore_X_Window window, + int *num) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Window root; + Ecore_X_Randr_Crtc *crtcs; + Ecore_X_Randr_Output *outputs, *ret = NULL, *tret; + int ncrtcs, noutputs, i, nret = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (num) *num = 0; + +#ifdef ECORE_XCB_RANDR + if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail; + + root = ecore_x_window_root_get(window); + if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs))) + goto _ecore_x_randr_current_output_get_fail; + + for (i = 0, nret = 0; i < ncrtcs; i++) + { + + outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i], + &noutputs); + if (!outputs) + goto _ecore_x_randr_current_output_get_fail_free; + tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output))); + if (!tret) goto _ecore_x_randr_current_output_get_fail_free; + ret = tret; + memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output))); + nret += noutputs; + free(outputs); + outputs = NULL; + } + free(crtcs); + + if (num) + *num = nret; + + return ret; + +_ecore_x_randr_current_output_get_fail_free: + free(outputs); + free(crtcs); + free(ret); +_ecore_x_randr_current_output_get_fail: +#endif + if (num) *num = 0; + return NULL; +} + +/* + * @brief get the backlight level of the given output + * @param root window which's screen should be queried + * @param output from which the backlight level should be retrieved + * @return the backlight level + */ +EAPI double +ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Atom _backlight; + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; + xcb_randr_get_output_property_cookie_t cookie; + xcb_randr_get_output_property_reply_t *reply; + xcb_randr_query_output_property_cookie_t qcookie; + xcb_randr_query_output_property_reply_t *qreply; + double dvalue; + long value, max, min; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(-1); + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, + strlen("Backlight"), "Backlight"); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + + if (!areply) + { + ERR("Backlight property is not suppported on this server or driver"); + return -1; + } + else + { + _backlight = areply->atom; + free(areply); + } + + if (!_ecore_xcb_randr_output_validate(root, output)) + { + ERR("Invalid output"); + return -1; + } + + cookie = + xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, + output, _backlight, + XCB_ATOM_NONE, 0, 4, 0, 0); + reply = + xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) + { + WRN("Backlight not supported on this output"); + return -1; + } + + if ((reply->format != 32) || (reply->num_items != 1) || + (reply->type != XCB_ATOM_INTEGER)) + { + free(reply); + return -1; + } + + value = *((long *)xcb_randr_get_output_property_data(reply)); + free (reply); + + /* I have the current value of the backlight */ + /* Now retrieve the min and max intensities of the output */ + qcookie = + xcb_randr_query_output_property_unchecked(_ecore_xcb_conn, + output, _backlight); + qreply = + xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL); + if (qreply) + { + dvalue = -1; + if ((qreply->range) && + (xcb_randr_query_output_property_valid_values_length(qreply) == 2)) + { + int32_t *vals; + + vals = xcb_randr_query_output_property_valid_values(qreply); + /* finally convert the current value in the interval [0..1] */ + min = vals[0]; + max = vals[1]; + dvalue = ((double)(value - min)) / ((double)(max - min)); + } + free(qreply); + return dvalue; + } +#endif + return -1; +} + +/* + * @brief Set the backlight level of a given output. + * + * @param root Window which's screen should be queried. + * @param output That should be set. + * @param level For which the backlight should be set. + * @return @c EINA_TRUE in case of success. + */ +EAPI Eina_Bool +ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, + Ecore_X_Randr_Output output, + double level) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Atom _backlight; + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; + xcb_randr_query_output_property_cookie_t qcookie; + xcb_randr_query_output_property_reply_t *qreply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if ((level < 0) || (level > 1)) + { + ERR("Backlight level should be between 0 and 1"); + return EINA_FALSE; + } + + if (!_ecore_xcb_randr_output_validate(root, output)) + { + ERR("Wrong output value"); + return EINA_FALSE; + } + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, + strlen("Backlight"), "Backlight"); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + if (!areply) + { + WRN("Backlight property is not suppported on this server or driver"); + return EINA_FALSE; + } + else + { + _backlight = areply->atom; + free(areply); + } + + qcookie = + xcb_randr_query_output_property_unchecked(_ecore_xcb_conn, + output, _backlight); + qreply = + xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL); + if (qreply) + { + if ((qreply->range) && (qreply->length == 2)) + { + int32_t *vals; + double min, max, tmp; + long n; + + vals = xcb_randr_query_output_property_valid_values(qreply); + min = vals[0]; + max = vals[1]; + tmp = (level * (max - min)) + min; + n = tmp; + if (n > max) n = max; + if (n < min) n = min; + xcb_randr_change_output_property(_ecore_xcb_conn, output, + _backlight, XCB_ATOM_INTEGER, + 32, XCB_PROP_MODE_REPLACE, + 1, (unsigned char *)&n); + ecore_x_flush(); // needed + } + + free(qreply); + return EINA_TRUE; + } +#endif + return EINA_FALSE; +} + +/* + * @brief Check if a backlight is available. + * + * @return Whether a backlight is available. + */ +EAPI Eina_Bool +ecore_x_randr_output_backlight_available(void) +{ +#ifdef ECORE_XCB_RANDR + Ecore_X_Atom _backlight; + xcb_intern_atom_cookie_t acookie; + xcb_intern_atom_reply_t *areply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + acookie = + xcb_intern_atom_unchecked(_ecore_xcb_conn, 1, + strlen("Backlight"), "Backlight"); + areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL); + + if (!areply) + { + ERR("Backlight property is not suppported on this server or driver"); + return EINA_FALSE; + } + else + { + _backlight = areply->atom; + free(areply); + return EINA_TRUE; + } +#endif + return EINA_FALSE; +} + +EAPI int +ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length) +{ + if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) && + (ecore_x_randr_edid_has_valid_header(edid, edid_length))) + return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) | + edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR]; + return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; +} + +EAPI char * +ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length) +{ + unsigned char *block = NULL; + int version = 0; + + version = ecore_x_randr_edid_version_get(edid, edid_length); + if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; + + _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) + { + if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc) + { + char *name, *p; + const char *edid_name; + + edid_name = (const char *)block + + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; + name = + malloc(sizeof(char) * + _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); + if (!name) return NULL; + + strncpy(name, edid_name, + (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); + name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; + for (p = name; *p; p++) + if ((*p < ' ') || (*p > '~')) *p = 0; + + return name; + } + } + return NULL; +} + +EAPI Eina_Bool +ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length) +{ + const unsigned char header[] = + { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 + }; + + if ((!edid) || (edid_length < 8)) return EINA_FALSE; + if (!memcmp(edid, header, 8)) return EINA_TRUE; + return EINA_FALSE; +} + +/* local functions */ +static Eina_Bool +_ecore_xcb_randr_output_validate(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if ((output) && (_ecore_xcb_randr_root_validate(root))) + { + if (_randr_version >= RANDR_1_3) + { + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + int len = 0, i = 0; + xcb_randr_output_t *outputs; + + len = + xcb_randr_get_screen_resources_current_outputs_length(reply); + outputs = + xcb_randr_get_screen_resources_current_outputs(reply); + for (i = 0; i < len; i++) + { + if (outputs[i] == output) + { + ret = EINA_TRUE; + break; + } + } + free(reply); + } + } + else if (_randr_version == RANDR_1_2) + { + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + int len = 0, i = 0; + xcb_randr_output_t *outputs; + + len = xcb_randr_get_screen_resources_outputs_length(reply); + outputs = xcb_randr_get_screen_resources_outputs(reply); + for (i = 0; i < len; i++) + { + if (outputs[i] == output) + { + ret = EINA_TRUE; + break; + } + } + free(reply); + } + } + } +#endif + return ret; +} + +/** + * @brief Validates a CRTC for a given root window's screen. + * + * @param root The window which's default display will be queried. + * @param crtc The CRTC to be validated. + * @return In case it is found @c EINA_TRUE will be returned, else + * @c EINA_FALSE is returned. + */ +static Eina_Bool +_ecore_xcb_randr_crtc_validate(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc) +{ + Eina_Bool ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if (((int)crtc == Ecore_X_Randr_None) || ((int)crtc == Ecore_X_Randr_Unset)) + return ret; + + if ((crtc) && (_ecore_xcb_randr_root_validate(root))) + { + if (_randr_version >= RANDR_1_3) + { + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + int i = 0; + xcb_randr_crtc_t *crtcs; + + crtcs = xcb_randr_get_screen_resources_current_crtcs(reply); + for (i = 0; i < reply->num_crtcs; i++) + { + if (crtcs[i] == crtc) + { + ret = EINA_TRUE; + break; + } + } + free(reply); + } + } + else if (_randr_version == RANDR_1_2) + { + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + int i = 0; + xcb_randr_crtc_t *crtcs; + + crtcs = xcb_randr_get_screen_resources_crtcs(reply); + for (i = 0; i < reply->num_crtcs; i++) + { + if (crtcs[i] == crtc) + { + ret = EINA_TRUE; + break; + } + } + free(reply); + } + } + } +#endif + + return ret; +} + +static Ecore_X_Randr_Mode * +_ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num, + int *npreferred) +{ + Ecore_X_Randr_Mode *modes = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_modes; + if (npreferred) *npreferred = oreply->num_preferred; + + modes = malloc(sizeof(Ecore_X_Randr_Mode) * + oreply->num_modes); + if (modes) + { + xcb_randr_mode_t *rmodes; + int len = 0; + + len = xcb_randr_get_output_info_modes_length(oreply); + rmodes = xcb_randr_get_output_info_modes(oreply); + memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len); + } + free(oreply); + } + free(reply); + } +#endif + return modes; +} + +static Ecore_X_Randr_Mode * +_ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num, + int *npreferred) +{ + Ecore_X_Randr_Mode *modes = NULL; +#ifdef ECORE_XCB_RANDR + xcb_timestamp_t stamp = 0; + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + stamp = _ecore_xcb_randr_13_get_resource_timestamp(root); + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, stamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_modes; + if (npreferred) *npreferred = oreply->num_preferred; + + modes = malloc(sizeof(Ecore_X_Randr_Mode) * oreply->num_modes); + if (modes) + { + xcb_randr_mode_t *rmodes; + int len = 0; + + len = xcb_randr_get_output_info_modes_length(oreply); + rmodes = xcb_randr_get_output_info_modes(oreply); + memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len); + } + free(oreply); + } +#endif + return modes; +} + +static Ecore_X_Randr_Mode_Info * +_ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode) +{ + Ecore_X_Randr_Mode_Info *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) + { + uint8_t *nbuf; + xcb_randr_mode_info_iterator_t miter; + + nbuf = xcb_randr_get_screen_resources_names(reply); + miter = xcb_randr_get_screen_resources_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + nbuf += minfo->name_len; + + if (minfo->id == mode) + { + ret->xid = minfo->id; + ret->width = minfo->width; + ret->height = minfo->height; + ret->dotClock = minfo->dot_clock; + ret->hSyncStart = minfo->hsync_start; + ret->hSyncEnd = minfo->hsync_end; + ret->hTotal = minfo->htotal; + ret->vSyncStart = minfo->vsync_start; + ret->vSyncEnd = minfo->vsync_end; + ret->vTotal = minfo->vtotal; + ret->modeFlags = minfo->mode_flags; + + ret->name = NULL; + ret->nameLength = minfo->name_len; + if (ret->nameLength > 0) + { + ret->name = malloc(ret->nameLength + 1); + if (ret->name) + memcpy(ret->name, nbuf, ret->nameLength + 1); + } + + break; + } + xcb_randr_mode_info_next(&miter); + } + } + + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Mode_Info * +_ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode) +{ + Ecore_X_Randr_Mode_Info *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) + { + uint8_t *nbuf; + xcb_randr_mode_info_iterator_t miter; + + nbuf = xcb_randr_get_screen_resources_current_names(reply); + miter = + xcb_randr_get_screen_resources_current_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + nbuf += minfo->name_len; + + if (minfo->id == mode) + { + ret->xid = minfo->id; + ret->width = minfo->width; + ret->height = minfo->height; + ret->dotClock = minfo->dot_clock; + ret->hSyncStart = minfo->hsync_start; + ret->hSyncEnd = minfo->hsync_end; + ret->hTotal = minfo->htotal; + ret->vSyncStart = minfo->vsync_start; + ret->vSyncEnd = minfo->vsync_end; + ret->vTotal = minfo->vtotal; + ret->modeFlags = minfo->mode_flags; + + ret->name = NULL; + ret->nameLength = minfo->name_len; + if (ret->nameLength > 0) + { + ret->name = malloc(ret->nameLength + 1); + if (ret->name) + memcpy(ret->name, nbuf, ret->nameLength + 1); + } + + break; + } + xcb_randr_mode_info_next(&miter); + } + } + + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Mode_Info ** +_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root, + int *num) +{ + Ecore_X_Randr_Mode_Info **ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + if (num) *num = reply->num_modes; + ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes); + if (ret) + { + xcb_randr_mode_info_iterator_t miter; + int i = 0; + uint8_t *nbuf; + + nbuf = xcb_randr_get_screen_resources_names(reply); + miter = xcb_randr_get_screen_resources_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + nbuf += minfo->name_len; + if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) + { + ret[i]->xid = minfo->id; + ret[i]->width = minfo->width; + ret[i]->height = minfo->height; + ret[i]->dotClock = minfo->dot_clock; + ret[i]->hSyncStart = minfo->hsync_start; + ret[i]->hSyncEnd = minfo->hsync_end; + ret[i]->hTotal = minfo->htotal; + ret[i]->vSyncStart = minfo->vsync_start; + ret[i]->vSyncEnd = minfo->vsync_end; + ret[i]->vTotal = minfo->vtotal; + ret[i]->modeFlags = minfo->mode_flags; + + ret[i]->name = NULL; + ret[i]->nameLength = minfo->name_len; + if (ret[i]->nameLength > 0) + { + ret[i]->name = malloc(ret[i]->nameLength + 1); + if (ret[i]->name) + memcpy(ret[i]->name, nbuf, + ret[i]->nameLength + 1); + } + } + else + { + while (i > 0) + free(ret[--i]); + free(ret); + ret = NULL; + break; + } + i++; + xcb_randr_mode_info_next(&miter); + } + } + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Mode_Info ** +_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root, + int *num) +{ + Ecore_X_Randr_Mode_Info **ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + if (num) *num = reply->num_modes; + ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes); + if (ret) + { + xcb_randr_mode_info_iterator_t miter; + int i = 0; + uint8_t *nbuf; + + nbuf = xcb_randr_get_screen_resources_current_names(reply); + miter = + xcb_randr_get_screen_resources_current_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + nbuf += minfo->name_len; + if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) + { + ret[i]->xid = minfo->id; + ret[i]->width = minfo->width; + ret[i]->height = minfo->height; + ret[i]->dotClock = minfo->dot_clock; + ret[i]->hSyncStart = minfo->hsync_start; + ret[i]->hSyncEnd = minfo->hsync_end; + ret[i]->hTotal = minfo->htotal; + ret[i]->vSyncStart = minfo->vsync_start; + ret[i]->vSyncEnd = minfo->vsync_end; + ret[i]->vTotal = minfo->vtotal; + ret[i]->modeFlags = minfo->mode_flags; + + ret[i]->name = NULL; + ret[i]->nameLength = minfo->name_len; + if (ret[i]->nameLength > 0) + { + ret[i]->name = malloc(ret[i]->nameLength + 1); + if (ret[i]->name) + memcpy(ret[i]->name, nbuf, + ret[i]->nameLength + 1); + } + } + else + { + while (i > 0) + free(ret[--i]); + free(ret); + ret = NULL; + break; + } + i++; + xcb_randr_mode_info_next(&miter); + } + } + free(reply); + } +#endif + return ret; +} + +static void +_ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode, + int *w, + int *h) +{ + if (w) *w = 0; + if (h) *h = 0; + +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + xcb_randr_mode_info_iterator_t miter; + + miter = xcb_randr_get_screen_resources_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + if (minfo->id == mode) + { + if (w) *w = minfo->width; + if (h) *h = minfo->height; + break; + } + xcb_randr_mode_info_next(&miter); + } + free(reply); + } +#endif +} + +static void +_ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode, + int *w, + int *h) +{ + if (w) *w = 0; + if (h) *h = 0; + +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + xcb_randr_mode_info_iterator_t miter; + + miter = xcb_randr_get_screen_resources_current_modes_iterator(reply); + while (miter.rem) + { + xcb_randr_mode_info_t *minfo; + + minfo = miter.data; + if (minfo->id == mode) + { + if (w) *w = minfo->width; + if (h) *h = minfo->height; + break; + } + xcb_randr_mode_info_next(&miter); + } + free(reply); + } +#endif +} + +static Ecore_X_Randr_Output * +_ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num) +{ + Ecore_X_Randr_Output *outputs = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_clones; + + outputs = + malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones); + if (outputs) + { + memcpy(outputs, xcb_randr_get_output_info_clones(oreply), + sizeof(Ecore_X_Randr_Output) * oreply->num_clones); + } + free(oreply); + } + free(reply); + } +#endif + return outputs; +} + +static Ecore_X_Randr_Output * +_ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num) +{ + Ecore_X_Randr_Output *outputs = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_clones; + + outputs = + malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones); + if (outputs) + { + memcpy(outputs, xcb_randr_get_output_info_clones(oreply), + sizeof(Ecore_X_Randr_Output) * oreply->num_clones); + } + free(oreply); + } + free(reply); + } +#endif + return outputs; +} + +static Ecore_X_Randr_Crtc * +_ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num) +{ + Ecore_X_Randr_Crtc *crtcs = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_crtcs; + + crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); + if (crtcs) + { + memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply), + sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); + } + free(oreply); + } + free(reply); + } +#endif + return crtcs; +} + +static Ecore_X_Randr_Crtc * +_ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num) +{ + Ecore_X_Randr_Crtc *crtcs = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + if (num) *num = oreply->num_crtcs; + + crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); + if (crtcs) + { + memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply), + sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs); + } + free(oreply); + } + free(reply); + } +#endif + return crtcs; +} + +static char * +_ecore_xcb_randr_12_output_name_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *len) +{ + char *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + uint8_t *nbuf; + + nbuf = xcb_randr_get_output_info_name(oreply); + nbuf += oreply->name_len; + + if (len) *len = oreply->name_len; + if (oreply->name_len > 0) + { + ret = malloc(oreply->name_len + 1); + if (ret) + memcpy(ret, nbuf, oreply->name_len + 1); + } + + free(oreply); + } + free(reply); + } +#endif + return ret; +} + +static char * +_ecore_xcb_randr_13_output_name_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *len) +{ + char *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + uint8_t *nbuf; + + nbuf = xcb_randr_get_output_info_name(oreply); + nbuf += oreply->name_len; + + if (len) *len = oreply->name_len; + if (oreply->name_len > 0) + { + ret = malloc(oreply->name_len + 1); + if (ret) + memcpy(ret, nbuf, oreply->name_len + 1); + } + + free(oreply); + } + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Connection_Status +_ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ + Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + ret = oreply->connection; + free(oreply); + } + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Connection_Status +_ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ + Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + ret = oreply->connection; + free(oreply); + } + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Output * +_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root, + int *num) +{ + Ecore_X_Randr_Output *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + if (num) *num = reply->num_outputs; + ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs); + if (ret) + memcpy(ret, xcb_randr_get_screen_resources_outputs(reply), + sizeof(Ecore_X_Randr_Output) * reply->num_outputs); + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Output * +_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root, + int *num) +{ + Ecore_X_Randr_Output *ret = NULL; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + if (num) *num = reply->num_outputs; + ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs); + if (ret) + memcpy(ret, xcb_randr_get_screen_resources_current_outputs(reply), + sizeof(Ecore_X_Randr_Output) * reply->num_outputs); + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Crtc +_ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ + Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + ret = oreply->crtc; + free(oreply); + } + free(reply); + } +#endif + return ret; +} + +static Ecore_X_Randr_Crtc +_ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ + Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(root); + if (reply) + { + xcb_randr_get_output_info_cookie_t ocookie; + xcb_randr_get_output_info_reply_t *oreply; + + ocookie = + xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, + reply->config_timestamp); + oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, + ocookie, NULL); + if (oreply) + { + ret = oreply->crtc; + free(oreply); + } + free(reply); + } +#endif + return ret; +} + +static xcb_randr_get_screen_resources_reply_t * +_ecore_xcb_randr_12_get_resources(Ecore_X_Window win) +{ + xcb_randr_get_screen_resources_cookie_t cookie; + xcb_randr_get_screen_resources_reply_t *reply; + + cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, win); + reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL); + return reply; +} + +static xcb_randr_get_screen_resources_current_reply_t * +_ecore_xcb_randr_13_get_resources(Ecore_X_Window win) +{ + xcb_randr_get_screen_resources_current_cookie_t cookie; + xcb_randr_get_screen_resources_current_reply_t *reply; + + cookie = + xcb_randr_get_screen_resources_current_unchecked(_ecore_xcb_conn, win); + reply = + xcb_randr_get_screen_resources_current_reply(_ecore_xcb_conn, + cookie, NULL); + return reply; +} + +static xcb_timestamp_t +_ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win) +{ + xcb_timestamp_t stamp = 0; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_reply_t *reply; + + reply = _ecore_xcb_randr_12_get_resources(win); + stamp = reply->config_timestamp; + free(reply); +#endif + return stamp; +} + +static xcb_timestamp_t +_ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win) +{ + xcb_timestamp_t stamp = 0; +#ifdef ECORE_XCB_RANDR + xcb_randr_get_screen_resources_current_reply_t *reply; + + reply = _ecore_xcb_randr_13_get_resources(win); + stamp = reply->config_timestamp; + free(reply); +#endif + return stamp; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_region.c b/src/lib/ecore_x/xcb/ecore_xcb_region.c new file mode 100644 index 0000000000..a221d8fc37 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_region.c @@ -0,0 +1,159 @@ +#include "ecore_xcb_private.h" +#include + +/* + * [ ] XPolygonRegion + * [ ] XShrinkRegion + * [ ] XClipBox + * [ ] XXorRegion + */ + +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 Eina_Bool +ecore_x_xregion_set(Ecore_X_XRegion *region, + Ecore_X_GC gc) +{ + xcb_rectangle_t *rects; + pixman_box16_t *boxes; + int num = 0, i = 0; + + CHECK_XCB_CONN; + + if (!region) return EINA_FALSE; + + boxes = pixman_region_rectangles((pixman_region16_t *)region, &num); + if ((!boxes) || (num == 0)) return EINA_FALSE; + + rects = (xcb_rectangle_t *)malloc(sizeof(xcb_rectangle_t) * num); + if (!rects) return EINA_FALSE; + + 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_xcb_conn, XCB_CLIP_ORDERING_YX_BANDED, + gc, 0, 0, num, rects); + +// ecore_x_flush(); + return EINA_TRUE; +} + +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 Eina_Bool +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 Eina_Bool +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 Eina_Bool +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 Eina_Bool +ecore_x_xregion_subtract(Ecore_X_XRegion *dst, + Ecore_X_XRegion *rm, + Ecore_X_XRegion *rs) +{ + return pixman_region_subtract((pixman_region16_t *)dst, + (pixman_region16_t *)rm, + (pixman_region16_t *)rs); +} + +EAPI Eina_Bool +ecore_x_xregion_is_empty(Ecore_X_XRegion *region) +{ + if (!region) return EINA_TRUE; + + return !pixman_region_not_empty((pixman_region16_t *)region); +} + +EAPI Eina_Bool +ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, + Ecore_X_XRegion *r2) +{ + if ((!r1) || (!r2)) return EINA_FALSE; + + return pixman_region_equal((pixman_region16_t *)r1, + (pixman_region16_t *)r2); +} + +EAPI Eina_Bool +ecore_x_xregion_point_contain(Ecore_X_XRegion *region, + int x, + int y) +{ + if (!region) return EINA_FALSE; + + return pixman_region_contains_point((pixman_region16_t *)region, x, y, NULL); +} + +EAPI Eina_Bool +ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, + Ecore_X_Rectangle *rect) +{ + pixman_box16_t box; + + if ((!region) || (!rect)) return EINA_FALSE; + + 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); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_render.c b/src/lib/ecore_x/xcb/ecore_xcb_render.c new file mode 100644 index 0000000000..f36b4d2489 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_render.c @@ -0,0 +1,225 @@ +#include "ecore_xcb_private.h" +#include // for isupper/tolower +#ifdef ECORE_XCB_RENDER +# include +# include +#endif + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_render_parse_boolean(char *v); + +/* local variables */ +static Eina_Bool _render_avail = EINA_FALSE; +static Eina_Bool _render_argb = EINA_FALSE; +static Eina_Bool _render_anim = EINA_FALSE; + +void +_ecore_xcb_render_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RENDER + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_render_id); +#endif +} + +void +_ecore_xcb_render_finalize(void) +{ +#ifdef ECORE_XCB_RENDER + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_RENDER + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_render_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_render_query_version_cookie_t cookie; + xcb_render_query_version_reply_t *reply; + + cookie = + xcb_render_query_version_unchecked(_ecore_xcb_conn, + XCB_RENDER_MAJOR_VERSION, + XCB_RENDER_MINOR_VERSION); + reply = xcb_render_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { +// if ((reply->major_version >= XCB_RENDER_MAJOR_VERSION) && + if (reply->minor_version >= XCB_RENDER_MINOR_VERSION) + { + char *v = NULL; + + _render_avail = EINA_TRUE; + _ecore_xcb_xdefaults_init(); + if ((reply->major_version > 0) || (reply->minor_version >= 5)) + { + _render_argb = EINA_TRUE; + v = getenv("XCURSOR_CORE"); + if (!v) + v = _ecore_xcb_xdefaults_string_get("Xcursor", "core"); + if ((v) && (_ecore_xcb_render_parse_boolean(v))) + _render_argb = EINA_FALSE; + } + if ((_render_argb) && + ((reply->major_version > 0) || (reply->minor_version >= 8))) + { + _render_anim = EINA_TRUE; + v = getenv("XCURSOR_ANIM"); + if (!v) + v = _ecore_xcb_xdefaults_string_get("Xcursor", "anim"); + if ((v) && (_ecore_xcb_render_parse_boolean(v))) + _render_anim = EINA_FALSE; + } + _ecore_xcb_xdefaults_shutdown(); + } + } + free(reply); + } +#endif +} + +Eina_Bool +_ecore_xcb_render_avail_get(void) +{ + return _render_avail; +} + +Eina_Bool +_ecore_xcb_render_argb_get(void) +{ + return _render_argb; +} + +Eina_Bool +_ecore_xcb_render_anim_get(void) +{ + return _render_anim; +} + +Eina_Bool +_ecore_xcb_render_visual_supports_alpha(Ecore_X_Visual visual) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef ECORE_XCB_RENDER + const xcb_render_query_pict_formats_reply_t *reply; + xcb_render_pictvisual_t *vis; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!visual) return EINA_FALSE; + if (!_render_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_RENDER + reply = xcb_render_util_query_formats(_ecore_xcb_conn); + if (!reply) return EINA_FALSE; + + vis = + xcb_render_util_find_visual_format(reply, + ((xcb_visualtype_t *)visual)->visual_id); + if (vis) + { + xcb_render_pictforminfo_t temp; + xcb_render_pictforminfo_t *format; + + temp.id = vis->format; + format = + xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID, &temp, 0); + + if ((format->type == XCB_RENDER_PICT_TYPE_DIRECT) && + (format->direct.alpha_mask)) + ret = EINA_TRUE; + } + +#endif + + return ret; +} + +uint32_t +_ecore_xcb_render_find_visual_id(int type, + Eina_Bool check_alpha) +{ +#ifdef ECORE_XCB_RENDER + const xcb_render_query_pict_formats_reply_t *reply; + xcb_render_pictvisual_t *visual = NULL; + xcb_render_pictscreen_iterator_t screens; + xcb_render_pictdepth_iterator_t depths; + xcb_render_pictvisual_iterator_t visuals; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_render_avail) return 0; + +#ifdef ECORE_XCB_RENDER + reply = xcb_render_util_query_formats(_ecore_xcb_conn); + if (!reply) return 0; + + for (screens = xcb_render_query_pict_formats_screens_iterator(reply); + screens.rem; xcb_render_pictscreen_next(&screens)) + { + for (depths = xcb_render_pictscreen_depths_iterator(screens.data); + depths.rem; xcb_render_pictdepth_next(&depths)) + { + for (visuals = xcb_render_pictdepth_visuals_iterator(depths.data); + visuals.rem; xcb_render_pictvisual_next(&visuals)) + { + xcb_render_pictforminfo_t temp; + xcb_render_pictforminfo_t *format; + + visual = visuals.data; + temp.id = visual->format; + + format = + xcb_render_util_find_format(reply, XCB_PICT_FORMAT_ID, + &temp, 0); + if (!format) continue; + if (format->type == type) + { + if (check_alpha) + { + if (format->direct.alpha_mask) + return visual->visual; + } + else + return visual->visual; + } + } + } + } +#endif + + return 0; +} + +/* local function prototypes */ +static Eina_Bool +_ecore_xcb_render_parse_boolean(char *v) +{ + char c; + + c = *v; + if (isupper((int)c)) + c = tolower(c); + if ((c == 't') || (c == 'y') || (c == '1')) + return EINA_TRUE; + if ((c == 'f') || (c == 'n') || (c == '0')) + return EINA_FALSE; + if (c == 'o') + { + char d; + + d = v[1]; + if (isupper((int)d)) + d = tolower(d); + if (d == 'n') return EINA_TRUE; + if (d == 'f') return EINA_FALSE; + } + return EINA_FALSE; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c b/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c new file mode 100644 index 0000000000..6106450c88 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_screensaver.c @@ -0,0 +1,370 @@ +#include "ecore_xcb_private.h" +# ifdef ECORE_XCB_SCREENSAVER +# include +# endif + +/* local variables */ +static Eina_Bool _screensaver_avail = EINA_FALSE; + +/* external variables */ +int _ecore_xcb_event_screensaver = -1; + +void +_ecore_xcb_screensaver_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SCREENSAVER + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); +#endif +} + +void +_ecore_xcb_screensaver_finalize(void) +{ +#ifdef ECORE_XCB_SCREENSAVER + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SCREENSAVER + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_screensaver_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_screensaver_query_version_cookie_t cookie; + xcb_screensaver_query_version_reply_t *reply; + + cookie = + xcb_screensaver_query_version_unchecked(_ecore_xcb_conn, + XCB_SCREENSAVER_MAJOR_VERSION, + XCB_SCREENSAVER_MINOR_VERSION); + reply = + xcb_screensaver_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if ((reply->server_major_version >= XCB_SCREENSAVER_MAJOR_VERSION) && + (reply->server_minor_version >= XCB_SCREENSAVER_MINOR_VERSION)) + _screensaver_avail = EINA_TRUE; + + free(reply); + } + + if (_screensaver_avail) + _ecore_xcb_event_screensaver = ext_reply->first_event; + } +#endif +} + +EAPI int +ecore_x_screensaver_idle_time_get(void) +{ + int ret = 0; +#ifdef ECORE_XCB_SCREENSAVER + xcb_screensaver_query_info_cookie_t cookie; + xcb_screensaver_query_info_reply_t *reply; + Ecore_X_Window root; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return 0; + +#ifdef ECORE_XCB_SCREENSAVER + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + cookie = xcb_screensaver_query_info_unchecked(_ecore_xcb_conn, root); + reply = xcb_screensaver_query_info_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + ret = (reply->ms_until_server / 1000); + free(reply); +#endif + + return ret; +} + +EAPI void +ecore_x_screensaver_set(int timeout, + int interval, + int prefer_blanking, + int allow_exposures) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return; + +#ifdef ECORE_XCB_SCREENSAVER + xcb_set_screen_saver(_ecore_xcb_conn, + timeout, interval, prefer_blanking, allow_exposures); +#endif +} + +EAPI void +ecore_x_screensaver_timeout_set(int timeout) +{ +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; + uint16_t pint; + uint8_t pblank, pexpo; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return; + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + pint = reply->interval; + pblank = reply->prefer_blanking; + pexpo = reply->allow_exposures; + free(reply); + xcb_set_screen_saver(_ecore_xcb_conn, timeout, pint, pblank, pexpo); +#endif +} + +EAPI int +ecore_x_screensaver_timeout_get(void) +{ + int timeout = 0; +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return 0; + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + timeout = reply->timeout; + free(reply); +#endif + + return timeout; +} + +EAPI void +ecore_x_screensaver_blank_set(int blank) +{ +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; + uint16_t pint, pto; + uint8_t pexpo; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return; + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + pto = reply->timeout; + pint = reply->interval; + pexpo = reply->allow_exposures; + free(reply); + xcb_set_screen_saver(_ecore_xcb_conn, pto, pint, blank, pexpo); +#endif +} + +EAPI int +ecore_x_screensaver_blank_get(void) +{ + int blank = 0; +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return 0; + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + blank = reply->prefer_blanking; + free(reply); +#endif + + return blank; +} + +EAPI void +ecore_x_screensaver_expose_set(int expose) +{ +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; + uint16_t pint, pto; + uint8_t pblank; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return; + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + pto = reply->timeout; + pint = reply->interval; + pblank = reply->prefer_blanking; + free(reply); + xcb_set_screen_saver(_ecore_xcb_conn, pto, pint, pblank, expose); +#endif +} + +EAPI int +ecore_x_screensaver_expose_get(void) +{ + int expose = 0; +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return 0; + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + expose = reply->allow_exposures; + free(reply); +#endif + + return expose; +} + +EAPI void +ecore_x_screensaver_interval_set(int interval) +{ +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; + uint16_t pto; + uint8_t pblank, pexpose; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return; + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + pto = reply->timeout; + pblank = reply->prefer_blanking; + pexpose = reply->allow_exposures; + free(reply); + xcb_set_screen_saver(_ecore_xcb_conn, pto, interval, pblank, pexpose); +#endif +} + +EAPI int +ecore_x_screensaver_interval_get(void) +{ + int interval = 0; +#ifdef ECORE_XCB_SCREENSAVER + xcb_get_screen_saver_cookie_t cookie; + xcb_get_screen_saver_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return 0; + +#ifdef ECORE_XCB_SCREENSAVER + cookie = xcb_get_screen_saver_unchecked(_ecore_xcb_conn); + reply = xcb_get_screen_saver_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + interval = reply->interval; + free(reply); +#endif + + return interval; +} + +EAPI void +ecore_x_screensaver_event_listen_set(Eina_Bool on) +{ +#ifdef ECORE_XCB_SCREENSAVER + Ecore_X_Window root; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_screensaver_avail) return; + +#ifdef ECORE_XCB_SCREENSAVER + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + if (on) + xcb_screensaver_select_input(_ecore_xcb_conn, root, + XCB_SCREENSAVER_EVENT_NOTIFY_MASK | + XCB_SCREENSAVER_EVENT_CYCLE_MASK); + else + xcb_screensaver_select_input(_ecore_xcb_conn, root, 0); +#endif +} + +EAPI Eina_Bool +ecore_x_screensaver_event_available_get(void) +{ + return _screensaver_avail; +} + +EAPI Eina_Bool +ecore_x_screensaver_custom_blanking_enable(void) +{ +#ifdef ECORE_XCB_SCREENSAVER + uint32_t mask_list[9]; + + xcb_screensaver_set_attributes_checked + (_ecore_xcb_conn, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + -9999, -9999, 1, 1, 0, + XCB_WINDOW_CLASS_INPUT_ONLY, + XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT, + 0, mask_list); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +EAPI Eina_Bool +ecore_x_screensaver_custom_blanking_disable(void) +{ +#ifdef ECORE_XCB_SCREENSAVER + xcb_screensaver_unset_attributes_checked + (_ecore_xcb_conn, + ((xcb_screen_t *)_ecore_xcb_screen)->root); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} diff --git a/src/lib/ecore_x/xcb/ecore_xcb_selection.c b/src/lib/ecore_x/xcb/ecore_xcb_selection.c new file mode 100644 index 0000000000..6d5c5aca4c --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_selection.c @@ -0,0 +1,1026 @@ +#include "ecore_xcb_private.h" +//#include "Ecore_X_Atoms.h" + +#define ECORE_XCB_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x)) + +/* local function prototypes */ +static void *_ecore_xcb_selection_parser_text(const char *target EINA_UNUSED, + void *data, + int size, + int format EINA_UNUSED); +static void *_ecore_xcb_selection_parser_files(const char *target, + void *data, + int size, + int format EINA_UNUSED); +static void *_ecore_xcb_selection_parser_targets(const char *target EINA_UNUSED, + void *data, + int size, + int format EINA_UNUSED); + +//static int _ecore_xcb_selection_data_free(void *data); +static int _ecore_xcb_selection_data_text_free(void *data); +static int _ecore_xcb_selection_data_targets_free(void *data); +static int _ecore_xcb_selection_data_files_free(void *data); +static int _ecore_xcb_selection_data_default_free(void *data); +static Eina_Bool _ecore_xcb_selection_set(Ecore_X_Window win, + const void *data, + int size, + Ecore_X_Atom selection); +static void _ecore_xcb_selection_request(Ecore_X_Window win, + Ecore_X_Atom selection, + const char *target); +static Ecore_X_Atom _ecore_xcb_selection_target_atom_get(const char *target); + +/* local variables */ +static Ecore_X_Selection_Intern _selections[4]; +static Ecore_X_Selection_Converter *_converters = NULL; +static Ecore_X_Selection_Parser *_parsers = NULL; + +/* local functions */ +void +_ecore_xcb_selection_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + memset(_selections, 0, sizeof(_selections)); + + /* init converters */ + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT, + ecore_x_selection_converter_text); + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING, + ecore_x_selection_converter_text); + 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); + + /* init parsers */ + ecore_x_selection_parser_add("text/plain", + _ecore_xcb_selection_parser_text); + ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING, + _ecore_xcb_selection_parser_text); + ecore_x_selection_parser_add("text/uri-list", + _ecore_xcb_selection_parser_files); + ecore_x_selection_parser_add("_NETSCAPE_URL", + _ecore_xcb_selection_parser_files); + ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS, + _ecore_xcb_selection_parser_targets); +} + +void +_ecore_xcb_selection_shutdown(void) +{ + Ecore_X_Selection_Converter *cnv; + Ecore_X_Selection_Parser *prs; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* free selection converters */ + cnv = _converters; + while (cnv) + { + Ecore_X_Selection_Converter *tmp; + + tmp = cnv->next; + free(cnv); + cnv = tmp; + } + _converters = NULL; + + /* free parsers */ + prs = _parsers; + while (prs) + { + Ecore_X_Selection_Parser *tmp; + + tmp = prs; + prs = prs->next; + free(tmp->target); + free(tmp); + } + _parsers = NULL; +} + +/* public functions */ +EAPI void +ecore_x_selection_converter_atom_add(Ecore_X_Atom target, + Eina_Bool (*func)(char *target, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *type, + int *size_type)) +{ + 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)); + if (!cnv->next) return; + cnv = cnv->next; + } + else + { + _converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); + if (!_converters) return; + cnv = _converters; + } + cnv->target = target; + cnv->convert = func; +} + +EAPI void +ecore_x_selection_converter_add(char *target, + Eina_Bool (*func)(char *target, + void *data, + int size, + void **date_ret, + int *size_ret, + Ecore_X_Atom *atom_ret, + int *ret)) +{ + Ecore_X_Atom atarget; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((!func) || (!target)) return; + atarget = _ecore_xcb_selection_target_atom_get(target); + ecore_x_selection_converter_atom_add(atarget, func); +} + +EAPI void +ecore_x_selection_converter_del(char *target) +{ + Ecore_X_Atom atarget; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!target) return; + atarget = _ecore_xcb_selection_target_atom_get(target); + ecore_x_selection_converter_atom_del(atarget); +} + +EAPI void +ecore_x_selection_converter_atom_del(Ecore_X_Atom target) +{ + Ecore_X_Selection_Converter *conv, *pconv = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + conv = _converters; + while (conv) + { + if (conv->target == target) + { + if (pconv) + pconv->next = conv->next; + else + _converters = conv->next; + free(conv); + return; + } + pconv = conv; + conv = conv->next; + } +} + +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; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!target) return; + prs = _parsers; + if (prs) + { + 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, *pprs = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!target) return; + + prs = _parsers; + while (prs) + { + if (!strcmp(prs->target, target)) + { + if (pprs) + pprs->next = prs->next; + else + _parsers = prs->next; + free(prs->target); + free(prs); + return; + } + pprs = prs; + prs = prs->next; + } +} + +/** + * 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 Eina_Bool +ecore_x_selection_primary_set(Ecore_X_Window win, + const void *data, + int size) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(win, 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 Eina_Bool +ecore_x_selection_primary_clear(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, + ECORE_X_ATOM_SELECTION_PRIMARY); +} + +EAPI void +ecore_x_selection_primary_request(Ecore_X_Window win, + const char *target) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_PRIMARY, target); +} + +/** + * 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 Eina_Bool +ecore_x_selection_secondary_set(Ecore_X_Window win, + const void *data, + int size) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(win, 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 Eina_Bool +ecore_x_selection_secondary_clear(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, + ECORE_X_ATOM_SELECTION_SECONDARY); +} + +EAPI void +ecore_x_selection_secondary_request(Ecore_X_Window win, + const char *target) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_SECONDARY, target); +} + +/** + * 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 Eina_Bool +ecore_x_selection_xdnd_set(Ecore_X_Window win, + const void *data, + int size) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(win, 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 Eina_Bool +ecore_x_selection_xdnd_clear(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, + ECORE_X_ATOM_SELECTION_XDND); +} + +EAPI void +ecore_x_selection_xdnd_request(Ecore_X_Window win, + const char *target) +{ + Ecore_X_Atom atom; + Ecore_X_DND_Target *_target; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + _target = _ecore_xcb_dnd_target_get(); + atom = _ecore_xcb_selection_target_atom_get(target); + + xcb_convert_selection(_ecore_xcb_conn, win, ECORE_X_ATOM_SELECTION_XDND, + atom, ECORE_X_ATOM_SELECTION_PROP_XDND, _target->time); +} + +/** + * 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 Eina_Bool +ecore_x_selection_clipboard_set(Ecore_X_Window win, + const void *data, + int size) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(win, 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 Eina_Bool +ecore_x_selection_clipboard_clear(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_selection_set(XCB_NONE, NULL, 0, + ECORE_X_ATOM_SELECTION_CLIPBOARD); +} + +EAPI void +ecore_x_selection_clipboard_request(Ecore_X_Window win, + const char *target) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_CLIPBOARD, target); +} + +EAPI Eina_Bool +ecore_x_selection_convert(Ecore_X_Atom selection, + Ecore_X_Atom target, + void **data_ret, + int *size, + Ecore_X_Atom *targtype, + int *typesize) +{ + Ecore_X_Selection_Intern *sel; + Ecore_X_Selection_Converter *cnv; + void *data; + char *tgt_str; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + sel = _ecore_xcb_selection_get(selection); + tgt_str = _ecore_xcb_selection_target_get(target); + + for (cnv = _converters; cnv; cnv = cnv->next) + { + if (cnv->target == target) + { + int r = 0; + + r = cnv->convert(tgt_str, sel->data, sel->length, &data, size, + targtype, typesize); + free(tgt_str); + if (r) + { + if (data_ret) *data_ret = data; + return r; + } + else + return EINA_FALSE; + } + } + + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_selection_notify_send(Ecore_X_Window requestor, + Ecore_X_Atom selection, + Ecore_X_Atom target, + Ecore_X_Atom property, + Ecore_X_Time tim) +{ + xcb_selection_notify_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + memset(&ev, 0, sizeof(xcb_selection_notify_event_t)); + + ev.response_type = XCB_SELECTION_NOTIFY; + ev.requestor = requestor; + ev.selection = selection; + ev.target = target; + ev.property = property; + ev.time = tim; + + xcb_send_event(_ecore_xcb_conn, 0, requestor, + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); +// ecore_x_flush(); + + return EINA_TRUE; +} + +EAPI void +ecore_x_selection_owner_set(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Time tim) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_set_selection_owner(_ecore_xcb_conn, win, atom, tim); +} + +EAPI Ecore_X_Window +ecore_x_selection_owner_get(Ecore_X_Atom atom) +{ + xcb_get_selection_owner_cookie_t cookie; + xcb_get_selection_owner_reply_t *reply; + Ecore_X_Window ret; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_selection_owner(_ecore_xcb_conn, atom); + reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + ret = reply->owner; + free(reply); + return ret; +} + +void * +_ecore_xcb_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); + if (sel) return sel; + } + } + + sel = calloc(1, sizeof(Ecore_X_Selection_Data)); + if (!sel) return NULL; + sel->free = _ecore_xcb_selection_data_default_free; + sel->length = size; + sel->format = format; + sel->data = data; + + return sel; +} + +Ecore_X_Selection_Intern * +_ecore_xcb_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; +} + +/* local functions */ +static Eina_Bool +_ecore_xcb_selection_set(Ecore_X_Window win, + const void *data, + int size, + Ecore_X_Atom selection) +{ + xcb_get_selection_owner_cookie_t cookie; + xcb_get_selection_owner_reply_t *reply; + int in = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_set_selection_owner(_ecore_xcb_conn, win, selection, XCB_CURRENT_TIME); + + cookie = xcb_get_selection_owner(_ecore_xcb_conn, selection); + reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + if (reply->owner != win) + { + free(reply); + return EINA_FALSE; + } + free(reply); + + 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 EINA_FALSE; + + if (data) + { + unsigned char *buff = NULL; + + _selections[in].win = win; + _selections[in].selection = selection; + _selections[in].length = size; + _selections[in].time = _ecore_xcb_events_last_time_get(); + + buff = malloc(size); + if (!buff) return EINA_FALSE; + memcpy(buff, data, size); + _selections[in].data = buff; + } + else if (_selections[in].data) + { + free(_selections[in].data); + memset(&_selections[in], 0, sizeof(Ecore_X_Selection_Data)); + } + + return EINA_TRUE; +} + +static void +_ecore_xcb_selection_request(Ecore_X_Window win, + Ecore_X_Atom selection, + const char *target) +{ + Ecore_X_Atom atarget, prop; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + 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; + + atarget = _ecore_xcb_selection_target_atom_get(target); + + xcb_convert_selection(_ecore_xcb_conn, win, selection, atarget, prop, + XCB_CURRENT_TIME); +} + +EAPI Eina_Bool +ecore_x_selection_converter_text(char *target, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *type EINA_UNUSED, + int *size_type EINA_UNUSED) +{ + Ecore_Xcb_Encoding_Style style; + Ecore_Xcb_Textproperty ret; + char *str; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!data) || (!size)) return EINA_FALSE; + + if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) + style = XcbTextStyle; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) + style = XcbCompoundTextStyle; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) + style = XcbStringStyle; +#ifdef HAVE_ICONV + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) + style = XcbUTF8StringStyle; +#endif + else + return EINA_FALSE; + + str = alloca(size + 1); + memcpy(str, data, size); + str[size] = '\0'; + +#ifdef HAVE_ICONV + if (_ecore_xcb_utf8_textlist_to_textproperty(&str, 1, style, &ret)) + { + int size = 0; + + size = (strlen((char *)ret.value) + 1); + *data_ret = malloc(size); + if (!*data_ret) return EINA_FALSE; + memcpy(*data_ret, ret.value, size); + *size_ret = size; + if (ret.value) free(ret.value); + return EINA_TRUE; + } +#else + if (_ecore_xcb_mb_textlist_to_textproperty(&str, 1, style, &ret)) + { + int size = 0; + + size = (strlen((char *)ret.value) + 1); + *data_ret = malloc(size); + if (!*data_ret) return EINA_FALSE; + memcpy(*data_ret, ret.value, size); + *size_ret = size; + if (ret.value) free(ret.value); + return EINA_TRUE; + } +#endif + else + return EINA_TRUE; +} + +static void * +_ecore_xcb_selection_parser_text(const char *target EINA_UNUSED, + void *data, + int size, + int format EINA_UNUSED) +{ + Ecore_X_Selection_Data_Text *sel; + unsigned char *_data; + void *t; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(_data = data)) return NULL; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); + if (!sel) return NULL; + + if (_data && _data[size - 1]) + { + size++; + t = realloc(_data, size); + if (!t) + { + free(sel); + return NULL; + } + _data = t; + _data[size - 1] = 0; + } + sel->text = (char *)_data; + ECORE_XCB_SELECTION_DATA(sel)->length = size; + ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT; + ECORE_XCB_SELECTION_DATA(sel)->data = _data; + ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_text_free; + return sel; +} + +static void * +_ecore_xcb_selection_parser_files(const char *target, + void *data, + int size, + int format EINA_UNUSED) +{ + Ecore_X_Selection_Data_Files *sel; + char *_data, *tmp, *t, **t2; + int i = 0, is = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if ((strcmp(target, "text/uri-list")) && + (strcmp(target, "_NETSCAPE_URL"))) return NULL; + + if (!(_data = data)) return NULL; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files)); + if (!sel) return NULL; + + ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_files_free; + + if (_data && _data[size - 1]) + { + size++; + t = realloc(_data, size); + if (!t) + { + free(sel); + return NULL; + } + _data = t; + _data[size - 1] = 0; + } + + tmp = malloc(size); + if (!tmp) + { + free(sel); + return NULL; + } + + 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++; + t2 = realloc(sel->files, sel->num_files * sizeof(char *)); + if (t2) + { + sel->files = t2; + sel->files[sel->num_files - 1] = strdup(tmp); + } + tmp[0] = 0; + i = 0; + } + } + } + if (i > 0) + { + tmp[i] = 0; + sel->num_files++; + t2 = realloc(sel->files, sel->num_files * sizeof(char *)); + if (t2) + { + sel->files = t2; + sel->files[sel->num_files - 1] = strdup(tmp); + } + } + if (tmp) free(tmp); + if (_data) free(_data); + + ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES; + ECORE_XCB_SELECTION_DATA(sel)->length = sel->num_files; + + return ECORE_XCB_SELECTION_DATA(sel); +} + +static void * +_ecore_xcb_selection_parser_targets(const char *target EINA_UNUSED, + void *data, + int size, + int format EINA_UNUSED) +{ + Ecore_X_Selection_Data_Targets *sel; + unsigned long *targets; + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!(targets = (unsigned long *)data)) return NULL; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); + if (!sel) return NULL; + + sel->num_targets = (size - 2); + sel->targets = malloc((size - 2) * sizeof(char *)); + if (!sel->targets) + { + free(sel); + return NULL; + } + + for (i = 2; i < size; i++) + { + xcb_get_atom_name_cookie_t cookie; + xcb_get_atom_name_reply_t *reply; + char *name = NULL; + int len = 0; + + cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, targets[i]); + reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + len = xcb_get_atom_name_name_length(reply); + name = (char *)malloc(sizeof(char) * (len + 1)); + if (name) + { + memcpy(name, xcb_get_atom_name_name(reply), len); + name[len] = '\0'; + sel->targets[i - 2] = name; + } + free(reply); + } + } + + ECORE_XCB_SELECTION_DATA(sel)->free = + _ecore_xcb_selection_data_targets_free; + ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS; + ECORE_XCB_SELECTION_DATA(sel)->length = size; + ECORE_XCB_SELECTION_DATA(sel)->data = data; + + return sel; +} + +/* + static int + _ecore_xcb_selection_data_free(void *data) + { + Ecore_X_Selection_Data *sel; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sel = data)) return 0; + if (sel->data) free(sel->data); + free(sel); + return 1; + } + */ + +static int +_ecore_xcb_selection_data_text_free(void *data) +{ + Ecore_X_Selection_Data_Text *sel; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sel = data)) return 0; + if (sel->text) free(sel->text); + free(sel); + return 1; +} + +static int +_ecore_xcb_selection_data_targets_free(void *data) +{ + Ecore_X_Selection_Data_Targets *sel; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sel = data)) return 0; + if (sel->targets) free(sel->targets); + free(ECORE_XCB_SELECTION_DATA(sel)->data); + free(sel); + return 1; +} + +static int +_ecore_xcb_selection_data_files_free(void *data) +{ + Ecore_X_Selection_Data_Files *sel; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(sel = data)) return 0; + if (sel->files) + { + int i = 0; + + for (i = 0; i < sel->num_files; i++) + if (sel->files[i]) free(sel->files[i]); + if (sel->files) free(sel->files); + } + free(sel); + return 0; +} + +static int +_ecore_xcb_selection_data_default_free(void *data) +{ + Ecore_X_Selection_Data *sel; + + if (!(sel = data)) return 1; + free(sel->data); + free(sel); + return 1; +} + +static Ecore_X_Atom +_ecore_xcb_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_xcb_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 + return ecore_x_atom_name_get(target); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_shape.c b/src/lib/ecore_x/xcb/ecore_xcb_shape.c new file mode 100644 index 0000000000..913f1992b9 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_shape.c @@ -0,0 +1,50 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_SHAPE +# include +#endif + +/* external variables */ +int _ecore_xcb_event_shape = -1; + +void +_ecore_xcb_shape_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_shape_id); +#endif +} + +void +_ecore_xcb_shape_finalize(void) +{ +#ifdef ECORE_XCB_SHAPE + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SHAPE + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_shape_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_shape_query_version_cookie_t cookie; + xcb_shape_query_version_reply_t *reply; + Eina_Bool _shape_avail; + + _shape_avail = EINA_FALSE; + cookie = xcb_shape_query_version_unchecked(_ecore_xcb_conn); + reply = xcb_shape_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + _shape_avail = EINA_TRUE; + free(reply); + } + + if (_shape_avail) + _ecore_xcb_event_shape = ext_reply->first_event; + } +#endif +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_sync.c b/src/lib/ecore_x/xcb/ecore_xcb_sync.c new file mode 100644 index 0000000000..75f4e4f2be --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_sync.c @@ -0,0 +1,338 @@ +#include "ecore_xcb_private.h" +# ifdef ECORE_XCB_SYNC +# include +# endif + +/* local variables */ +static Eina_Bool _sync_avail = EINA_FALSE; + +/* external variables */ +int _ecore_xcb_event_sync = -1; + +void +_ecore_xcb_sync_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SYNC + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_sync_id); +#endif +} + +void +_ecore_xcb_sync_finalize(void) +{ +#ifdef ECORE_XCB_SYNC + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_SYNC + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_sync_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_sync_initialize_cookie_t cookie; + xcb_sync_initialize_reply_t *reply; + + cookie = + xcb_sync_initialize_unchecked(_ecore_xcb_conn, + XCB_SYNC_MAJOR_VERSION, + XCB_SYNC_MINOR_VERSION); + reply = xcb_sync_initialize_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (reply->major_version >= 3) _sync_avail = EINA_TRUE; + free(reply); + } + + if (_sync_avail) + _ecore_xcb_event_sync = ext_reply->first_event; + } +#endif +} + +void +_ecore_xcb_sync_magic_send(int val, + Ecore_X_Window win) +{ + xcb_client_message_event_t ev; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + memset(&ev, 0, sizeof(xcb_client_message_event_t)); + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 32; + ev.window = win; + ev.type = 27777; + ev.data.data32[0] = 0x7162534; + ev.data.data32[1] = (0x10000000 + val); + ev.data.data32[2] = win; + + xcb_send_event(_ecore_xcb_conn, 0, win, XCB_EVENT_MASK_NO_EVENT, + (const char *)&ev); +// ecore_x_flush(); +} + +/* public functions */ +EAPI Ecore_X_Sync_Alarm +ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter) +{ +#ifdef ECORE_XCB_SYNC + uint32_t list[6], mask; + xcb_sync_int64_t init; + Ecore_X_Sync_Alarm alarm; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!counter)) return 0; + +#ifdef ECORE_XCB_SYNC + init.lo = 0; + init.hi = 0; + xcb_sync_set_counter(_ecore_xcb_conn, counter, init); + + 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); + list[0] = counter; + list[1] = XCB_SYNC_VALUETYPE_ABSOLUTE; + list[2] = 1; + list[3] = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON; + list[4] = 1; + list[5] = 1; + alarm = xcb_generate_id(_ecore_xcb_conn); + + xcb_sync_create_alarm(_ecore_xcb_conn, alarm, mask, list); + ecore_x_sync(); // needed + + return alarm; +#endif + return 0; +} + +EAPI Eina_Bool +ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!alarm)) return EINA_FALSE; + +#ifdef ECORE_XCB_SYNC + xcb_sync_destroy_alarm(_ecore_xcb_conn, alarm); +// ecore_x_flush(); + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + +EAPI Eina_Bool +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; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!counter)) return EINA_FALSE; + +#ifdef ECORE_XCB_SYNC + cookie = xcb_sync_query_counter_unchecked(_ecore_xcb_conn, counter); + reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + if (val) *val = (unsigned int)reply->counter_value.lo; + free(reply); + return EINA_TRUE; + } +#endif + return EINA_FALSE; +} + +EAPI void +ecore_x_sync_counter_inc(Ecore_X_Sync_Counter counter, + int by) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_int64_t v; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!counter)) return; + +#ifdef ECORE_XCB_SYNC + v.hi = (by < 0) ? ~0 : 0; + v.lo = by; + + xcb_sync_change_counter(_ecore_xcb_conn, counter, v); +// ecore_x_flush(); +#endif +} + +EAPI void +ecore_x_sync_counter_val_wait(Ecore_X_Sync_Counter counter, + int val) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_query_counter_cookie_t cookie; + xcb_sync_query_counter_reply_t *reply; + xcb_sync_int64_t v1, v2; + xcb_sync_waitcondition_t cond; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!counter)) return; + +#ifdef ECORE_XCB_SYNC + cookie = xcb_sync_query_counter_unchecked(_ecore_xcb_conn, counter); + reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + v1 = reply->counter_value; + free(reply); + + v1.hi = (val < 0) ? ~0 : 0; + v1.lo = val; + v2.hi = ((val + 1) < 0) ? ~0 : 0; + v2.lo = (val + 1); + + cond.trigger.counter = counter; + cond.trigger.wait_type = XCB_SYNC_VALUETYPE_ABSOLUTE; + cond.trigger.wait_value = v1; + cond.trigger.test_type = XCB_SYNC_TESTTYPE_POSITIVE_COMPARISON; + cond.event_threshold = v2; + + xcb_sync_await(_ecore_xcb_conn, 1, &cond); +// ecore_x_flush(); +#endif +} + +EAPI Ecore_X_Sync_Counter +ecore_x_sync_counter_new(int val) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_counter_t counter; + xcb_sync_int64_t v; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_sync_avail) return 0; + +#ifdef ECORE_XCB_SYNC + v.hi = (val < 0) ? ~0 : 0; + v.lo = val; + + counter = xcb_generate_id(_ecore_xcb_conn); + xcb_sync_create_counter(_ecore_xcb_conn, counter, v); +// ecore_x_flush(); + + return counter; +#endif + + return 0; +} + +EAPI void +ecore_x_sync_counter_free(Ecore_X_Sync_Counter counter) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!counter)) return; + +#ifdef ECORE_XCB_SYNC + xcb_sync_destroy_counter(_ecore_xcb_conn, counter); +// ecore_x_flush(); +#endif +} + +EAPI void +ecore_x_sync_counter_set(Ecore_X_Sync_Counter counter, + int val) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_int64_t v; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!counter)) return; + +#ifdef ECORE_XCB_SYNC + v.hi = (val < 0) ? ~0 : 0; + v.lo = val; + + xcb_sync_set_counter(_ecore_xcb_conn, counter, v); +// ecore_x_flush(); +#endif +} + +EAPI void +ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter, + int val_hi, + unsigned int val_lo) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_int64_t v; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!counter)) return; + +#ifdef ECORE_XCB_SYNC + v.hi = val_hi; + v.lo = val_lo; + + xcb_sync_set_counter(_ecore_xcb_conn, counter, v); +// ecore_x_flush(); +#endif +} + +EAPI Eina_Bool +ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter, + int *val_hi, + unsigned int *val_lo) +{ +#ifdef ECORE_XCB_SYNC + xcb_sync_query_counter_cookie_t cookie; + xcb_sync_query_counter_reply_t *reply; + xcb_sync_int64_t value; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if ((!_sync_avail) || (!counter)) return EINA_FALSE; + +#ifdef ECORE_XCB_SYNC + cookie = + xcb_sync_query_counter_unchecked(_ecore_xcb_conn, + (xcb_sync_counter_t)counter); + reply = xcb_sync_query_counter_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + value = reply->counter_value; + free(reply); + if (val_hi) *val_hi = (int)value.hi; + if (val_lo) *val_lo = (unsigned int)value.lo; + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_textlist.c b/src/lib/ecore_x/xcb/ecore_xcb_textlist.c new file mode 100644 index 0000000000..2a5c854494 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_textlist.c @@ -0,0 +1,509 @@ +#include "ecore_xcb_private.h" +//#include "Ecore_X_Atoms.h" +#include +#ifdef HAVE_ICONV +# include +#endif +#ifndef CODESET +# define CODESET "INVALID" +#endif + +static int _ecore_xcb_textlist_get_buffer_size(Eina_Bool is_wide, + void *list, + int count); +static int _ecore_xcb_textlist_get_wc_len(wchar_t *wstr); +static void *_ecore_xcb_textlist_alloc_list(Eina_Bool is_wide, + int count, + int nitems); +static void _ecore_xcb_textlist_copy_list(Eina_Bool is_wide, + void *text, + char **list, + int count); +static wchar_t *_ecore_xcb_textlist_copy_wchar(wchar_t *str1, + wchar_t *str2); +static int _ecore_xcb_textlist_len_wchar(wchar_t *str); + +#ifdef HAVE_ICONV +Eina_Bool +_ecore_xcb_utf8_textlist_to_textproperty(char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textlist_to_textproperty("utf8string", list, count, + style, ret); +} + +#endif + +Eina_Bool +_ecore_xcb_mb_textlist_to_textproperty(char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textlist_to_textproperty("multiByte", list, count, + style, ret); +} + +/* NB: This Function May Not Be Correct !!! + * (as I do not know text conversion, locales, etc, etc very well) + * + * Portions were ripped from libX11 XTextListToTextProperty + */ +Eina_Bool +_ecore_xcb_textlist_to_textproperty(const char *type, + char **list, + int count, + Ecore_Xcb_Encoding_Style style, + Ecore_Xcb_Textproperty *ret) +{ + Eina_Bool is_wide = EINA_FALSE; + Ecore_X_Atom encoding; + int len = 0, nitems = 0, i = 0; + size_t from_left = 0, to_left = 0; + int unconv_num = 0, val = 0; + char *buff, *to, *value, *from; + const char *to_type, *from_type; + char **mb = NULL; + wchar_t **wc = NULL; +#ifdef HAVE_ICONV + iconv_t conv; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!strcmp("wideChar", type)) is_wide = EINA_TRUE; + len = _ecore_xcb_textlist_get_buffer_size(is_wide, list, count); + if (!(buff = (char *)malloc(len * sizeof(char)))) return EINA_FALSE; + from_type = nl_langinfo(CODESET); + switch (style) + { + case XcbStringStyle: + case XcbStdICCTextStyle: + encoding = ECORE_X_ATOM_STRING; + to_type = nl_langinfo(CODESET); +// to_type = "string"; + break; + + case XcbUTF8StringStyle: + encoding = ECORE_X_ATOM_UTF8_STRING; + to_type = "UTF-8"; + break; + + case XcbCompoundTextStyle: + encoding = ECORE_X_ATOM_COMPOUND_TEXT; + to_type = nl_langinfo(CODESET); +// to_type = "compoundText"; + break; + + case XcbTextStyle: + encoding = ECORE_X_ATOM_TEXT; + to_type = nl_langinfo(CODESET); +// to_type = "multiByte"; + if (!is_wide) + { + nitems = 0; + mb = (char **)list; + to = buff; + for (i = 0; ((i < count) && (len > 0)); i++) + { + if (*mb) strcpy(to, *mb); + else *to = '\0'; + from_left = (*mb ? strlen(*mb) : 0) + 1; + nitems += from_left; + to += from_left; + mb++; + } + unconv_num = 0; + goto done; + } + break; + + default: + free(buff); + return EINA_FALSE; + break; + } + + if (count < 1) + { + nitems = 0; + goto done; + } + +retry: +#ifdef HAVE_ICONV + conv = iconv_open(to_type, from_type); +#endif + + if (is_wide) + wc = (wchar_t **)list; + else + mb = (char **)list; + + to = buff; + to_left = len; + unconv_num = 0; + for (i = 1; to_left > 0; i++) + { + if (is_wide) + { + from = (char *)*wc; + from_left = _ecore_xcb_textlist_get_wc_len(*wc); + wc++; + } + else + { + from = *mb; + from_left = (*mb ? strlen(*mb) : 0); + mb++; + } + +#ifdef HAVE_ICONV + val = iconv(conv, &from, &from_left, &to, &to_left); +#endif + if (val < 0) continue; + if ((val > 0) && (style == XcbStdICCTextStyle) && + (encoding == ECORE_X_ATOM_STRING)) + { +#ifdef HAVE_ICONV + iconv_close(conv); +#endif + encoding = ECORE_X_ATOM_COMPOUND_TEXT; + goto retry; + } + + unconv_num += val; + *to++ = '\0'; + to_left--; + if (i >= count) break; + } + +#ifdef HAVE_ICONV + iconv_close(conv); +#endif + nitems = (to - buff); + +done: + if (nitems <= 0) nitems = 1; + if (!(value = (char *)malloc(nitems * sizeof(char)))) + { + free(buff); + return EINA_FALSE; + } + if (nitems == 1) + *value = 0; + else + memcpy(value, buff, nitems); + nitems--; + free(buff); + + ret->value = value; + ret->encoding = encoding; + ret->format = 8; + ret->nitems = nitems; + + return EINA_TRUE; +} + +#ifdef HAVE_ICONV +Eina_Bool +_ecore_xcb_utf8_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + char ***list_ret, + int *count_ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textproperty_to_textlist(text_prop, "utf8String", + list_ret, count_ret); +} + +#endif + +Eina_Bool +_ecore_xcb_mb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + char ***list_ret, + int *count_ret) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return _ecore_xcb_textproperty_to_textlist(text_prop, "multiByte", + list_ret, count_ret); +} + +Eina_Bool +_ecore_xcb_textproperty_to_textlist(const Ecore_Xcb_Textproperty *text_prop, + const char *type, + char ***list_ret, + int *count_ret) +{ + Eina_Bool is_wide = EINA_FALSE; + Eina_Bool do_strcpy = EINA_FALSE; + const char *from_type; + char *buff, *to, *from; + char *lptr, *sptr; + int nitems = 0, len = 0, num = 0, ret = 0; + size_t from_left = 0, to_left = 0; +#ifdef HAVE_ICONV + iconv_t conv = 0; +#endif + + *list_ret = NULL; + *count_ret = 0; + if (!strcmp("wideChar", type)) is_wide = EINA_TRUE; + + nitems = text_prop->nitems; + if (nitems <= 0) return EINA_TRUE; + + if (text_prop->format != 8) return EINA_FALSE; + + from_type = nl_langinfo(CODESET); + if (text_prop->encoding == ECORE_X_ATOM_UTF8_STRING) + from_type = "UTF-8"; + + if (is_wide) + len = (text_prop->nitems + 1) * sizeof(wchar_t); + else + { + if (!strcmp(type, "utf8String")) + len = text_prop->nitems * 6 + 1; + else + len = text_prop->nitems * MB_CUR_MAX + 1; + } + + buff = (char *)malloc(len * sizeof(char)); + if (!buff) return EINA_FALSE; + + to = buff; + to_left = len; + + if (!strcmp(from_type, type)) + do_strcpy = EINA_TRUE; + else + { +#ifdef HAVE_ICONV + conv = iconv_open(type, from_type); +#endif + if (!conv) + { + free(buff); + return EINA_FALSE; + } + } + + lptr = sptr = text_prop->value; + num = *count_ret = 0; + while (1) + { + if ((nitems == 0) || (*sptr == 0)) + { + from = lptr; + from_left = sptr - lptr; + lptr = sptr; + if (do_strcpy) + { + int l = 0; + + l = MIN(from_left, to_left); + strncpy(to, from, l); + from += len; + to += len; + from_left -= l; + to_left -= l; + ret = 0; + } + else + ret = iconv(conv, &from, &from_left, &to, &to_left); + + if (ret < 0) continue; + num += ret; + (*count_ret)++; + if (nitems == 0) break; + lptr = ++sptr; + if (is_wide) + { + *((wchar_t *)to) = (wchar_t)0; + to += sizeof(wchar_t); + to_left -= sizeof(wchar_t); + } + else + { + *((char *)to) = '\0'; + to++; + to_left--; + } + } + else + sptr++; + + nitems--; + } + +#if HAVE_ICONV + if (!do_strcpy) iconv_close(conv); +#endif + + if (is_wide) + { + *((wchar_t *)to) = (wchar_t)0; + to_left -= sizeof(wchar_t); + } + else + { + *((char *)to) = '\0'; + to_left--; + } + + *list_ret = + _ecore_xcb_textlist_alloc_list(is_wide, *count_ret, (len - to_left)); + if (*list_ret) + _ecore_xcb_textlist_copy_list(is_wide, buff, *list_ret, *count_ret); + + free(buff); + + return EINA_TRUE; +} + +static int +_ecore_xcb_textlist_get_buffer_size(Eina_Bool is_wide, + void *list, + int count) +{ + int len = 0; + char **mb; + wchar_t **wc; + + if (!list) return 0; + if (is_wide) + { + wc = (wchar_t **)list; + for (; count-- > 0; wc++) + if (*wc) len += _ecore_xcb_textlist_get_wc_len(*wc) + 1; + len *= 5; + } + else + { + mb = (char **)list; + for (; count-- > 0; mb++) + if (*mb) len += strlen(*mb) + 1; + len *= 3; + } + len = (len / 2048 + 1) * 2048; + return len; +} + +static int +_ecore_xcb_textlist_get_wc_len(wchar_t *wstr) +{ + wchar_t *ptr; + + ptr = wstr; + while (*ptr) + ptr++; + + return ptr - wstr; +} + +static void * +_ecore_xcb_textlist_alloc_list(Eina_Bool is_wide, + int count, + int nitems) +{ + if (is_wide) + { + wchar_t **list; + + list = (wchar_t **)malloc(count * sizeof(wchar_t *)); + if (!list) return NULL; + *list = (wchar_t *)malloc(nitems * sizeof(wchar_t)); + if (!*list) + { + free(list); + return NULL; + } + return *list; + } + else + { + char **list; + + list = (char **)malloc(count * sizeof(char *)); + if (!list) return NULL; + *list = (char *)malloc(nitems * sizeof(char)); + if (!*list) + { + free(list); + return NULL; + } + return *list; + } +} + +static void +_ecore_xcb_textlist_copy_list(Eina_Bool is_wide, + void *text, + char **list, + int count) +{ + int len = 0; + + if (is_wide) + { + wchar_t *txt, *str, **wlist; + + txt = (wchar_t *)text; + wlist = (wchar_t **)list; + for (str = *wlist; count > 0; count--, wlist++) + { + _ecore_xcb_textlist_copy_wchar(str, txt); + *wlist = str; + len = (_ecore_xcb_textlist_len_wchar(str) + 1); + str += len; + txt += len; + } + } + else + { + char *txt, *str, **slist; + + txt = (char *)text; + slist = (char **)list; + for (str = *slist; count > 0; count--, slist++) + { + strcpy(str, txt); + *slist = str; + len = strlen(str) + 1; + str += len; + txt += len; + } + } +} + +static wchar_t * +_ecore_xcb_textlist_copy_wchar(wchar_t *str1, + wchar_t *str2) +{ + wchar_t *tmp; + + tmp = str1; + while ((*str1++ = *str2++)) + ; + return tmp; +} + +static int +_ecore_xcb_textlist_len_wchar(wchar_t *str) +{ + wchar_t *ptr; + + ptr = str; + while (*ptr) + ptr++; + return ptr - str; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_vsync.c b/src/lib/ecore_x/xcb/ecore_xcb_vsync.c new file mode 100644 index 0000000000..7888796f9a --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_vsync.c @@ -0,0 +1,375 @@ +#include "ecore_xcb_private.h" +# include +# include +# include + +#define ECORE_XCB_VSYNC_DRI2 1 +#define DRM_EVENT_CONTEXT_VERSION 2 + +#ifdef ECORE_XCB_VSYNC_DRI2 + +/* relevant header bits of dri/drm inlined here to avoid needing external */ +/* headers to build drm */ +typedef unsigned int drm_magic_t; + +typedef enum +{ + DRM_VBLANK_ABSOLUTE = 0x00000000, + DRM_VBLANK_RELATIVE = 0x00000001, + DRM_VBLANK_EVENT = 0x04000000, + DRM_VBLANK_FLIP = 0x08000000, + DRM_VBLANK_NEXTONMISS = 0x10000000, + DRM_VBLANK_SECONDARY = 0x20000000, + DRM_VBLANK_SIGNAL = 0x40000000 +} drmVBlankSeqType; + +typedef struct _drmVBlankReq +{ + drmVBlankSeqType type; + unsigned int sequence; + unsigned long signal; +} drmVBlankReq; + +typedef struct _drmVBlankReply +{ + drmVBlankSeqType type; + unsigned int sequence; + long tval_sec, tval_usec; +} drmVBlankReply; + +typedef union _drmVBlank +{ + drmVBlankReq request; + drmVBlankReply reply; +} drmVBlank; + +typedef struct _drmEventContext +{ + int version; + void (*vblank_handler)(int fd, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void *user_data); + void (*page_flip_handler)(int fd, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void *user_data); +} drmEventContext; + +static int (*sym_drmClose)(int fd) = NULL; +static int (*sym_drmGetMagic)(int fd, + drm_magic_t *magic) = NULL; +static int (*sym_drmWaitVBlank)(int fd, + drmVBlank *vbl) = NULL; +static int (*sym_drmHandleEvent)(int fd, + drmEventContext *evctx) = NULL; + +/* dri */ +static Bool (*sym_DRI2QueryExtension)(Display *display, + int *eventBase, + int *errorBase) = NULL; +static Bool (*sym_DRI2QueryVersion)(Display *display, + int *major, + int *minor) = NULL; +static Bool (*sym_DRI2Connect)(Display *display, + XID window, + char **driverName, + char **deviceName) = NULL; +static Bool (*sym_DRI2Authenticate)(Display *display, + XID window, + drm_magic_t magic) = NULL; + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_dri_link(void); +static Eina_Bool _ecore_xcb_dri_start(void); +static void _ecore_xcb_dri_shutdown(void); + +static Eina_Bool _ecore_xcb_dri_cb(void *data EINA_UNUSED, + Ecore_Fd_Handler *fdh EINA_UNUSED); +static void _ecore_xcb_dri_tick_begin(void *data EINA_UNUSED); +static void _ecore_xcb_dri_tick_end(void *data EINA_UNUSED); +static void _ecore_xcb_dri_tick_schedule(void); +static void _ecore_xcb_dri_vblank_handler(int fd EINA_UNUSED, + unsigned int frame EINA_UNUSED, + unsigned int sec EINA_UNUSED, + unsigned int usec EINA_UNUSED, + void *data EINA_UNUSED); + +/* local variables */ +static Ecore_X_Window _vsync_root = 0; +static int _drm_fd = -1; +static Ecore_Fd_Handler *_drm_fdh = NULL; +static unsigned int _drm_magic = 0; +static Eina_Bool _drm_event_busy = EINA_FALSE; +static void *_drm_lib = NULL; +static void *_dri_lib = NULL; +static drmEventContext _drm_evctx; +#endif + +void +_ecore_xcb_dri_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +} + +void +_ecore_xcb_dri_finalize(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); +} + +EAPI Eina_Bool +ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win) +{ +#ifdef ECORE_XCB_VSYNC_DRI2 + Ecore_X_Window root; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_VSYNC_DRI2 + root = ecore_x_window_root_get(win); + if (root != _vsync_root) + { + _vsync_root = root; + if (_vsync_root) + { + if (!_ecore_xcb_dri_link()) + { + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + _ecore_xcb_dri_shutdown(); + if (!_ecore_xcb_dri_start()) + { + _vsync_root = 0; + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + ecore_animator_custom_source_tick_begin_callback_set + (_ecore_xcb_dri_tick_begin, NULL); + ecore_animator_custom_source_tick_end_callback_set + (_ecore_xcb_dri_tick_end, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); + } + else + { + if (_drm_fd >= 0) + { + _ecore_xcb_dri_shutdown(); + ecore_animator_custom_source_tick_begin_callback_set + (NULL, NULL); + ecore_animator_custom_source_tick_end_callback_set + (NULL, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + } + } + } + return EINA_TRUE; +#else + return EINA_FALSE; + win = 0; +#endif +} + +/* local functions */ +#ifdef ECORE_XCB_VSYNC_DRI2 +static Eina_Bool +_ecore_xcb_dri_link(void) +{ + const char *_drm_libs[] = + { + "libdrm.so.2", + "libdrm.so.1", + "libdrm.so.0", + "libdrm.so", + NULL, + }; + const char *_dri_libs[] = + { + "libdri2.so.2", + "libdri2.so.1", + "libdri2.so.0", + "libdri2.so", + "libGL.so.4", + "libGL.so.3", + "libGL.so.2", + "libGL.so.1", + "libGL.so.0", + "libGL.so", + NULL, + }; + int i = 0, fail = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +# define SYM(lib, xx) \ + do { \ + sym_## xx = dlsym(lib, #xx); \ + if (!(sym_## xx)) { \ + fprintf(stderr, "%s\n", dlerror()); \ + fail = 1; \ + } \ + } while (0); + + if (_drm_lib) return EINA_TRUE; + + for (i = 0; _drm_libs[i]; i++) + { + _drm_lib = dlopen(_drm_libs[i], (RTLD_LOCAL | RTLD_LAZY)); + if (_drm_lib) + { + fail = 0; + SYM(_drm_lib, drmClose); + SYM(_drm_lib, drmGetMagic); + SYM(_drm_lib, drmWaitVBlank); + SYM(_drm_lib, drmHandleEvent); + if (fail) + { + dlclose(_drm_lib); + _drm_lib = NULL; + } + else + break; + } + } + if (!_drm_lib) return EINA_FALSE; + for (i = 0; _dri_libs[i]; i++) + { + if ((_dri_lib = dlopen(_dri_libs[i], (RTLD_LOCAL | RTLD_LAZY)))) + { + fail = 0; + SYM(_dri_lib, DRI2QueryExtension); + SYM(_dri_lib, DRI2QueryVersion); + SYM(_dri_lib, DRI2Connect); + SYM(_dri_lib, DRI2Authenticate); + if (fail) + { + dlclose(_dri_lib); + _dri_lib = NULL; + } + else + break; + } + } + if (!_dri_lib) + { + dlclose(_drm_lib); + _drm_lib = NULL; + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_xcb_dri_start(void) +{ + Ecore_X_Display *disp; + int _dri2_event = 0, _dri2_error = 0; + int _dri2_major = 0, _dri2_minor = 0; + char *device = NULL, *driver = NULL; + + disp = ecore_x_display_get(); + if (!sym_DRI2QueryExtension(disp, &_dri2_event, &_dri2_error)) + return 0; + if (!sym_DRI2QueryVersion(disp, &_dri2_major, &_dri2_minor)) + return 0; + if (_dri2_major < 2) return 0; + if (!sym_DRI2Connect(disp, _vsync_root, &driver, &device)) + return 0; + + _drm_fd = open(device, O_RDWR); + if (_drm_fd < 0) return 0; + + sym_drmGetMagic(_drm_fd, &_drm_magic); + if (!sym_DRI2Authenticate(disp, _vsync_root, _drm_magic)) + { + close(_drm_fd); + _drm_fd = -1; + return EINA_FALSE; + } + + memset(&_drm_evctx, 0, sizeof(_drm_evctx)); + _drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; + _drm_evctx.vblank_handler = _ecore_xcb_dri_vblank_handler; + _drm_evctx.page_flip_handler = NULL; + + _drm_fdh = ecore_main_fd_handler_add(_drm_fd, ECORE_FD_READ, + _ecore_xcb_dri_cb, NULL, NULL, NULL); + if (!_drm_fdh) + { + close(_drm_fd); + _drm_fd = -1; + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static void +_ecore_xcb_dri_shutdown(void) +{ + if (_drm_fd >= 0) + { + close(_drm_fd); + _drm_fd = -1; + } + if (_drm_fdh) + { + ecore_main_fd_handler_del(_drm_fdh); + _drm_fdh = NULL; + } +} + +static Eina_Bool +_ecore_xcb_dri_cb(void *data EINA_UNUSED, + Ecore_Fd_Handler *fdh EINA_UNUSED) +{ + sym_drmHandleEvent(_drm_fd, &_drm_evctx); + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_xcb_dri_tick_begin(void *data EINA_UNUSED) +{ + _drm_event_busy = EINA_TRUE; + _ecore_xcb_dri_tick_schedule(); +} + +static void +_ecore_xcb_dri_tick_end(void *data EINA_UNUSED) +{ + _drm_event_busy = EINA_FALSE; +} + +static void +_ecore_xcb_dri_tick_schedule(void) +{ + drmVBlank vbl; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + vbl.request.type = (DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT); + vbl.request.sequence = 1; + vbl.request.signal = 0; + + sym_drmWaitVBlank(_drm_fd, &vbl); +} + +static void +_ecore_xcb_dri_vblank_handler(int fd EINA_UNUSED, + unsigned int frame EINA_UNUSED, + unsigned int sec EINA_UNUSED, + unsigned int usec EINA_UNUSED, + void *data EINA_UNUSED) +{ + ecore_animator_custom_tick(); + if (_drm_event_busy) _ecore_xcb_dri_tick_schedule(); +} + +#endif diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window.c b/src/lib/ecore_x/xcb/ecore_xcb_window.c new file mode 100644 index 0000000000..f8405fe1ec --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_window.c @@ -0,0 +1,2238 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_RENDER +# include +#endif +#ifdef ECORE_XCB_SHAPE +# include +#endif +#ifdef ECORE_XCB_XPRINT +#include +#endif + +/* local function prototypes */ +static Ecore_X_Window _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent, + int x, + int y, + int w, + int h, + uint8_t override_redirect, + uint8_t save_under); +static Ecore_X_Window _ecore_xcb_window_at_xy_get(Ecore_X_Window base, + int bx, + int by, + int x, + int y, + Ecore_X_Window *skip, + int skip_num); +static int _ecore_xcb_window_modifiers_get(unsigned int state); +static xcb_visualtype_t *_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id); +#ifdef ECORE_XCB_XPRINT +static xcb_screen_t *_ecore_xcb_window_screen_of_display(int screen); +#endif + +/* local variables */ +static int ignore_num = 0; +static Ecore_X_Window *ignore_list = NULL; + +/* external variables */ +int _ecore_xcb_button_grabs_num = 0; +int _ecore_xcb_key_grabs_num = 0; +Ecore_X_Window *_ecore_xcb_button_grabs = NULL; +Ecore_X_Window *_ecore_xcb_key_grabs = NULL; +Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data, + int type, + void *event); +void *_ecore_xcb_window_grab_replay_data; + +/** + * @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) +{ + Ecore_X_Window win; + uint32_t mask, mask_list[9]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + /* NB: Order here is very important due to xcb_cw_t enum */ + 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); + + mask_list[0] = XCB_BACK_PIXMAP_NONE; + mask_list[1] = 0; + mask_list[2] = XCB_GRAVITY_NORTH_WEST; + mask_list[3] = XCB_GRAVITY_NORTH_WEST; + mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL; + mask_list[5] = 0; + mask_list[6] = 0; + mask_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); + mask_list[8] = XCB_EVENT_MASK_NO_EVENT; + + win = xcb_generate_id(_ecore_xcb_conn); + xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, + win, parent, x, y, w, h, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + XCB_COPY_FROM_PARENT, mask, mask_list); + + if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root) + 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) +{ + Ecore_X_Window win; + uint32_t mask, mask_list[9]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + /* NB: Order here is very important due to xcb_cw_t enum */ + 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); + + mask_list[0] = XCB_BACK_PIXMAP_NONE; + mask_list[1] = 0; + mask_list[2] = XCB_GRAVITY_NORTH_WEST; + mask_list[3] = XCB_GRAVITY_NORTH_WEST; + mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL; + mask_list[5] = 1; + mask_list[6] = 0; + mask_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); + mask_list[8] = XCB_EVENT_MASK_NO_EVENT; + + win = xcb_generate_id(_ecore_xcb_conn); + xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, + win, parent, x, y, w, h, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + XCB_COPY_FROM_PARENT, mask, mask_list); + + 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) +{ + Ecore_X_Window win; + uint32_t mask, mask_list[3]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__) + CHECK_XCB_CONN; + + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + /* NB: Order here is very important due to xcb_cw_t enum */ + mask = (XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | + XCB_CW_DONT_PROPAGATE); + + mask_list[0] = 1; + mask_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); + mask_list[2] = XCB_EVENT_MASK_NO_EVENT; + + win = xcb_generate_id(_ecore_xcb_conn); + xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT, + win, parent, x, y, w, h, 0, + XCB_WINDOW_CLASS_INPUT_ONLY, + XCB_COPY_FROM_PARENT, mask, mask_list); + + return win; +} + +/** + * 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) +{ + Ecore_X_Window win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0); + + return win; +} + +/** + * 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) +{ + Ecore_X_Window win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 0, 0); + + 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_argb_new(Ecore_X_Window parent, + int x, + int y, + int w, + int h) +{ + Ecore_X_Window win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0); + + return win; +} + +/** + * @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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (win) + { + /* xcb_destroy_notify_event_t ev; */ + /* Ecore_X_Window root; */ + + /* 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 *reply; */ + + /* cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); */ + /* reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); */ + /* if (!reply) return; */ + /* root = reply->root; */ + /* free(reply); */ + /* } */ + + /* memset(&ev, 0, sizeof(xcb_destroy_notify_event_t)); */ + + /* ev.response_type = XCB_DESTROY_NOTIFY; */ + /* ev.window = win; */ + /* ev.event = root; */ + + /* xcb_send_event(_ecore_xcb_conn, 0, root, */ + /* XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | */ + /* XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, */ + /* (const char *)&ev); */ + + xcb_destroy_window(_ecore_xcb_conn, win); +// ecore_x_flush(); + } +} + +/** + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + XCB_EVENT_MASK_NO_EVENT, + ECORE_X_ATOM_WM_DELETE_WINDOW, + XCB_CURRENT_TIME, 0, 0, 0); +} + +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) +{ + uint16_t vmask = 0; + uint32_t vlist[7]; + unsigned int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + + if (mask & XCB_CONFIG_WINDOW_X) + { + vmask |= XCB_CONFIG_WINDOW_X; + vlist[i++] = x; + } + if (mask & XCB_CONFIG_WINDOW_Y) + { + vmask |= XCB_CONFIG_WINDOW_Y; + vlist[i++] = y; + } + if (mask & XCB_CONFIG_WINDOW_WIDTH) + { + vmask |= XCB_CONFIG_WINDOW_WIDTH; + vlist[i++] = w; + } + if (mask & XCB_CONFIG_WINDOW_HEIGHT) + { + vmask |= XCB_CONFIG_WINDOW_HEIGHT; + vlist[i++] = h; + } + if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) + { + vmask |= XCB_CONFIG_WINDOW_BORDER_WIDTH; + vlist[i++] = border_width; + } + if (mask & XCB_CONFIG_WINDOW_SIBLING) + { + vmask |= XCB_CONFIG_WINDOW_SIBLING; + vlist[i++] = sibling; + } + if (mask & XCB_CONFIG_WINDOW_STACK_MODE) + { + vmask |= XCB_CONFIG_WINDOW_STACK_MODE; + vlist[i++] = stack_mode; + } + + xcb_configure_window(_ecore_xcb_conn, win, vmask, + (const uint32_t *)&vlist); +// ecore_x_flush(); +} + +/** + * @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) +{ + uint32_t list[2], mask; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + + mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y); + list[0] = x; + list[1] = y; + + xcb_configure_window(_ecore_xcb_conn, win, mask, + (const uint32_t *)&list); +// ecore_x_flush(); +} + +/** + * 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) +{ + uint32_t list[2], mask; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + if (w < 1) w = 1; + if (h < 1) h = 1; + + mask = (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT); + list[0] = w; + list[1] = h; + + xcb_configure_window(_ecore_xcb_conn, win, mask, + (const uint32_t *)&list); +// ecore_x_flush(); +} + +/** + * 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) +{ + uint32_t list[4], mask; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + if (w < 1) w = 1; + if (h < 1) h = 1; + + mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT); + list[0] = x; + list[1] = y; + list[2] = w; + list[3] = h; + + xcb_configure_window(_ecore_xcb_conn, win, mask, + (const uint32_t *)&list); +// ecore_x_flush(); +} + +/** + * 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__); + + 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 border_width) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) return; + + list = border_width; + + xcb_configure_window(_ecore_xcb_conn, win, + XCB_CONFIG_WINDOW_BORDER_WIDTH, &list); +// ecore_x_flush(); +} + +/** + * @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) +{ + uint32_t list[] = { XCB_STACK_MODE_ABOVE }; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_configure_window(_ecore_xcb_conn, win, + XCB_CONFIG_WINDOW_STACK_MODE, list); +// ecore_x_flush(); +} + +/** + * 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) +{ + uint32_t list[] = { XCB_STACK_MODE_BELOW }; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_configure_window(_ecore_xcb_conn, win, + XCB_CONFIG_WINDOW_STACK_MODE, list); +// ecore_x_flush(); +} + +/** + * 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); +} + +/** + * @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_Group + */ +EAPI void +ecore_x_window_defaults_set(Ecore_X_Window win) +{ + char buff[MAXHOSTNAMELEN], **argv; + int argc; + pid_t pid; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + gethostname(buff, MAXHOSTNAMELEN); + buff[MAXHOSTNAMELEN - 1] = '\0'; + + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + ECORE_X_ATOM_WM_CLIENT_MACHINE, ECORE_X_ATOM_STRING, + 8, strlen(buff), buff); + + 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); +} + +/** + * @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__); + CHECK_XCB_CONN; + + if (win) + xcb_map_window(_ecore_xcb_conn, 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (win) + { + xcb_unmap_notify_event_t ev; + Ecore_X_Window root; + + 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 *reply; + + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + root = reply->root; + free(reply); + } + + xcb_unmap_window(_ecore_xcb_conn, win); + memset(&ev, 0, sizeof(xcb_unmap_notify_event_t)); + + ev.response_type = XCB_UNMAP_NOTIFY; + ev.window = win; + ev.event = root; + 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); + +// ecore_x_flush(); + } +} + +/** + * @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__); + CHECK_XCB_CONN; + + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + xcb_set_input_focus(_ecore_xcb_conn, + XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME); +// ecore_x_flush(); +} + +/** + * 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 time EINA_UNUSED) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + xcb_set_input_focus(_ecore_xcb_conn, + XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME); +// ecore_x_flush(); +} + +/** + * @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 parent, + int x, + int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + xcb_reparent_window(_ecore_xcb_conn, win, parent, x, y); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_pixmap_set(Ecore_X_Window win, + Ecore_X_Pixmap pixmap) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = pixmap; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_BACK_PIXMAP, &list); +// ecore_x_flush(); +} + +/** + * 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 red, + unsigned short green, + unsigned short blue) +{ + xcb_alloc_color_cookie_t cookie; + xcb_alloc_color_reply_t *reply; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = + xcb_alloc_color_unchecked(_ecore_xcb_conn, + ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap, + red, green, blue); + reply = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return; + list = reply->pixel; + free(reply); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_BACK_PIXEL, &list); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_pixel_gravity_set(Ecore_X_Window win, + Ecore_X_Gravity gravity) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = gravity; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_BIT_GRAVITY, &list); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_gravity_set(Ecore_X_Window win, + Ecore_X_Gravity gravity) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = gravity; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_WIN_GRAVITY, &list); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_override_set(Ecore_X_Window win, + Eina_Bool override) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = override; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_OVERRIDE_REDIRECT, &list); +// ecore_x_flush(); +} + +/** + * @brief Show the cursor on a window of type Ecore_X_Window. + * @param win The window for which the cursor will be showed. + * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE. + */ +EAPI void +ecore_x_window_cursor_show(Ecore_X_Window win, + Eina_Bool show) +{ + uint32_t list = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (!show) + { + Ecore_X_Cursor cursor; + Ecore_X_Pixmap p, m; + Ecore_X_GC gc; + xcb_point_t point; + + p = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 1, p, win, 1, 1); + m = xcb_generate_id(_ecore_xcb_conn); + xcb_create_pixmap(_ecore_xcb_conn, 1, m, win, 1, 1); + gc = xcb_generate_id(_ecore_xcb_conn); + xcb_create_gc(_ecore_xcb_conn, gc, win, 0, NULL); + xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list); + point.x = 0; + point.y = 0; + xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN, + win, gc, 1, &point); + xcb_free_gc(_ecore_xcb_conn, gc); + + cursor = xcb_generate_id(_ecore_xcb_conn); + xcb_create_cursor(_ecore_xcb_conn, cursor, + p, m, 0, 0, 0, 0, 0, 0, 0, 0); + list = cursor; + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_CURSOR, &list); + + xcb_free_cursor(_ecore_xcb_conn, cursor); + xcb_free_pixmap(_ecore_xcb_conn, m); + xcb_free_pixmap(_ecore_xcb_conn, p); + } + else + { + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_CURSOR, &list); + } +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_cursor_set(Ecore_X_Window win, + Ecore_X_Cursor cursor) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = cursor; + + xcb_change_window_attributes(_ecore_xcb_conn, win, XCB_CW_CURSOR, &list); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_container_manage(Ecore_X_Window win) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_client_manage(Ecore_X_Window win) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = (XCB_EVENT_MASK_VISIBILITY_CHANGE | + XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); + +#ifdef ECORE_XCB_SHAPE + xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE); +#endif +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_sniff(Ecore_X_Window win) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_PROPERTY_CHANGE); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_client_sniff(Ecore_X_Window win) +{ + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + list = (XCB_EVENT_MASK_VISIBILITY_CHANGE | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_FOCUS_CHANGE | + XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE); + + xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); +#ifdef ECORE_XCB_SHAPE + xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE); +#endif +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_area_clear(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_clear_area(_ecore_xcb_conn, 0, win, x, y, w, h); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_area_expose(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_clear_area(_ecore_xcb_conn, 1, win, x, y, w, h); +// ecore_x_flush(); +} + +EAPI void +ecore_x_window_save_set_add(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, win); +} + +EAPI void +ecore_x_window_save_set_del(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, win); +} + +/** + * gets the window that has focus. + * @return The window that has focus. + * @ingroup Ecore_X_Window_Focus_Functions + */ +EAPI Ecore_X_Window +ecore_x_window_focus_get(void) +{ + xcb_get_input_focus_cookie_t cookie; + xcb_get_input_focus_reply_t *reply; + Ecore_X_Window focus = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn); + reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + focus = reply->focus; + free(reply); + return focus; +} + +EAPI int +ecore_x_window_argb_get(Ecore_X_Window win) +{ + uint8_t ret = 0; +#ifdef ECORE_XCB_RENDER + Ecore_X_Visual visual; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +// if (!win) return ret; + +#ifdef ECORE_XCB_RENDER + /* grab the window's visual */ + visual = _ecore_xcb_window_visual_get(win); + + /* check if this visual supports alpha */ + ret = _ecore_xcb_render_visual_supports_alpha(visual); +#endif + + return ret; +} + +EAPI Eina_Bool +ecore_x_window_manage(Ecore_X_Window win) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + xcb_void_cookie_t change_cookie; + xcb_generic_error_t *err; + uint32_t list; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_window_attributes(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + ecore_x_sync(); // needed + + list = (XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | + XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | + reply->your_event_mask); + free(reply); + + change_cookie = xcb_change_window_attributes(_ecore_xcb_conn, win, + XCB_CW_EVENT_MASK, &list); + + ecore_x_sync(); // needed + + err = xcb_request_check(_ecore_xcb_conn, change_cookie); + if (err) + { + _ecore_xcb_error_handle(err); + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_window_attributes_get(Ecore_X_Window win, + Ecore_X_Window_Attributes *att_ret) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + xcb_get_geometry_cookie_t gcookie; + xcb_get_geometry_reply_t *greply; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes)); + + if (reply->map_state != XCB_MAP_STATE_UNMAPPED) + att_ret->visible = EINA_TRUE; + + if (reply->map_state == XCB_MAP_STATE_VIEWABLE) + att_ret->viewable = EINA_TRUE; + + if (reply->override_redirect) + att_ret->override = EINA_TRUE; + + if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY) + att_ret->input_only = EINA_TRUE; + + if (reply->save_under) + att_ret->save_under = EINA_TRUE; + + 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 = _ecore_xcb_window_find_visual_by_id(reply->visual); + + free(reply); + + gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); + greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL); + if (!greply) return EINA_TRUE; + + /* xcb_translate_coordinates_reply_t *trans; */ + /* xcb_query_tree_cookie_t tcookie; */ + /* xcb_query_tree_reply_t *treply; */ + + /* tcookie = xcb_query_tree(_ecore_xcb_conn, win); */ + /* treply = xcb_query_tree_reply(_ecore_xcb_conn, tcookie, NULL); */ + + /* trans = */ + /* xcb_translate_coordinates_reply(_ecore_xcb_conn, */ + /* xcb_translate_coordinates(_ecore_xcb_conn, */ + /* win, treply->parent, greply->x, greply->y), NULL); */ + /* free(treply); */ + + att_ret->root = greply->root; + att_ret->depth = greply->depth; +// att_ret->x = trans->dst_x; +// att_ret->y = trans->dst_y; + att_ret->x = greply->x; + att_ret->y = greply->y; + att_ret->w = greply->width; + att_ret->h = greply->height; + att_ret->border = greply->border_width; + +// free(trans); + + free(greply); + return EINA_TRUE; +} + +/** + * 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 *width, + int *height) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + ecore_x_drawable_geometry_get(win, NULL, NULL, width, height); +} + +/** + * 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 = 0, j = 0, count = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + 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)); + if (!ignore_list) return; + ignore_list[ignore_num++] = win; + } + } + else + { + if (!ignore_list) return; + for (count = ignore_num, i = 0, j = 0; i < count; i++) + { + if (win != ignore_list[i]) + ignore_list[j++] = ignore_list[i]; + else + ignore_num--; + } + if (ignore_num <= 0) + { + free(ignore_list); + ignore_list = NULL; + return; + } + + 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (num) *num = ignore_num; + return ignore_list; +} + +/** + * 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; + uint8_t i, num; + Ecore_X_Window *roots = NULL; +#ifdef ECORE_XCB_XPRINT + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!num_ret) return NULL; + if (num_ret) *num_ret = 0; + + /* if (xcb_connection_has_error(_ecore_xcb_conn)) */ + /* { */ + /* DBG("XCB Connection Has Error !!!"); */ + /* return NULL; */ + /* } */ + + num = ecore_x_screen_count_get(); + +#ifdef ECORE_XCB_XPRINT + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_x_print_print_query_screens_cookie_t cookie; + xcb_x_print_print_query_screens_reply_t *reply; + + cookie = xcb_x_print_print_query_screens_unchecked(_ecore_xcb_conn); + reply = + xcb_x_print_print_query_screens_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + xcb_window_t *screens; + int psnum = 0, overlap = 0, j = 0, k = 0; + + psnum = xcb_x_print_print_query_screens_roots_length(reply); + screens = xcb_x_print_print_query_screens_roots(reply); + for (i = 0; i < num; i++) + { + for (j = 0; j < psnum; j++) + { + xcb_screen_t *s; + + if ((s = _ecore_xcb_window_screen_of_display(i))) + { + if (s->root == screens[j]) + overlap++; + } + } + } + if (!(roots = malloc((num - overlap) + * sizeof(Ecore_X_Window)))) return NULL; + for (i = 0; i < num; i++) + { + Eina_Bool is_print = EINA_FALSE; + + for (j = 0; j < psnum; j++) + { + xcb_screen_t *s; + + if ((s = _ecore_xcb_window_screen_of_display(i))) + { + if (s->root == screens[j]) + { + is_print = EINA_TRUE; + break; + } + } + } + if (!is_print) + { + xcb_screen_t *s; + + if ((s = _ecore_xcb_window_screen_of_display(i))) + { + roots[k] = s->root; + k++; + } + } + } + if (num_ret) *num_ret = k; + free(reply); + } + else + { + /* Fallback to default method */ + iter = + xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); + if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL; + if (num_ret) *num_ret = num; + for (i = 0; iter.rem; xcb_screen_next(&iter), i++) + roots[i] = iter.data->root; + } + } + else + { + /* Fallback to default method */ + iter = + xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); + if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL; + if (num_ret) *num_ret = num; + for (i = 0; iter.rem; xcb_screen_next(&iter), i++) + roots[i] = iter.data->root; + } +#else + iter = + xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); + if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL; + if (num_ret) *num_ret = num; + for (i = 0; iter.rem; xcb_screen_next(&iter), i++) + roots[i] = iter.data->root; +#endif + + return roots; +} + +EAPI Ecore_X_Window * +ecore_x_window_children_get(Ecore_X_Window win, + int *num) +{ + xcb_query_tree_cookie_t cookie; + xcb_query_tree_reply_t *reply; + Ecore_X_Window *windows = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (num) *num = 0; + cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, win); + reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + + if (num) *num = reply->children_len; + if (reply->children_len > 0) + { + windows = malloc(sizeof(Ecore_X_Window) * reply->children_len); + if (windows) + { + unsigned int i = 0; + xcb_window_t *w; + + w = xcb_query_tree_children(reply); + for (i = 0; i < reply->children_len; i++) + windows[i] = w[i]; + } + } + + free(reply); + return windows; +} + +/** + * 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) +{ + xcb_get_geometry_cookie_t gcookie; + xcb_get_geometry_reply_t *greply; + Ecore_X_Window window = 0; + + /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */ + CHECK_XCB_CONN; + + gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); + greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL); + if (!greply) return 0; + window = greply->root; + free(greply); + + return window; +} + +EAPI Ecore_X_Window +ecore_x_window_root_first_get(void) +{ + return ((xcb_screen_t *)_ecore_xcb_screen)->root; +} + +/** + * Retrieves the geometry of the given window. + * + * Note that the x & y coordingates are relative to your parent. In + * particular for reparenting window managers - relative to you window border. + * If you want screen coordinates either walk the window tree to the root, + * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary + * applications can use elm_win_screen_position_get(). + * + * @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__); + CHECK_XCB_CONN; + + if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + ecore_x_drawable_geometry_get(win, x, y, w, h); +} + +/** + * 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 root, win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + ecore_x_grab(); + win = _ecore_xcb_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. + * @param skip The list of windows to be skipped. + * @param skip_num The number of windows to be skipped. + * @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 root, win = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + ecore_x_grab(); + win = _ecore_xcb_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 = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + ecore_x_grab(); + win = _ecore_xcb_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) +{ + xcb_query_tree_cookie_t cookie; + xcb_query_tree_reply_t *reply; + Ecore_X_Window window = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +// if (!win) return 0; + cookie = xcb_query_tree(_ecore_xcb_conn, win); + reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + window = reply->parent; + free(reply); + + return window; +} + +/** + * 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) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + int ret = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + if (reply->map_state == XCB_MAP_STATE_VIEWABLE) + ret = EINA_TRUE; + + free(reply); + return ret; +} + +EAPI void +ecore_x_window_button_grab(Ecore_X_Window win, + int button, + Ecore_X_Event_Mask mask, + int mod, + int any_mod) +{ + int i = 0; + uint16_t m, locks[8], ev; + uint8_t b; + Ecore_X_Window *t; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + b = button; + if (b == 0) + b = XCB_BUTTON_INDEX_ANY; + + m = _ecore_xcb_window_modifiers_get(mod); + if (any_mod) m = XCB_MOD_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 = mask; + for (i = 0; i < 8; i++) + xcb_grab_button(_ecore_xcb_conn, 0, win, ev, + XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, + XCB_NONE, XCB_NONE, b, m | locks[i]); + + _ecore_xcb_button_grabs_num++; + t = realloc(_ecore_xcb_button_grabs, + _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window)); + if (!t) return; + + _ecore_xcb_button_grabs = t; + _ecore_xcb_button_grabs[_ecore_xcb_button_grabs_num - 1] = win; +} + +EAPI void +ecore_x_window_button_ungrab(Ecore_X_Window win, + int button, + int mod, + int any_mod) +{ + int i = 0; + uint16_t m = 0, locks[8]; + uint8_t b; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + b = button; + if (b == 0) b = XCB_BUTTON_INDEX_ANY; + + m = _ecore_xcb_window_modifiers_get(mod); + if (any_mod) m = XCB_MOD_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, b, win, m | locks[i]); + + _ecore_xcb_sync_magic_send(1, win); +} + +EAPI void +ecore_x_window_key_grab(Ecore_X_Window win, + const char *key, + int mod, + int any_mod) +{ + xcb_keycode_t keycode = XCB_NO_SYMBOL; + uint16_t m = 0, locks[8]; + int i = 0; + Ecore_X_Window *t; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + keycode = _ecore_xcb_keymap_string_to_keycode(key); + if (keycode == XCB_NO_SYMBOL) return; + + m = _ecore_xcb_window_modifiers_get(mod); + if (any_mod) m = XCB_MOD_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, 0, win, m | locks[i], + keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); + _ecore_xcb_key_grabs_num++; + t = realloc(_ecore_xcb_key_grabs, + _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window)); + if (!t) return; + _ecore_xcb_key_grabs = t; + _ecore_xcb_key_grabs[_ecore_xcb_key_grabs_num - 1] = win; +} + +EAPI void +ecore_x_window_key_ungrab(Ecore_X_Window win, + const char *key, + int mod, + int any_mod) +{ + xcb_keycode_t keycode = XCB_NO_SYMBOL; + uint16_t m = 0, locks[8]; + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + keycode = _ecore_xcb_keymap_string_to_keycode(key); + if (keycode == XCB_NO_SYMBOL) return; + + m = _ecore_xcb_window_modifiers_get(mod); + if (any_mod) m = XCB_MOD_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, win, m | locks[i]); + + _ecore_xcb_sync_magic_send(2, win); +} + +/* local functions */ +Ecore_X_Window +_ecore_xcb_window_root_of_screen_get(int screen) +{ + xcb_screen_iterator_t iter; + + CHECK_XCB_CONN; + iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); + for (; iter.rem; --screen, xcb_screen_next(&iter)) + if (screen == 0) + { + xcb_screen_t *s; + + if ((s = iter.data)) + return s->root; + } + return 0; +} + +static Ecore_X_Window +_ecore_xcb_window_argb_internal_new(Ecore_X_Window parent, + int x, + int y, + int w, + int h, + uint8_t override_redirect, + uint8_t save_under) +{ + Ecore_X_Window win = 0; +#ifdef ECORE_XCB_RENDER + uint32_t value_list[10]; + uint32_t value_mask; + uint32_t vis; + Ecore_X_Colormap colormap; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_RENDER + if (parent == 0) + parent = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + vis = + _ecore_xcb_render_find_visual_id(XCB_RENDER_PICT_TYPE_DIRECT, EINA_TRUE); + + 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_BACK_PIXMAP_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, 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); +#endif + + return win; +} + +static Ecore_X_Window +_ecore_xcb_window_at_xy_get(Ecore_X_Window base, + int bx, + int by, + int x, + int y, + Ecore_X_Window *skip, + int skip_num) +{ + xcb_query_tree_cookie_t cookie; + xcb_query_tree_reply_t *reply; + Ecore_X_Window *windows = NULL; + int wx, wy, ww, wh, num, i = 0; + Eina_Bool skipit = EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!ecore_x_window_visible_get(base)) return 0; + + 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; + + cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, base); + reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + + num = reply->children_len; + windows = xcb_query_tree_children(reply); + + for (i = (num - 1); i >= 0; --i) + { + skipit = EINA_FALSE; + + if (skip) + { + int j = 0; + + for (j = 0; j < skip_num; j++) + { + if (windows[i] == skip[j]) + { + skipit = EINA_TRUE; + goto onward; + } + } + } +onward: + if (!skipit) + { + Ecore_X_Window child = 0; + + child = + _ecore_xcb_window_at_xy_get(windows[i], + wx, wy, x, y, skip, skip_num); + if (child) + { + if (reply) free(reply); + return child; + } + } + } + + if (reply) free(reply); + return base; +} + +Ecore_X_Visual +_ecore_xcb_window_visual_get(Ecore_X_Window win) +{ + xcb_get_window_attributes_cookie_t cookie; + xcb_get_window_attributes_reply_t *reply; + Ecore_X_Visual visual = 0; + + CHECK_XCB_CONN; + + cookie = xcb_get_window_attributes(_ecore_xcb_conn, win); + reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + visual = _ecore_xcb_window_find_visual_by_id(reply->visual); + free(reply); + + return visual; +} + +void +_ecore_xcb_window_button_grab_remove(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (_ecore_xcb_button_grabs_num > 0) + { + int i = 0, shuffle = 0; + + for (i = 0; i < _ecore_xcb_button_grabs_num; i++) + { + if (shuffle) + _ecore_xcb_button_grabs[i - 1] = _ecore_xcb_button_grabs[i]; + + if ((!shuffle) && (_ecore_xcb_button_grabs[i] == win)) + shuffle = 1; + } + + if (shuffle) + { + Ecore_X_Window *t; + + _ecore_xcb_button_grabs_num--; + if (_ecore_xcb_button_grabs_num <= 0) + { + free(_ecore_xcb_button_grabs); + _ecore_xcb_button_grabs = NULL; + return; + } + + t = realloc(_ecore_xcb_button_grabs, + _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window)); + if (!t) return; + _ecore_xcb_button_grabs = t; + } + } +} + +void +_ecore_xcb_window_key_grab_remove(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (_ecore_xcb_key_grabs_num > 0) + { + int i = 0, shuffle = 0; + + for (i = 0; i < _ecore_xcb_key_grabs_num; i++) + { + if (shuffle) + _ecore_xcb_key_grabs[i - 1] = _ecore_xcb_key_grabs[i]; + + if ((!shuffle) && (_ecore_xcb_key_grabs[i] == win)) + shuffle = 1; + } + + if (shuffle) + { + Ecore_X_Window *t; + + _ecore_xcb_key_grabs_num--; + if (_ecore_xcb_key_grabs_num <= 0) + { + free(_ecore_xcb_key_grabs); + _ecore_xcb_key_grabs = NULL; + return; + } + + t = realloc(_ecore_xcb_key_grabs, + _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window)); + if (!t) return; + _ecore_xcb_key_grabs = t; + } + } +} + +void +_ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win, + Ecore_X_Window child_win, + int type, + void *event, + Ecore_X_Time timestamp) +{ + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + for (i = 0; i < _ecore_xcb_button_grabs_num; i++) + { + if ((_ecore_xcb_button_grabs[i] == event_win) || + (_ecore_xcb_button_grabs[i] == child_win)) + { + Eina_Bool replay = EINA_FALSE; + + if (_ecore_xcb_window_grab_replay_func) + { + replay = + _ecore_xcb_window_grab_replay_func(_ecore_xcb_window_grab_replay_data, + type, event); + } + if (replay) + { + xcb_allow_events(_ecore_xcb_conn, + XCB_ALLOW_REPLAY_POINTER, timestamp); + } + else + { + xcb_allow_events(_ecore_xcb_conn, + XCB_ALLOW_ASYNC_POINTER, timestamp); + } + break; + } + } +} + +static int +_ecore_xcb_window_modifiers_get(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_MODIFIER_ALTGR) + xmodifiers |= ECORE_X_MODIFIER_ALTGR; + 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; + if (state & ECORE_EVENT_LOCK_SHIFT) + xmodifiers |= ECORE_X_LOCK_SHIFT; + + return xmodifiers; +} + +static xcb_visualtype_t * +_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id) +{ + xcb_depth_iterator_t diter; + xcb_visualtype_iterator_t viter; + + CHECK_XCB_CONN; + diter = xcb_screen_allowed_depths_iterator(_ecore_xcb_screen); + for (; diter.rem; xcb_depth_next(&diter)) + { + viter = xcb_depth_visuals_iterator(diter.data); + for (; viter.rem; xcb_visualtype_next(&viter)) + { + if (viter.data->visual_id == id) + return viter.data; + } + } + return 0; +} + +#ifdef ECORE_XCB_XPRINT +static xcb_screen_t * +_ecore_xcb_window_screen_of_display(int screen) +{ + xcb_screen_iterator_t iter; + + CHECK_XCB_CONN; + iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)); + for (; iter.rem; --screen, xcb_screen_next(&iter)) + if (screen == 0) + return iter.data; + + return NULL; +} + +#endif diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c b/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c new file mode 100644 index 0000000000..e00fdc1963 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c @@ -0,0 +1,720 @@ +#include "ecore_xcb_private.h" +#include + +EAPI int +ecore_x_window_prop_card32_get(Ecore_X_Window win, + Ecore_X_Atom atom, + unsigned int *val, + unsigned int len) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + int num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, + ECORE_X_ATOM_CARDINAL, 0, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return -1; + + if ((reply->type != ECORE_X_ATOM_CARDINAL) || (reply->format != 32)) + num = -1; + else if (reply->value_len == 0) + num = 0; + else + { + if (reply->value_len < len) + len = reply->value_len; + + if (val) + { + unsigned int i = 0; + unsigned char *v; + + v = xcb_get_property_value(reply); + for (i = 0; i < len; i++) + val[i] = ((uint32_t *)v)[i]; + num = len; + } + } + + if (reply) free(reply); + return num; +} + +EAPI void +ecore_x_window_prop_card32_set(Ecore_X_Window win, + Ecore_X_Atom atom, + unsigned int *val, + unsigned int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#if SIZEOF_INT == SIZEOF_LONG + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, + ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)val); +// ecore_x_flush(); +#else + long *v2; + unsigned int i; + + v2 = malloc(num * sizeof(long)); + if (!v2) return; + for (i = 0; i < num; i++) + v2[i] = val[i]; + + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, + ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)v2); + free(v2); +// ecore_x_flush(); +#endif +} + +EAPI int +ecore_x_window_prop_card32_list_get(Ecore_X_Window win, + Ecore_X_Atom atom, + unsigned int **list) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + int num = -1; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (list) *list = NULL; + + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, + XCB_ATOM_CARDINAL, 0, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return -1; + + if ((reply->type != XCB_ATOM_CARDINAL) || (reply->format != 32)) + num = -1; + else if ((reply->value_len == 0) || (!xcb_get_property_value(reply))) + num = 0; + else + { + num = reply->value_len; + if (list) + { + unsigned int *val; + void *data; + int i = 0; + + val = malloc(num * sizeof(unsigned int)); + if (!val) + { + free(reply); + return -1; + } + data = xcb_get_property_value(reply); + for (i = 0; i < num; i++) + val[i] = ((uint32_t *)data)[i]; + *list = val; + } + } + + free(reply); + return num; +} + +EAPI int +ecore_x_window_prop_atom_get(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Atom *list, + unsigned int len) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len); +} + +EAPI void +ecore_x_window_prop_atom_set(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Atom *list, + unsigned int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, */ + /* ECORE_X_ATOM_ATOM, 32, num, list); */ + ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_ATOM, list, num); +} + +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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#if SIZEOF_INT == SIZEOF_LONG + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, + type, 32, num, (unsigned char *)xids); +// ecore_x_flush(); +#else + long *v2; + unsigned int i; + + v2 = malloc(num * sizeof(long)); + if (!v2) return; + for (i = 0; i < num; i++) + v2[i] = xids[i]; + + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom, + type, 32, num, (unsigned char *)v2); + free(v2); +// ecore_x_flush(); +#endif +} + +EAPI int +ecore_x_window_prop_xid_get(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Atom type, + Ecore_X_ID *xids, + unsigned int len) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + int num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + num = len; + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, type, + 0, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return -1; + + if ((reply->type != type) || (reply->format != 32)) + num = -1; + else if (reply->value_len == 0) + num = 0; + else + { + unsigned int i = 0; + unsigned char *v; + + if (reply->value_len < len) + len = reply->value_len; + + v = xcb_get_property_value(reply); + for (i = 0; i < len; i++) + xids[i] = ((uint32_t *)v)[i]; + + num = len; + } + + if (reply) free(reply); + return num; +} + +EAPI void +ecore_x_window_prop_string_set(Ecore_X_Window win, + Ecore_X_Atom type, + const char *str) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, type, + ECORE_X_ATOM_UTF8_STRING, 8, strlen(str), str); +// ecore_x_flush(); +} + +EAPI char * +ecore_x_window_prop_string_get(Ecore_X_Window win, + Ecore_X_Atom type) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + char *str = NULL; + int len = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + cookie = + xcb_get_property_unchecked(_ecore_xcb_conn, 0, + win ? win : ((xcb_screen_t *)_ecore_xcb_screen)->root, + type, XCB_GET_PROPERTY_TYPE_ANY, 0, 1000000L); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + + len = ((reply->value_len * reply->format) / 8); + str = (char *)malloc((len + 1) * sizeof(char)); + memcpy(str, xcb_get_property_value(reply), len); + str[len] = '\0'; + + if (reply->type != ECORE_X_ATOM_UTF8_STRING) + { + Ecore_Xcb_Textproperty prop; + int count = 0; + char **list = NULL; + Eina_Bool ret = EINA_FALSE; + + prop.value = strdup(str); + prop.nitems = len; + prop.encoding = reply->type; + +#ifdef HAVE_ICONV + ret = _ecore_xcb_utf8_textproperty_to_textlist(&prop, &list, &count); +#else + ret = _ecore_xcb_mb_textproperty_to_textlist(&prop, &list, &count); +#endif + if (ret) + { + if (count > 0) + str = strdup(list[0]); + else + str = strdup((char *)prop.value); + + if (list) free(list); + } + else + str = strdup((char *)prop.value); + } + + free(reply); + return str; +} + +EAPI int +ecore_x_window_prop_window_get(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Window *list, + unsigned int len) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_WINDOW, list, len); +} + +EAPI void +ecore_x_window_prop_window_set(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Window *list, + unsigned int num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_WINDOW, list, num); +} + +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, ECORE_X_ATOM_WINDOW, plst); +} + +EAPI Ecore_X_Atom +ecore_x_window_prop_any_type(void) +{ + return XCB_ATOM_ANY; +} + +EAPI void +ecore_x_window_prop_property_del(Ecore_X_Window win, + Ecore_X_Atom property) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + xcb_delete_property(_ecore_xcb_conn, win, property); +} + +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 num) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (win == 0) + win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + if (size != 32) + { + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + property, type, size, num, (unsigned char *)data); +// ecore_x_flush(); + } + else + { + uint32_t *dat; + int i = 0, *ptr; + + dat = malloc(sizeof(uint32_t) * num); + if (dat) + { + for (ptr = (int *)data, i = 0; i < num; i++) + dat[i] = ptr[i]; + xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, + property, type, size, num, + (unsigned char *)dat); + free(dat); +// ecore_x_flush(); + } + } +} + +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) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + int format = 0; + unsigned int i = 0; + void *value; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (num) *num = 0; + + if (data) + *data = NULL; + else + return 0; + + if (win == 0) + win = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + cookie = + xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, + property, type, 0, UINT_MAX); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + if ((reply->format != size) || (reply->value_len == 0)) + { + free(reply); + return 0; + } + + if (!(*data = malloc(reply->value_len * reply->format / 8))) + { + free(reply); + return 0; + } + + value = xcb_get_property_value(reply); + switch (reply->format) + { + case 8: + for (i = 0; i < reply->value_len; i++) + (*data)[i] = ((unsigned char *)value)[i]; + break; + + case 16: + for (i = 0; i < reply->value_len; i++) + ((unsigned short *)*data)[i] = ((unsigned short *)value)[i]; + break; + + case 32: + for (i = 0; i < reply->value_len; i++) + ((unsigned int *)*data)[i] = ((uint32_t *)value)[i]; + break; + } + + if (num) *num = reply->value_len; + format = reply->format; + free(reply); + return format; +} + +EAPI int +ecore_x_window_prop_atom_list_get(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Atom **list) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, list); +} + +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, ECORE_X_ATOM_ATOM, item, op); +} + +EAPI int +ecore_x_window_prop_xid_list_get(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Atom type, + Ecore_X_ID **xids) +{ + xcb_get_property_cookie_t cookie; + xcb_get_property_reply_t *reply; + int num = -1; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (xids) *xids = NULL; + + cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, type, + 0, 0x7fffffff); + reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return -1; + + if ((reply->type != type) || (reply->format != 32)) + num = -1; + else if ((reply->value_len == 0) || (!xcb_get_property_value(reply))) + num = 0; + else + { + Ecore_X_Atom *alst; + void *val; + + num = xcb_get_property_value_length(reply); + val = xcb_get_property_value(reply); + alst = malloc(num * sizeof(Ecore_X_ID)); + if (alst) + { + int i = 0; + + for (i = 0; i < num; i++) + alst[i] = ((uint32_t *)val)[i]; + *xids = alst; + } + } + + free(reply); + return num; +} + +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 = 0, num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst); + if (num < 0) return; + + for (i = 0; i < num; i++) + { + if (lst[i] == item) break; + } + + if (i < num) + { + if (op == ECORE_X_PROP_LIST_ADD) + goto done; + num--; + for (; i < num; i++) + lst[i] = lst[i + 1]; + } + else + { + if (op == ECORE_X_PROP_LIST_REMOVE) + goto done; + 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); +} + +EAPI Eina_Bool +ecore_x_window_prop_protocol_isset(Ecore_X_Window win, + Ecore_X_WM_Protocol protocol) +{ + Eina_Bool ret = EINA_FALSE; + Ecore_X_Atom proto; +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_t protos; +#else + xcb_icccm_get_wm_protocols_reply_t protos; +#endif + xcb_get_property_cookie_t cookie; + uint8_t reply; + uint32_t count = 0, i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE; + + proto = _ecore_xcb_atoms_wm_protocol[protocol]; +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS); + reply = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL); +#else + cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS); + reply = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, + &protos, NULL); +#endif + if (!reply) return EINA_FALSE; + + count = protos.atoms_len; + for (i = 0; i < count; i++) + { + if (protos.atoms[i] == proto) + { + ret = EINA_TRUE; + break; + } + } + +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_wipe(&protos); +#else + xcb_icccm_get_wm_protocols_reply_wipe(&protos); +#endif + return ret; +} + +EAPI Ecore_X_WM_Protocol * +ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, + int *num_ret) +{ +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_t protos; +#else + xcb_icccm_get_wm_protocols_reply_t protos; +#endif + xcb_get_property_cookie_t cookie; + uint8_t reply; + uint32_t count = 0, i = 0; + Ecore_X_WM_Protocol *prot_ret = NULL; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!num_ret) return NULL; + + *num_ret = 0; + +#ifdef OLD_XCB_VERSION + cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS); + reply = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL); +#else + cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, + ECORE_X_ATOM_WM_PROTOCOLS); + reply = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, + &protos, NULL); +#endif + if (!reply) return NULL; + + count = protos.atoms_len; + if (count <= 0) + { +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_wipe(&protos); +#else + xcb_icccm_get_wm_protocols_reply_wipe(&protos); +#endif + return NULL; + } + + prot_ret = calloc(1, count * sizeof(Ecore_X_WM_Protocol)); + if (!prot_ret) + { +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_wipe(&protos); +#else + xcb_icccm_get_wm_protocols_reply_wipe(&protos); +#endif + return NULL; + } + + for (i = 0; i < count; 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_protocol[j] == protos.atoms[i]) + prot_ret[i] = j; + } + } + + if (num_ret) *num_ret = count; + +#ifdef OLD_XCB_VERSION + xcb_get_wm_protocols_reply_wipe(&protos); +#else + xcb_icccm_get_wm_protocols_reply_wipe(&protos); +#endif + return prot_ret; +} + +EAPI Ecore_X_Atom * +ecore_x_window_prop_list(Ecore_X_Window win, + int *num) +{ + xcb_list_properties_cookie_t cookie; + xcb_list_properties_reply_t *reply; + xcb_atom_t *atm; + Ecore_X_Atom *atoms; + int i = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (num) *num = 0; + + cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, win); + reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + + atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom)); + if (!atoms) + { + free(reply); + return NULL; + } + + atm = xcb_list_properties_atoms(reply); + for (i = 0; i < reply->atoms_len; i++) + atoms[i] = atm[i]; + + if (num) *num = reply->atoms_len; + free(reply); + + return atoms; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c b/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c new file mode 100644 index 0000000000..d46e306c8d --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_window_shadow.c @@ -0,0 +1,410 @@ +#include "ecore_xcb_private.h" + +typedef struct _Shadow Shadow; +struct _Shadow +{ + Shadow *parent, **children; + Ecore_X_Window win; + int children_num; + short x, y; + unsigned short w, h; +}; + +static Eina_Bool _inside_rects(Shadow *s, + int x, + int y, + int bx, + int by, + Ecore_X_Rectangle *rects, + int num); + +//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, **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, j; + + CHECK_XCB_CONN; + + cookie_attr = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window); + reply_attr = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_attr, NULL); + if (!reply_attr) return NULL; + if (reply_attr->map_state != XCB_MAP_STATE_VIEWABLE) + { + free(reply_attr); + return NULL; + } + + free(reply_attr); + + 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 NULL; + + if (!(s = calloc(1, sizeof(Shadow)))) + { + free(reply_geom); + 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); + + cookie_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, window); + reply_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_tree, NULL); + if (reply_tree) + { + 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 = 0; + + 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 = 0; + + 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 = NULL; + int i = 0, num = 0; + + if ((roots = ecore_x_window_root_list(&num))) + { + 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 = 0; + + 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 = 0; + + 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; + Ecore_X_Rectangle *rects; + int i = 0, j = 0, wx = 0, wy = 0, num = 0; + + wx = s->x + bx; + wy = s->y + by; + if (!((x >= wx) && (y >= wy) && (x < (wx + s->w)) && (y < (wy + s->h)))) + return 0; + + rects = ecore_x_window_shape_rectangles_get(s->win, &num); + if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0; + num = 0; + rects = ecore_x_window_shape_input_rectangles_get(s->win, &num); + if (!_inside_rects(s, x, y, bx, by, rects, num)) 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); +} + +static Eina_Bool +_inside_rects(Shadow *s, + int x, + int y, + int bx, + int by, + Ecore_X_Rectangle *rects, + int num) +{ + Eina_Bool inside = EINA_FALSE; + int i = 0; + + if (!rects) return EINA_FALSE; + for (i = 0; i < num; i++) + { + if ((x >= s->x + bx + rects[i].x) && + (y >= s->y + by + rects[i].y) && + (x < (int)(s->x + bx + rects[i].x + rects[i].width)) && + (y < (int)(s->y + by + rects[i].y + rects[i].height))) + { + inside = EINA_TRUE; + break; + } + } + free(rects); + return inside; +} + +/** + * 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. + * @param skip The list of windows to be skipped. + * @param skip_num The number of windows to be skipped. + * @return The window at the desired 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 EINA_UNUSED, + Ecore_X_Window win) +{ + Shadow *s; + int i = 0; + + 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(); +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c b/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c new file mode 100644 index 0000000000..6206a51833 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_window_shape.c @@ -0,0 +1,790 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_SHAPE +# include +#endif + +/** + * @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 input shape of the given window to that given by the pixmap @p mask. + * @param win The given window. + * @param mask A 1-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__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, + win, 0, 0, mask); +// ecore_x_flush(); +#else + return; + win = 0; + mask = 0; +#endif +} + +/** + * 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__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_mask(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, + win, 0, 0, mask); +// ecore_x_flush(); +#else + return; + win = 0; + mask = 0; +#endif +} + +EAPI void +ecore_x_window_shape_window_set(Ecore_X_Window win, + Ecore_X_Window shape_win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, + XCB_SHAPE_SK_BOUNDING, win, 0, 0, shape_win); +// ecore_x_flush(); +#else + return; + win = 0; + shape_win = 0; +#endif +} + +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__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, + XCB_SHAPE_SK_BOUNDING, win, x, y, shape_win); +// ecore_x_flush(); +#else + return; + win = 0; + shape_win = 0; + x = 0; + y = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_set(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +// ecore_x_flush(); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangles_set(Ecore_X_Window win, + Ecore_X_Rectangle *rects, + int num) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t *rect = NULL; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!rects) return; + +#ifdef ECORE_XCB_SHAPE + if (num > 0) + { + int i = 0; + + if (!(rect = malloc(sizeof(xcb_rectangle_t) * num))) + return; + + 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; + } + } + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, num, (xcb_rectangle_t *)rect); + + if (rect) free(rect); +// ecore_x_flush(); +#else + return; + win = 0; + num = 0; + rects = NULL; +#endif +} + +EAPI void +ecore_x_window_shape_window_add(Ecore_X_Window win, + Ecore_X_Window shape_win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, + win, 0, 0, shape_win); +// ecore_x_flush(); +#else + return; + win = 0; + shape_win = 0; +#endif +} + +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__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_SHAPE_SK_BOUNDING, + win, x, y, shape_win); +// ecore_x_flush(); +#else + return; + win = 0; + shape_win = 0; + x = 0; + y = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_add(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +// ecore_x_flush(); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_subtract(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SUBTRACT, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +// ecore_x_flush(); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_INTERSECT, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +// ecore_x_flush(); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangles_add(Ecore_X_Window win, + Ecore_X_Rectangle *rects, + int num) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t *rect = NULL; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + if (num > 0) + { + int i = 0; + + if (!(rect = malloc(sizeof(xcb_rectangle_t) * num))) + return; + + 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; + } + } + + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, num, (xcb_rectangle_t *)&rect); + + if (rect) free(rect); +// ecore_x_flush(); +#else + return; + win = 0; + num = 0; + rects = NULL; +#endif +} + +EAPI Ecore_X_Rectangle * +ecore_x_window_shape_rectangles_get(Ecore_X_Window win, + int *num_ret) +{ + Ecore_X_Rectangle *rects = NULL; +#ifdef ECORE_XCB_SHAPE + xcb_shape_get_rectangles_cookie_t cookie; + xcb_shape_get_rectangles_reply_t *reply; + xcb_rectangle_t *r; + unsigned int i = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (num_ret) *num_ret = 0; + +#ifdef ECORE_XCB_SHAPE + cookie = + xcb_shape_get_rectangles(_ecore_xcb_conn, win, XCB_SHAPE_SK_BOUNDING); + reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + if (num_ret) *num_ret = reply->rectangles_len; + + if (reply->rectangles_len < 1) + { + free(reply); + if (num_ret) *num_ret = 0; + return NULL; + } + + rects = malloc(sizeof(Ecore_X_Rectangle) * reply->rectangles_len); + if (!rects) + { + free(reply); + if (num_ret) *num_ret = 0; + return NULL; + } + r = xcb_shape_get_rectangles_rectangles(reply); + for (i = 0; i < reply->rectangles_len; i++) + { + rects[i].x = r[i].x; + rects[i].y = r[i].y; + rects[i].width = r[i].width; + rects[i].height = r[i].height; + } + + free(reply); + + return rects; +#else + return rects; + win = 0; +#endif +} + +EAPI void +ecore_x_window_shape_events_select(Ecore_X_Window win, + Eina_Bool on) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_select_input(_ecore_xcb_conn, win, on); +// ecore_x_flush(); +#else + return; + win = 0; + on = 0; +#endif +} + +EAPI Ecore_X_Rectangle * +ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win, + int *num_ret) +{ + Ecore_X_Rectangle *rects = NULL; +#ifdef ECORE_XCB_SHAPE + xcb_shape_get_rectangles_cookie_t cookie; + xcb_shape_get_rectangles_reply_t *reply; + xcb_rectangle_t *r; + unsigned int i = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (num_ret) *num_ret = 0; + +#ifdef ECORE_XCB_SHAPE + cookie = + xcb_shape_get_rectangles(_ecore_xcb_conn, win, XCB_SHAPE_SK_INPUT); + reply = xcb_shape_get_rectangles_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + if (num_ret) *num_ret = reply->rectangles_len; + + if (reply->rectangles_len < 1) + { + free(reply); + if (num_ret) *num_ret = 0; + return NULL; + } + + rects = malloc(sizeof(Ecore_X_Rectangle) * reply->rectangles_len); + if (!rects) + { + free(reply); + if (num_ret) *num_ret = 0; + return NULL; + } + r = xcb_shape_get_rectangles_rectangles(reply); + for (i = 0; i < reply->rectangles_len; i++) + { + rects[i].x = r[i].x; + rects[i].y = r[i].y; + rects[i].width = r[i].width; + rects[i].height = r[i].height; + } + + free(reply); + + return rects; +#else + xcb_get_geometry_cookie_t cookie; + xcb_get_geometry_reply_t *reply; + + if (!(rects = malloc(sizeof(Ecore_X_Rectangle)))) + return NULL; + + /* get geometry */ + cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); + reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + rects[0].x = reply->x; + rects[0].y = reply->y; + rects[0].width = reply->width; + rects[0].height = reply->height; + free(reply); + } + if (num_ret) *num_ret = 1; + return rects; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win, + Ecore_X_Rectangle *rects, + int num) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t *rect = NULL; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!rects) return; + +#ifdef ECORE_XCB_SHAPE + if (num > 0) + { + int i = 0; + + if (!(rect = malloc(sizeof(xcb_rectangle_t) * num))) + return; + + 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; + } + } + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, num, (xcb_rectangle_t *)rect); + + if (rect) free(rect); +// ecore_x_flush(); +#else + return; + win = 0; + num = 0; + rects = NULL; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SUBTRACT, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +// ecore_x_flush(); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangle_add(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +// ecore_x_flush(); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangle_set(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_SET, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +// ecore_x_flush(); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_window_set_xy(Ecore_X_Window win, + Ecore_X_Window shape_win, + int x, + int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, + XCB_SHAPE_SK_INPUT, win, x, y, shape_win); +// ecore_x_flush(); +#else + return; + win = 0; + shape_win = 0; + x = 0; + y = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_window_add_xy(Ecore_X_Window win, + Ecore_X_Window shape_win, + int x, + int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, XCB_SHAPE_SK_INPUT, + XCB_SHAPE_SK_INPUT, win, x, y, shape_win); +// ecore_x_flush(); +#else + return; + win = 0; + shape_win = 0; + x = 0; + y = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_window_set(Ecore_X_Window win, + Ecore_X_Window shape_win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + xcb_shape_combine(_ecore_xcb_conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, + XCB_SHAPE_SK_INPUT, win, 0, 0, shape_win); +// ecore_x_flush(); +#else + return; + win = 0; + shape_win = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangle_clip(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t rect; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_INTERSECT, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, 1, &rect); +// ecore_x_flush(); +#else + return; + win = 0; + x = 0; + y = 0; + w = 0; + h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win, + Ecore_X_Rectangle *rects, + int num) +{ +#ifdef ECORE_XCB_SHAPE + xcb_rectangle_t *rect = NULL; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + +#ifdef ECORE_XCB_SHAPE + if (num > 0) + { + int i = 0; + + if (!(rect = malloc(sizeof(xcb_rectangle_t) * num))) + return; + + 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; + } + } + + xcb_shape_rectangles(_ecore_xcb_conn, XCB_SHAPE_SO_UNION, + XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, + win, 0, 0, num, (xcb_rectangle_t *)&rect); + + if (rect) free(rect); +// ecore_x_flush(); +#else + return; + win = 0; + num = 0; + rects = NULL; +#endif +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c b/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c new file mode 100644 index 0000000000..e0e56102e2 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_xdefaults.c @@ -0,0 +1,116 @@ +#include "ecore_xcb_private.h" +#include + +/* local function prototypes */ +static Eina_Bool _ecore_xcb_xdefaults_glob_match(const char *str, + const char *glob); + +/* local variables */ +static Eina_File *_ecore_xcb_xdefaults_file = NULL; +static char *_ecore_xcb_xdefaults_data = NULL; + +void +_ecore_xcb_xdefaults_init(void) +{ + char buff[PATH_MAX]; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + snprintf(buff, sizeof(buff), "%s/.Xdefaults", getenv("HOME")); + if ((_ecore_xcb_xdefaults_file = eina_file_open(buff, EINA_FALSE))) + { + eina_mmap_safety_enabled_set(EINA_TRUE); + + _ecore_xcb_xdefaults_data = + eina_file_map_all(_ecore_xcb_xdefaults_file, EINA_FILE_SEQUENTIAL); + } +} + +void +_ecore_xcb_xdefaults_shutdown(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!_ecore_xcb_xdefaults_file) return; + if (_ecore_xcb_xdefaults_data) + eina_file_map_free(_ecore_xcb_xdefaults_file, _ecore_xcb_xdefaults_data); + if (_ecore_xcb_xdefaults_file) eina_file_close(_ecore_xcb_xdefaults_file); +} + +char * +_ecore_xcb_xdefaults_string_get(const char *prog, + const char *param) +{ + char buff[1024], ret[1024]; + char *str = NULL; + char **ea = NULL; + unsigned int count = 0, i = 0; + + if ((!_ecore_xcb_xdefaults_data) || (!_ecore_xcb_xdefaults_file)) + return NULL; + + snprintf(buff, sizeof(buff), "*%s*.*%s*", prog, param); + + str = _ecore_xcb_xdefaults_data; + ea = eina_str_split_full(str, "\n", -1, &count); + for (i = 0; i < count; i++) + { + if (_ecore_xcb_xdefaults_glob_match(ea[i], buff)) + sscanf(ea[i], "%*[^:]:%*[ ]%s", ret); + } + if ((ea) && (ea[0])) + { + free(ea[0]); + free(ea); + } + + return strdup(ret); +} + +int +_ecore_xcb_xdefaults_int_get(const char *prog, + const char *param) +{ + char buff[1024]; + char *str = NULL; + char **ea = NULL; + unsigned int count = 0, i = 0; + int ret = -1; + + if ((!_ecore_xcb_xdefaults_data) || (!_ecore_xcb_xdefaults_file)) + return 0; + + snprintf(buff, sizeof(buff), "*%s*.*%s*", prog, param); + + str = _ecore_xcb_xdefaults_data; + ea = eina_str_split_full(str, "\n", -1, &count); + for (i = 0; i < count; i++) + { + if (_ecore_xcb_xdefaults_glob_match(ea[i], buff)) + sscanf(ea[i], "%*[^:]:%*[ ]%d", &ret); + } + if ((ea) && (ea[0])) + { + free(ea[0]); + free(ea); + } + + return ret; +} + +/* local functions */ +static Eina_Bool +_ecore_xcb_xdefaults_glob_match(const char *str, + const char *glob) +{ + if ((!str) || (!glob)) return EINA_FALSE; + if (glob[0] == 0) + { + if (str[0] == 0) return EINA_TRUE; + return EINA_FALSE; + } + if (!strcmp(glob, "*")) return EINA_TRUE; + if (!fnmatch(glob, str, 0)) return EINA_TRUE; + return EINA_FALSE; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c b/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c new file mode 100644 index 0000000000..58444cdf1f --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_xfixes.c @@ -0,0 +1,744 @@ +#include "ecore_xcb_private.h" +# ifdef ECORE_XCB_XFIXES +# include +# endif + +/* local function prototypes */ +static xcb_rectangle_t *_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects, + int num); +static Ecore_X_Rectangle *_ecore_xcb_rect_to_ecore(xcb_rectangle_t *rects, + int num); + +/* local variables */ +static Eina_Bool _xfixes_avail = EINA_FALSE; + +/* external variables */ +int _ecore_xcb_event_xfixes = -1; + +void +_ecore_xcb_xfixes_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); +#endif +} + +void +_ecore_xcb_xfixes_finalize(void) +{ +#ifdef ECORE_XCB_XFIXES + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XFIXES + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xfixes_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_xfixes_query_version_cookie_t cookie; + xcb_xfixes_query_version_reply_t *reply; + + cookie = + xcb_xfixes_query_version_unchecked(_ecore_xcb_conn, + XCB_XFIXES_MAJOR_VERSION, + XCB_XFIXES_MINOR_VERSION); + reply = xcb_xfixes_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + /* NB: XFixes Extension >= 3 needed for shape stuff. + * for now, I am removing this check so that it matches the + * xlib code closer. If the extension version ends up being + * that important, then re-enable this */ + + /* if (reply->major_version >= 3) */ + _xfixes_avail = EINA_TRUE; + free(reply); + } + + if (_xfixes_avail) + _ecore_xcb_event_xfixes = ext_reply->first_event; + } +#endif +} + +EAPI Eina_Bool +ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection) +{ +#ifdef ECORE_XCB_XFIXES + Ecore_X_Window root = 0; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; + int mask = 0; +#endif + + CHECK_XCB_CONN; + + if (!_xfixes_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XFIXES + root = ((xcb_screen_t *)_ecore_xcb_screen)->root; + + mask = (XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER | + XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY | + XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE); + + cookie = + xcb_xfixes_select_selection_input_checked(_ecore_xcb_conn, root, + selection, mask); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + + return EINA_TRUE; +#endif + return EINA_FALSE; +} + +Eina_Bool +_ecore_xcb_xfixes_avail_get(void) +{ + return _xfixes_avail; +} + +/** + * @defgroup Ecore_X_Fixes_Group X Fixes Extension Functions + * + * Functions related to the X Fixes extension. + */ + +/** + * 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 = 0; +#ifdef ECORE_XCB_XFIXES + xcb_rectangle_t *xrects; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return 0; + +#ifdef ECORE_XCB_XFIXES + xrects = _ecore_xcb_rect_to_xcb(rects, num); + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region(_ecore_xcb_conn, region, num, xrects); + free(xrects); +// ecore_x_flush(); +#endif + + 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 = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return 0; + +#ifdef ECORE_XCB_XFIXES + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region_from_bitmap(_ecore_xcb_conn, region, bitmap); +// ecore_x_flush(); +#endif + + return region; +} + +/** + * Create a region from a window. + * @param win 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 win, + Ecore_X_Region_Type type) +{ + Ecore_X_Region region = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return 0; + +#ifdef ECORE_XCB_XFIXES + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region_from_window(_ecore_xcb_conn, region, win, type); +// ecore_x_flush(); +#endif + + 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 = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return 0; + +#ifdef ECORE_XCB_XFIXES + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region_from_gc(_ecore_xcb_conn, region, gc); +// ecore_x_flush(); +#endif + + 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 = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return 0; + +#ifdef ECORE_XCB_XFIXES + region = xcb_generate_id(_ecore_xcb_conn); + xcb_xfixes_create_region_from_picture(_ecore_xcb_conn, region, picture); +// ecore_x_flush(); +#endif + + 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_destroy_region(_ecore_xcb_conn, region); +// ecore_x_flush(); +#endif +} + +/** + * 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_XFIXES + xcb_rectangle_t *xrects; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xrects = _ecore_xcb_rect_to_xcb(rects, num); + xcb_xfixes_set_region(_ecore_xcb_conn, region, num, xrects); + free(xrects); +// ecore_x_flush(); +#endif +} + +/** + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + + // NB: Hmmmm...this may need converting to/fro xcb_rectangle_t +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_copy_region(_ecore_xcb_conn, source, dest); +// ecore_x_flush(); +#endif +} + +/** + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_union_region(_ecore_xcb_conn, source1, source2, dest); +// ecore_x_flush(); +#endif +} + +/** + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_intersect_region(_ecore_xcb_conn, source1, source2, dest); +// ecore_x_flush(); +#endif +} + +/** + * Make the subtraction 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 subtraction 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_subtract_region(_ecore_xcb_conn, source1, source2, dest); +// ecore_x_flush(); +#endif +} + +/** + * Make the subtraction 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_XFIXES + xcb_rectangle_t xrects; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xrects.x = bounds->x; + xrects.y = bounds->y; + xrects.width = bounds->width; + xrects.height = bounds->height; + + xcb_xfixes_invert_region(_ecore_xcb_conn, source, xrects, dest); +// ecore_x_flush(); +#endif +} + +/** + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_translate_region(_ecore_xcb_conn, region, dx, dy); +// ecore_x_flush(); +#endif +} + +/** + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_region_extents(_ecore_xcb_conn, source, dest); +// ecore_x_flush(); +#endif +} + +/** + * 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. + * + * @ingroup Ecore_X_Fixes_Group + */ +EAPI Ecore_X_Rectangle * +ecore_x_region_fetch(Ecore_X_Region region, + int *num, + Ecore_X_Rectangle *bounds) +{ + Ecore_X_Rectangle extents = { 0, 0, 0, 0 }; + Ecore_X_Rectangle *rects = NULL; +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_fetch_region_cookie_t cookie; + xcb_xfixes_fetch_region_reply_t *reply; + xcb_rectangle_t *r; + int n = 0; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (num) *num = 0; + if (bounds) *bounds = extents; + if (!_xfixes_avail) return NULL; + +#ifdef ECORE_XCB_XFIXES + cookie = xcb_xfixes_fetch_region_unchecked(_ecore_xcb_conn, region); + reply = xcb_xfixes_fetch_region_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return NULL; + + r = xcb_xfixes_fetch_region_rectangles(reply); + n = xcb_xfixes_fetch_region_rectangles_length(reply); + rects = _ecore_xcb_rect_to_ecore(r, n); + if (num) *num = n; + + /* rects = (Ecore_X_Rectangle *)malloc(n * sizeof(Ecore_X_Rectangle)); */ + /* if (!rects) */ + /* { */ + /* free(reply); */ + /* return NULL; */ + /* } */ + + /* for (i = 0; i < n; i++) */ + /* { */ + /* rects[i].x = r[i].x; */ + /* rects[i].y = r[i].y; */ + /* rects[i].width = r[i].width; */ + /* rects[i].height = r[i].height; */ + /* } */ + + (*bounds).x = reply->extents.x; + (*bounds).y = reply->extents.y; + (*bounds).width = reply->extents.width; + (*bounds).height = reply->extents.height; + + free(reply); +#endif + + return rects; +} + +/** + * 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) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_expand_region(_ecore_xcb_conn, source, dest, left, right, top, bottom); +// ecore_x_flush(); +#endif +} + +/** + * 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 The horizontal translation. + * @param y 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, + int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_set_gc_clip_region(_ecore_xcb_conn, gc, region, x, y); +// ecore_x_flush(); +#endif +} + +/** + * 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 The horizontal offset. + * @param y 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, + int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_set_window_shape_region(_ecore_xcb_conn, dest, type, x, y, region); +// ecore_x_flush(); +#endif +} + +/** + * Change clip-mask in picture to the specified region. + * @param region The region. + * @param picture The picture. + * @param x The X coordinate of the origin. + * @param y 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, + int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xfixes_avail) return; + +#ifdef ECORE_XCB_XFIXES + xcb_xfixes_set_picture_clip_region(_ecore_xcb_conn, picture, region, x, y); +// ecore_x_flush(); +#endif +} + +/* local function prototypes */ +static xcb_rectangle_t * +_ecore_xcb_rect_to_xcb(Ecore_X_Rectangle *rects, + int num) +{ + xcb_rectangle_t *xrect; + int i = 0; + + if (!num) return NULL; + + xrect = malloc(sizeof(xcb_rectangle_t) * 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_xcb_rect_to_ecore(xcb_rectangle_t *rects, + int num) +{ + Ecore_X_Rectangle *erect; + int i = 0; + + if (!num) return NULL; + + erect = malloc(sizeof(Ecore_X_Rectangle) * num); + if (!erect) return NULL; + + for (i = 0; i < num; i++) + { + erect[i].x = rects[i].x; + erect[i].y = rects[i].y; + erect[i].width = rects[i].width; + erect[i].height = rects[i].height; + } + + return erect; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c b/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c new file mode 100644 index 0000000000..37a2339e9b --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_xinerama.c @@ -0,0 +1,139 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_XINERAMA +# include +#endif + +/* local variables */ +static Eina_Bool _xinerama_avail = EINA_FALSE; +static Eina_Bool _xinerama_active = EINA_FALSE; + +void +_ecore_xcb_xinerama_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XINERAMA + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_xinerama_id); +#endif +} + +void +_ecore_xcb_xinerama_finalize(void) +{ +#ifdef ECORE_XCB_XINERAMA + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XINERAMA + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_xinerama_id); + if ((ext_reply) && (ext_reply->present)) + { + xcb_xinerama_query_version_cookie_t cookie; + xcb_xinerama_query_version_reply_t *reply; + + cookie = + xcb_xinerama_query_version_unchecked(_ecore_xcb_conn, + XCB_XINERAMA_MAJOR_VERSION, + XCB_XINERAMA_MINOR_VERSION); + reply = + xcb_xinerama_query_version_reply(_ecore_xcb_conn, cookie, NULL); + if (reply) + { + _xinerama_avail = EINA_TRUE; + // NB: Do we need to compare version numbers here ? + free(reply); + } + + if (_xinerama_avail) + { + xcb_xinerama_is_active_cookie_t acookie; + xcb_xinerama_is_active_reply_t *areply; + + acookie = xcb_xinerama_is_active_unchecked(_ecore_xcb_conn); + areply = + xcb_xinerama_is_active_reply(_ecore_xcb_conn, acookie, NULL); + if (areply) + { + _xinerama_active = areply->state; + free(areply); + } + } + } +#endif +} + +EAPI int +ecore_x_xinerama_screen_count_get(void) +{ + int count = 0; +#ifdef ECORE_XCB_XINERAMA + xcb_xinerama_query_screens_cookie_t cookie; + xcb_xinerama_query_screens_reply_t *reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_xinerama_avail) return 0; + +#ifdef ECORE_XCB_XINERAMA + cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn); + reply = + xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return 0; + count = reply->number; +#endif + + return count; +} + +EAPI Eina_Bool +ecore_x_xinerama_screen_geometry_get(int screen, + int *x, + int *y, + int *w, + int *h) +{ +#ifdef ECORE_XCB_XINERAMA + xcb_xinerama_query_screens_cookie_t cookie; + xcb_xinerama_query_screens_reply_t *reply; + xcb_xinerama_screen_info_t *info; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels; + if (h) *h = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels; + + if (!_xinerama_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XINERAMA + cookie = xcb_xinerama_query_screens_unchecked(_ecore_xcb_conn); + reply = + xcb_xinerama_query_screens_reply(_ecore_xcb_conn, cookie, NULL); + if (!reply) return EINA_FALSE; + + info = xcb_xinerama_query_screens_screen_info(reply); + if (!info) + { + free(reply); + return EINA_FALSE; + } + + if (x) *x = info[screen].x_org; + if (y) *y = info[screen].y_org; + if (w) *w = info[screen].width; + if (h) *h = info[screen].height; + + free(reply); + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + diff --git a/src/lib/ecore_x/xcb/ecore_xcb_xtest.c b/src/lib/ecore_x/xcb/ecore_xcb_xtest.c new file mode 100644 index 0000000000..7f76b2ccb5 --- /dev/null +++ b/src/lib/ecore_x/xcb/ecore_xcb_xtest.c @@ -0,0 +1,215 @@ +#include "ecore_xcb_private.h" +#ifdef ECORE_XCB_XTEST +# include +# include +#endif + +/* local variables */ +static Eina_Bool _test_avail = EINA_FALSE; + +void +_ecore_xcb_xtest_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XTEST + xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_test_id); +#endif +} + +void +_ecore_xcb_xtest_finalize(void) +{ +#ifdef ECORE_XCB_XTEST + const xcb_query_extension_reply_t *ext_reply; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + +#ifdef ECORE_XCB_XTEST + ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_test_id); + if ((ext_reply) && (ext_reply->present)) + _test_avail = EINA_TRUE; +#endif +} + +EAPI Eina_Bool +#ifdef ECORE_XCB_XTEST +ecore_x_test_fake_key_down(const char *key) +#else +ecore_x_test_fake_key_down(const char *key EINA_UNUSED) +#endif +{ +#ifdef ECORE_XCB_XTEST + xcb_keycode_t keycode = 0; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_test_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XTEST + keycode = _ecore_xcb_keymap_string_to_keycode(key); + if (keycode == XCB_NO_SYMBOL) return EINA_FALSE; + + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, + keycode, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + +EAPI Eina_Bool +#ifdef ECORE_XCB_XTEST +ecore_x_test_fake_key_up(const char *key) +#else +ecore_x_test_fake_key_up(const char *key EINA_UNUSED) +#endif +{ +#ifdef ECORE_XCB_XTEST + xcb_keycode_t keycode = 0; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_test_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XTEST + keycode = _ecore_xcb_keymap_string_to_keycode(key); + if (keycode == XCB_NO_SYMBOL) return EINA_FALSE; + + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, + keycode, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + return EINA_TRUE; +#endif + + return EINA_FALSE; +} + +EAPI Eina_Bool +#ifdef ECORE_XCB_XTEST +ecore_x_test_fake_key_press(const char *key) +#else +ecore_x_test_fake_key_press(const char *key EINA_UNUSED) +#endif +{ +#ifdef ECORE_XCB_XTEST + xcb_keycode_t keycode = 0; + xcb_keysym_t keysym = 0; + xcb_keycode_t shift_code = 0; + xcb_void_cookie_t cookie; + xcb_generic_error_t *err; + Eina_Bool shift = EINA_FALSE; +#endif + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + CHECK_XCB_CONN; + + if (!_test_avail) return EINA_FALSE; + +#ifdef ECORE_XCB_XTEST + keycode = _ecore_xcb_keymap_string_to_keycode(key); + keysym = _ecore_xcb_keymap_keycode_to_keysym(keycode, 0); + if (keysym == XCB_NO_SYMBOL) + { + keysym = _ecore_xcb_keymap_keycode_to_keysym(keycode, 1); + if (keysym != XCB_NO_SYMBOL) + shift = EINA_TRUE; + } + + if (shift) + { + xcb_keycode_t *keycodes; + int i = 0; + + keycodes = _ecore_xcb_keymap_keysym_to_keycode(XK_Shift_L); + while (keycodes[i] != XCB_NO_SYMBOL) + { + if (keycodes[i] != 0) + { + shift_code = keycodes[i]; + break; + } + i++; + } + } + + if (shift) + { + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, + shift_code, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + } + + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_PRESS, + keycode, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, + keycode, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + + if (shift) + { + cookie = + xcb_test_fake_input(_ecore_xcb_conn, XCB_KEY_RELEASE, + shift_code, XCB_CURRENT_TIME, + ((xcb_screen_t *)_ecore_xcb_screen)->root, + 0, 0, 0); + err = xcb_request_check(_ecore_xcb_conn, cookie); + if (err) + { + free(err); + return EINA_FALSE; + } + } + + return EINA_TRUE; +#endif + + return EINA_FALSE; +} diff --git a/src/lib/ecore_x/xlib/ecore_x.c b/src/lib/ecore_x/xlib/ecore_x.c new file mode 100644 index 0000000000..d9b81bc0f8 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x.c @@ -0,0 +1,2242 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include +#include +#include + +//#define LOGRT 1 + +#ifdef LOGRT +#include +#endif /* ifdef LOGRT */ + +#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 Eina_Bool _ecore_x_fd_handler(void *data, + Ecore_Fd_Handler *fd_handler); +static Eina_Bool _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_XRANDR */ +#ifdef ECORE_XFIXES +static int _ecore_x_event_fixes_selection_id = 0; +#endif /* ifdef ECORE_XFIXES */ +#ifdef ECORE_XDAMAGE +static int _ecore_x_event_damage_id = 0; +#endif /* ifdef ECORE_XDAMAGE */ +#ifdef ECORE_XGESTURE +static int _ecore_x_event_gesture_id = 0; +#endif /* ifdef ECORE_XGESTURE */ +#ifdef ECORE_XKB +static int _ecore_x_event_xkb_id = 0; +#endif /* ifdef ECORE_XKB */ +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; +Eina_Bool _ecore_x_xcursor = EINA_FALSE; + +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_MAPPING_CHANGE = 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_FIXES_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_GESTURE_NOTIFY_FLICK; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD; +EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP; +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_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_XKB_STATE_NOTIFY = 0; +EAPI int ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = 0; + + +EAPI int ECORE_X_EVENT_GENERIC = 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_MODIFIER_ALTGR = 0; + +EAPI int ECORE_X_LOCK_SCROLL = 0; +EAPI int ECORE_X_LOCK_NUM = 0; +EAPI int ECORE_X_LOCK_CAPS = 0; +EAPI int ECORE_X_LOCK_SHIFT = 0; + +EAPI int ECORE_X_RAW_BUTTON_PRESS = 0; +EAPI int ECORE_X_RAW_BUTTON_RELEASE = 0; +EAPI int ECORE_X_RAW_MOTION = 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 /* ifdef LOGRT */ + +/* wrapper to use XkbKeycodeToKeysym when possible */ +KeySym +_ecore_x_XKeycodeToKeysym(Display *display, KeyCode keycode, int idx) +{ +#ifdef ECORE_XKB + return XkbKeycodeToKeysym(display, keycode, 0, idx); +#else + return XKeycodeToKeysym(display, keycode, idx); +#endif +} + +void +_ecore_x_modifiers_get(void) +{ + /* 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_Meta_L); + + ECORE_X_MODIFIER_ALTGR = _ecore_x_key_mask_get(XK_Mode_switch); + + 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_LOCK_SHIFT = _ecore_x_key_mask_get(XK_Shift_Lock); +} + +/** + * @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 /* ifdef ECORE_XSS */ + int sync_base = 0; + int sync_err_base = 0; +#ifdef ECORE_XRANDR + int randr_base = 0; + int randr_err_base = 0; +#endif /* ifdef ECORE_XRANDR */ +#ifdef ECORE_XFIXES + int fixes_base = 0; + int fixes_err_base = 0; +#endif /* ifdef ECORE_XFIXES */ +#ifdef ECORE_XDAMAGE + int damage_base = 0; + int damage_err_base = 0; +#endif /* ifdef ECORE_XDAMAGE */ +#ifdef ECORE_XGESTURE + int gesture_base = 0; + int gesture_err_base = 0; +#endif /* ifdef ECORE_XGESTURE */ +#ifdef ECORE_XKB + int xkb_base = 0; +#endif /* ifdef ECORE_XKB */ + if (++_ecore_x_init_count != 1) + return _ecore_x_init_count; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); +#ifdef LOGRT + _logrt_init(); +#endif /* ifdef LOGRT */ + + eina_init(); + _ecore_xlib_log_dom = eina_log_domain_register + ("ecore_x", 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_init()) + goto shutdown_eina; + if (!ecore_event_init()) + goto shutdown_ecore; + +#ifdef EVAS_FRAME_QUEUING + XInitThreads(); +#endif /* ifdef EVAS_FRAME_QUEUING */ + _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 /* ifdef ECORE_XSS */ + + 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_XRANDR */ + +#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_XFIXES */ + +#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 /* ifdef ECORE_XDAMAGE */ + +#ifdef ECORE_XGESTURE + if (XGestureQueryExtension(_ecore_x_disp, &gesture_base, &gesture_err_base)) + _ecore_x_event_gesture_id = gesture_base; + + ECORE_X_EVENT_HANDLERS_GROW(gesture_base, GestureNumberEvents); +#endif /* ifdef ECORE_XGESTURE */ +#ifdef ECORE_XKB + { + int dummy; + + if (XkbQueryExtension(_ecore_x_disp, &dummy, &xkb_base, + &dummy, &dummy, &dummy)) + _ecore_x_event_xkb_id = xkb_base; + XkbSelectEventDetails(_ecore_x_disp, XkbUseCoreKbd, XkbStateNotify, + XkbAllStateComponentsMask, XkbGroupStateMask); + } + ECORE_X_EVENT_HANDLERS_GROW(xkb_base, XkbNumberEvents); +#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) ? EINA_TRUE : EINA_FALSE; +#endif /* ifdef ECORE_XCURSOR */ + _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 /* ifdef GenericEvent */ + + 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_XRANDR */ +#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_XFIXES */ +#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_XDAMAGE */ +#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); + if (_ecore_x_event_xkb_id) + _ecore_x_event_handlers[_ecore_x_event_xkb_id] = _ecore_x_event_handle_xkb; +#endif /* ifdef ECORE_XKB */ + +#ifdef ECORE_XGESTURE + if (_ecore_x_event_gesture_id) + { + _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyFlick] = + _ecore_x_event_handle_gesture_notify_flick; + _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyPan] = + _ecore_x_event_handle_gesture_notify_pan; + _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyPinchRotation] = + _ecore_x_event_handle_gesture_notify_pinchrotation; + _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyTap] = + _ecore_x_event_handle_gesture_notify_tap; + _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyTapNHold] = + _ecore_x_event_handle_gesture_notify_tapnhold; + _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyHold] = + _ecore_x_event_handle_gesture_notify_hold; + _ecore_x_event_handlers[_ecore_x_event_gesture_id + GestureNotifyGroup] = + _ecore_x_event_handle_gesture_notify_group; + } + +#endif /* ifdef ECORE_XGESTURE */ + + 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_MAPPING_CHANGE = 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_GESTURE_NOTIFY_FLICK = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new(); + ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 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_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_XKB_STATE_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_XKB_NEWKBD_NOTIFY = ecore_event_type_new(); + + ECORE_X_EVENT_GENERIC = ecore_event_type_new(); + + ECORE_X_RAW_BUTTON_PRESS = ecore_event_type_new(); + ECORE_X_RAW_BUTTON_RELEASE = ecore_event_type_new(); + ECORE_X_RAW_MOTION = ecore_event_type_new(); + } + + _ecore_x_modifiers_get(); + + _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_gesture_init(); + _ecore_x_input_init(); + _ecore_x_events_init(); + + _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456); + + 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(); +shutdown_ecore: + ecore_shutdown(); +shutdown_eina: + eina_log_domain_unregister(_ecore_xlib_log_dom); + _ecore_xlib_log_dom = -1; + eina_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__); + + ecore_main_fd_handler_del(_ecore_x_fd_handler_handle); + if (close_display) + XCloseDisplay(_ecore_x_disp); + else + { + close(ConnectionNumber(_ecore_x_disp)); + // FIXME: may have to clean up x display internal here +// getting segv here? hmmm. odd. disable +// XFree(_ecore_x_disp); + } + + free(_ecore_x_event_handlers); + _ecore_x_fd_handler_handle = NULL; + _ecore_x_disp = NULL; + _ecore_x_event_handlers = NULL; + _ecore_x_events_shutdown(); + _ecore_x_input_shutdown(); + _ecore_x_selection_shutdown(); + _ecore_x_dnd_shutdown(); + ecore_x_netwm_shutdown(); + + ecore_event_shutdown(); + ecore_shutdown(); + + eina_log_domain_unregister(_ecore_xlib_log_dom); + _ecore_xlib_log_dom = -1; + eina_shutdown(); + + 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. 0 is returned if an error occurs. + * @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_X_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); +} + +/** + * Retrieves the size of an Ecore_X_Screen. + * @param screen the handle to the screen to query. + * @param w where to return the width. May be NULL. Returns 0 on errors. + * @param h where to return the height. May be NULL. Returns 0 on errors. + * @ingroup Ecore_X_Display_Attr_Group + * @see ecore_x_default_screen_get() + * + * @since 1.1 + */ +EAPI void +ecore_x_screen_size_get(const Ecore_X_Screen *screen, + int *w, + int *h) +{ + Screen *s = (Screen *)screen; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (w) *w = 0; + if (h) *h = 0; + if (!s) return; + if (w) *w = s->width; + if (h) *h = s->height; +} + +/** + * Retrieves the number of screens. + * + * @return The count of the number of screens. + * @ingroup Ecore_X_Display_Attr_Group + * + * @since 1.1 + */ +EAPI int +ecore_x_screen_count_get(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + return ScreenCount(_ecore_x_disp); +} + +/** + * Retrieves the index number of the given screen. + * + * @param screen The screen for which the index will be retrieved. + * @return The index number of the screen. + * @ingroup Ecore_X_Display_Attr_Group + * + * @since 1.1 + */ +EAPI int +ecore_x_screen_index_get(const Ecore_X_Screen *screen) +{ + return XScreenNumberOfScreen((Screen *)screen); +} + +/** + * Retrieves the screen based on index number. + * + * @param idx The index that will be used to retrieve the screen. + * @return The Ecore_X_Screen at this index. + * @ingroup Ecore_X_Display_Attr_Group + * + * @since 1.1 + */ +EAPI Ecore_X_Screen * +ecore_x_screen_get(int idx) +{ + return XScreenOfDisplay(_ecore_x_disp, idx); +} + +/** + * 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 account for multihead or xinerama and + * xrander where different parts of the screen may have different 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; +} + +/** + * Invoke the standard system beep to alert users + * + * @param percent The volume at which the bell rings. Must be in the range + * [-100,+100]. If percent >= 0, the final volume will be: + * base - [(base * percent) / 100] + percent + * Otherwise, it's calculated as: + * base + [(base * percent) / 100] + * where @c base is the bell's base volume as set by XChangeKeyboardControl(3). + * + * @returns @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_bell(int percent) +{ + int ret; + + ret = XBell(_ecore_x_disp, percent); + if (ret == BadValue) + return EINA_FALSE; + + return EINA_TRUE; +} + +static Eina_Bool +_ecore_x_fd_handler(void *data, + Ecore_Fd_Handler *fd_handler EINA_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 /* ifdef ENABLE_XIM */ + 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 ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_ecore_x_fd_handler_buf(void *data, + Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + Display *d; + + d = data; + if (XPending(d)) + return ECORE_CALLBACK_RENEW; + + return ECORE_CALLBACK_CANCEL; +} + +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 = _ecore_x_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 /* ifdef ECORE_XPRINT */ + + 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(MAX((num - overlap) * sizeof(Window), 1)); + 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 /* ifdef ECORE_XPRINT */ + 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 /* ifdef ECORE_XPRINT */ + 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 EINA_UNUSED) +{ + if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) && + (ecore_x_error_code_get() == BadAccess)) + _ecore_x_window_manage_failed = 1; +} + +EAPI Eina_Bool +ecore_x_window_manage(Ecore_X_Window win) +{ + XWindowAttributes att; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True) + return EINA_FALSE; + + 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 EINA_FALSE; + } + + return EINA_TRUE; +} + +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 Eina_Bool +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 EINA_FALSE; + + 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 EINA_TRUE; +} + +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 Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_pointer_mapping_set(unsigned char *map, + int nmap) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return (XSetPointerMapping(_ecore_x_disp, map, nmap) == MappingSuccess) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_pointer_mapping_get(unsigned char *map, + int nmap) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return XGetPointerMapping(_ecore_x_disp, map, nmap) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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 EINA_TRUE; + + return EINA_FALSE; +} + +EAPI Eina_Bool +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 EINA_TRUE; + + return EINA_FALSE; +} + +EAPI void +ecore_x_pointer_ungrab(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XUngrabPointer(_ecore_x_disp, CurrentTime); +} + +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_keyboard_grab(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (XGrabKeyboard(_ecore_x_disp, win, False, + GrabModeAsync, GrabModeAsync, + CurrentTime) == GrabSuccess) + return EINA_TRUE; + + return EINA_FALSE; +} + +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; +Eina_Bool (*_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(Eina_Bool (*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; + Window *t; + + 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++; + t = realloc(_ecore_window_grabs, + _ecore_window_grabs_num * sizeof(Window)); + if (!t) return; + _ecore_window_grabs = t; + _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; + Window *t; + + 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--; + if (_ecore_window_grabs_num <= 0) + { + free(_ecore_window_grabs); + _ecore_window_grabs = NULL; + return; + } + t = realloc(_ecore_window_grabs, + _ecore_window_grabs_num * + sizeof(Window)); + if (!t) return; + _ecore_window_grabs = t; + } + } +} + +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; + Window *t; + + 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++; + t = realloc(_ecore_key_grabs, + _ecore_key_grabs_num * sizeof(Window)); + if (!t) return; + _ecore_key_grabs = t; + _ecore_key_grabs[_ecore_key_grabs_num - 1] = win; +} + +void +_ecore_x_key_grab_remove(Ecore_X_Window win) +{ + int i, shuffle = 0; + Window *t; + + 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--; + if (_ecore_key_grabs_num <= 0) + { + free(_ecore_key_grabs); + _ecore_key_grabs = NULL; + return; + } + t = realloc(_ecore_key_grabs, + _ecore_key_grabs_num * sizeof(Window)); + if (!t) return; + _ecore_key_grabs = t; + } + } +} + +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 mask The mask of the message to be sent. + * @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 @c EINA_TRUE on success @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +/** + * 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 @c 20. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_mouse_in_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.xcrossing.type = EnterNotify; + xev.xcrossing.window = win; + xev.xcrossing.root = att.root; + xev.xcrossing.subwindow = win; + xev.xcrossing.time = _ecore_x_event_last_time; + xev.xcrossing.x = x; + xev.xcrossing.y = y; + xev.xcrossing.x_root = rx; + xev.xcrossing.y_root = ry; + xev.xcrossing.mode = NotifyNormal; + xev.xcrossing.detail = NotifyNonlinear; + xev.xcrossing.same_screen = 1; + xev.xcrossing.focus = 0; + xev.xcrossing.state = 0; + return XSendEvent(_ecore_x_disp, win, True, EnterWindowMask, &xev) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_mouse_out_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.xcrossing.type = LeaveNotify; + xev.xcrossing.window = win; + xev.xcrossing.root = att.root; + xev.xcrossing.subwindow = win; + xev.xcrossing.time = _ecore_x_event_last_time; + xev.xcrossing.x = x; + xev.xcrossing.y = y; + xev.xcrossing.x_root = rx; + xev.xcrossing.y_root = ry; + xev.xcrossing.mode = NotifyNormal; + xev.xcrossing.detail = NotifyNonlinear; + xev.xcrossing.same_screen = 1; + xev.xcrossing.focus = 0; + xev.xcrossing.state = 0; + return XSendEvent(_ecore_x_disp, win, True, LeaveWindowMask, &xev) ? EINA_TRUE : EINA_FALSE; +} + +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; +} + +/** + * Retrieve the Visual ID from a given Visual. + * + * @param visual The Visual to get the ID for. + * + * @return The visual id. + * @since 1.1.0 + */ +EAPI unsigned int +ecore_x_visual_id_get(Ecore_X_Visual visual) +{ + return XVisualIDFromVisual(visual); +} + +/** + * Retrieve the default Visual. + * + * @param disp The Display to get the Default Visual from + * @param screen The Screen. + * + * @return The default visual. + * @since 1.1.0 + */ +EAPI Ecore_X_Visual +ecore_x_default_visual_get(Ecore_X_Display *disp, + Ecore_X_Screen *screen) +{ + return DefaultVisual(disp, ecore_x_screen_index_get(screen)); +} + +/** + * Retrieve the default Colormap. + * + * @param disp The Display to get the Default Colormap from + * @param screen The Screen. + * + * @return The default colormap. + * @since 1.1.0 + */ +EAPI Ecore_X_Colormap +ecore_x_default_colormap_get(Ecore_X_Display *disp, + Ecore_X_Screen *screen) +{ + return DefaultColormap(disp, ecore_x_screen_index_get(screen)); +} + +/** + * Retrieve the default depth. + * + * @param disp The Display to get the Default Depth from + * @param screen The Screen. + * + * @return The default depth. + * @since 1.1.0 + */ +EAPI int +ecore_x_default_depth_get(Ecore_X_Display *disp, + Ecore_X_Screen *screen) +{ + return DefaultDepth(disp, ecore_x_screen_index_get(screen)); +} + +EAPI void +ecore_x_xkb_select_group(int group) +{ +#ifdef ECORE_XKB + XkbLockGroup(_ecore_x_disp, XkbUseCoreKbd, group); +#endif +} + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +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_MODIFIER_ALTGR) + xmodifiers |= ECORE_X_MODIFIER_ALTGR; + + 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; + + if (state & ECORE_EVENT_LOCK_SHIFT) + xmodifiers |= ECORE_X_LOCK_SHIFT; + + return xmodifiers; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_atoms.c b/src/lib/ecore_x/xlib/ecore_x_atoms.c new file mode 100644 index 0000000000..2aec7ce740 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_atoms.c @@ -0,0 +1,109 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include + +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" +#include "ecore_x_atoms_decl.h" + +void +_ecore_x_atoms_init(void) +{ + Atom *atoms; + char **names; + int i, num; + + num = sizeof(atom_items) / sizeof(Atom_Item); + atoms = alloca(num * sizeof(Atom)); + names = alloca(num * sizeof(char *)); + for (i = 0; i < num; i++) + names[i] = (char *) atom_items[i].name; + XInternAtoms(_ecore_x_disp, names, num, False, atoms); + for (i = 0; i < num; i++) + *(atom_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; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_composite.c b/src/lib/ecore_x/xlib/ecore_x_composite.c new file mode 100644 index 0000000000..b919db96d2 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_composite.c @@ -0,0 +1,176 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include "ecore_x_private.h" +#include "Ecore_X.h" + +static Eina_Bool _composite_available = EINA_FALSE; + +void +_ecore_x_composite_init(void) +{ + _composite_available = EINA_FALSE; + +#ifdef ECORE_XCOMPOSITE + int major, minor; + + if (XCompositeQueryVersion(_ecore_x_disp, &major, &minor)) + { +# ifdef ECORE_XRENDER + if (XRenderQueryExtension(_ecore_x_disp, &major, &minor)) + { +# ifdef ECORE_XFIXES + if (XFixesQueryVersion(_ecore_x_disp, &major, &minor)) + { + _composite_available = EINA_TRUE; + } +# endif + } +# endif + } +#endif +} + +EAPI Eina_Bool +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 /* ifdef ECORE_XCOMPOSITE */ +} + +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 /* ifdef ECORE_XCOMPOSITE */ +} + +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 /* ifdef ECORE_XCOMPOSITE */ +} + +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 /* ifdef ECORE_XCOMPOSITE */ +} + +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 /* ifdef ECORE_XCOMPOSITE */ + return pixmap; +} + +EAPI void +ecore_x_composite_window_events_disable(Ecore_X_Window win) +{ +#ifdef ECORE_XCOMPOSITE + ecore_x_window_shape_input_rectangle_set(win, -1, -1, 1, 1); +#endif /* ifdef ECORE_XCOMPOSITE */ +} + +EAPI void +ecore_x_composite_window_events_enable(Ecore_X_Window win) +{ +#ifdef ECORE_XCOMPOSITE + ecore_x_window_shape_input_rectangle_set(win, 0, 0, 65535, 65535); +#endif /* ifdef ECORE_XCOMPOSITE */ +} + +EAPI Ecore_X_Window +ecore_x_composite_render_window_enable(Ecore_X_Window root) +{ + Ecore_X_Window win = 0; +#ifdef ECORE_XCOMPOSITE + win = XCompositeGetOverlayWindow(_ecore_x_disp, root); + ecore_x_composite_window_events_disable(win); +#endif /* ifdef ECORE_XCOMPOSITE */ + 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 /* ifdef ECORE_XCOMPOSITE */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_cursor.c b/src/lib/ecore_x/xlib/ecore_x_cursor.c new file mode 100644 index 0000000000..a968c56af2 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_cursor.c @@ -0,0 +1,246 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include + +#include "ecore_x_private.h" + +EAPI Eina_Bool +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 /* ifdef ECORE_XCURSOR */ + { + 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 /* ifdef ECORE_XCURSOR */ + size = 0; +#endif /* ifdef ECORE_XCURSOR */ +} + +EAPI int +ecore_x_cursor_size_get(void) +{ +#ifdef ECORE_XCURSOR + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return XcursorGetDefaultSize(_ecore_x_disp); +#else /* ifdef ECORE_XCURSOR */ + return 0; +#endif /* ifdef ECORE_XCURSOR */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_damage.c b/src/lib/ecore_x/xlib/ecore_x_damage.c new file mode 100644 index 0000000000..b094f85235 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_damage.c @@ -0,0 +1,71 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include "ecore_x_private.h" +#include "Ecore_X.h" + +static Eina_Bool _damage_available = EINA_FALSE; +#ifdef ECORE_XDAMAGE +static int _damage_major, _damage_minor; +#endif /* ifdef ECORE_XDAMAGE */ + +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 = EINA_TRUE; + else + _damage_available = EINA_FALSE; + +#else /* ifdef ECORE_XDAMAGE */ + _damage_available = EINA_FALSE; +#endif /* ifdef ECORE_XDAMAGE */ +} + +EAPI Eina_Bool +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 /* ifdef ECORE_XDAMAGE */ + return 0; +#endif /* ifdef ECORE_XDAMAGE */ +} + +EAPI void +ecore_x_damage_free(Ecore_X_Damage damage) +{ +#ifdef ECORE_XDAMAGE + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XDamageDestroy(_ecore_x_disp, damage); +#endif /* ifdef ECORE_XDAMAGE */ +} + +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 /* ifdef ECORE_XDAMAGE */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_dnd.c b/src/lib/ecore_x/xlib/ecore_x_dnd.c new file mode 100644 index 0000000000..e4f74a7257 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_dnd.c @@ -0,0 +1,706 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include +#include + +#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; +static void (*_posupdatecb)(void *, + Ecore_X_Xdnd_Position *); +static void *_posupdatedata; + +void +_ecore_x_dnd_init(void) +{ + if (!_ecore_x_dnd_init_count) + { + _source = calloc(1, sizeof(Ecore_X_DND_Source)); + if (!_source) return; + _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)); + if (!_target) + { + free(_source); + _source = NULL; + return; + } + _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 Eina_Bool +_ecore_x_dnd_converter_copy(char *target EINA_UNUSED, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *tprop EINA_UNUSED, + int *count EINA_UNUSED) +{ + XTextProperty text_prop; + char *mystr; + XICCEncodingStyle style = XTextStyle; + + if (!data || !size) + return EINA_FALSE; + + mystr = calloc(1, size + 1); + if (!mystr) + return EINA_FALSE; + + 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); + if (!*data_ret) + { + free(mystr); + return EINA_FALSE; + } + memcpy(*data_ret, text_prop.value, bufsize); + *size_ret = bufsize; + XFree(text_prop.value); + free(mystr); + return EINA_TRUE; + } + else + { + free(mystr); + return EINA_FALSE; + } +} + +EAPI void +ecore_x_dnd_aware_set(Ecore_X_Window win, + Eina_Bool 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; + Version_Cache_Item *t; + + 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; + + t = realloc(_version_cache, + _version_cache_alloc * + sizeof(Version_Cache_Item)); + if (!t) return 0; + _version_cache = t; + _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; + + t = realloc(_version_cache, _version_cache_alloc * + sizeof(Version_Cache_Item)); + if (!t) return 0; + _version_cache = t; + _version_cache[_version_cache_num - 1].win = win; + _version_cache[_version_cache_num - 1].ver = 0; + } + + return 0; +} + +EAPI Eina_Bool +ecore_x_dnd_type_isset(Ecore_X_Window win, + const char *type) +{ + int num, i, ret = EINA_FALSE; + 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 = EINA_TRUE; + break; + } + } + + XFree(data); + return ret; +} + +EAPI void +ecore_x_dnd_type_set(Ecore_X_Window win, + const char *type, + Eina_Bool 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); + } +} + +/** + * The DND position update cb is called Ecore_X sends a DND position to a + * client. + * + * It essentially mirrors some of the data sent in the position message. + * Generally this cb should be set just before position update is called. + * Please note well you need to look after your own data pointer if someone + * trashes you position update cb set. + * + * It is considered good form to clear this when the dnd event finishes. + * + * @param cb Callback to updated each time ecore_x sends a position update. + * @param data User data. + */ +EAPI void +ecore_x_dnd_callback_pos_update_set( + void (*cb)(void *, + Ecore_X_Xdnd_Position *data), + const void *data) +{ + _posupdatecb = cb; + _posupdatedata = (void *)data; /* Discard the const early */ +} + +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 Eina_Bool +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 EINA_FALSE; + + /* Take ownership of XdndSelection */ + if (!ecore_x_selection_xdnd_set(source, data, size)) + return EINA_FALSE; + + 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 EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_dnd_drop(void) +{ + XEvent xev; + int status = EINA_FALSE; + + 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 = EINA_TRUE; + } + 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(Eina_Bool will_accept, + Eina_Bool 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; +} + +EAPI 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); +} + +EAPI 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; + Ecore_X_Xdnd_Position pos; + 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; + } + } + + if (_posupdatecb) + { + pos.position.x = x; + pos.position.y = y; + pos.win = win; + pos.prev = _source->dest; + _posupdatecb(_posupdatedata, &pos); + } + + _source->prev.x = x; + _source->prev.y = y; + _source->prev.window = root; + _source->dest = win; +} + +/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ diff --git a/src/lib/ecore_x/xlib/ecore_x_dpms.c b/src/lib/ecore_x/xlib/ecore_x_dpms.c new file mode 100644 index 0000000000..23349f44e6 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_dpms.c @@ -0,0 +1,247 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include "ecore_x_private.h" + +static Eina_Bool _dpms_available = EINA_FALSE; + +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 = EINA_TRUE; + else + _dpms_available = EINA_FALSE; + +#else /* ifdef ECORE_XDPMS */ + _dpms_available = EINA_FALSE; +#endif /* ifdef ECORE_XDPMS */ +} + +/** + * @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 Eina_Bool +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 Eina_Bool +ecore_x_dpms_capable_get(void) +{ +#ifdef ECORE_XDPMS + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return DPMSCapable(_ecore_x_disp) ? EINA_TRUE : EINA_FALSE; +#else /* ifdef ECORE_XDPMS */ + return EINA_FALSE; +#endif /* ifdef ECORE_XDPMS */ +} + +/** + * Checks the DPMS state of the display. + * @return @c 1 if DPMS is enabled, @c 0 otherwise. + * @ingroup Ecore_X_DPMS_Group + */ +EAPI Eina_Bool +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 ? EINA_TRUE : EINA_FALSE; +#else /* ifdef ECORE_XDPMS */ + return EINA_FALSE; +#endif /* ifdef ECORE_XDPMS */ +} + +/** + * 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 /* ifdef ECORE_XDPMS */ +} + +/** + * 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 /* ifdef ECORE_XDPMS */ +} + +/** + * 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 Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +#else /* ifdef ECORE_XDPMS */ + return EINA_FALSE; +#endif /* ifdef ECORE_XDPMS */ +} + +/** + * 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(void) +{ +#ifdef ECORE_XDPMS + unsigned short standby, suspend, off; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off); + return standby; +#else /* ifdef ECORE_XDPMS */ + return 0; +#endif /* ifdef ECORE_XDPMS */ +} + +/** + * 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(void) +{ +#ifdef ECORE_XDPMS + unsigned short standby, suspend, off; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off); + return suspend; +#else /* ifdef ECORE_XDPMS */ + return 0; +#endif /* ifdef ECORE_XDPMS */ +} + +/** + * 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(void) +{ +#ifdef ECORE_XDPMS + unsigned short standby, suspend, off; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + DPMSGetTimeouts(_ecore_x_disp, &standby, &suspend, &off); + return off; +#else /* ifdef ECORE_XDPMS */ + return 0; +#endif /* ifdef ECORE_XDPMS */ +} + +/** + * Sets the standby timeout (in unit of seconds). + * @param new_timeout 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 /* ifdef ECORE_XDPMS */ +} + +/** + * Sets the suspend timeout (in unit of seconds). + * @param new_timeout 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 /* ifdef ECORE_XDPMS */ +} + +/** + * Sets the off timeout (in unit of seconds). + * @param new_timeout 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 /* ifdef ECORE_XDPMS */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_drawable.c b/src/lib/ecore_x/xlib/ecore_x_drawable.c new file mode 100644 index 0000000000..d1b41114da --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_drawable.c @@ -0,0 +1,118 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#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); +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_e.c b/src/lib/ecore_x/xlib/ecore_x_e.c new file mode 100644 index 0000000000..430b24b117 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_e.c @@ -0,0 +1,1670 @@ +/* + * OLD E hints + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#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 Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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: break; + } + 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 = 0; + + 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: + break; + } + 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 Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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_access_action_next_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_prev_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_activate_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_read_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_read_next_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_read_prev_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_up_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP, + 0, 0, 0); +} + +EAPI void +ecore_x_e_illume_access_action_down_send(Ecore_X_Window win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + win, + ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN, + 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 Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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 Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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 Eina_Bool +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 EINA_FALSE; + + if (x) + *x = geom[0]; + + if (y) + *y = geom[1]; + + if (w) + *w = geom[2]; + + if (h) + *h = geom[3]; + + return EINA_TRUE; +} + +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 Eina_Bool +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 EINA_FALSE; + + if (x) + *x = geom[0]; + + if (y) + *y = geom[1]; + + if (w) + *w = geom[2]; + + if (h) + *h = geom[3]; + + return EINA_TRUE; +} + +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 Eina_Bool +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 EINA_FALSE; + + if (x) + *x = geom[0]; + + if (y) + *y = geom[1]; + + if (w) + *w = geom[2]; + + if (h) + *h = geom[3]; + + return EINA_TRUE; +} + +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: + break; + } + 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 Eina_Bool +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 EINA_FALSE; + + return val ? EINA_TRUE : EINA_FALSE; +} + +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 = 0; + + 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); +} + +static Ecore_X_Atom +_ecore_x_e_clipboard_atom_get(Ecore_X_Illume_Clipboard_State state) +{ + switch (state) + { + case ECORE_X_ILLUME_CLIPBOARD_STATE_ON: + return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON; + case ECORE_X_ILLUME_CLIPBOARD_STATE_OFF: + return ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF; + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Clipboard_State +_ecore_x_e_clipboard_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_ON) + return ECORE_X_ILLUME_CLIPBOARD_STATE_ON; + + if (atom == ECORE_X_ATOM_E_ILLUME_CLIPBOARD_OFF) + return ECORE_X_ILLUME_CLIPBOARD_STATE_OFF; + + return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; +} + +EAPI void +ecore_x_e_illume_clipboard_state_set(Ecore_X_Window win, + Ecore_X_Illume_Clipboard_State state) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_x_e_clipboard_atom_get(state); + + ecore_x_window_prop_atom_set(win, + ECORE_X_ATOM_E_ILLUME_CLIPBOARD_STATE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Clipboard_State +ecore_x_e_illume_clipboard_state_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_CLIPBOARD_STATE, + &atom, 1)) + return ECORE_X_ILLUME_CLIPBOARD_STATE_UNKNOWN; + return _ecore_x_e_clipboard_state_get(atom); +} + +EAPI void +ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY, + geom, 4); +} + +EAPI Eina_Bool +ecore_x_e_illume_clipboard_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_CLIPBOARD_GEOMETRY, + geom, 4); + if (ret != 4) return EINA_FALSE; + + if (x) *x = geom[0]; + if (y) *y = geom[1]; + if (w) *w = geom[2]; + if (h) *h = geom[3]; + + return EINA_TRUE; +} + +/* for sliding window */ +EAPI void +ecore_x_e_illume_sliding_win_state_set(Ecore_X_Window win, + unsigned int is_visible) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_window_prop_card32_set(win, + ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE, + &is_visible, 1); +} /* ecore_x_e_illume_sliding_win_state_set */ + +EAPI int +ecore_x_e_illume_sliding_win_state_get(Ecore_X_Window win) +{ + unsigned int is_visible = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ecore_x_window_prop_card32_get(win, + ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE, + &is_visible, 1)) + return 0; + + return is_visible; +} + +EAPI void +ecore_x_e_illume_sliding_win_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_SLIDING_WIN_GEOMETRY, + geom, 4); +} /* ecore_x_e_illume_sliding_win_geometry_set */ + +EAPI int +ecore_x_e_illume_sliding_win_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_SLIDING_WIN_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; +}/* ecore_x_e_illume_sliding_win_geometry_get */ + +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; // version + 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_draw_size_done_send(Ecore_X_Window root, + Ecore_X_Window win, + int w, + int h) +{ + 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] = 1; // version + xev.xclient.data.l[2] = w; // win width at draw time + xev.xclient.data.l[3] = h; // win height at draw time + xev.xclient.data.l[4] = 0; // later + + XSendEvent(_ecore_x_disp, root, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); +} + +/* + * @since 1.3 + * + */ +EAPI void +ecore_x_e_window_profile_list_set(Ecore_X_Window win, + const char **profiles, + unsigned int num_profiles) +{ + Ecore_X_Atom *atoms; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!win) + return; + + if (!num_profiles) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE_LIST); + else + { + atoms = alloca(num_profiles * sizeof(Ecore_X_Atom)); + ecore_x_atoms_get(profiles, num_profiles, atoms); + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_E_PROFILE_LIST, + XA_ATOM, 32, (void *)atoms, + num_profiles); + } +} + +/* + * @since 1.3 + */ +EAPI Eina_Bool +ecore_x_e_window_profile_list_get(Ecore_X_Window win, + const char ***profiles, + int *ret_num) +{ + unsigned char *data; + Ecore_X_Atom *atoms; + int num, i; + + if (ret_num) + *ret_num = 0; + + if (profiles) + *profiles = NULL; + + if (!win) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_E_PROFILE_LIST, + XA_ATOM, 32, &data, &num)) + return EINA_FALSE; + + if (ret_num) + *ret_num = num; + + if (profiles) + { + (*profiles) = calloc(num, sizeof(char *)); + if (!(*profiles)) + { + if (ret_num) + *ret_num = 0; + + if (data) + free(data); + + return EINA_FALSE; + } + + atoms = (Ecore_X_Atom *)data; + for (i = 0; i < num; i++) + (*profiles)[i] = ecore_x_atom_name_get(atoms[i]); + } + + if (data) + XFree(data); + + return EINA_TRUE; +} + +/* + * @since 1.3 + */ +EAPI void +ecore_x_e_window_profile_set(Ecore_X_Window win, + const char *profile) +{ + Ecore_X_Atom atom; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!win) + return; + + if (!profile) + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_E_PROFILE); + else + { + atom = ecore_x_atom_get(profile); + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_E_PROFILE, + XA_ATOM, 32, (void *)&atom, 1); + } +} + +/* + * @since 1.3 + */ +EAPI char * +ecore_x_e_window_profile_get(Ecore_X_Window win) +{ + Ecore_X_Atom *atom = NULL; + unsigned char *data; + char *profile = NULL; + int num; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_E_PROFILE, + XA_ATOM, 32, &data, &num)) + return NULL; + + if (data) + atom = (Ecore_X_Atom *)data; + + if (atom) + profile = ecore_x_atom_name_get(atom[0]); + + return profile; +} + +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 EINA_TRUE; + } + + return EINA_FALSE; +} + +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); +} + +EAPI void +ecore_x_e_comp_pixmap_set(Ecore_X_Window win, + Ecore_X_Pixmap pixmap) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (pixmap) + ecore_x_window_prop_xid_set(win, ECORE_X_ATOM_E_COMP_PIXMAP, + ECORE_X_ATOM_PIXMAP, &pixmap, 1); + else + ecore_x_window_prop_property_del(win, pixmap); +} + +EAPI Ecore_X_Pixmap +ecore_x_e_comp_pixmap_get(Ecore_X_Window win) +{ + int ret = 0; + Ecore_X_Pixmap pixmap = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ret = + ecore_x_window_prop_xid_get(win, + ECORE_X_ATOM_E_COMP_PIXMAP, + ECORE_X_ATOM_PIXMAP, + &pixmap, 1); + if (ret != 1) + return 0; + + return pixmap; +} + +static Ecore_X_Atom +_ecore_x_e_indicator_atom_get(Ecore_X_Illume_Indicator_State state) +{ + switch (state) + { + case ECORE_X_ILLUME_INDICATOR_STATE_ON: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_ON; + + case ECORE_X_ILLUME_INDICATOR_STATE_OFF: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF; + + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Indicator_State +_ecore_x_e_indicator_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_ON) + return ECORE_X_ILLUME_INDICATOR_STATE_ON; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OFF) + return ECORE_X_ILLUME_INDICATOR_STATE_OFF; + + return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; +} + +EAPI void +ecore_x_e_illume_indicator_state_set(Ecore_X_Window win, + Ecore_X_Illume_Indicator_State state) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_x_e_indicator_atom_get(state); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Indicator_State +ecore_x_e_illume_indicator_state_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_INDICATOR_STATE, + &atom, 1)) + return ECORE_X_ILLUME_INDICATOR_STATE_UNKNOWN; + + return _ecore_x_e_indicator_state_get(atom); +} + +EAPI void +ecore_x_e_illume_indicator_state_send(Ecore_X_Window win, + Ecore_X_Illume_Indicator_State state) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_x_e_indicator_atom_get(state), + 0, 0, 0, 0); +} + +static Ecore_X_Atom +_ecore_x_e_indicator_opacity_atom_get(Ecore_X_Illume_Indicator_Opacity_Mode mode) +{ + switch (mode) + { + case ECORE_X_ILLUME_INDICATOR_OPAQUE: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE; + + case ECORE_X_ILLUME_INDICATOR_TRANSLUCENT: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT; + + case ECORE_X_ILLUME_INDICATOR_TRANSPARENT: + return ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT; + + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Indicator_Opacity_Mode +_ecore_x_e_indicator_opacity_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OPAQUE) + return ECORE_X_ILLUME_INDICATOR_OPAQUE; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSLUCENT) + return ECORE_X_ILLUME_INDICATOR_TRANSLUCENT; + + if (atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_TRANSPARENT) + return ECORE_X_ILLUME_INDICATOR_TRANSPARENT; + + return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; +} + +EAPI void +ecore_x_e_illume_indicator_opacity_set(Ecore_X_Window win, + Ecore_X_Illume_Indicator_Opacity_Mode mode) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_x_e_indicator_opacity_atom_get(mode); + ecore_x_window_prop_atom_set(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Indicator_Opacity_Mode +ecore_x_e_illume_indicator_opacity_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_INDICATOR_OPACITY_MODE, + &atom, 1)) + return ECORE_X_ILLUME_INDICATOR_OPACITY_UNKNOWN; + + return _ecore_x_e_indicator_opacity_get(atom); +} + +EAPI void +ecore_x_e_illume_indicator_opacity_send(Ecore_X_Window win, + Ecore_X_Illume_Indicator_Opacity_Mode mode) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_client_message32_send(win, + ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + _ecore_x_e_indicator_opacity_atom_get(mode), + 0, 0, 0, 0); +} + +static Ecore_X_Atom +_ecore_x_e_illume_window_state_atom_get(Ecore_X_Illume_Window_State state) +{ + switch (state) + { + case ECORE_X_ILLUME_WINDOW_STATE_NORMAL: + return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL; + + case ECORE_X_ILLUME_WINDOW_STATE_FLOATING: + return ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING; + + default: + break; + } + return 0; +} + +static Ecore_X_Illume_Window_State +_ecore_x_e_illume_window_state_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_NORMAL) + return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; + + if (atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE_FLOATING) + return ECORE_X_ILLUME_WINDOW_STATE_FLOATING; + + return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; +} + +EAPI void +ecore_x_e_illume_window_state_set(Ecore_X_Window win, + Ecore_X_Illume_Window_State state) +{ + Ecore_X_Atom atom = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + atom = _ecore_x_e_illume_window_state_atom_get(state); + ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_E_ILLUME_WINDOW_STATE, + &atom, 1); +} + +EAPI Ecore_X_Illume_Window_State +ecore_x_e_illume_window_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_WINDOW_STATE, + &atom, 1)) + return ECORE_X_ILLUME_WINDOW_STATE_NORMAL; + + return _ecore_x_e_illume_window_state_get(atom); +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_error.c b/src/lib/ecore_x/xlib/ecore_x_error.c new file mode 100644 index 0000000000..f6eb075b54 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_error.c @@ -0,0 +1,126 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include + +#include "Ecore.h" +#include "ecore_private.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" + +static int _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; +static Ecore_X_ID _error_resource_id = 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 + */ +//FIXME: Use Ecore_X_Error_Code type when 2.0 is released +EAPI int +ecore_x_error_code_get(void) +{ + return _error_code; +} + +/** + * Get the resource id that caused the error. + * @return The resource id causing the X error + * + * Return the X resource id that caused the last X error + */ +EAPI Ecore_X_ID +ecore_x_error_resource_id_get(void) +{ + return _error_resource_id; +} + +void +_ecore_x_error_handler_init(void) +{ + XSetErrorHandler((XErrorHandler)_ecore_x_error_handle); + XSetIOErrorHandler((XIOErrorHandler)_ecore_x_io_error_handle); +} + +static int +_ecore_x_error_handle(Display *d, + XErrorEvent *ev) +{ + if (d == _ecore_x_disp) + { + _error_request_code = ev->request_code; + _error_code = ev->error_code; + _error_resource_id = ev->resourceid; + if (_error_func) + _error_func(_error_data); + } + return 0; +} + +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; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_events.c b/src/lib/ecore_x/xlib/ecore_x_events.c new file mode 100644 index 0000000000..9ce7163d53 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_events.c @@ -0,0 +1,2523 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include +#include +#include + +#include + +#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 /* ifndef CODESET */ + +typedef struct _Ecore_X_Mouse_Down_Info +{ + EINA_INLIST; + int dev; + Window last_win; + Window last_last_win; + Window last_event_win; + Window last_last_event_win; + Time last_time; + Time last_last_time; + Eina_Bool did_double : 1; + Eina_Bool did_triple : 1; +} Ecore_X_Mouse_Down_Info; + +static int _ecore_x_last_event_mouse_move = 0; +static Ecore_Event *_ecore_x_last_event_mouse_move_event = NULL; +static Eina_Inlist *_ecore_x_mouse_down_info_list = NULL; + +static void +_ecore_x_mouse_down_info_clear(void) +{ + Eina_Inlist *l = _ecore_x_mouse_down_info_list; + Ecore_X_Mouse_Down_Info *info = NULL; + while (l) + { + info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info); + l = eina_inlist_remove(l, l); + free(info); + } + _ecore_x_mouse_down_info_list = NULL; +} + +void +_ecore_x_events_init(void) +{ + //Actually, Nothing to do. +} + +void +_ecore_x_events_shutdown(void) +{ + _ecore_x_mouse_down_info_clear(); +} + +static Ecore_X_Mouse_Down_Info * +_ecore_x_mouse_down_info_get(int dev) +{ + Eina_Inlist *l = _ecore_x_mouse_down_info_list; + Ecore_X_Mouse_Down_Info *info = NULL; + + //Return the exist info + EINA_INLIST_FOREACH(l, info) + if (info->dev == dev) return info; + + //New Device. Add it. + info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info)); + if (!info) return NULL; + + info->dev = dev; + l = eina_inlist_append(l, (Eina_Inlist *)info); + _ecore_x_mouse_down_info_list = l; + return info; +} + +static void +_ecore_x_event_free_mouse_move(void *data EINA_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); +} + +static void +_ecore_x_event_free_xdnd_enter(void *data EINA_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 EINA_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_MODIFIER_ALTGR) + modifiers |= ECORE_EVENT_MODIFIER_ALTGR; + + 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; + + if (state & ECORE_X_LOCK_SHIFT) + modifiers |= ECORE_EVENT_LOCK_SHIFT; + + 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(_ecore_x_XKeycodeToKeysym(xevent->display, + xevent->keycode, 0)); + if (!keyname) + { + snprintf(keyname_buffer, + sizeof(keyname_buffer), + "Keycode-%i", + xevent->keycode); + keyname = keyname_buffer; + } + + sym = 0; + key = NULL; + compose = NULL; + 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); + if (!compose) + ERR("Ecore_X cannot convert input key string '%s' to UTF-8. " + "Is Eina built with iconv support?", compose_buffer); + tmp = compose; + } + + key = XKeysymToString(sym); + if (!key) + key = keyname; + + 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; + + Ecore_X_Mouse_Down_Info *down_info = _ecore_x_mouse_down_info_get(dev); + + if (down_info) + { + if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && + down_info->did_triple) + { + down_info->last_win = 0; + down_info->last_last_win = 0; + down_info->last_event_win = 0; + down_info->last_last_event_win = 0; + down_info->last_time = 0; + down_info->last_last_time = 0; + } + if (event_window == window) + { + if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) + { + //Check Double Clicked + if (((int)(timestamp - down_info->last_time) <= + (int)(1000 * _ecore_x_double_click_time)) && + (window == down_info->last_win) && + (event_window == down_info->last_event_win)) + { + e->double_click = 1; + down_info->did_double = EINA_TRUE; + } + else + { + down_info->did_double = EINA_FALSE; + down_info->did_triple = EINA_FALSE; + } + + //Check Triple Clicked + if (((int)(timestamp - down_info->last_last_time) <= + (int)(2 * 1000 * _ecore_x_double_click_time)) && + (window == down_info->last_win) && + (window == down_info->last_last_win) && + (event_window == down_info->last_event_win) && + (event_window == down_info->last_last_event_win) + ) + { + e->triple_click = 1; + down_info->did_triple = EINA_TRUE; + } + else + { + down_info->did_triple = EINA_FALSE; + } + } + else + { + if (down_info->did_double) + e->double_click = 1; + if (down_info->did_triple) + e->triple_click = 1; + } + } + } + + /* NB: Block commented out as _ecore_x_mouse_up_count appears to have + * no use. The variable is also commented out above. This code block is + * the only place that this variable is used, and appears to serve no + * purpose. - dh + 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); + + if ((down_info) && + (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) && + (window == event_window) && + (!down_info->did_triple)) + { + down_info->last_last_win = down_info->last_win; + down_info->last_win = window; + down_info->last_last_event_win = down_info->last_event_win; + down_info->last_event_win = event_window; + down_info->last_last_time = down_info->last_time; + down_info->last_time = timestamp; + } + + return e; +} + +void +_ecore_x_event_handle_any_event(XEvent *xevent) +{ + XEvent *ev = malloc(sizeof(XEvent)); + if (!ev) return; + 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)) + { + Eina_Bool replay = EINA_FALSE; + + 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; + + 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)) + { + Eina_Bool replay = EINA_FALSE; + + 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; + } + } + } + } +} + +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; + + 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; + + 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 EINA_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 EINA_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; + { + 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; +/* errr..... why? paranoia. + 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 = NULL; + int len; + int typesize; + + 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 = None; + Ecore_X_Atom type; + + /* Set up defaults for strings first */ + type = xevent->xselectionrequest.target; + typesize = 8; + len = sd->length; + + if (!ecore_x_selection_convert(xevent->xselectionrequest.selection, + xevent->xselectionrequest.target, + &data, &len, &type, &typesize)) + /* Refuse selection, conversion to requested target failed */ + property = None; + else if (data) + { + /* FIXME: This does not properly handle large data transfers */ + ecore_x_window_prop_property_set( + xevent->xselectionrequest.requestor, + xevent->xselectionrequest. + property, + type, + typesize, + data, + len); + property = xevent->xselectionrequest.property; + free(data); + } + + ecore_x_selection_notify_send(xevent->xselectionrequest.requestor, + xevent->xselectionrequest.selection, + xevent->xselectionrequest.target, + property, + xevent->xselectionrequest.time); + } + } +} + +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) + { + /* fallback if targets handling is not working and try get the + * selection directly */ + XConvertSelection(_ecore_x_disp, selection, + ECORE_X_ATOM_UTF8_STRING, + selection, + xevent->xselection.requestor, + CurrentTime); + return; + } + } + else + format = ecore_x_window_prop_property_get(xevent->xselection.requestor, + xevent->xselection.property, + AnyPropertyType, 8, &data, + &num_ret); + + 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 = EINA_TRUE; + else + e->installed = EINA_FALSE; + + 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); + free(e); + 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."); + free(e); + 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; + Eina_Bool completed = EINA_TRUE; + + 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 = EINA_FALSE; + 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_Event_Mapping_Change *e; + + _ecore_x_last_event_mouse_move = 0; + XRefreshKeyboardMapping((XMappingEvent *)xevent); + _ecore_x_modifiers_get(); + e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change)); + if (!e) return; + switch (xevent->xmapping.request) + { + case MappingModifier: + e->type = ECORE_X_MAPPING_MODIFIER; + break; + + case MappingKeyboard: + e->type = ECORE_X_MAPPING_KEYBOARD; + break; + + case MappingPointer: + default: + e->type = ECORE_X_MAPPING_MOUSE; + break; + } + e->keycode = xevent->xmapping.first_keycode; + e->num = xevent->xmapping.count; + ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL); +} + +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; + switch (shape_event->kind) + { + case ShapeBounding: + e->type = ECORE_X_SHAPE_BOUNDING; + break; + + case ShapeClip: + e->type = ECORE_X_SHAPE_CLIP; + break; + + case ShapeInput: + e->type = ECORE_X_SHAPE_INPUT; + break; + + default: + break; + } + e->x = shape_event->x; + e->y = shape_event->y; + e->w = shape_event->width; + e->h = shape_event->height; + e->shaped = shape_event->shaped; + 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) || + (screensaver_event->state == ScreenSaverCycle)) + e->on = EINA_TRUE; + else + e->on = EINA_FALSE; + + e->time = screensaver_event->time; + ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL); +#else /* ifdef ECORE_XSS */ + xevent = NULL; +#endif /* ifdef ECORE_XSS */ +} + +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->size.width = randr_event->width; + e->size.height = randr_event->height; + e->time = randr_event->timestamp; + e->config_time = randr_event->config_timestamp; + e->size.width_mm = randr_event->mwidth; + e->size.height_mm = randr_event->mheight; + e->orientation = 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->orientation = randr_event->rotation; + e->geo.x = randr_event->x; + e->geo.y = randr_event->y; + e->geo.w = randr_event->width; + e->geo.h = 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->orientation = 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; + if (randr_event->state == PropertyNewValue) + e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD; + else + e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL; + 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_XRANDR */ + +#ifdef ECORE_XFIXES +void +_ecore_x_event_handle_fixes_selection_notify(XEvent *event) +{ + XFixesSelectionNotifyEvent *notify_event = + (XFixesSelectionNotifyEvent *)event; + Ecore_X_Event_Fixes_Selection_Notify *e; + Ecore_X_Atom sel; + + _ecore_x_last_event_mouse_move = 0; + /* Nothing here yet */ + + e = calloc(1, sizeof(*e)); + if (!e) + return; + + e->win = notify_event->window; + e->owner = notify_event->owner; + e->time = notify_event->timestamp; + e->selection_time = notify_event->selection_timestamp; + e->atom = sel = notify_event->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; + e->reason = notify_event->subtype; + + ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL); +} + +#endif /* ifdef ECORE_XFIXES */ + +#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 /* ifdef ECORE_XDAMAGE */ + +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 (data) + { + if (e->data) + XFreeEventData(_ecore_x_disp, (XGenericEventCookie *)data); + free(data); + } + free(e); +#else + return; + data = NULL; ev = NULL; +#endif /* ifdef ECORE_XI2 */ +} + +void +_ecore_x_event_handle_generic_event(XEvent *event) +{ +#ifdef ECORE_XI2 + XGenericEvent *generic_event; + Ecore_X_Event_Generic *e; + XGenericEventCookie *data; + + 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); + + data = malloc(sizeof(XGenericEventCookie)); + if (data) memcpy(data, &(event->xcookie), sizeof(XGenericEventCookie)); + ecore_event_add(ECORE_X_EVENT_GENERIC, + e, + _ecore_x_event_free_generic_event, + data); +#else + return; + event = NULL; +#endif /* ifdef ECORE_XI2 */ +} + +#ifdef ECORE_XGESTURE +void +_ecore_x_event_handle_gesture_notify_flick(XEvent *xevent) +{ + XGestureNotifyFlickEvent *xfe; + Ecore_X_Event_Gesture_Notify_Flick *e; + + _ecore_x_last_event_mouse_move = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xfe = (XGestureNotifyFlickEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick)); + if (!e) + return; + + e->win = xfe->window; + e->time = xfe->time; + e->subtype = xfe->kind; + e->num_fingers = xfe->num_finger; + e->distance = xfe->distance; + e->duration = xfe->duration; + e->direction = xfe->direction; + e->angle = XFixedToDouble(xfe->angle); + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL); +} + +void +_ecore_x_event_handle_gesture_notify_pan(XEvent *xevent) +{ + XGestureNotifyPanEvent *xpe; + Ecore_X_Event_Gesture_Notify_Pan *e; + + _ecore_x_last_event_mouse_move = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xpe = (XGestureNotifyPanEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan)); + if (!e) + return; + + e->win = xpe->window; + e->time = xpe->time; + e->subtype = xpe->kind; + e->num_fingers = xpe->num_finger; + e->dx = xpe->dx; + e->dy = xpe->dy; + e->distance = xpe->distance; + e->duration = xpe->duration; + e->direction = xpe->direction; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL); +} + +void +_ecore_x_event_handle_gesture_notify_pinchrotation(XEvent *xevent) +{ + XGestureNotifyPinchRotationEvent *xpre; + Ecore_X_Event_Gesture_Notify_PinchRotation *e; + + _ecore_x_last_event_mouse_move = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xpre = (XGestureNotifyPinchRotationEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation)); + if (!e) + return; + + e->win = xpre->window; + e->time = xpre->time; + e->subtype = xpre->kind; + e->num_fingers = xpre->num_finger; + e->distance = xpre->distance; + e->cx = xpre->cx; + e->cy = xpre->cy; + e->zoom = XFixedToDouble(xpre->zoom); + e->angle = XFixedToDouble(xpre->angle); + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL); +} + +void +_ecore_x_event_handle_gesture_notify_tap(XEvent *xevent) +{ + XGestureNotifyTapEvent *xte; + Ecore_X_Event_Gesture_Notify_Tap *e; + + _ecore_x_last_event_mouse_move = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xte = (XGestureNotifyTapEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap)); + if (!e) + return; + + e->win = xte->window; + e->time = xte->time; + e->subtype = xte->kind; + e->num_fingers = xte->num_finger; + e->cx = xte->cx; + e->cy = xte->cy; + e->tap_repeat = xte->tap_repeat; + e->interval = xte->interval; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL); +} + +void +_ecore_x_event_handle_gesture_notify_tapnhold(XEvent *xevent) +{ + XGestureNotifyTapNHoldEvent *xthe; + Ecore_X_Event_Gesture_Notify_TapNHold *e; + + _ecore_x_last_event_mouse_move = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xthe = (XGestureNotifyTapNHoldEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold)); + if (!e) + return; + + e->win = xthe->window; + e->time = xthe->time; + e->subtype = xthe->kind; + e->num_fingers = xthe->num_finger; + e->cx = xthe->cx; + e->cy = xthe->cy; + e->interval = xthe->interval; + e->hold_time = xthe->holdtime; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL); +} + +void +_ecore_x_event_handle_gesture_notify_hold(XEvent *xevent) +{ + XGestureNotifyHoldEvent *xhe; + Ecore_X_Event_Gesture_Notify_Hold *e; + + _ecore_x_last_event_mouse_move = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xhe = (XGestureNotifyHoldEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold)); + if (!e) + return; + + e->win = xhe->window; + e->time = xhe->time; + e->subtype = xhe->kind; + e->num_fingers = xhe->num_finger; + e->cx = xhe->cx; + e->cy = xhe->cy; + e->hold_time = xhe->holdtime; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL); +} + +void +_ecore_x_event_handle_gesture_notify_group(XEvent *xevent) +{ + XGestureNotifyGroupEvent *xge; + Ecore_X_Event_Gesture_Notify_Group *e; + + _ecore_x_last_event_mouse_move = 0; + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + xge = (XGestureNotifyGroupEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group)); + if (!e) + return; + + e->win = xge->window; + e->time = xge->time; + e->subtype = xge->kind; + e->num_groups = xge->num_group; + e->group_id = xge->groupid; + + ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL); +} + +#endif /* ifdef ECORE_XGESTURE */ +#ifdef ECORE_XKB +void +_ecore_x_event_handle_xkb(XEvent *xevent) +{ + XkbEvent *xkbev; + Ecore_X_Event_Xkb *e; + + xkbev = (XkbEvent *) xevent; + e = calloc(1, sizeof(Ecore_X_Event_Xkb)); + if (!e) + return; + e->group = xkbev->state.group; + if (xkbev->any.xkb_type == XkbStateNotify) + ecore_event_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, e, NULL, NULL); + else if ((xkbev->any.xkb_type == XkbNewKeyboardNotify) || + (xkbev->any.xkb_type == XkbMapNotify)) + { + if (xkbev->any.xkb_type == XkbMapNotify) + { + XkbMapNotifyEvent *xkbmapping; + + xkbmapping = (XkbMapNotifyEvent *)xkbev; + XkbRefreshKeyboardMapping(xkbmapping); + } + ecore_event_add(ECORE_X_EVENT_XKB_NEWKBD_NOTIFY, e, NULL, NULL); + } +} +#endif /* ifdef ECORE_XKB */ diff --git a/src/lib/ecore_x/xlib/ecore_x_fixes.c b/src/lib/ecore_x/xlib/ecore_x_fixes.c new file mode 100644 index 0000000000..da0a6c3ac9 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_fixes.c @@ -0,0 +1,365 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include + +#include "ecore_x_private.h" +#include "Ecore_X.h" + +static int _fixes_available; +#ifdef ECORE_XFIXES +static int _fixes_major, _fixes_minor; +#endif /* ifdef ECORE_XFIXES */ + +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; + + ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = ecore_event_type_new(); + } + else + _fixes_available = 0; + +#else /* ifdef ECORE_XFIXES */ + _fixes_available = 0; +#endif /* ifdef ECORE_XFIXES */ +} + +#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 /* ifdef ECORE_XFIXES */ + +EAPI Eina_Bool +ecore_x_fixes_selection_notification_request(Ecore_X_Atom selection) +{ +#ifdef ECORE_XFIXES + if (_fixes_available) + { + XFixesSelectSelectionInput (_ecore_x_disp, + DefaultRootWindow(_ecore_x_disp), + selection, + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); + return EINA_TRUE; + } +#endif + return EINA_FALSE; +} + +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 /* ifdef ECORE_XFIXES */ + return 0; +#endif /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ + return 0; +#endif /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ + return 0; +#endif /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ + return 0; +#endif /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ + return 0; +#endif /* ifdef ECORE_XFIXES */ +} + +EAPI void +ecore_x_region_free(Ecore_X_Region region) +{ +#ifdef ECORE_XFIXES + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XFixesDestroyRegion(_ecore_x_disp, region); +#endif /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ + return NULL; +#endif /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + +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 /* ifdef ECORE_XFIXES */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_gc.c b/src/lib/ecore_x/xlib/ecore_x_gc.c new file mode 100644 index 0000000000..539636648f --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_gc.c @@ -0,0 +1,171 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include + +#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 idx; + int i; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!draw) + draw = DefaultRootWindow(_ecore_x_disp); + + memset(&gcv, 0, sizeof (gcv)); + + for (i = 0, idx = 0, mask = 1; i <= 22; i++, mask <<= 1) + { + switch (mask & value_mask) + { + case ECORE_X_GC_VALUE_MASK_FUNCTION: + gcv.function = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_PLANE_MASK: + gcv.plane_mask = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_FOREGROUND: + gcv.foreground = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_BACKGROUND: + gcv.background = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_LINE_WIDTH: + gcv.line_width = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_LINE_STYLE: + gcv.line_style = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_CAP_STYLE: + gcv.cap_style = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_JOIN_STYLE: + gcv.join_style = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_FILL_STYLE: + gcv.fill_style = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_FILL_RULE: + gcv.fill_rule = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_TILE: + gcv.tile = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_STIPPLE: + gcv.stipple = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_X: + gcv.ts_x_origin = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_TILE_STIPPLE_ORIGIN_Y: + gcv.ts_y_origin = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_FONT: + gcv.font = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_SUBWINDOW_MODE: + gcv.subwindow_mode = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_GRAPHICS_EXPOSURES: + gcv.graphics_exposures = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_X: + gcv.clip_x_origin = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_CLIP_ORIGIN_Y: + gcv.clip_y_origin = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_CLIP_MASK: + gcv.clip_mask = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_DASH_OFFSET: + gcv.dash_offset = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_DASH_LIST: + gcv.dashes = value_list[idx]; + idx++; + break; + + case ECORE_X_GC_VALUE_MASK_ARC_MODE: + gcv.arc_mode = value_list[idx]; + idx++; + 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); +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_gesture.c b/src/lib/ecore_x/xlib/ecore_x_gesture.c new file mode 100644 index 0000000000..dbde8b0db2 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_gesture.c @@ -0,0 +1,137 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include "ecore_x_private.h" + +static Eina_Bool _gesture_available = EINA_FALSE; + +#ifdef ECORE_XGESTURE +static int _gesture_major, _gesture_minor, _gesture_patch; +int _gesture_version; +#endif /* ifdef ECORE_XGESTURE */ + +void +_ecore_x_gesture_init(void) +{ +#ifdef ECORE_XGESTURE + _gesture_major = 0; + _gesture_minor = 0; + _gesture_patch = 0; + _gesture_version = 0; + + if (XGestureQueryVersion(_ecore_x_disp, &_gesture_major, &_gesture_minor, &_gesture_patch)) + { + _gesture_version = (_gesture_major << 16) | _gesture_minor; + _gesture_available = EINA_TRUE; + } + else + _gesture_available = EINA_FALSE; +#else /* ifdef ECORE_XGESTURE */ + _gesture_available = EINA_FALSE; +#endif /* ifdef ECORE_XGESTURE */ +} + +/* + * @brief Query whether gesture is available or not. + * + * @return @c EINA_TRUE, if extension is available, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_gesture_supported(void) +{ + return _gesture_available; +} + +EAPI Eina_Bool +ecore_x_gesture_events_select(Ecore_X_Window win, + Ecore_X_Gesture_Event_Mask mask) +{ +#ifdef ECORE_XGESTURE + if (!_gesture_available) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XGestureSelectEvents(_ecore_x_disp, win, mask); + + return EINA_TRUE; +#else /* ifdef ECORE_XGESTURE */ + (void) win; + (void) mask; + return EINA_FALSE; +#endif /* ifdef ECORE_XGESTURE */ +} + +EAPI Ecore_X_Gesture_Event_Mask +ecore_x_gesture_events_selected_get(Ecore_X_Window win) +{ +#ifdef ECORE_XGESTURE + Ecore_X_Gesture_Event_Mask mask; + + if (!_gesture_available) + return ECORE_X_GESTURE_EVENT_MASK_NONE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (GestureSuccess != XGestureGetSelectedEvents(_ecore_x_disp, win, &mask)) + { + mask = ECORE_X_GESTURE_EVENT_MASK_NONE; + return mask; + } + + return mask; +#else /* ifdef ECORE_XGESTURE */ + (void) win; + return ECORE_X_GESTURE_EVENT_MASK_NONE; +#endif /* ifdef ECORE_XGESTURE */ +} + +EAPI Eina_Bool +ecore_x_gesture_event_grab(Ecore_X_Window win, + Ecore_X_Gesture_Event_Type type, + int num_fingers) +{ +#ifdef ECORE_XGESTURE + if (!_gesture_available) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (GestureGrabSuccess != XGestureGrabEvent(_ecore_x_disp, win, type, num_fingers, CurrentTime)) + { + return EINA_FALSE; + } + + return EINA_TRUE; +#else /* ifdef ECORE_XGESTURE */ + (void) win; + (void) type; + (void) num_fingers; + return EINA_FALSE; +#endif /* ifdef ECORE_XGESTURE */ +} + +EAPI Eina_Bool +ecore_x_gesture_event_ungrab(Ecore_X_Window win, + Ecore_X_Gesture_Event_Type type, + int num_fingers) +{ +#ifdef ECORE_XGESTURE + Ecore_X_Gesture_Event_Mask mask; + + if (!_gesture_available) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (GestureUngrabSuccess != XGestureUngrabEvent(_ecore_x_disp, win, type, num_fingers, CurrentTime)) + { + return EINA_FALSE; + } + + return EINA_TRUE; +#else /* ifdef ECORE_XGESTURE */ + (void) win; + (void) type; + (void) num_fingers; + return EINA_FALSE; +#endif /* ifdef ECORE_XGESTURE */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_icccm.c b/src/lib/ecore_x/xlib/ecore_x_icccm.c new file mode 100644 index 0000000000..8d6ea1f50e --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_icccm.c @@ -0,0 +1,1214 @@ +/* + * Various ICCCM related functions. + * + * This is ALL the code involving anything ICCCM related. for both WM and + * client. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include +#include + +#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, + Eina_Bool 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, + Eina_Bool 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 Eina_Bool +ecore_x_icccm_hints_get(Ecore_X_Window win, + Eina_Bool *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, + Eina_Bool *is_urgent) +{ + XWMHints *hints; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (accepts_focus) + *accepts_focus = EINA_TRUE; + + 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 = EINA_FALSE; + + hints = XGetWMHints(_ecore_x_disp, win); + if (hints) + { + if ((hints->flags & InputHint) && (accepts_focus)) + { + if (hints->input) + *accepts_focus = EINA_TRUE; + else + *accepts_focus = EINA_FALSE; + } + + 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 = EINA_TRUE; + + XFree(hints); + return EINA_TRUE; + } + + return EINA_FALSE; +} + +EAPI void +ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, + Eina_Bool 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 Eina_Bool +ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, + Eina_Bool *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 EINA_FALSE; + + if ((hint.flags & USPosition) || ((hint.flags & PPosition))) + { + if (request_pos) + *request_pos = EINA_TRUE; + } + else if (request_pos) + *request_pos = EINA_FALSE; + + 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 EINA_TRUE; +} + +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 /* ifdef X_HAVE_UTF8_STRING */ + list[0] = strdup(t); + ret = + XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle, + &xprop); +#endif /* ifdef X_HAVE_UTF8_STRING */ + 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 /* ifdef X_HAVE_UTF8_STRING */ + ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop, + &list, &num); +#endif /* ifdef X_HAVE_UTF8_STRING */ + + 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, + Eina_Bool 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 Eina_Bool +ecore_x_icccm_protocol_isset(Ecore_X_Window win, + Ecore_X_WM_Protocol protocol) +{ + Atom proto, *protos = NULL; + int i, protos_count = 0; + Eina_Bool ret = EINA_FALSE; + + /* check for invalid values */ + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + proto = _ecore_x_atoms_wm_protocols[protocol]; + + if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count)) + return EINA_FALSE; + + for (i = 0; i < protos_count; i++) + if (protos[i] == proto) + { + ret = EINA_TRUE; + 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 /* ifdef X_HAVE_UTF8_STRING */ + list[0] = strdup(t); + ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1, + XStdICCTextStyle, &xprop); +#endif /* ifdef X_HAVE_UTF8_STRING */ + 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 /* ifdef X_HAVE_UTF8_STRING */ + ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop, + &list, &num); +#endif /* ifdef X_HAVE_UTF8_STRING */ + + 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 win 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 */ diff --git a/src/lib/ecore_x/xlib/ecore_x_image.c b/src/lib/ecore_x/xlib/ecore_x_image.c new file mode 100644 index 0000000000..def81104a2 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_image.c @@ -0,0 +1,626 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include +#include +#include +#include + +#include "ecore_x_private.h" +#include "Ecore_X.h" + +#include +#include + +static int _ecore_x_image_shm_can = -1; +static int _ecore_x_image_err = 0; + +static int +_ecore_x_image_error_handler(Display *d EINA_UNUSED, + XErrorEvent *ev EINA_UNUSED) +{ + _ecore_x_image_err = 1; + return 0; +} + +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)) + { + 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) +{ + Eina_Bool ret = EINA_TRUE; + 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; + XGrabServer(_ecore_x_disp); + if (!XShmGetImage(_ecore_x_disp, draw, im->xim, x, y, 0xffffffff)) + ret = EINA_FALSE; + XUngrabServer(_ecore_x_disp); + 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 = EINA_FALSE; + } + else + { + printf("currently unimplemented ecore_x_image_get without shm\n"); + ret = EINA_FALSE; + } + + return ret; +} + +EAPI void +ecore_x_image_put(Ecore_X_Image *im, + Ecore_X_Drawable draw, + Ecore_X_GC gc, + int x, + int y, + int sx, + int sy, + int w, + int h) +{ + Ecore_X_GC tgc = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!gc) + { + XGCValues gcv; + memset(&gcv, 0, sizeof(gcv)); + gcv.subwindow_mode = IncludeInferiors; + tgc = XCreateGC(_ecore_x_disp, draw, GCSubwindowMode, &gcv); + gc = tgc; + } + if (!im->xim) _ecore_x_image_shm_create(im); + if (im->xim) + XShmPutImage(_ecore_x_disp, draw, gc, im->xim, sx, sy, x, y, w, h, False); + if (tgc) ecore_x_gc_free(tgc); +} + +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; +} + +EAPI Eina_Bool +ecore_x_image_is_argb32_get(Ecore_X_Image *im) +{ + Visual *vis = im->vis; + if (!im->xim) _ecore_x_image_shm_create(im); + if (((vis->class == TrueColor) || + (vis->class == DirectColor)) && + (im->depth >= 24) && + (vis->red_mask == 0xff0000) && + (vis->green_mask == 0x00ff00) && + (vis->blue_mask == 0x0000ff)) + { +#ifdef WORDS_BIGENDIAN + if (im->xim->bitmap_bit_order == MSBFirst) return EINA_TRUE; +#else + if (im->xim->bitmap_bit_order == LSBFirst) return EINA_TRUE; +#endif + } + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_image_to_argb_convert(void *src, + int sbpp, + int sbpl, + Ecore_X_Colormap c, + Ecore_X_Visual v, + int x, + int y, + int w, + int h, + unsigned int *dst, + int dbpl, + int dx, + int dy) +{ + Visual *vis = v; + XColor *cols = NULL; + int n = 0, nret = 0, i, row; + unsigned int pal[256], r, g, b; + enum + { + rgbnone = 0, + rgb565, + bgr565, + rgbx555, + argbx888, + abgrx888, + rgba888x, + bgra888x, + argbx666 + }; + int mode = 0; + + sbpp *= 8; + + n = vis->map_entries; + if ((n <= 256) && + ((vis->class == PseudoColor) || + (vis->class == StaticColor) || + (vis->class == GrayScale) || + (vis->class == StaticGray))) + { + if (!c) + c = DefaultColormap(_ecore_x_disp, + DefaultScreen(_ecore_x_disp)); + cols = alloca(n * sizeof(XColor)); + for (i = 0; i < n; i++) + { + cols[i].pixel = i; + cols[i].flags = DoRed | DoGreen | DoBlue; + cols[i].red = 0; + cols[i].green = 0; + cols[i].blue = 0; + } + XQueryColors(_ecore_x_disp, c, cols, n); + for (i = 0; i < n; i++) + { + pal[i] = 0xff000000 | + ((cols[i].red >> 8) << 16) | + ((cols[i].green >> 8) << 8) | + ((cols[i].blue >> 8)); + } + nret = n; + } + else if ((vis->class == TrueColor) || + (vis->class == DirectColor)) + { + if ((vis->red_mask == 0x00ff0000) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x000000ff)) + mode = argbx888; + else if ((vis->red_mask == 0x000000ff) && + (vis->green_mask == 0x0000ff00) && + (vis->blue_mask == 0x00ff0000)) + mode = abgrx888; + else if ((vis->red_mask == 0xff000000) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0x0000ff00)) + mode = rgba888x; + else if ((vis->red_mask == 0x0000ff00) && + (vis->green_mask == 0x00ff0000) && + (vis->blue_mask == 0xff000000)) + mode = bgra888x; + else if ((vis->red_mask == 0x0003f000) && + (vis->green_mask == 0x00000fc0) && + (vis->blue_mask == 0x0000003f)) + mode = argbx666; + else if ((vis->red_mask == 0x0000f800) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgb565; + else if ((vis->red_mask == 0x0000001f) && + (vis->green_mask == 0x000007e0) && + (vis->blue_mask == 0x0000f800)) + mode = bgr565; + else if ((vis->red_mask == 0x00007c00) && + (vis->green_mask == 0x000003e0) && + (vis->blue_mask == 0x0000001f)) + mode = rgbx555; + else + return EINA_FALSE; + } + for (row = 0; row < h; row++) + { + unsigned char *s8; + unsigned short *s16; + unsigned int *s32; + unsigned int *dp, *de; + + dp = ((unsigned int *)(((unsigned char *)dst) + + ((dy + row) * dbpl))) + dx; + de = dp + w; + switch (sbpp) + { + case 8: + s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; + if (nret > 0) + { + while (dp < de) + { + *dp = pal[*s8]; + s8++; dp++; + } + } + else + return EINA_FALSE; + break; + + case 16: + s16 = ((unsigned short *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; + switch (mode) + { + case rgb565: + while (dp < de) + { + r = (*s16 & 0xf800) << 8; + g = (*s16 & 0x07e0) << 5; + b = (*s16 & 0x001f) << 3; + r |= (r >> 5) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + + case bgr565: + while (dp < de) + { + r = (*s16 & 0x001f) << 19; + g = (*s16 & 0x07e0) << 5; + b = (*s16 & 0xf800) >> 8; + r |= (r >> 5) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + + case rgbx555: + while (dp < de) + { + r = (*s16 & 0x7c00) << 9; + g = (*s16 & 0x03e0) << 6; + b = (*s16 & 0x001f) << 3; + r |= (r >> 5) & 0xff0000; + g |= (g >> 5) & 0x00ff00; + b |= (b >> 5); + *dp = 0xff000000 | r | g | b; + s16++; dp++; + } + break; + + default: + return EINA_FALSE; + break; + } + break; + + case 24: + case 32: + s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x; + switch (mode) + { + case argbx888: + while (dp < de) + { + *dp = 0xff000000 | *s32; + s32++; dp++; + } + break; + + case abgrx888: + while (dp < de) + { + r = *s32 & 0x000000ff; + g = *s32 & 0x0000ff00; + b = *s32 & 0x00ff0000; + *dp = 0xff000000 | (r << 16) | (g) | (b >> 16); + s32++; dp++; + } + break; + + case rgba888x: + while (dp < de) + { + *dp = 0xff000000 | (*s32 >> 8); + s32++; dp++; + } + break; + + case bgra888x: + while (dp < de) + { + r = *s32 & 0x0000ff00; + g = *s32 & 0x00ff0000; + b = *s32 & 0xff000000; + *dp = 0xff000000 | (r << 8) | (g >> 8) | (b >> 24); + s32++; dp++; + } + break; + + case argbx666: + while (dp < de) + { + r = (*s32 & 0x3f000) << 6; + g = (*s32 & 0x00fc0) << 4; + b = (*s32 & 0x0003f) << 2; + r |= (r >> 6) & 0xff0000; + g |= (g >> 6) & 0x00ff00; + b |= (b >> 6); + *dp = 0xff000000 | r | g | b; + s32++; dp++; + } + break; + + default: + return EINA_FALSE; + break; + } + break; + break; + + default: + return EINA_FALSE; + break; + } + } + return EINA_TRUE; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_mwm.c b/src/lib/ecore_x/xlib/ecore_x_mwm.c new file mode 100644 index 0000000000..7812cc23ae --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_mwm.c @@ -0,0 +1,106 @@ +/* + * Various MWM related functions. + * + * This is ALL the code involving anything MWM related. for both WM and + * client. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include + +#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 Eina_Bool +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; + Eina_Bool ret; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ret = EINA_FALSE; + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_MOTIF_WM_HINTS, + ECORE_X_ATOM_MOTIF_WM_HINTS, + 32, &p, &num)) + return EINA_FALSE; + + 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 = EINA_TRUE; + } + + free(mwmhints); + } + + return ret; +} + +EAPI void +ecore_x_mwm_borderless_set(Ecore_X_Window win, + Eina_Bool 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); +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_netwm.c b/src/lib/ecore_x/xlib/ecore_x_netwm.c new file mode 100644 index 0000000000..3f08af8b9c --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_netwm.c @@ -0,0 +1,2083 @@ +/* + * _NET_WM... aka Extended Window Manager Hint (EWMH) functions. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#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 /* if 0 */ +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(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); + ecore_x_window_prop_window_set(root, + ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, + &check, + 1); +} + +/* + * 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 Eina_Bool +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 EINA_FALSE; + + if (num) + *num = num_ret; + + return EINA_TRUE; +} + +/* + * 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, *t; + 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-" */ + sprintf(ss, "Desk-%d", i); + s = ss; + } + + l = strlen(s) + 1; + t = realloc(buf, len + l); + if (t) + { + buf = t; + 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 unsigned int * +ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks) +{ + int ret; + unsigned int *areas = NULL; + + if (!root) root = DefaultRootWindow(_ecore_x_disp); + + ret = ecore_x_window_prop_card32_list_get(root, ECORE_X_ATOM_NET_WORKAREA, + &areas); + if (!areas) + { + if (n_desks) *n_desks = 0; + return 0; + } + if (n_desks) *n_desks = ret / 4; + return areas; +} + +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, + Eina_Bool 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 Eina_Bool +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 ? EINA_TRUE : EINA_FALSE; +} + +/* + * _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 Eina_Bool +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 EINA_FALSE; + + if (left) + *left = strut[0]; + + if (right) + *right = strut[1]; + + if (top) + *top = strut[2]; + + if (bottom) + *bottom = strut[3]; + + return EINA_TRUE; +} + +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 Eina_Bool +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 EINA_FALSE; + + 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 EINA_TRUE; +} + +EAPI void +ecore_x_netwm_icons_set(Ecore_X_Window win, + Ecore_X_Icon *icon, + int num) +{ + unsigned int *data, *p, *p2; + unsigned int i, size, x, y; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + size = 0; + for (i = 0; i < (unsigned int)num; i++) + { + size += 2 + (icon[i].width * icon[i].height); + } + data = malloc(size * sizeof(unsigned int)); + if (!data) return; + p = data; + for (i = 0; i < (unsigned int)num; i++) + { + p[0] = icon[i].width; + p[1] = icon[i].height; + p += 2; + p2 = icon[i].data; + for (y = 0; y < icon[i].height; y++) + { + for (x = 0; x < icon[i].width; x++) + { + unsigned int r, g, b, a; + + a = (*p2 >> 24) & 0xff; + r = (*p2 >> 16) & 0xff; + g = (*p2 >> 8 ) & 0xff; + b = (*p2 ) & 0xff; + if ((a > 0) && (a < 255)) + { + // unpremul + r = (r * 255) / a; + g = (g * 255) / a; + b = (b * 255) / a; + } + *p = (a << 24) | (r << 16) | (g << 8) | b; + p++; + p2++; + } + } + } + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON, + data, size); + free(data); +} + +EAPI Eina_Bool +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 EINA_FALSE; + + if (!data) + return EINA_FALSE; + + if (num_ret < 2) + { + free(data); + return EINA_FALSE; + } + + /* 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 EINA_FALSE; + } + + 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 EINA_TRUE; + } + + /* Allocate memory */ + *icon = malloc(icons * sizeof(Ecore_X_Icon)); + if (!(*icon)) + { + free(data); + return EINA_FALSE; + } + + /* 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 EINA_FALSE; + } + + 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 EINA_TRUE; +} + +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 Eina_Bool +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 EINA_FALSE; + + if (x) + *x = geometry[0]; + + if (y) + *y = geometry[1]; + + if (width) + *width = geometry[2]; + + if (height) + *height = geometry[3]; + + return EINA_TRUE; +} + +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 Eina_Bool +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 ? EINA_TRUE : EINA_FALSE; +} + +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 Eina_Bool +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 ? EINA_TRUE : EINA_FALSE; +} + +EAPI void +ecore_x_netwm_user_time_set(Ecore_X_Window win, + unsigned int tim) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME, + &tim, 1); +} + +EAPI Eina_Bool +ecore_x_netwm_user_time_get(Ecore_X_Window win, + unsigned int *tim) +{ + 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 (tim) + *tim = tmp; + + return ret == 1 ? EINA_TRUE : EINA_FALSE; +} + +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 Eina_Bool +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 EINA_FALSE; + + 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 EINA_TRUE; +} + +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 Eina_Bool +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 EINA_TRUE; + + return EINA_FALSE; +} + +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 Eina_Bool +ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, + Ecore_X_Action action) +{ + int num, i; + Ecore_X_Atom *atoms, atom; + Eina_Bool ret = EINA_FALSE; + + 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 Eina_Bool +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 EINA_FALSE; + + 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 EINA_TRUE; +} + +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 Eina_Bool +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 ? EINA_TRUE : EINA_FALSE; +} + +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 Eina_Bool +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 EINA_FALSE; + + if (fl) + *fl = frames[0]; + + if (fr) + *fr = frames[1]; + + if (ft) + *ft = frames[2]; + + if (fb) + *fb = frames[3]; + + return EINA_TRUE; +} + +EAPI Eina_Bool +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 ? EINA_TRUE : EINA_FALSE; +} + +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, + Eina_Bool 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); +} + +EAPI void +ecore_x_netwm_moveresize_request_send(Ecore_X_Window win, + int x, + int y, + Ecore_X_Netwm_Direction direction, + unsigned int button) +{ + XEvent xev; + + if (!win) + return; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = ECORE_X_ATOM_NET_WM_MOVERESIZE; + xev.xclient.format = 32; + xev.xclient.data.l[0] = x; + xev.xclient.data.l[1] = y; + xev.xclient.data.l[2] = direction; + xev.xclient.data.l[3] = button; + xev.xclient.data.l[4] = 1; + + XSendEvent(_ecore_x_disp, win, False, + SubstructureNotifyMask | SubstructureRedirectMask, &xev); +} + +int +_ecore_x_netwm_startup_info_begin(Ecore_X_Window win EINA_UNUSED, + char *data EINA_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 /* if 0 */ + return 1; +} + +int +_ecore_x_netwm_startup_info(Ecore_X_Window win EINA_UNUSED, + char *data EINA_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 /* if 0 */ + 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 /* if 0 */ + +/* + * 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 Eina_Bool +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 EINA_FALSE; + + win = XGetSelectionOwner(_ecore_x_disp, atom); + + return (win != None) ? EINA_TRUE : EINA_FALSE; +} + +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); +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_pixmap.c b/src/lib/ecore_x/xlib/ecore_x_pixmap.c new file mode 100644 index 0000000000..7b13615675 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_pixmap.c @@ -0,0 +1,121 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#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); +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_private.h b/src/lib/ecore_x/xlib/ecore_x_private.h new file mode 100644 index 0000000000..f962ffb4b2 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_private.h @@ -0,0 +1,379 @@ +#ifndef _ECORE_X_PRIVATE_H +#define _ECORE_X_PRIVATE_H + +#include +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif /* ifndef MAXHOSTNAMELEN */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ECORE_XCURSOR +#include +#endif /* ifdef ECORE_XCURSOR */ +#ifdef ECORE_XPRINT +#include +#endif /* ifdef ECORE_XPRINT */ +#ifdef ECORE_XINERAMA +#include +#endif /* ifdef ECORE_XINERAMA */ +#ifdef ECORE_XRANDR +#include +#endif /* ifdef ECORE_XRANDR */ +#ifdef ECORE_XSS +#include +#endif /* ifdef ECORE_XSS */ +#ifdef ECORE_XRENDER +#include +#endif /* ifdef ECORE_XRENDER */ +#ifdef ECORE_XFIXES +#include +#endif /* ifdef ECORE_XFIXES */ +#ifdef ECORE_XCOMPOSITE +#include +#endif /* ifdef ECORE_XCOMPOSITE */ +#ifdef ECORE_XDAMAGE +#include +#endif /* ifdef ECORE_XDAMAGE */ +#ifdef ECORE_XGESTURE +#include +#include +#endif /* ifdef ECORE_XGESTURE */ +#ifdef ECORE_XDPMS +#include +#endif /* ifdef ECORE_XDPMS */ +#ifdef ECORE_XKB +#include +#endif /* ifdef ECORE_XKB */ +#ifdef ECORE_XI2 +#include +#endif /* ifdef ECORE_XI2 */ + +#ifndef XK_MISCELLANY +# define XK_MISCELLANY 1 +#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 /* ifdef ECORE_XLIB_DEFAULT_LOG_COLOR */ +#define ECORE_XLIB_DEFAULT_LOG_COLOR EINA_COLOR_BLUE + +#ifdef ERR +# undef ERR +#endif /* ifdef ERR */ +#define ERR(...) EINA_LOG_DOM_ERR(_ecore_xlib_log_dom, __VA_ARGS__) + +#ifdef DBG +# undef DBG +#endif /* ifdef DBG */ +#define DBG(...) EINA_LOG_DOM_DBG(_ecore_xlib_log_dom, __VA_ARGS__) + +#ifdef INF +# undef INF +#endif /* ifdef INF */ +#define INF(...) EINA_LOG_DOM_INFO(_ecore_xlib_log_dom, __VA_ARGS__) + +#ifdef WRN +# undef WRN +#endif /* ifdef WRN */ +#define WRN(...) EINA_LOG_DOM_WARN(_ecore_xlib_log_dom, __VA_ARGS__) + +#ifdef CRIT +# undef CRIT +#endif /* ifdef CRIT */ +#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; + Eina_Bool (*convert)(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *type, int *typeseize); + 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 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 Eina_Bool _ecore_x_xcursor; + +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 Eina_Bool (*_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); +#ifdef ECORE_XGESTURE +void _ecore_x_event_handle_gesture_notify_flick(XEvent *xevent); +void _ecore_x_event_handle_gesture_notify_pan(XEvent *xevent); +void _ecore_x_event_handle_gesture_notify_pinchrotation(XEvent *xevent); +void _ecore_x_event_handle_gesture_notify_tap(XEvent *xevent); +void _ecore_x_event_handle_gesture_notify_tapnhold(XEvent *xevent); +void _ecore_x_event_handle_gesture_notify_hold(XEvent *xevent); +void _ecore_x_event_handle_gesture_notify_group(XEvent *xevent); +#endif /* ifdef ECORE_XGESTURE */ +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_XRANDR */ +#ifdef ECORE_XFIXES +void _ecore_x_event_handle_fixes_selection_notify(XEvent *xevent); +#endif /* ifdef ECORE_XFIXES */ +#ifdef ECORE_XDAMAGE +void _ecore_x_event_handle_damage_notify(XEvent *xevent); +#endif /* ifdef ECORE_XDAMAGE */ +#ifdef ECORE_XKB +void _ecore_x_event_handle_xkb(XEvent *xevent); +#endif /* ifdef ECORE_XKB */ +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); +Eina_Bool _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, + Ecore_X_Atom *targettype, + int *targetsize); +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_gesture_init(void); + +void _ecore_x_atoms_init(void); + +extern int _ecore_x_xi2_opcode; + +void _ecore_x_events_init(void); +void _ecore_x_events_shutdown(void); + +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); + +void _ecore_x_modifiers_get(void); +KeySym _ecore_x_XKeycodeToKeysym(Display *display, KeyCode keycode, int index); + +//#define LOGFNS 1 + +#ifdef LOGFNS +#include +#define LOGFN(fl, ln, fn) printf("-ECORE-X: %25s: %5i - %s\n", fl, ln, fn); +#else /* ifdef LOGFNS */ +#define LOGFN(fl, ln, fn) +#endif /* ifdef LOGFNS */ + +#endif /* ifndef _ECORE_X_PRIVATE_H */ diff --git a/src/lib/ecore_x/xlib/ecore_x_randr.c b/src/lib/ecore_x/xlib/ecore_x_randr.c new file mode 100644 index 0000000000..58a28305ac --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_randr.c @@ -0,0 +1,103 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include "ecore_x_private.h" +#include "ecore_x_randr.h" + +static Eina_Bool _randr_available = EINA_FALSE; +#ifdef ECORE_XRANDR +static int _randr_major, _randr_minor; +int _randr_version; +#define RANDR_1_1 ((1 << 16) | 1) +#define RANDR_1_2 ((1 << 16) | 2) +#define RANDR_1_3 ((1 << 16) | 3) + +#define RANDR_VALIDATE_ROOT(screen, \ + root) ((screen = \ + XRRRootToScreen(_ecore_x_disp, \ + root)) != -1) + +#define Ecore_X_Randr_Unset -1 + +XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * dpy, + Window window); + +#endif /* ifdef ECORE_XRANDR */ + +void +_ecore_x_randr_init(void) +{ +#ifdef ECORE_XRANDR + _randr_major = 1; + _randr_minor = 3; + _randr_version = 0; + + _ecore_x_randr_get_screen_resources = NULL; + if (XRRQueryVersion(_ecore_x_disp, &_randr_major, &_randr_minor)) + { + _randr_version = (_randr_major << 16) | _randr_minor; + if (_randr_version >= RANDR_1_3) + _ecore_x_randr_get_screen_resources = XRRGetScreenResourcesCurrent; + else if (_randr_version == RANDR_1_2) + _ecore_x_randr_get_screen_resources = XRRGetScreenResources; + + _randr_available = EINA_TRUE; + } + else + _randr_available = EINA_FALSE; + +#else + _randr_available = EINA_FALSE; +#endif +} + +/* + * @brief Query whether randr is available or not. + * + * @return @c EINA_TRUE, if extension is available, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_randr_query(void) +{ + return _randr_available; +} + +/* + * @return version of the RandR extension supported by the server or, in case + * RandR extension is not available, Ecore_X_Randr_Unset (=-1). + * bit version information: 31 MAJOR 16 | 15 MINOR 0 + */ +EAPI int +ecore_x_randr_version_get(void) +{ +#ifdef ECORE_XRANDR + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (_randr_available) + { + return _randr_version; + } + else + { + return Ecore_X_Randr_Unset; + } +#else + return -1; +#endif +} + +Eina_Bool +_ecore_x_randr_root_validate(Ecore_X_Window root) +{ +#ifdef ECORE_XRANDR + Ecore_X_Randr_Screen scr = -1; + if (root && RANDR_VALIDATE_ROOT(scr, root)) + return EINA_TRUE; + else + return EINA_FALSE; + +#else + return EINA_FALSE; +#endif +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_randr.h b/src/lib/ecore_x/xlib/ecore_x_randr.h new file mode 100644 index 0000000000..eca3c0c32c --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_randr.h @@ -0,0 +1,7 @@ +#ifndef ECORE_X_INLINE_X +#define ECORE_X_INLINE_X +Eina_Bool _ecore_x_randr_root_validate(Ecore_X_Window root); +Eina_Bool _ecore_x_randr_output_validate(Ecore_X_Window root, + Ecore_X_Randr_Output + output); +#endif diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_11.c b/src/lib/ecore_x/xlib/ecore_x_randr_11.c new file mode 100644 index 0000000000..7d2b3b34b5 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_randr_11.c @@ -0,0 +1,334 @@ +/* + * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include "ecore_x_private.h" +#include "ecore_x_randr.h" +#include +#include +#include +#include + +#define Ecore_X_Randr_None 0 +#ifdef ECORE_XRANDR + +#define RANDR_1_1 ((1 << 16) | 1) + +#define RANDR_VALIDATE_ROOT(screen, \ + root) ((screen = \ + XRRRootToScreen(_ecore_x_disp, \ + root)) != -1) +#define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) \ + return ret + +extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * + dpy, + Window + window); +extern int _randr_version; +#endif /* ifdef ECORE_XRANDR */ + +/* + * @param root window which's primary output will be queried + */ +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root) +{ +#ifdef ECORE_XRANDR + Rotation rot = Ecore_X_Randr_None, crot; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + rot = + XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, + root), &crot); + return rot; +#else /* ifdef ECORE_XRANDR */ + return Ecore_X_Randr_None; +#endif /* ifdef ECORE_XRANDR */ +} + +/* + * @param root window which's primary output will be queried + * @return the current orientation of the root window's screen primary output + */ +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root) +{ +#ifdef ECORE_XRANDR + Rotation crot = Ecore_X_Randr_None; + XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, + root), &crot); + return crot; +#else /* ifdef ECORE_XRANDR */ + return Ecore_X_Randr_None; +#endif /* ifdef ECORE_XRANDR */ +} + +/* + * @brief Sets a given screen's primary output's orientation. + * + * @param root Window which's screen's primary output will be queried. + * @param orientation orientation which should be set for the root window's + * screen primary output. + * @return @c EINA_TRUE if the primary output's orientation could be + * successfully altered. + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_orientation_set( + Ecore_X_Window root, + Ecore_X_Randr_Orientation + orientation) +{ +#ifdef ECORE_XRANDR + XRRScreenConfiguration *xrr_screen_cfg = NULL; + int sizeid; + Rotation crot; + Eina_Bool ret = EINA_FALSE; + if (!(xrr_screen_cfg = XRRGetScreenInfo(_ecore_x_disp, root))) + return EINA_FALSE; + + sizeid = XRRConfigCurrentConfiguration(xrr_screen_cfg, &crot); + if (!XRRSetScreenConfig(_ecore_x_disp, xrr_screen_cfg, root, sizeid, + orientation, CurrentTime)) + ret = EINA_TRUE; + + if (xrr_screen_cfg) + XRRFreeScreenConfigInfo(xrr_screen_cfg); + + return ret; +#else /* ifdef ECORE_XRANDR */ + return EINA_FALSE; +#endif /* ifdef ECORE_XRANDR */ +} + +/* + * @brief gets a screen's primary output's possible sizes + * @param root window which's primary output will be queried + * @param num number of sizes reported as supported by the screen's primary output + * @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL + */ +EAPI Ecore_X_Randr_Screen_Size_MM * +ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root, + int *num) +{ +#ifdef ECORE_XRANDR + Ecore_X_Randr_Screen_Size_MM *ret = NULL; + XRRScreenSize *sizes; + int i, n; + + /* we don't have to free sizes, because they're hold in a cache inside X*/ + sizes = + XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, + root), &n); + if ((!sizes) || (n <= 0)) return NULL; + ret = calloc(n, sizeof(Ecore_X_Randr_Screen_Size_MM)); + 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; + ret[i].width_mm = sizes[i].mwidth; + ret[i].height_mm = sizes[i].mheight; + } + return ret; +#else /* ifdef ECORE_XRANDR */ + return NULL; +#endif /* ifdef ECORE_XRANDR */ +} + +EAPI void +ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root, + int *w, + int *h, + int *w_mm, + int *h_mm, + int *size_index) +{ +#ifdef ECORE_XRANDR + XRRScreenSize *sizes; + XRRScreenConfiguration *sc = NULL; + int idx; + Rotation orientation; + int n; + + if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root))) + { + ERR("Couldn't get screen information for %d", root); + return; + } + + idx = XRRConfigCurrentConfiguration(sc, &orientation); + + sizes = + XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, + root), &n); + if ((idx < n) && (idx >= 0)) + { + if (w) + *w = sizes[idx].width; + + if (h) + *h = sizes[idx].height; + + if (w_mm) + *w_mm = sizes[idx].mwidth; + + if (h_mm) + *h_mm = sizes[idx].mheight; + + if (size_index) + *size_index = idx; + } + + XRRFreeScreenConfigInfo(sc); +#endif /* ifdef ECORE_XRANDR */ +} + +/* + * @brief Sets a given screen's primary output size, but disables all other + * outputs at the same time. + * + * @param root Window which's primary output will be queried. + * @param size_index Within the list of sizes reported as supported by the root + * window's screen primary output. + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure due to e.g. + * invalid times. + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root, + int size_index) +{ +#ifdef ECORE_XRANDR + XRRScreenConfiguration *sc = NULL; + Eina_Bool ret = EINA_FALSE; + int nsizes = 0; + + if (size_index >= 0 && _ecore_x_randr_root_validate(root)) + { + XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp, + root), &nsizes); + + if (size_index < nsizes) + { + sc = XRRGetScreenInfo(_ecore_x_disp, root); + if (!XRRSetScreenConfig(_ecore_x_disp, sc, + root, size_index, + ECORE_X_RANDR_ORIENTATION_ROT_0, CurrentTime)) + { + ret = EINA_TRUE; + } + + if (sc) + XRRFreeScreenConfigInfo(sc); + } + } + + return ret; +#else /* ifdef ECORE_XRANDR */ + return EINA_FALSE; +#endif /* ifdef ECORE_XRANDR */ +} + +/* + * @param root window which's primary output will be queried + * @return currently used refresh rate or - if request failed or RandRR is not available - 0.0 + */ +EAPI Ecore_X_Randr_Refresh_Rate +ecore_x_randr_screen_primary_output_current_refresh_rate_get( + Ecore_X_Window root) +{ +#ifdef ECORE_XRANDR + Ecore_X_Randr_Refresh_Rate ret = 0.0; + XRRScreenConfiguration *sc = NULL; + + if (!_ecore_x_randr_root_validate(root) || + !(sc = XRRGetScreenInfo(_ecore_x_disp, root))) + return ret; + + ret = XRRConfigCurrentRate(sc); + if (sc) + XRRFreeScreenConfigInfo(sc); + + return ret; +#else /* ifdef ECORE_XRANDR */ + return 0.0; +#endif /* ifdef ECORE_XRANDR */ +} + +/* + * @param root window which's primary output will be queried + * @param size_index referencing the size to query valid refresh rates for + * @return currently used refresh rate or - if request failed or RandRR is not available - NULL + */ +EAPI Ecore_X_Randr_Refresh_Rate * +ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root, + int size_index, + int *num) +{ +#ifdef ECORE_XRANDR + Ecore_X_Randr_Refresh_Rate *ret = NULL, *rates = NULL; + Ecore_X_Randr_Screen scr; + int n; + + if (num + && RANDR_VALIDATE_ROOT(scr, root) + && (rates = XRRRates(_ecore_x_disp, scr, size_index, &n))) + { + if (rates && (ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * n))) + { + memcpy(ret, rates, (sizeof(Ecore_X_Randr_Refresh_Rate) * n)); + *num = n; + } + } + + return ret; +#else /* ifdef ECORE_XRANDR */ + return NULL; +#endif /* ifdef ECORE_XRANDR */ +} + +//>= 1.1 +/* + * @brief Sets the current primary output's refresh rate. + * + * @param root Window which's primary output will be queried. + * @param size_index Referencing the size to be set. + * @param rate The refresh rate to be set. + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_randr_screen_primary_output_refresh_rate_set( + Ecore_X_Window root, + int size_index, + Ecore_X_Randr_Refresh_Rate + rate) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_1_RET(EINA_FALSE); + Eina_Bool ret = EINA_FALSE; + XRRScreenConfiguration *sc = NULL; + + if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root))) + return ret; + + if (!XRRSetScreenConfigAndRate(_ecore_x_disp, sc, + root, size_index, + RR_Rotate_0, rate, CurrentTime)) + ret = EINA_TRUE; + + XRRFreeScreenConfigInfo(sc); + return ret; +#else /* ifdef ECORE_XRANDR */ + return EINA_FALSE; +#endif /* ifdef ECORE_XRANDR */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_12.c b/src/lib/ecore_x/xlib/ecore_x_randr_12.c new file mode 100644 index 0000000000..9e937d7bf7 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_randr_12.c @@ -0,0 +1,2438 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include "ecore_x_private.h" +#include "ecore_x_randr.h" +#include +#include +#include +#include + +#define Ecore_X_Randr_None (Ecore_X_Randr_Crtc)0 +#define Ecore_X_Randr_Unset (Ecore_X_Randr_Crtc) - 1 + +#ifdef ECORE_XRANDR + +#define RANDR_1_2 ((1 << 16) | 2) + +#define RANDR_VALIDATE_ROOT(screen, root) \ + ((screen = XRRRootToScreen(_ecore_x_disp, root)) != -1) + +#define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) \ + return ret + +#define RANDR_PROPERTY_EDID "EDID" +#define RANDR_PROPERTY_BACKLIGHT "Backlight" +#define RANDR_PROPERTY_SIGNAL_FORMAT "SignalFormat" +#define RANDR_PROPERTY_SIGNAL_PROPERTIES "SignalProperties" +#define RANDR_PROPERTY_CONNECTOR_TYPE "ConnectorType" +#define RANDR_PROPERTY_CONNECTOR_NUMBER "ConnectorNumber" +#define RANDR_PROPERTY_COMPATIBILITY_LIST "CompatibilityList" +#define RANDR_PROPERTY_CLONE_LIST "CloneList" + +extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * + dpy, + Window + window); +extern int _randr_version; +#endif + +/** + * @brief Enable event selection. This enables basic interaction with + * output/crtc events and requires RandR >= 1.2. + * + * @param win Select this window's properties for RandR events. + * @param on Enable/disable selecting. + */ +EAPI void +ecore_x_randr_events_select(Ecore_X_Window win, + Eina_Bool 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); +#endif +} + +/** + * @brief Validates a CRTC for a given root window's screen. + * + * @param root The window which's default display will be queried. + * @param crtc The CRTC to be validated. + * @return In case it is found, @c EINA_TRUE will be returned, @c EINA_FALSE + * otherwise. + */ +static inline Eina_Bool +_ecore_x_randr_crtc_validate(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + XRRScreenResources *res = NULL; + int i; + Eina_Bool ret = EINA_FALSE; + + if ((crtc == Ecore_X_Randr_None) || + (crtc == Ecore_X_Randr_Unset)) + return ret; + + if (_ecore_x_randr_root_validate(root) && crtc && + (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + { + for (i = 0; i < res->ncrtc; i++) + { + if (res->crtcs[i] == crtc) + { + ret = EINA_TRUE; + break; + } + } + XRRFreeScreenResources(res); + } + + return ret; +#else + return EINA_FALSE; +#endif +} + +Eina_Bool +_ecore_x_randr_output_validate(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + Eina_Bool ret = EINA_FALSE; + XRRScreenResources *res = NULL; + int i; + + if (_ecore_x_randr_root_validate(root) && output && + (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + { + for (i = 0; i < res->noutput; i++) + { + if (res->outputs[i] == output) + { + ret = EINA_TRUE; + break; + } + } + XRRFreeScreenResources(res); + } + + return ret; +#else + return EINA_FALSE; +#endif +} + +static inline Eina_Bool +_ecore_x_randr_mode_validate(Ecore_X_Window root, + Ecore_X_Randr_Mode mode) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + Eina_Bool ret = EINA_FALSE; + XRRScreenResources *res = NULL; + int i; + + if (_ecore_x_randr_root_validate(root) && mode && + (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + { + for (i = 0; i < res->nmode; i++) + { + if (res->modes[i].id == mode) + { + ret = EINA_TRUE; + break; + } + } + XRRFreeScreenResources(res); + } + + return ret; +#else + return EINA_FALSE; +#endif +} + +/* + * @param w width of screen in px + * @param h height of screen in px + */ +EAPI void +ecore_x_randr_screen_current_size_get(Ecore_X_Window root, + int *w, + int *h, + int *w_mm, + int *h_mm) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + Ecore_X_Randr_Screen scr; + + if (!RANDR_VALIDATE_ROOT(scr, root)) + return; + + if (w) + *w = DisplayWidth(_ecore_x_disp, scr); + + if (h) + *h = DisplayHeight(_ecore_x_disp, scr); + + if (w_mm) + *w_mm = DisplayWidthMM(_ecore_x_disp, scr); + + if (h_mm) + *h_mm = DisplayHeightMM(_ecore_x_disp, scr); + +#endif +} + +/* + * @param root window which's screen will be queried + * @param wmin minimum width the screen can be set to + * @param hmin minimum height the screen can be set to + * @param wmax maximum width the screen can be set to + * @param hmax maximum height the screen can be set to + */ +EAPI void +ecore_x_randr_screen_size_range_get(Ecore_X_Window root, + int *wmin, + int *hmin, + int *wmax, + int *hmax) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + int twmin, thmin, twmax, thmax; + if (XRRGetScreenSizeRange (_ecore_x_disp, root, &twmin, &thmin, &twmax, + &thmax)) + { + if (wmin) + *wmin = twmin; + + if (hmin) + *hmin = thmin; + + if (wmax) + *wmax = twmax; + + if (hmax) + *hmax = thmax; + } + +#endif +} + +/* + * @param root Window which's screen's size should be set. If invalid (e.g. + * @c NULL) no action is taken. + * @param w Width in px the screen should be set to. If out of valid + * boundaries, current value is assumed. + * @param h Height in px the screen should be set to. If out of valid + * boundaries, current value is assumed. + * @param w_mm Width in mm the screen should be set to. If @c 0, current + * aspect is assumed. + * @param h_mm Height in mm the screen should be set to. If @c 0, current + * aspect is assumed. + * @return @c EINA_TRUE if request was successfully sent or screen is already + * in requested size, @c EINA_FALSE if parameters are invalid. + */ +EAPI Eina_Bool +ecore_x_randr_screen_current_size_set(Ecore_X_Window root, + int w, + int h, + int w_mm, + int h_mm) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + Ecore_X_Randr_Screen scr; + int w_c, h_c, w_mm_c, h_mm_c, twmin, thmin, twmax, thmax; + + if (!RANDR_VALIDATE_ROOT(scr, root)) + return EINA_FALSE; + + ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, &w_mm_c, &h_mm_c); + if ((w == w_c) && (h == h_c) && (w_mm_c == w_mm) && (h_mm_c == h_mm)) + return EINA_TRUE; + + ecore_x_randr_screen_size_range_get(root, &twmin, &thmin, &twmax, &thmax); + + if (((w != Ecore_X_Randr_None) && + ((w < twmin) || + (w > twmax))) || + ((h != Ecore_X_Randr_None) && ((h < thmin) || (h > thmax)))) + return EINA_FALSE; + + if (w <= 0) + w = DisplayWidth(_ecore_x_disp, scr); + + if (h <= 0) + h = DisplayHeight(_ecore_x_disp, scr); + + if (w_mm <= 0) + w_mm = + (int)(((double)(DisplayWidthMM(_ecore_x_disp, + scr) / + (double)DisplayWidth(_ecore_x_disp, + scr))) * (double)w); + + if (h_mm <= 0) + h_mm = + (int)(((double)(DisplayHeightMM(_ecore_x_disp, + scr) / + (double)DisplayHeight(_ecore_x_disp, + scr))) * (double)h); + + XRRSetScreenSize (_ecore_x_disp, root, w, h, w_mm, h_mm); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +/* + * @brief get detailed information for all modes related to a root window's screen + * @param root window which's screen's ressources are queried + * @param num number of modes returned + * @return modes' information + */ +EAPI Ecore_X_Randr_Mode_Info ** +ecore_x_randr_modes_info_get(Ecore_X_Window root, + int *num) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + Ecore_X_Randr_Mode_Info **ret = NULL; + int i; + + if (_ecore_x_randr_root_validate(root) && + (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + { + if ((ret = + (Ecore_X_Randr_Mode_Info **)malloc(sizeof( + Ecore_X_Randr_Mode_Info *) + * + res->nmode))) + { + for (i = 0; i < res->nmode; i++) + { + if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) + { + ret[i]->xid = res->modes[i].id; + ret[i]->width = res->modes[i].width; + ret[i]->height = res->modes[i].height; + ret[i]->dotClock = res->modes[i].dotClock; + ret[i]->hSyncStart = res->modes[i].hSyncStart; + ret[i]->hSyncEnd = res->modes[i].hSyncEnd; + ret[i]->hTotal = res->modes[i].hTotal; + ret[i]->hSkew = res->modes[i].hSkew; + ret[i]->vSyncStart = res->modes[i].vSyncStart; + ret[i]->vSyncEnd = res->modes[i].vSyncEnd; + ret[i]->vTotal = res->modes[i].vTotal; + if ((ret[i]->name = (malloc(res->modes[i].nameLength + 1)))) + strncpy(ret[i]->name, res->modes[i].name, + (res->modes[i].nameLength + 1)); + else + ret[i]->name = NULL; + + ret[i]->nameLength = res->modes[i].nameLength; + ret[i]->modeFlags = res->modes[i].modeFlags; + } + else + { + while (i > 0) + free(ret[--i]); + free(ret); + ret = NULL; + break; + } + } + } + + if (ret && num) + *num = res->nmode; + + XRRFreeScreenResources(res); + } + + return ret; +#else + return NULL; +#endif +} + +/* + * @brief Add a mode to a display. + * + * @param root Window to which's screen's ressources are added. + * @param mode_info + * @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode + * adding failed. + * @since 1.2.0 + */ +EAPI Ecore_X_Randr_Mode +ecore_x_randr_mode_info_add(Ecore_X_Window root, + Ecore_X_Randr_Mode_Info *mode_info) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + Ecore_X_Randr_Mode mode = Ecore_X_Randr_None; + + if (_ecore_x_randr_root_validate(root) && mode_info) + mode = XRRCreateMode(_ecore_x_disp, root, (XRRModeInfo*)mode_info); + + return mode; +#else + return Ecore_X_Randr_None; +#endif +} + +/* + * @brief Delete a mode from the display. + * + * @param mode_info + * @since 1.2.0 + */ +EAPI void +ecore_x_randr_mode_del(Ecore_X_Randr_Mode mode) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + + XRRDestroyMode(_ecore_x_disp, mode); +#else + return; +#endif +} + +/* + * @brief get detailed information for a given mode id + * @param root window which's screen's ressources are queried + * @param mode the XID which identifies the mode of interest + * @return mode's detailed information + */ +EAPI Ecore_X_Randr_Mode_Info * +ecore_x_randr_mode_info_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + Ecore_X_Randr_Mode_Info *ret = NULL; + int i; + + if (_ecore_x_randr_root_validate(root) && + (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + { + for (i = 0; i < res->nmode; i++) + { + if ((res->modes[i].id == mode) && + (ret = malloc(sizeof(Ecore_X_Randr_Mode_Info)))) + { + ret->xid = res->modes[i].id; + ret->width = res->modes[i].width; + ret->height = res->modes[i].height; + ret->dotClock = res->modes[i].dotClock; + ret->hSyncStart = res->modes[i].hSyncStart; + ret->hSyncEnd = res->modes[i].hSyncEnd; + ret->hTotal = res->modes[i].hTotal; + ret->hSkew = res->modes[i].hSkew; + ret->vSyncStart = res->modes[i].vSyncStart; + ret->vSyncEnd = res->modes[i].vSyncEnd; + ret->vTotal = res->modes[i].vTotal; + ret->name = NULL; + ret->nameLength = 0; + if (res->modes[i].nameLength > 0) + { + ret->nameLength = res->modes[i].nameLength; + ret->name = malloc(res->modes[i].nameLength + 1); + if (ret->name) + memcpy(ret->name, res->modes[i].name, + res->modes[i].nameLength + 1); + } + ret->modeFlags = res->modes[i].modeFlags; + break; + } + } + XRRFreeScreenResources(res); + } + + return ret; +#else + return NULL; +#endif +} + +/* + * @brief Free detailed mode information. The pointer handed in will be set to + * @c NULL after freeing the memory. + * + * @param mode_info The mode information that should be freed. + */ +EAPI void +ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + if (!mode_info) + return; + + if (mode_info->name) + free(mode_info->name); + + free(mode_info); + mode_info = NULL; +#endif +} + +/* + * @brief Get all known CRTCs related to a root window's screen. + * + * @param root Window which's screen's ressources are queried. + * @param num Number of CRTCs returned. + * @return CRTC IDs. + */ +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_crtcs_get(Ecore_X_Window root, + int *num) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + Ecore_X_Randr_Crtc *ret = NULL; + + if (root && + (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + { + if ((ret = malloc(sizeof(Ecore_X_Randr_Crtc) * res->ncrtc))) + { + int i = 0; + + if (num) *num = res->ncrtc; + + for (i = 0; i < res->ncrtc; i++) + ret[i] = res->crtcs[i]; + } + + XRRFreeScreenResources(res); + } + + return ret; +#else + return NULL; +#endif +} + +/* + * @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead. + * @brief get the CRTCs, which display a certain window + * @param window window the displaying crtcs shall be found for + * @param num the number of crtcs displaying the window + * @return Array of crtcs that display a certain window. @c NULL if no crtcs + * was found that displays the specified window. + */ +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_current_crtc_get(Ecore_X_Window window, + int *num) +{ + return ecore_x_randr_window_crtcs_get(window, num); +} + +/* + * @brief get the CRTCs, which display a certain window + * @param window window the displaying crtcs shall be found for + * @param num the number of crtcs displaying the window + * @return Array of crtcs that display a certain window. @c NULL if no crtcs + * was found that displays the specified window. + * @since 1.2.0 + */ +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_window_crtcs_get(Ecore_X_Window window, + int *num) +{ +#ifdef ECORE_XRANDR + Ecore_X_Window root; + Eina_Rectangle w_geo, c_geo; + Ecore_X_Randr_Crtc *crtcs; + Ecore_X_Randr_Mode mode; + Ecore_X_Randr_Output *ret = NULL; + Window tw; + int ncrtcs, i, nret = 0, rx = 0, ry = 0; + + if (_randr_version < RANDR_1_2) goto _ecore_x_randr_window_crtcs_get_fail; + + ecore_x_window_geometry_get(window, + &w_geo.x, &w_geo.y, + &w_geo.w, &w_geo.h); + + root = ecore_x_window_root_get(window); + crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs); + if (!crtcs) goto _ecore_x_randr_window_crtcs_get_fail; + + /* now get window RELATIVE to root window - thats what matters. */ + XTranslateCoordinates(_ecore_x_disp, window, root, 0, 0, &rx, &ry, &tw); + w_geo.x = rx; + w_geo.y = ry; + + ret = calloc(1, ncrtcs * sizeof(Ecore_X_Randr_Crtc)); + if (!ret) + { + free(crtcs); + goto _ecore_x_randr_window_crtcs_get_fail; + } + for (i = 0, nret = 0; i < ncrtcs; i++) + { + /* if crtc is not enabled, don't bother about it any further */ + mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]); + if (mode == Ecore_X_Randr_None) continue; + + ecore_x_randr_crtc_geometry_get(root, crtcs[i], + &c_geo.x, &c_geo.y, + &c_geo.w, &c_geo.h); + if (eina_rectangles_intersect(&w_geo, &c_geo)) + { + ret[nret] = crtcs[i]; + nret++; + } + } + free(crtcs); + + if (num) *num = nret; + return ret; + +_ecore_x_randr_window_crtcs_get_fail: +#endif + if (num) *num = 0; + return NULL; +} + +EAPI Ecore_X_Randr_Output * +ecore_x_randr_outputs_get(Ecore_X_Window root, + int *num) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + Ecore_X_Randr_Output *ret = NULL; + + if (root && + (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + { + if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * res->noutput))) + { + int i = 0; + + if (num) *num = res->noutput; + + for (i = 0; i < res->noutput; i++) + ret[i] = res->outputs[i]; + } + + if (res) + XRRFreeScreenResources(res); + } + + return ret; +#else + return NULL; +#endif +} + +//Per Crtc +/* + * @brief get a CRTC's outputs. + * @param root the root window which's screen will be queried + * @param num number of outputs referenced by given CRTC + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_crtc_outputs_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *num) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + Ecore_X_Randr_Output *ret = NULL; + XRRCrtcInfo *crtc_info = NULL; + + if (_ecore_x_randr_crtc_validate(root, crtc) && + (res = + _ecore_x_randr_get_screen_resources (_ecore_x_disp, root)) && + (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) + { + if ((ret = malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->noutput))) + { + int i = 0; + + if (num) *num = crtc_info->noutput; + + for (i = 0; i < crtc_info->noutput; i++) + ret[i] = crtc_info->outputs[i]; + } + + if (crtc_info) + XRRFreeCrtcInfo(crtc_info); + + if (res) + XRRFreeScreenResources(res); + } + + return ret; +#else + return NULL; +#endif +} + +/* + * @brief get a CRTC's possible outputs. + * @param root the root window which's screen will be queried + * @param num number of possible outputs referenced by given CRTC + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *num) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + Ecore_X_Randr_Output *ret = NULL; + XRRCrtcInfo *crtc_info = NULL; + + if (_ecore_x_randr_crtc_validate(root, crtc) && + (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + { + if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) + { + if ((ret = + malloc(sizeof(Ecore_X_Randr_Output) * crtc_info->npossible))) + { + int i = 0; + + if (num) *num = crtc_info->npossible; + + for (i = 0; i < crtc_info->npossible; i++) + ret[i] = crtc_info->possible[i]; + } + + XRRFreeCrtcInfo(crtc_info); + } + + XRRFreeScreenResources(res); + } + + return ret; +#else + return NULL; +#endif +} + +EAPI void +ecore_x_randr_crtc_geometry_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *x, + int *y, + int *w, + int *h) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + XRRScreenResources *res = NULL; + XRRCrtcInfo *crtc_info = NULL; + + if (_ecore_x_randr_crtc_validate(root, + crtc) && + (res = + _ecore_x_randr_get_screen_resources (_ecore_x_disp, + root)) && + (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) + { + if (x) + *x = crtc_info->x; + + if (y) + *y = crtc_info->y; + + if (w) + *w = crtc_info->width; + + if (h) + *h = crtc_info->height; + + XRRFreeCrtcInfo(crtc_info); + XRRFreeScreenResources(res); + } + +#endif +} + +/* + * @brief Sets the position of given CRTC within root window's screen. + * + * @param root The window's screen to be queried. + * @param crtc The CRTC which's position within the mentioned screen is to be + * altered. + * @param x Position on the x-axis (0 == left) of the screen. if x < 0 current + * value will be kept. + * @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current + * value will be kept. + * @return @c EINA_TRUE if position could successfully be altered. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_pos_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int x, + int y) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + int w_c, h_c, w_new = 0, h_new = 0; + Eina_Rectangle crtc_geo; + + ecore_x_randr_crtc_geometry_get(root, + crtc, + &crtc_geo.x, + &crtc_geo.y, + &crtc_geo.w, + &crtc_geo.h); + ecore_x_randr_screen_current_size_get(root, &w_c, &h_c, NULL, NULL); + if (x < 0) + x = crtc_geo.x; + + if (y < 0) + y = crtc_geo.y; + + if ((x + crtc_geo.w) > w_c) + w_new = x + crtc_geo.w; + + if ((y + crtc_geo.h) > h_c) + h_new = y + crtc_geo.h; + + if ((w_new != 0) || (h_new != 0)) + if (!ecore_x_randr_screen_current_size_set(root, w_new, h_new, 0, 0)) + return EINA_FALSE; + + return ecore_x_randr_crtc_settings_set(root, + crtc, + NULL, + Ecore_X_Randr_Unset, + x, + y, + Ecore_X_Randr_Unset, + Ecore_X_Randr_Unset); +#else + return EINA_FALSE; +#endif +} + +/** + * @brief Get the current set mode of a given CRTC + * @param root the window's screen to be queried + * @param crtc the CRTC which's should be queried + * @return currently set mode or - in case parameters are invalid - + * Ecore_X_Randr_Unset + */ +EAPI Ecore_X_Randr_Mode +ecore_x_randr_crtc_mode_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset); + XRRScreenResources *res = NULL; + XRRCrtcInfo *crtc_info = NULL; + Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset; + if (_ecore_x_randr_root_validate(root) && + _ecore_x_randr_crtc_validate(root, + crtc) && + (res = + _ecore_x_randr_get_screen_resources(_ecore_x_disp, + root)) && + (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) + { + ret = crtc_info->mode; + XRRFreeCrtcInfo(crtc_info); + XRRFreeScreenResources(res); + } + + return ret; +#else + return Ecore_X_Randr_Unset; +#endif +} + +/** + * @brief Sets a mode for a CRTC and the outputs attached to it. + * + * @param root The window's screen to be queried. + * @param crtc The CRTC which shall be set. + * @param outputs Array of outputs which have to be compatible with the mode. + * If @c NULL, CRTC will be disabled. + * @param noutputs Number of outputs in array to be used. Use + * Ecore_X_Randr_Unset (or @c -1) to use currently used outputs. + * @param mode XID of the mode to be set. If set to @c 0 the CRTC will be + * disabled. If set to @c -1 the call will fail. + * @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE + * otherwise. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_mode_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + Ecore_X_Randr_Output *outputs, + int noutputs, + Ecore_X_Randr_Mode mode) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if (mode == Ecore_X_Randr_Unset) + return EINA_FALSE; + + return ecore_x_randr_crtc_settings_set(root, + crtc, + outputs, + noutputs, + Ecore_X_Randr_Unset, + Ecore_X_Randr_Unset, + mode, + Ecore_X_Randr_Unset); +#else + return EINA_FALSE; +#endif +} + +EAPI void +ecore_x_randr_crtc_size_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *w, + int *h) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h); +#endif +} + +EAPI Ecore_X_Randr_Refresh_Rate +ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + Ecore_X_Randr_Mode mode) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(0.0); + XRRScreenResources *res = NULL; + XRRCrtcInfo *crtc_info = NULL; + Ecore_X_Randr_Refresh_Rate ret = 0.0; + int i; + + if (_ecore_x_randr_crtc_validate(root, + crtc) && + (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + { + for (i = 0; i < res->nmode; i++) + if (res->modes[i].id == mode) + { + if (res->modes[i].hTotal && res->modes[i].vTotal) + ret = ((double)res->modes[i].dotClock / + ((double)res->modes[i].hTotal * + (double)res->modes[i].vTotal)); + + break; + } + } + + if (crtc_info) + XRRFreeCrtcInfo(crtc_info); + + if (res) + XRRFreeScreenResources(res); + + return ret; +#else + return 0.0; +#endif +} + +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_crtc_orientations_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); + XRRCrtcInfo *crtc_info = NULL; + XRRScreenResources *res = NULL; + Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; + + if (_ecore_x_randr_crtc_validate(root, + crtc) && + (res = + _ecore_x_randr_get_screen_resources (_ecore_x_disp, + root)) && + (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) + { + ret = crtc_info->rotations; + } + if (crtc_info) + XRRFreeCrtcInfo(crtc_info); + + if (res) + XRRFreeScreenResources(res); + + return ret; +#else + return Ecore_X_Randr_None; +#endif +} + +EAPI Ecore_X_Randr_Orientation +ecore_x_randr_crtc_orientation_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); + XRRCrtcInfo *crtc_info = NULL; + XRRScreenResources *res = NULL; + Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None; + + if (_ecore_x_randr_crtc_validate(root, + crtc) && + (res = + _ecore_x_randr_get_screen_resources (_ecore_x_disp, + root)) && + (crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) + { + ret = crtc_info->rotation; + } + if (crtc_info) + XRRFreeCrtcInfo(crtc_info); + + if (res) + XRRFreeScreenResources(res); + + return ret; +#else + return Ecore_X_Randr_None; +#endif +} + +EAPI Eina_Bool +ecore_x_randr_crtc_orientation_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + Ecore_X_Randr_Orientation orientation) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + Eina_Bool ret = EINA_FALSE; + + if (orientation != Ecore_X_Randr_None) + { + ret = ecore_x_randr_crtc_settings_set(root, + crtc, + NULL, + Ecore_X_Randr_Unset, + Ecore_X_Randr_Unset, + Ecore_X_Randr_Unset, + Ecore_X_Randr_Unset, + orientation); + } + + return ret; +#else + return EINA_FALSE; +#endif +} + +EAPI void +ecore_x_randr_crtc_pos_get(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + int *x, + int *y) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + + ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL); +#endif +} + +EAPI Eina_Bool +ecore_x_randr_crtc_clone_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc original, + Ecore_X_Randr_Crtc clon) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + XRRScreenResources *res = NULL; + XRRCrtcInfo *clone_crtc_info = NULL; + Ecore_X_Randr_Mode original_mode = Ecore_X_Randr_None; + Ecore_X_Randr_Orientation original_orientation = Ecore_X_Randr_None; + Eina_Bool ret = EINA_FALSE; + int x, y; + + if (_ecore_x_randr_root_validate(root) && + _ecore_x_randr_crtc_validate(root, + original) && + _ecore_x_randr_crtc_validate(root, + clon) && + (res = + _ecore_x_randr_get_screen_resources (_ecore_x_disp, + root)) && + (clone_crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, clon))) + { + ecore_x_randr_crtc_geometry_get(root, original, &x, &y, NULL, NULL); + original_mode = ecore_x_randr_crtc_mode_get(root, original); + original_orientation = ecore_x_randr_crtc_orientation_get(root, + original); + ret = ecore_x_randr_crtc_settings_set(root, + clon, + NULL, + Ecore_X_Randr_Unset, + x, + y, + original_mode, + original_orientation); + XRRFreeCrtcInfo(clone_crtc_info); + XRRFreeScreenResources(res); + } + + return ret; +#else + return EINA_FALSE; +#endif +} + +/** + * @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is + * auto enabled in it's preferred mode, when it was disabled before. + * + * @param root The root window which's default display will be queried. + * @param crtc The CRTC which's configuration should be altered. + * @param outputs An array of outputs, that should display this CRTC's content. + * @param noutputs Number of outputs in the array of outputs. If set to + * Ecore_X_Randr_Unset, current outputs and number of outputs will be used. + * If set to Ecore_X_Randr_None, CRTC will be disabled. + * @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x + * corrdinate will be assumed. + * @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y + * corrdinate will be assumed. + * @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the + * CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is + * assumed. + * @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is + * used, the current mode is assumed. + * @return @c EINA_TRUE if the configuration alteration was successful, + * @c EINA_FALSE otherwise. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_settings_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc, + Ecore_X_Randr_Output *outputs, + int noutputs, + int x, + int y, + Ecore_X_Randr_Mode mode, + Ecore_X_Randr_Orientation orientation) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + XRRScreenResources *res = NULL; + XRRCrtcInfo *crtc_info = NULL; + Eina_Bool ret = EINA_FALSE; + + if (_ecore_x_randr_crtc_validate(root, + crtc) && + (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + { + if ((crtc_info = XRRGetCrtcInfo(_ecore_x_disp, res, crtc))) + { + if ((mode == Ecore_X_Randr_None) || + (noutputs == Ecore_X_Randr_None)) + { + outputs = NULL; + noutputs = 0; + } + else if (noutputs == (int)Ecore_X_Randr_Unset) + { + outputs = (Ecore_X_Randr_Output *)crtc_info->outputs; + noutputs = crtc_info->noutput; + } + + if (mode == Ecore_X_Randr_Unset) + mode = crtc_info->mode; + + if (x < 0) + x = crtc_info->x; + + if (y < 0) + y = crtc_info->y; + + if (orientation == Ecore_X_Randr_Unset) + orientation = crtc_info->rotation; + + if (!XRRSetCrtcConfig(_ecore_x_disp, res, crtc, CurrentTime, + x, y, mode, orientation, (RROutput *)outputs, + noutputs)) + ret = EINA_TRUE; + + XRRFreeCrtcInfo(crtc_info); + } + + XRRFreeScreenResources(res); + } + + return ret; +#else + return EINA_FALSE; +#endif +} + +/** + * @brief Sets a CRTC relative to another one. + * + * @param root The root window which's default display will be set. + * @param crtc_r1 The CRTC to be positioned. + * @param crtc_r2 The CRTC the position should be relative to. + * @param policy The relation between the crtcs. + * @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at + * CRTC2's borders. + * @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE + * if repositioning failed or if position of new crtc would be out of given + * screen's min/max bounds. + */ +EAPI Eina_Bool +ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root, + Ecore_X_Randr_Crtc crtc_r1, + Ecore_X_Randr_Crtc crtc_r2, + Ecore_X_Randr_Output_Policy policy, + Ecore_X_Randr_Relative_Alignment alignment) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + Eina_Rectangle r1_geo, r2_geo; + int w_max, h_max, cw, ch, x_n = Ecore_X_Randr_Unset, y_n = + Ecore_X_Randr_Unset; + /* + int r1_noutputs, r2_noutputs, r1_nmodes, i, j, outputs_mode_found, mode_w, mode_h; + Ecore_X_Randr_Output *r1_outputs, *r2_outputs, *r2_r1_outputs; + Ecore_X_Randr_Mode *r1_modes, r2_mode, r1_mode; + Eina_Bool ret; + */ + + if ((ecore_x_randr_crtc_mode_get(root, crtc_r1) == Ecore_X_Randr_None) + || (ecore_x_randr_crtc_mode_get(root, crtc_r2) == Ecore_X_Randr_None)) + return EINA_FALSE; + + if (!_ecore_x_randr_crtc_validate(root, crtc_r1) || + (!(crtc_r1 != crtc_r2) && + !_ecore_x_randr_crtc_validate(root, crtc_r2))) + return EINA_FALSE; + + ecore_x_randr_crtc_geometry_get(root, + crtc_r1, + &r1_geo.x, + &r1_geo.y, + &r1_geo.w, + &r1_geo.h); + ecore_x_randr_crtc_geometry_get(root, + crtc_r2, + &r2_geo.x, + &r2_geo.y, + &r2_geo.w, + &r2_geo.h); + ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); + ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); + + switch (policy) + { + case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT: + //set r1 right of r2 + x_n = r2_geo.x + r2_geo.w; + + switch (alignment) + { + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: + y_n = Ecore_X_Randr_Unset; + break; + + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: + y_n = + ((int)(((double)r2_geo.h / + 2.0) + (double)r2_geo.y - ((double)r1_geo.h / 2.0))); + break; + + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: + y_n = ((int)((double)ch / 2.0) - ((double)r1_geo.h / 2.0)); + break; + } + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: + //set r1 left of r2 + x_n = r2_geo.x - r1_geo.w; + + switch (alignment) + { + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: + y_n = Ecore_X_Randr_Unset; + break; + + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: + y_n = + ((int)(((double)r2_geo.h / + 2.0) + r2_geo.y - ((double)r1_geo.h / 2.0))); + break; + + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: + y_n = ((int)(((double)ch / 2.0) - ((double)r1_geo.h / 2.0))); + break; + } + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_BELOW: + //set r1 below r2 + y_n = r2_geo.y + r2_geo.h; + + switch (alignment) + { + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: + x_n = Ecore_X_Randr_Unset; + break; + + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: + x_n = + ((int)((((double)r2_geo.x + + (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0))); + break; + + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: + x_n = ((int)((double)cw / 2.0)); + break; + } + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: + y_n = r2_geo.y - r1_geo.h; + + //set r1 above r2 + switch (alignment) + { + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE: + x_n = Ecore_X_Randr_Unset; + break; + + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL: + x_n = + ((int)((((double)r2_geo.x + + (double)r2_geo.w) / 2.0) - ((double)r1_geo.w / 2.0))); + break; + + case ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR: + x_n = ((int)((double)cw / 2.0)); + break; + } + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: + return ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y); + + /* entire cloning (including modesetting) + //all outputs of crtc1 capable of crtc2's current mode? + r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2); + if (!(r1_outputs = + ecore_x_randr_crtc_outputs_get(root, crtc_r1, + &r1_noutputs)) || + (r1_noutputs == 0)) + return EINA_FALSE; + + for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++) + { + if (!(r1_modes = + ecore_x_randr_output_modes_get(root, r1_outputs[i], + &r1_nmodes, NULL))) + { + free(r1_outputs); + return EINA_FALSE; + } + + for (j = 0; j < r1_nmodes; j++) + { + ecore_x_randr_mode_size_get(root, + r1_modes[j], + &mode_w, + &mode_h); + if ((mode_w == r2_geo.w) && (mode_h == r2_geo.h)) + { + r1_mode = r1_modes[j]; + ++outputs_mode_found; + free(r1_modes); + r1_modes = NULL; + break; + } + } + if (r1_modes) + free(r1_modes); + + if (outputs_mode_found <= i) + { + //an output doesn't support the set mode, cancel! + free(r1_outputs); + return EINA_FALSE; + } + } + free (r1_outputs); + //CRTC 1's outputs support a mode of same geometry as CRTC 2. + ret = + (ecore_x_randr_crtc_mode_set(root, crtc_r1, Ecore_X_Randr_None, + Ecore_X_Randr_None, + r1_mode) && + ecore_x_randr_crtc_pos_set(root, crtc_r1, r2_geo.x, r2_geo.y)); + return ret; + */ + + /* entire cloning on same CRTC + //all outputs of crtc1 capable of crtc2's current mode? + r2_mode = ecore_x_randr_crtc_mode_get(root, crtc_r2); + if (!(r1_outputs = + ecore_x_randr_crtc_outputs_get(root, crtc_r1, + &r1_noutputs)) || + (r1_noutputs == 0)) + return EINA_FALSE; + + for (i = 0, outputs_mode_found = 0; i < r1_noutputs; i++) + { + if (!(r1_modes = + ecore_x_randr_output_modes_get(root, r1_outputs[i], + &r1_nmodes, NULL))) + { + free(r1_outputs); + return EINA_FALSE; + } + + for (j = 0; j < r1_nmodes; j++) + { + if (r1_modes[j] == r2_mode) + { + ++outputs_mode_found; + free(r1_modes); + r1_modes = NULL; + break; + } + } + if (r1_modes) + free(r1_modes); + + if (outputs_mode_found <= i) + { + //an output doesn't support the set mode, cancel! + free(r1_outputs); + return EINA_FALSE; + } + } + //check whether crtc r2 can use all outputs of r1. + if (!(r2_outputs = + ecore_x_randr_crtc_possible_outputs_get(root, crtc_r2, + &r2_noutputs)) || + (r2_noutputs == 0)) + { + free(r1_outputs); + return EINA_FALSE; + } + + for (i = 0; i < r1_noutputs; i++) + { + for (j = 0; j < r2_noutputs; ) + { + if (r1_outputs[i] == r2_outputs[j]) + break; + + j++; + } + if (j == r2_noutputs) + { + //didn't find the output! + free (r1_outputs); + free (r2_outputs); + return EINA_FALSE; + } + } + + //apparently crtc2 supports all outputs of r1 + //TODO: check with the compatible list of outputs (property in RR1.3) + r2_r1_outputs = + malloc(sizeof(Ecore_X_Randr_Output) * (r1_noutputs + r2_noutputs)); + for (i = 0; i < r1_noutputs; i++) + { + r2_r1_outputs[i] = r1_outputs[i]; + } + free(r1_outputs); + for (; i < r2_noutputs; i++) + { + r2_r1_outputs[i] = r2_outputs[i]; + } + free(r2_outputs); + ret = + ecore_x_randr_crtc_mode_set(root, crtc_r2, r2_r1_outputs, + (r1_noutputs + r1_noutputs), r2_mode); + free (r2_r1_outputs); + return ret; + */ + case ECORE_X_RANDR_OUTPUT_POLICY_NONE: + break; + default: + return EINA_FALSE; + } + if ((x_n == r1_geo.x) && (y_n == r1_geo.x)) + return EINA_TRUE; + + //out of possible bounds? + if (((y_n + r1_geo.h) > h_max) || ((x_n + r1_geo.w) > w_max)) + return EINA_FALSE; + + return ecore_x_randr_crtc_pos_set(root, crtc_r1, x_n, y_n); +#else + return EINA_FALSE; +#endif +} + +/* + * @brief Add given mode to given output. + * + * @param output The output the mode is added to. + * @param mode The mode added to the output. + * @return @c EINA_FALSE if output or mode equal Ecore_X_Randr_None, else + * @c EINA_TRUE. + * Additionally, if xcb backend is used, the success of the addition is + * reported back directly. + * @since 1.2.0 + */ +EAPI Eina_Bool +ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, + Ecore_X_Randr_Mode mode) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + + if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None)) + return EINA_FALSE; + + XRRAddOutputMode(_ecore_x_disp, output, mode); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +/* + * @brief delete given mode from given output + * @param output the output the mode is removed from + * @param mode the mode removed from the output + * @since 1.2.0 + */ +EAPI void +ecore_x_randr_output_mode_del(Ecore_X_Randr_Output output, + Ecore_X_Randr_Mode mode) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + + if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None)) + return; + + XRRDeleteOutputMode(_ecore_x_disp, output, mode); +#else + return; +#endif +} + +EAPI Ecore_X_Randr_Mode * +ecore_x_randr_output_modes_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num, + int *npreferred) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + XRROutputInfo *output_info = NULL; + Ecore_X_Randr_Mode *modes = NULL; + + if ((output != Ecore_X_Randr_None) + && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) + && (output_info = + XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output))) + { + if ((modes = malloc(sizeof(Ecore_X_Randr_Mode) * output_info->nmode))) + { + int i = 0; + + if (num) *num = output_info->nmode; + if (npreferred) *npreferred = output_info->npreferred; + + for (i = 0; i < output_info->nmode; i++) + modes[i] = output_info->modes[i]; + } + } + + if (output_info) + XRRFreeOutputInfo(output_info); + + if (res) + XRRFreeScreenResources(res); + + return modes; +#else + return NULL; +#endif +} + +EAPI Ecore_X_Randr_Crtc * +ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + XRROutputInfo *output_info = NULL; + Ecore_X_Randr_Crtc *crtcs = NULL; + + if ((output != Ecore_X_Randr_None)) + { + if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + { + if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) + { + if ((crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc))) + { + memcpy(crtcs, output_info->crtcs, (sizeof(Ecore_X_Randr_Crtc) * output_info->ncrtc)); + if (num) *num = output_info->ncrtc; + } + XRRFreeOutputInfo(output_info); + } + XRRFreeScreenResources(res); + } + } + return crtcs; +#else + return Ecore_X_Randr_None; +#endif +} + +/** + * @brief gets the the outputs which might be used simultenously on the same + * CRTC. + * @param root window that this information should be queried for. + * @param output the output which's clones we concern + * @param num number of possible clones + */ +EAPI Ecore_X_Randr_Output * +ecore_x_randr_output_clones_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *num) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + XRROutputInfo *output_info = NULL; + Ecore_X_Randr_Output *outputs = NULL; + + if ((output != Ecore_X_Randr_None)) + { + if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + { + if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) + { + if ((outputs = malloc(sizeof(Ecore_X_Randr_Output) * output_info->nclone))) + { + memcpy(outputs, output_info->clones, (sizeof(Ecore_X_Randr_Output) * output_info->nclone)); + if (num) *num = output_info->nclone; + } + XRRFreeOutputInfo(output_info); + } + XRRFreeScreenResources(res); + } + } + return outputs; +#else + return Ecore_X_Randr_None; +#endif +} + +EAPI Ecore_X_Randr_Crtc +ecore_x_randr_output_crtc_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(Ecore_X_Randr_None); + XRRScreenResources *res = NULL; + XRROutputInfo *output_info = NULL; + Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None; + + if ((output != Ecore_X_Randr_None)) + { + if ((res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + { + if ((output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) + { + ret = output_info->crtc; + XRRFreeOutputInfo(output_info); + } + XRRFreeScreenResources(res); + } + } + + return ret; +#else + return Ecore_X_Randr_None; +#endif +} + +/** + * @brief gets the given output's name as reported by X + * @param root the window which's screen will be queried + * @param output The output for which the name will be reported. + * @param len length of returned c-string. + * @return name of the output as reported by X + */ +EAPI char * +ecore_x_randr_output_name_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *len) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + XRRScreenResources *res = NULL; + XRROutputInfo *output_info = NULL; + char *ret = NULL; + + if ((output != Ecore_X_Randr_None) + && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) + && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) + { + /* + * Actually the below command is correct, but due to a bug in libXrandr + * it doesn't work. Therefore we stick with strlen(). + * Replace the line below with the following once this bug is + * fixed within libXrandr. + * + * *len = output_info->nameLen; + * + */ + if ((ret = strdup(output_info->name)) && len) + *len = strlen(ret); + + XRRFreeOutputInfo(output_info); + } + + if (res) + XRRFreeScreenResources(res); + + return ret; +#else + return NULL; +#endif +} + +/** + * @brief gets the width and hight of a given mode + * @param mode the mode which's size is to be looked up + * @param w width of given mode in px + * @param h height of given mode in px + */ +EAPI void +ecore_x_randr_mode_size_get(Ecore_X_Window root, + Ecore_X_Randr_Mode mode, + int *w, + int *h) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + XRRScreenResources *res = NULL; + int i; + + if ((mode != Ecore_X_Randr_None) + && (w || h) + && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + { + for (i = 0; i < res->nmode; i++) + { + if (res->modes[i].id == mode) + { + if (w) + *w = res->modes[i].width; + + if (h) + *h = res->modes[i].height; + + break; + } + } + } + + if (res) + XRRFreeScreenResources(res); + +#endif +} + +/** + * @brief gets the EDID information of an attached output if available. + * Note that this information is not to be compared using ordinary string + * comparison functions, since it includes 0-bytes. + * @param root window this information should be queried from + * @param output the XID of the output + * @param length length of the byte-array. If NULL, request will fail. + */ +EAPI unsigned char * +ecore_x_randr_output_edid_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + unsigned long *length) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(NULL); + Atom name = XInternAtom (_ecore_x_disp, RANDR_PROPERTY_EDID, False); + unsigned char *prop_data, *ret = NULL; + int actual_format; + unsigned long nitems, bytes_after; + Atom actual_type; + + if (!length || !_ecore_x_randr_output_validate(root, output)) + return NULL; + + if (XRRGetOutputProperty (_ecore_x_disp, output, name, + 0, 100, False, False, + AnyPropertyType, + &actual_type, &actual_format, + &nitems, &bytes_after, &prop_data) == Success) + { + if (actual_type == XA_INTEGER && actual_format == 8) + { + if ((ret = malloc(nitems * sizeof(unsigned char)))) + { + if (length && + (memcpy(ret, prop_data, (nitems * sizeof(unsigned char))))) + *length = nitems; + + return ret; + } + } + } + + return NULL; +#else + return NULL; +#endif +} + +EAPI Ecore_X_Randr_Connection_Status +ecore_x_randr_output_connection_status_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN); + XRRScreenResources *res = NULL; + XRROutputInfo *output_info = NULL; + Ecore_X_Randr_Connection_Status ret = + ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; + + if ((output != Ecore_X_Randr_None) + && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root)) + && (output_info = XRRGetOutputInfo(_ecore_x_disp, res, output))) + { + ret = output_info->connection; + } + + if (output_info) + XRRFreeOutputInfo(output_info); + + if (res) + XRRFreeScreenResources(res); + + return ret; +#else + return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN; +#endif +} + +EAPI void +ecore_x_randr_output_size_mm_get(Ecore_X_Window root, + Ecore_X_Randr_Output output, + int *w_mm, + int *h_mm) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + XRRScreenResources *res = NULL; + XRROutputInfo *output_info = NULL; + + if ((output != Ecore_X_Randr_None) + && (res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + { + if ((output_info = + XRRGetOutputInfo(_ecore_x_disp, res, (RROutput)output))) + { + if (w_mm) + *w_mm = output_info->mm_width; + + if (h_mm) + *h_mm = output_info->mm_height; + + XRRFreeOutputInfo(output_info); + } + + XRRFreeScreenResources(res); + } + +#endif +} + +EAPI Eina_Bool +ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root, + const Ecore_X_Randr_Crtc *not_moved, + int nnot_moved, + int dx, + int dy) +{ +#ifdef ECORE_XRANDR + Ecore_X_Randr_Crtc *crtcs_to_be_moved = NULL; + XRRScreenResources *res = NULL; + int i, j, k, n; + Eina_Bool ret; + + if ((nnot_moved <= 0) || (!not_moved) + || !_ecore_x_randr_root_validate(root) + || !(res = + _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + return EINA_FALSE; + + n = (res->ncrtc - nnot_moved); + if ((crtcs_to_be_moved = malloc(sizeof(Ecore_X_Randr_Crtc) * n))) + { + for (i = 0, k = 0; (i < res->ncrtc) && (k < n); i++) + { + for (j = 0; j < nnot_moved; j++) + { + if (res->crtcs[i] == not_moved[j]) + break; + } + if (j == nnot_moved) + //crtcs[i] is not in the 'not to move'-list + crtcs_to_be_moved[k++] = res->crtcs[i]; + } + } + + XRRFreeScreenResources(res); + ret = ecore_x_randr_move_crtcs(root, crtcs_to_be_moved, n, dx, dy); + free(crtcs_to_be_moved); + return ret; +#else + return EINA_FALSE; +#endif +} + +/* + * @brief Move given CRTCs belonging to the given root window's screen dx/dy + * pixels relative to their current position. The screen size will be + * automatically adjusted if necessary and possible. + * + * @param root Window which's screen's resources are used. + * @param crtcs List of CRTCs to be moved. + * @param ncrtc Number of CRTCs in array. + * @param dx Amount of pixels the CRTCs should be moved in x direction. + * @param dy Amount of pixels the CRTCs should be moved in y direction. + * @return @c EINA_TRUE if all crtcs could be moved successfully. + */ +EAPI Eina_Bool +ecore_x_randr_move_crtcs(Ecore_X_Window root, + const Ecore_X_Randr_Crtc *crtcs, + int ncrtc, + int dx, + int dy) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + XRRScreenResources *res = NULL; + XRRCrtcInfo **crtc_info = NULL; + Eina_Bool ret = EINA_TRUE; + int i, cw, ch, w_max, h_max, nw, nh; + + crtc_info = alloca(sizeof(XRRCrtcInfo *) * ncrtc); + memset(crtc_info, 0, sizeof(XRRCrtcInfo *) * ncrtc); + if (_ecore_x_randr_root_validate(root) + && (res = _ecore_x_randr_get_screen_resources (_ecore_x_disp, root))) + { + ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max); + ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL); + nw = cw; + nh = ch; + + for (i = 0; + (i < ncrtc) && + (crtc_info[i] = XRRGetCrtcInfo(_ecore_x_disp, res, crtcs[i])); + i++) + { + if (((crtc_info[i]->x + dx) < 0) || + ((int)(crtc_info[i]->x + crtc_info[i]->width + dx) > w_max) + || ((crtc_info[i]->y + dy) < 0) || + ((int)(crtc_info[i]->y + crtc_info[i]->height + dy) > h_max) + ) + goto _ecore_x_randr_move_crtcs_fail_free_crtc_info; + + nw = MAX((int)(crtc_info[i]->x + crtc_info[i]->width + dx), nw); + nh = MAX((int)(crtc_info[i]->y + crtc_info[i]->height + dy), nh); + } + //not out of bounds + + //resize if necessary + if (!(((nw > cw) || + (nh > ch)) || + ecore_x_randr_screen_current_size_set(root, nw, nh, + Ecore_X_Randr_Unset, + Ecore_X_Randr_Unset))) + goto _ecore_x_randr_move_crtcs_fail_free_crtc_info; + + //actually move all the crtcs, keep their rotation and mode. + for (i = 0; (i < ncrtc) && crtc_info[i]; i++) + { + if ((crtc_info[i]) && + (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, + Ecore_X_Randr_Unset, + (crtc_info[i]->x + dx), + (crtc_info[i]->y + dy), + crtc_info[i]->mode, + crtc_info[i]->rotation))) + { + ret = EINA_FALSE; + break; + } + } + if (i < ncrtc) + { + //something went wrong, let's try to move the already moved crtcs + //back. + while ((i--) >= 0) + { + if (crtc_info[i]) + ecore_x_randr_crtc_settings_set(root, + crtcs[i], + NULL, + Ecore_X_Randr_Unset, + (crtc_info[i]->x - dx), + (crtc_info[i]->y - dy), + crtc_info[i]->mode, + crtc_info[i]->rotation); + } + } + + for (i = 0; i < ncrtc; i++) + { + if (crtc_info[i]) XRRFreeCrtcInfo(crtc_info[i]); + } + } + + XRRFreeScreenResources(res); + + return ret; +_ecore_x_randr_move_crtcs_fail_free_crtc_info: + while (i-- > 0) + XRRFreeCrtcInfo(crtc_info[i]); + XRRFreeScreenResources(res); + return EINA_FALSE; +#else + return EINA_FALSE; +#endif +} + +/** + * @brief removes unused screen space. The most upper left CRTC is set to 0x0 + * and all other CRTCs dx,dy respectively. + * @param root the window's screen which will be reset. + */ +EAPI void +ecore_x_randr_screen_reset(Ecore_X_Window root) +{ +#ifdef ECORE_XRANDR + XRRCrtcInfo *crtc_info = NULL; + XRRScreenResources *res = NULL; + //the 100000 are just a random huge number. + int i, dx_min = 100000, dy_min = 100000, w_n = 0, h_n = 0, nenabled_crtcs = 0; + + if (!_ecore_x_randr_root_validate(root) || + !(res = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root))) + return; + + Ecore_X_Randr_Crtc enabled_crtcs[res->ncrtc]; + + for (i = 0; i < res->ncrtc; i++) + { + if (!(crtc_info = + XRRGetCrtcInfo(_ecore_x_disp, res, + res->crtcs[i])) || + (crtc_info->mode == Ecore_X_Randr_None) || + (crtc_info->mode == Ecore_X_Randr_Unset) + || ((crtc_info->noutput == 0))) + continue; + + enabled_crtcs[nenabled_crtcs++] = res->crtcs[i]; + + if ((int)(crtc_info->x + crtc_info->width) > w_n) + w_n = (crtc_info->x + crtc_info->width); + + if ((int)(crtc_info->y + crtc_info->height) > h_n) + h_n = (crtc_info->y + crtc_info->height); + + if (crtc_info->x < dx_min) + dx_min = crtc_info->x; + if (crtc_info->y < dy_min) + dy_min = crtc_info->y; + + XRRFreeCrtcInfo(crtc_info); + } + if ((dx_min > 0) || (dy_min > 0)) + { + if (ecore_x_randr_move_crtcs(root, enabled_crtcs, nenabled_crtcs, -dx_min, -dy_min)) + { + w_n -= dx_min; + h_n -= dy_min; + } + } + ecore_x_randr_screen_current_size_set(root, + w_n, + h_n, + Ecore_X_Randr_Unset, + Ecore_X_Randr_Unset); +#endif +} + +/** + * @brief Set up the backlight level to the given level. + * + * @param root The window's screen which will be set. + * @param level Of the backlight between @c 0 and @c 1. + */ + +EAPI void +ecore_x_randr_screen_backlight_level_set(Ecore_X_Window root, + double level) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(); + Atom _backlight; + XRRScreenResources *resources = NULL; + Ecore_X_Randr_Output output; + int o; + + if ((level < 0) || (level > 1)) + { + ERR("Wrong value for the backlight level. It should be between 0 and 1."); + return; + } + + /* + * To make sure that the _backlight atomic property still exists. + */ + _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); + if (_backlight == None) + { + WRN("Backlight setting is not supported on this server or driver"); + return; + } + + /* get the ressources */ + resources = _ecore_x_randr_get_screen_resources(_ecore_x_disp, root); + if (!resources) return; + + for (o = 0; o < resources->noutput; o++) + { + output = resources->outputs[o]; + if (ecore_x_randr_output_backlight_level_get(root, output) >= 0) + { + ecore_x_randr_output_backlight_level_set(root, output, level); + } + } + XRRFreeScreenResources(resources); +#endif +} + +/* + * @brief Check if a backlight is available. + * @return Whether a backlight is available. + */ + +EAPI Eina_Bool +ecore_x_randr_output_backlight_available(void) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(-1); + Atom _backlight; + + _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); + + return (_backlight == None) ? EINA_FALSE : EINA_TRUE; + +#endif + return EINA_FALSE; +} + +/* + * @brief Get the backlight level of the given output. + * + * @param root Window which's screen should be queried. + * @param output From which the backlight level should be retrieved. + * @return The backlight level. + */ + +EAPI double +ecore_x_randr_output_backlight_level_get(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(-1); + Atom actual_type; + Atom _backlight; + XRRPropertyInfo *info = NULL; + double dvalue; + int actual_format; + long value, max, min; + unsigned long nitems; + unsigned long bytes_after; + unsigned char *prop = NULL; + + /* set backlight variable if not already done */ + + _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); + if (_backlight == None) + { + ERR("Backlight property is not suppported on this server or driver"); + return -1; + } + + if (!_ecore_x_randr_output_validate(root, output)) + { + ERR("Invalid output"); + return -1; + } + + if (XRRGetOutputProperty(_ecore_x_disp, output, _backlight, + 0, 4, False, False, None, + &actual_type, &actual_format, + &nitems, &bytes_after, &prop) != Success) + { + WRN("Backlight not supported on this output"); + return -1; + } + + if ((actual_type != XA_INTEGER) || (nitems != 1) || (actual_format != 32)) return -1; + + value = *((long *)prop); + free (prop); + + /* I have the current value of the backlight */ + /* Now retrieve the min and max intensities of the output */ + info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight); + if (info) + { + dvalue = -1; + if ((info->range) && (info->num_values == 2)) + { + /* finally convert the current value in the interval [0..1] */ + min = info->values[0]; + max = info->values[1]; + dvalue = ((double)(value - min)) / ((double)(max - min)); + } + free(info); + return dvalue; + } +#endif + return -1; +} + +/* + * @brief Set the backlight level of a given output. + * + * @param root Window which's screen should be queried. + * @param output That should be set. + * @param level For which the backlight should be set. + * @return @c EINA_TRUE in case of success. + */ + +EAPI Eina_Bool +ecore_x_randr_output_backlight_level_set(Ecore_X_Window root, + Ecore_X_Randr_Output output, + double level) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_2_RET(EINA_FALSE); + Atom _backlight; + XRRPropertyInfo *info = NULL; + double min, max, tmp; + long new; + + if ((level < 0) || (level > 1)) + { + ERR("Backlight level should be between 0 and 1"); + return EINA_FALSE; + } + + if (!_ecore_x_randr_output_validate(root, output)) + { + ERR("Wrong output value"); + return EINA_FALSE; + } + + _backlight = XInternAtom(_ecore_x_disp, RANDR_PROPERTY_BACKLIGHT, True); + if (_backlight == None) + { + WRN("Backlight property is not suppported on this server or driver"); + return EINA_FALSE; + } + + info = XRRQueryOutputProperty(_ecore_x_disp, output, _backlight); + if (info) + { + if ((info->range) && (info->num_values == 2)) + { + min = info->values[0]; + max = info->values[1]; + tmp = (level * (max - min)) + min; + new = tmp; + if (new > max) new = max; + if (new < min) new = min; + XRRChangeOutputProperty(_ecore_x_disp, output, _backlight, XA_INTEGER, 32, + PropModeReplace, (unsigned char *)&new, 1); + XFlush(_ecore_x_disp); + } + free(info); + return EINA_TRUE; + } +#endif + return EINA_FALSE; +} + +/* + * @brief Get the outputs, which display a certain window. + * + * @param window Window the displaying outputs shall be found for + * @param num The number of outputs displaying the window + * @return Array of outputs that display a certain window. @c NULL if no + * outputs was found that displays the specified window. + */ + +EAPI Ecore_X_Randr_Output * +ecore_x_randr_window_outputs_get(Ecore_X_Window window, + int *num) +{ +#ifdef ECORE_XRANDR + Ecore_X_Window root; + Ecore_X_Randr_Crtc *crtcs; + Ecore_X_Randr_Output *outputs, *ret = NULL, *tret; + int ncrtcs, noutputs, i, nret = 0; + + if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail; + + root = ecore_x_window_root_get(window); + if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs))) + goto _ecore_x_randr_current_output_get_fail; + + for (i = 0, nret = 0; i < ncrtcs; i++) + { + + outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i], + &noutputs); + if (!outputs) + goto _ecore_x_randr_current_output_get_fail_free; + tret = realloc(ret, ((nret + noutputs) * sizeof(Ecore_X_Randr_Output))); + if (!tret) goto _ecore_x_randr_current_output_get_fail_free; + ret = tret; + memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output))); + nret += noutputs; + free(outputs); + outputs = NULL; + } + free(crtcs); + + if (num) + *num = nret; + + return ret; + +_ecore_x_randr_current_output_get_fail_free: + free(outputs); + free(crtcs); + free(ret); +_ecore_x_randr_current_output_get_fail: +#endif + if (num) *num = 0; + return NULL; +} + +/* + * @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead. + * @brief Get the outputs, which display a certain window. + * + * @param window Window the displaying outputs shall be found for. + * @param num The number of outputs displaying the window. + * @return Array of outputs that display a certain window. @c NULL if no + * outputs was found that displays the specified window. + */ + +EAPI Ecore_X_Randr_Output * +ecore_x_randr_current_output_get(Ecore_X_Window window, + int *num) +{ + return ecore_x_randr_window_outputs_get(window, num); +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c b/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c new file mode 100644 index 0000000000..5bda332a06 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_randr_12_edid.c @@ -0,0 +1,463 @@ +/* + * Copyright 2006-2009 Red Hat, Inc. + * + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, 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 (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * 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 NON-INFRINGEMENT. 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. + */ +/* Original Author: Adam Jackson */ +/* Heavily modified by: Leif Middelschulte */ + +#include "Ecore_X.h" +#include +#include +#include +#include + +/* TODO: + * - see other TODO's within this file. + */ + +#define ECORE_X_RANDR_EDID_VERSION_10 ((1 << 8) | 0) +#define ECORE_X_RANDR_EDID_VERSION_11 ((1 << 8) | 1) +#define ECORE_X_RANDR_EDID_VERSION_12 ((1 << 8) | 2) +#define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3) +#define ECORE_X_RANDR_EDID_VERSION_14 ((1 << 8) | 4) + +#define _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER 0x08 +#define _ECORE_X_RANDR_EDID_OFFSET_TYPE 0x14 +#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12 +#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13 +#define _ECORE_X_RANDR_EDID_OFFSET_DPMS 0x18 +#define _ECORE_X_RANDR_EDID_OFFSET_COLORSPACE 0x18 +#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36 +#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3 +#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5 +#define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED 15 +#define _ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO 14 + +#define _ECORE_X_RANDR_EDID_MASK_DIGITAL 0x80 +#define _ECORE_X_RANDR_EDID_MASK_DIGITAL_INTERFACE 0x0f +#define _ECORE_X_RANDR_EDID_MASK_DIGITAL_TMDS_DFP_10 0x01 +#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS 0x18 +#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444 0x10 +#define _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422 0x08 +#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED 0xe0 +#define _ECORE_X_RANDR_EDID_MASK_DPMS 0xE0 +#define _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY 0x80 +#define _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND 0x40 +#define _ECORE_X_RANDR_EDID_MASK_DPMS_OFF 0x20 +#define _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE 0x0f +#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3 0x80 +#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9 0x40 +#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10 0x20 +#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4 0x10 +#define _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9 0x08 + +#define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13 + +typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio_Preferred { + ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3 = 0x00, + ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9 = 0x01, + ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10 = 0x02, + ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4 = 0x03, + ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9 = 0x04 +} Ecore_X_Randr_Edid_Aspect_Ratio_Preferred; + +/* Some convenience loops */ +#define _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, extension_block_iter) \ + for (extension_block_iter = edid; extension_block_iter < (edid + edid_length); extension_block_iter += 128) + +#define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \ + _ECORE_X_RANDR_EDID_FOR_EACH_EXTENSION_BLOCK(edid, edid_length, cea_block_iter) \ + if (cea_block_iter[0] == 0x02) + +/* The following macro is to be used with caution as it inherits another loop. + * Therefore using a 'break;' statement will lead to continuation in the + * inherent 'Extension block'-loop. + */ +#define _ECORE_X_RANDR_EDID_FOR_EACH_CEA_DETAILED_BLOCK(edid, edid_length, cea_block_iter, detailed_block_iter) \ + _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) \ + for (detailed_block_iter = cea_block_iter + cea_block_iter[2]; detailed_block_iter + 18 < cea_block_iter + 127; detailed_block_iter += 18) \ + if (detailed_block_iter[0]) + +#define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ + for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18) + +#define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \ + _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \ + if ((block[0] == 0) && (block[1] == 0)) + +EAPI Eina_Bool +ecore_x_randr_edid_has_valid_header(unsigned char *edid, + unsigned long edid_length) +{ + const unsigned char header[] = + { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; + if (!edid) return EINA_FALSE; + if (edid_length < 8) return EINA_FALSE; + if (!memcmp(edid, header, 8)) return EINA_TRUE; + return EINA_FALSE; +} + +EAPI int +ecore_x_randr_edid_version_get(unsigned char *edid, + unsigned long edid_length) +{ + if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) && + (ecore_x_randr_edid_has_valid_header(edid, edid_length))) + return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) | + edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR]; + return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; +} + +EAPI int +ecore_x_randr_edid_manufacturer_model_get(unsigned char *edid, + unsigned long edid_length) +{ + if ((edid_length > 0x0b) && + (ecore_x_randr_edid_has_valid_header(edid, edid_length))) + return (int)(edid[0x0a] + (edid[0x0b] << 8)); + return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; +} + +EAPI int +ecore_x_randr_edid_manufacturer_serial_number_get(unsigned char *edid, + unsigned long edid_length) +{ + if ((edid_length > 0x0f) && + (ecore_x_randr_edid_has_valid_header(edid, edid_length))) + return (int)(edid[0x0c] + (edid[0x0d] << 8) + + (edid[0x0e] << 16) + (edid[0x0f] << 24)); + return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; +} + +EAPI char * +ecore_x_randr_edid_manufacturer_name_get(unsigned char *edid, + unsigned long edid_length) +{ + if ((edid_length > (_ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER + 1)) && + (ecore_x_randr_edid_has_valid_header(edid, edid_length))) + { + unsigned char *x; + char *name; + + x = (edid + _ECORE_X_RANDR_EDID_OFFSET_MANUFACTURER); + name = malloc(sizeof(char) * 4); + if (!name) return NULL; + name[0] = ((x[0] & 0x7c) >> 2) + '@'; + name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xe0) >> 5) + '@'; + name[2] = (x[1] & 0x1f) + '@'; + name[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] = 0; + return name; + } + return NULL; +} + +EAPI char * +ecore_x_randr_edid_display_name_get(unsigned char *edid, + unsigned long edid_length) +{ + unsigned char *block = NULL; + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; + _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) + { + if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc) + { + char *name, *p; + const char *edid_name; + + edid_name = (const char *)block + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; + name = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); + if (!name) return NULL; + strncpy(name, edid_name, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); + name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; + for (p = name; *p; p++) + { + if ((*p < ' ') || (*p > '~')) *p = 0; + } + return name; + } + } + return NULL; +} + +EAPI Ecore_X_Randr_Edid_Aspect_Ratio +ecore_x_randr_edid_display_aspect_ratio_preferred_get(unsigned char *edid, + unsigned long edid_length) +{ + unsigned char *block = NULL; + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; + _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) + { + if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfd) && + (block[10] == 0x04)) + { + Ecore_X_Randr_Edid_Aspect_Ratio_Preferred preferred_ratio = + (Ecore_X_Randr_Edid_Aspect_Ratio_Preferred) + ((block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO_PREFERRED] & + _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_PREFERRED) >> 5); + switch (preferred_ratio) + { + case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_4_3: + return ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3; + + case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_9: + return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9; + + case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_16_10: + return ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10; + + case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_5_4: + return ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4; + + case ECORE_X_RANDR_EDID_ASPECT_RATIO_PREFERRED_15_9: + return ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9; + + default: + return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; + } + } + } + return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; +} + +EAPI Ecore_X_Randr_Edid_Aspect_Ratio +ecore_x_randr_edid_display_aspect_ratios_get(unsigned char *edid, + unsigned long edid_length) +{ + Ecore_X_Randr_Edid_Aspect_Ratio ret = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; + unsigned char *block = NULL; + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return ECORE_X_RANDR_EDID_UNKNOWN_VALUE; + _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) + { + if ((block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfd) && + (block[10] == 0x04)) + { + if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_4_3) + ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_4_3; + if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_9) + ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_9; + if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_16_10) + ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_16_10; + if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_5_4) + ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_5_4; + if (block[_ECORE_X_RANDR_EDID_OFFSET_ASPECT_RATIO] & _ECORE_X_RANDR_EDID_MASK_ASPECT_RATIO_15_9) + ret |= ECORE_X_RANDR_EDID_ASPECT_RATIO_15_9; + } + } + return ret; +} + +EAPI char * +ecore_x_randr_edid_display_ascii_get(unsigned char *edid, + unsigned long edid_length) +{ + unsigned char *block = NULL; + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; + _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) + { + if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfe) + { + char *ascii, *p; + const char *edid_ascii = (const char *)block + + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; + /* + * TODO: Two of these in a row, in the third and fourth slots, + * seems to be specified by SPWG: http://www.spwg.org/ + */ + ascii = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); + if (!ascii) return NULL; + strncpy(ascii, edid_ascii, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); + ascii[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; + for (p = ascii; *p; p++) + { + if ((*p < ' ') || (*p > '~')) *p = 0; + } + return ascii; + } + } + return NULL; +} + +EAPI char * +ecore_x_randr_edid_display_serial_get(unsigned char *edid, + unsigned long edid_length) +{ + unsigned char *block = NULL; + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL; + _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) + { + if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xff) + { + char *serial, *p; + const char *edid_serial = (const char *)block + + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT; + /* + * TODO: Two of these in a row, in the third and fourth slots, + * seems to be specified by SPWG: http://www.spwg.org/ + */ + serial = malloc(sizeof(char) * _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX); + if (!serial) return NULL; + strncpy(serial, edid_serial, (_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1)); + serial[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0; + for (p = serial; *p; p++) + { + if ((*p < ' ') || (*p > '~')) *p = 0; + } + return serial; + } + } + return NULL; +} + +EAPI Eina_Bool +ecore_x_randr_edid_info_has_valid_checksum(unsigned char *edid, + unsigned long edid_length) +{ + unsigned char *cea_block_iter = NULL; + char sum = 0; + int i; + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; + if (edid_length < 128) return EINA_FALSE; + + /* Check the EDID block itself */ + for (i = 0; i < 128; i++) + sum += edid[i]; + if (sum) return EINA_FALSE; + + /* Check the cea extension blocks */ + _ECORE_X_RANDR_EDID_FOR_EACH_CEA_BLOCK(edid, edid_length, cea_block_iter) + { + for (i = 0, sum = 0; i < 128; i++) + sum += cea_block_iter[i]; + } + if (sum) return EINA_FALSE; + return EINA_TRUE; +} + +EAPI Eina_Bool +ecore_x_randr_edid_dpms_available_get(unsigned char *edid, + unsigned long edid_length) +{ + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; + return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & + _ECORE_X_RANDR_EDID_MASK_DPMS); +} + +EAPI Eina_Bool +ecore_x_randr_edid_dpms_standby_available_get(unsigned char *edid, + unsigned long edid_length) +{ + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; + if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) + return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & + _ECORE_X_RANDR_EDID_MASK_DPMS_STANDBY); + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_randr_edid_dpms_suspend_available_get(unsigned char *edid, + unsigned long edid_length) +{ + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; + if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) + return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & + _ECORE_X_RANDR_EDID_MASK_DPMS_SUSPEND); + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_randr_edid_dpms_off_available_get(unsigned char *edid, + unsigned long edid_length) +{ + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; + if (edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & _ECORE_X_RANDR_EDID_MASK_DPMS) + return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_DPMS] & + _ECORE_X_RANDR_EDID_MASK_DPMS_OFF); + return EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_randr_edid_display_type_digital_get(unsigned char *edid, + unsigned long edid_length) +{ + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return EINA_FALSE; + return !!(edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] & + _ECORE_X_RANDR_EDID_MASK_DIGITAL); +} + +EAPI Ecore_X_Randr_Edid_Display_Colorscheme +ecore_x_randr_edid_display_colorscheme_get(unsigned char *edid, + unsigned long edid_length) +{ + Ecore_X_Randr_Edid_Display_Colorscheme colorscheme = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return colorscheme; + if (ecore_x_randr_edid_display_type_digital_get(edid, edid_length)) + { + colorscheme = ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_4_4_4; + if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & + _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_444) + colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_4_4; + if (edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & + _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_DIGITAL_YCRCB_422) + colorscheme |= ECORE_X_RANDR_EDID_DISPLAY_COLORSCHEME_COLOR_RGB_YCRCB_4_2_2; + } + else + colorscheme = edid[_ECORE_X_RANDR_EDID_OFFSET_COLORSPACE] & _ECORE_X_RANDR_EDID_MASK_COLORSCHEME_ANALOGOUS; + return colorscheme; +} + +EAPI Ecore_X_Randr_Edid_Display_Interface_Type +ecore_x_randr_edid_display_interface_type_get(unsigned char *edid, + unsigned long edid_length) +{ + Ecore_X_Randr_Edid_Display_Interface_Type type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; + int version = ecore_x_randr_edid_version_get(edid, edid_length); + + if (version < ECORE_X_RANDR_EDID_VERSION_13) return type; + type = edid[_ECORE_X_RANDR_EDID_OFFSET_TYPE] & + _ECORE_X_RANDR_EDID_MASK_INTERFACE_TYPE; + if (type > ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT) + type = ECORE_X_RANDR_EDID_UNKNOWN_VALUE; + return type; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_randr_13.c b/src/lib/ecore_x/xlib/ecore_x_randr_13.c new file mode 100644 index 0000000000..5d1c8e96db --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_randr_13.c @@ -0,0 +1,68 @@ +/* + * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2 + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "ecore_x_private.h" +#include "ecore_x_randr.h" +#include +#include +#include +#include + +#define Ecore_X_Randr_None 0 +#define Ecore_X_Randr_Unset -1 + +#ifdef ECORE_XRANDR + +#define RANDR_1_3 ((1 << 16) | 3) +#define RANDR_CHECK_1_3_RET(ret) if (_randr_version < RANDR_1_3) \ + return ret + +extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display * + dpy, + Window + window); +extern int _randr_version; +#endif + +/* + * @param root window which's screen should be queried + * @return Ecore_X_Randr_Ouptut_Id or - if query failed or none is set - Ecore_X_Randr_None + */ +EAPI Ecore_X_Randr_Output +ecore_x_randr_primary_output_get(Ecore_X_Window root) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_3_RET(Ecore_X_Randr_None); + if (!_ecore_x_randr_root_validate(root)) + return Ecore_X_Randr_None; + + return XRRGetOutputPrimary(_ecore_x_disp, root); +#else + return Ecore_X_Randr_None; +#endif +} + +/* + * @param root window which's screen should be queried + * @param output that should be set as given root window's screen primary output + */ +EAPI void +ecore_x_randr_primary_output_set(Ecore_X_Window root, + Ecore_X_Randr_Output output) +{ +#ifdef ECORE_XRANDR + RANDR_CHECK_1_3_RET(); + + if (_ecore_x_randr_output_validate(root, output)) + { + XRRSetOutputPrimary(_ecore_x_disp, root, output); + } + +#endif +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_region.c b/src/lib/ecore_x/xlib/ecore_x_region.c new file mode 100644 index 0000000000..81d7eea49c --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_region.c @@ -0,0 +1,158 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#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 Eina_Bool +ecore_x_xregion_set(Ecore_X_XRegion *region, + Ecore_X_GC gc) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return XSetRegion(_ecore_x_disp, gc, (Region)region) ? EINA_TRUE : EINA_FALSE; +} + +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 Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +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) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_xregion_is_empty(Ecore_X_XRegion *region) +{ + if (!region) + return EINA_TRUE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return XEmptyRegion((Region)region) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_xregion_is_equal(Ecore_X_XRegion *r1, + Ecore_X_XRegion *r2) +{ + if (!r1 || !r2) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return XEqualRegion((Region)r1, (Region)r1) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_xregion_point_contain(Ecore_X_XRegion *region, + int x, + int y) +{ + if (!region) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return XPointInRegion((Region)region, x, y) ? EINA_TRUE : EINA_FALSE; +} + +EAPI Eina_Bool +ecore_x_xregion_rect_contain(Ecore_X_XRegion *region, + Ecore_X_Rectangle *rect) +{ + if (!region || !rect) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return XRectInRegion((Region)region, + rect->x, + rect->y, + rect->width, + rect->height) ? EINA_TRUE : EINA_FALSE; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_screensaver.c b/src/lib/ecore_x/xlib/ecore_x_screensaver.c new file mode 100644 index 0000000000..3688a44c56 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_screensaver.c @@ -0,0 +1,204 @@ +/* + * Screensaver code + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +static int _screensaver_available = -1; + +EAPI Eina_Bool +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 /* ifdef ECORE_XSS */ + _screensaver_available = 0; +#endif /* ifdef ECORE_XSS */ + 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; +#else + return 0; +#endif /* ifdef ECORE_XSS */ +} + +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(Eina_Bool 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 | ScreenSaverCycle); + else + XScreenSaverSelectInput(_ecore_x_disp, root, 0); +#else + return; + on = EINA_FALSE; +#endif /* ifdef ECORE_XSS */ +} + + +EAPI Eina_Bool +ecore_x_screensaver_custom_blanking_enable(void) +{ +#ifdef ECORE_XSS + XSetWindowAttributes attr; + + XScreenSaverSetAttributes(_ecore_x_disp, + DefaultRootWindow(_ecore_x_disp), + -9999, -9999, 1, 1, 0, + CopyFromParent, InputOnly, CopyFromParent, + 0, &attr); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif /* ifdef ECORE_XSS */ +} + +EAPI Eina_Bool +ecore_x_screensaver_custom_blanking_disable(void) +{ +#ifdef ECORE_XSS + XScreenSaverUnsetAttributes(_ecore_x_disp, + DefaultRootWindow(_ecore_x_disp)); + return EINA_TRUE; +#else + return EINA_FALSE; +#endif /* ifdef ECORE_XSS */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_selection.c b/src/lib/ecore_x/xlib/ecore_x_selection.c new file mode 100644 index 0000000000..3e1d2d34a2 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_selection.c @@ -0,0 +1,1021 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include +#include + +#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_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 /* ifdef X_HAVE_UTF8_STRING */ + 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; +} + +Eina_Bool +_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 EINA_FALSE; + + 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 EINA_FALSE; + + 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); + if (!buf) return EINA_FALSE; + 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 EINA_TRUE; +} + +/** + * 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 Eina_Bool +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 Eina_Bool +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 Eina_Bool +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 Eina_Bool +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 Eina_Bool +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 Eina_Bool +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 Eina_Bool +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 Eina_Bool +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, + Eina_Bool (*func)(char *target, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *ttype, + int *tsize)) +{ + 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)); + if (!cnv->next) return; + cnv = cnv->next; + } + else + { + converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); + if (!converters) return; + cnv = converters; + } + + cnv->target = target; + cnv->convert = func; +} + +EAPI void +ecore_x_selection_converter_add(char *target, + Eina_Bool (*func)(char *target, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *, + int *)) +{ + 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 Eina_Bool +ecore_x_selection_notify_send(Ecore_X_Window requestor, + Ecore_X_Atom selection, + Ecore_X_Atom target, + Ecore_X_Atom property, + Ecore_X_Time tim) +{ + 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 = tim; + xnotify.send_event = True; + xnotify.serial = 0; + + xev.xselection = xnotify; + return (XSendEvent(_ecore_x_disp, requestor, False, 0, &xev) > 0) ? EINA_TRUE : EINA_FALSE; +} + +/* Locate and run conversion callback for specified selection target */ +EAPI Eina_Bool +ecore_x_selection_convert(Ecore_X_Atom selection, + Ecore_X_Atom target, + void **data_ret, + int *size, + Ecore_X_Atom *targtype, + int *typesize) +{ + Ecore_X_Selection_Intern *sel; + Ecore_X_Selection_Converter *cnv; + void *data; + 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, + targtype, typesize); + free(tgt_str); + if (r) + { + *data_ret = data; + return r; + } + else + return EINA_FALSE; + } + } + + /* 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 EINA_FALSE; + + /* 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 */ +EAPI Eina_Bool +ecore_x_selection_converter_text(char *target, + void *data, + int size, + void **data_ret, + int *size_ret, + Ecore_X_Atom *targprop EINA_UNUSED, + int *s EINA_UNUSED) +{ + XTextProperty text_prop; + char *mystr; + XICCEncodingStyle style; + + if (!data || !size) + return EINA_FALSE; + + 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 /* ifdef X_HAVE_UTF8_STRING */ + else + return EINA_FALSE; + + mystr = alloca(size + 1); + memcpy(mystr, data, size); + mystr[size] = '\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); + if (!*data_ret) + { + return EINA_FALSE; + } + memcpy(*data_ret, text_prop.value, bufsize); + *size_ret = bufsize; + XFree(text_prop.value); + return EINA_TRUE; + } + +#else /* ifdef X_HAVE_UTF8_STRING */ + if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, + &text_prop) == Success) + { + int bufsize = strlen(text_prop.value) + 1; + *data_ret = malloc(bufsize); + if (!*data_ret) return EINA_FALSE; + memcpy(*data_ret, text_prop.value, bufsize); + *size_ret = bufsize; + XFree(text_prop.value); + return EINA_TRUE; + } + +#endif /* ifdef X_HAVE_UTF8_STRING */ + else + { + return EINA_TRUE; + } +} + +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)); + if (!prs->next) return; + prs = prs->next; + } + else + { + parsers = calloc(1, sizeof(Ecore_X_Selection_Parser)); + if (!parsers) return; + 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; + } +} + +/** + * Change the owner and last-change time for the specified selection. + * @param win The owner of the specified atom. + * @param atom The selection atom + * @param tim Specifies the time + * @since 1.1.0 + */ +EAPI void +ecore_x_selection_owner_set(Ecore_X_Window win, + Ecore_X_Atom atom, + Ecore_X_Time tim) +{ + XSetSelectionOwner(_ecore_x_disp, atom, win, tim); +} + +/** + * Return the window that currently owns the specified selection. + * + * @param atom The specified selection atom. + * + * @return The window that currently owns the specified selection. + * @since 1.1.0 + */ +EAPI Ecore_X_Window +ecore_x_selection_owner_get(Ecore_X_Atom atom) +{ + return XGetSelectionOwner(_ecore_x_disp, atom); +} + +/* 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); + if (sel) return sel; + } + } + + /* Default, just return the data */ + sel = calloc(1, sizeof(Ecore_X_Selection_Data)); + if (!sel) return NULL; + 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 EINA_UNUSED) +{ + Ecore_X_Selection_Data_Files *sel; + char *t, *data = _data; + int i, is; + char *tmp; + char **t2; + + if (strcmp(target, "text/uri-list") && + strcmp(target, "_NETSCAPE_URL")) + return NULL; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files)); + if (!sel) return NULL; + ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free; + + if (data && data[size - 1]) + { + /* Isn't nul terminated */ + size++; + t = realloc(data, size); + if (!t) + { + free(sel); + return NULL; + } + data = t; + data[size - 1] = 0; + } + + tmp = malloc(size); + if (!tmp) + { + free(sel); + return NULL; + } + 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++; + t2 = realloc(sel->files, sel->num_files * sizeof(char *)); + if (t2) + { + sel->files = t2; + sel->files[sel->num_files - 1] = strdup(tmp); + } + tmp[0] = 0; + i = 0; + } + } + } + if (i > 0) + { + tmp[i] = 0; + sel->num_files++; + t2 = realloc(sel->files, sel->num_files * sizeof(char *)); + if (t2) + { + sel->files = t2; + 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 EINA_UNUSED, + void *_data, + int size, + int format EINA_UNUSED) +{ + Ecore_X_Selection_Data_Text *sel; + unsigned char *data = _data; + void *t; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); + if (!sel) return NULL; + if (data && data[size - 1]) + { + /* Isn't nul terminated */ + size++; + t = realloc(data, size); + if (!t) + { + free(sel); + return NULL; + } + data = t; + 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)->data = data; + 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 EINA_UNUSED, + void *data, + int size, + int format EINA_UNUSED) +{ + Ecore_X_Selection_Data_Targets *sel; + unsigned long *targets; + int i; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); + if (!sel) return NULL; + targets = (unsigned long *)data; + + sel->num_targets = size - 2; + sel->targets = malloc((size - 2) * sizeof(char *)); + if (!sel->targets) + { + free(sel); + return NULL; + } + for (i = 2; i < size; i++) + sel->targets[i - 2] = XGetAtomName(_ecore_x_disp, targets[i]); + + 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; + ECORE_X_SELECTION_DATA(sel)->data = data; + 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(ECORE_X_SELECTION_DATA(sel)->data); + free(sel); + return 1; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_sync.c b/src/lib/ecore_x/xlib/ecore_x_sync.c new file mode 100644 index 0000000000..0c7f546f1a --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_sync.c @@ -0,0 +1,159 @@ +/* + * XSync code + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#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 Eina_Bool +ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + return XSyncDestroyAlarm(_ecore_x_disp, alarm); +} + +EAPI Eina_Bool +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 EINA_TRUE; + } + + return EINA_FALSE; +} + +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 +} + +EAPI void +ecore_x_sync_counter_set(Ecore_X_Sync_Counter counter, + int val) +{ + XSyncValue v; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XSyncIntToValue(&v, val); + XSyncSetCounter(_ecore_x_disp, counter, v); +} + +EAPI void +ecore_x_sync_counter_2_set(Ecore_X_Sync_Counter counter, + int val_hi, + unsigned int val_lo) +{ + XSyncValue v; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XSyncIntsToValue(&v, val_lo, val_hi); + XSyncSetCounter(_ecore_x_disp, counter, v); +} + +EAPI Eina_Bool +ecore_x_sync_counter_2_query(Ecore_X_Sync_Counter counter, + int *val_hi, + unsigned int *val_lo) +{ + XSyncValue value; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (XSyncQueryCounter(_ecore_x_disp, counter, &value)) + { + *val_lo = (unsigned int)XSyncValueLow32(value); + *val_hi = (int)XSyncValueHigh32(value); + return EINA_TRUE; + } + return EINA_FALSE; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_test.c b/src/lib/ecore_x/xlib/ecore_x_test.c new file mode 100644 index 0000000000..4eec6b74b3 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_test.c @@ -0,0 +1,167 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include + +#ifdef ECORE_XTEST +# include +#endif /* ifdef ECORE_XTEST */ + +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include + +EAPI Eina_Bool +#ifdef ECORE_XTEST +ecore_x_test_fake_key_down(const char *key) +#else +ecore_x_test_fake_key_down(const char *key EINA_UNUSED) +#endif +{ +#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 EINA_FALSE; + + keycode = XKeysymToKeycode(_ecore_x_disp, keysym); + } + + if (keycode == 0) + return EINA_FALSE; + + return XTestFakeKeyEvent(_ecore_x_disp, keycode, 1, 0) ? EINA_TRUE : EINA_FALSE; +#else /* ifdef ECORE_XTEST */ + return EINA_FALSE; +#endif /* ifdef ECORE_XTEST */ +} + +EAPI Eina_Bool +#ifdef ECORE_XTEST +ecore_x_test_fake_key_up(const char *key) +#else +ecore_x_test_fake_key_up(const char *key EINA_UNUSED) +#endif +{ +#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 EINA_FALSE; + + keycode = XKeysymToKeycode(_ecore_x_disp, keysym); + } + + if (keycode == 0) + return EINA_FALSE; + + return XTestFakeKeyEvent(_ecore_x_disp, keycode, 0, 0) ? EINA_TRUE : EINA_FALSE; +#else /* ifdef ECORE_XTEST */ + return EINA_FALSE; +#endif /* ifdef ECORE_XTEST */ +} + +EAPI Eina_Bool +#ifdef ECORE_XTEST +ecore_x_test_fake_key_press(const char *key) +#else +ecore_x_test_fake_key_press(const char *key EINA_UNUSED) +#endif +{ +#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 EINA_FALSE; + + keycode = XKeysymToKeycode(_ecore_x_disp, keysym); + if (_ecore_x_XKeycodeToKeysym(_ecore_x_disp, keycode, 0) != keysym) + { + if (_ecore_x_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 EINA_TRUE; +#else /* ifdef ECORE_XTEST */ + return EINA_FALSE; +#endif /* ifdef ECORE_XTEST */ +} + +EAPI const char * +ecore_x_keysym_string_get(int keysym) +{ + return XKeysymToString(keysym); +} + +EAPI int +ecore_x_keysym_keycode_get(const char *keyname) +{ + int keycode = 0; + + if (!strncmp(keyname, "Keycode-", 8)) + keycode = atoi(keyname + 8); + else + keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(keyname)); + + return keycode; +} diff --git a/src/lib/ecore_x/xlib/ecore_x_vsync.c b/src/lib/ecore_x/xlib/ecore_x_vsync.c new file mode 100644 index 0000000000..a316a33c45 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_vsync.c @@ -0,0 +1,351 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ECORE_X_VSYNC_DRI2 1 + +#ifdef ECORE_X_VSYNC_DRI2 +// relevant header bits of dri/drm inlined here to avoid needing external +// headers to build +/// drm +typedef unsigned int drm_magic_t; + +typedef enum +{ + DRM_VBLANK_ABSOLUTE = 0x00000000, + DRM_VBLANK_RELATIVE = 0x00000001, + DRM_VBLANK_EVENT = 0x04000000, + DRM_VBLANK_FLIP = 0x08000000, + DRM_VBLANK_NEXTONMISS = 0x10000000, + DRM_VBLANK_SECONDARY = 0x20000000, + DRM_VBLANK_SIGNAL = 0x40000000 +} +drmVBlankSeqType; + +typedef struct _drmVBlankReq +{ + drmVBlankSeqType type; + unsigned int sequence; + unsigned long signal; +} drmVBlankReq; + +typedef struct _drmVBlankReply +{ + drmVBlankSeqType type; + unsigned int sequence; + long tval_sec; + long tval_usec; +} drmVBlankReply; + +typedef union _drmVBlank +{ + drmVBlankReq request; + drmVBlankReply reply; +} drmVBlank; + +#define DRM_EVENT_CONTEXT_VERSION 2 + +typedef struct _drmEventContext +{ + int version; + void (*vblank_handler)(int fd, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void *user_data); + void (*page_flip_handler)(int fd, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void *user_data); +} drmEventContext; + +static int (*sym_drmClose)(int fd) = NULL; +static int (*sym_drmGetMagic)(int fd, + drm_magic_t *magic) = NULL; +static int (*sym_drmWaitVBlank)(int fd, + drmVBlank *vbl) = NULL; +static int (*sym_drmHandleEvent)(int fd, + drmEventContext *evctx) = NULL; + +//// dri + +static Bool (*sym_DRI2QueryExtension)(Display *display, + int *eventBase, + int *errorBase) = NULL; +static Bool (*sym_DRI2QueryVersion)(Display *display, + int *major, + int *minor) = NULL; +static Bool (*sym_DRI2Connect)(Display *display, + XID window, + char **driverName, + char **deviceName) = NULL; +static Bool (*sym_DRI2Authenticate)(Display *display, + XID window, + drm_magic_t magic) = NULL; + +//// dri/drm data needed +static int dri2_event = 0; +static int dri2_error = 0; +static int dri2_major = 0; +static int dri2_minor = 0; +static char *device_name = 0; +static char *driver_name = 0; +static drm_magic_t drm_magic; + +static int drm_fd = -1; +static int drm_event_is_busy = 0; +static int drm_animators_interval = 1; +static drmEventContext drm_evctx; +static Ecore_Fd_Handler *dri_drm_fdh = NULL; + +static void *dri_lib = NULL; +static void *drm_lib = NULL; + +static Window dri_drm_vsync_root = 0; + +static void +_dri_drm_tick_schedule(void) +{ + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT; + vbl.request.sequence = drm_animators_interval; + vbl.request.signal = 0; + sym_drmWaitVBlank(drm_fd, &vbl); +} + +static void +_dri_drm_tick_begin(void *data EINA_UNUSED) +{ + drm_event_is_busy = 1; + _dri_drm_tick_schedule(); +} + +static void +_dri_drm_tick_end(void *data EINA_UNUSED) +{ + drm_event_is_busy = 0; +} + +static void +_dri_drm_vblank_handler(int fd EINA_UNUSED, + unsigned int frame EINA_UNUSED, + unsigned int sec EINA_UNUSED, + unsigned int usec EINA_UNUSED, + void *data EINA_UNUSED) +{ + ecore_animator_custom_tick(); + if (drm_event_is_busy) _dri_drm_tick_schedule(); +} + +static Eina_Bool +_dri_drm_cb(void *data EINA_UNUSED, + Ecore_Fd_Handler *fd_handler EINA_UNUSED) +{ + sym_drmHandleEvent(drm_fd, &drm_evctx); + return ECORE_CALLBACK_RENEW; +} + +// yes. most evil. we dlopen libdrm and libGL etc. to manually find smbols +// so we can be as compatible as possible given the whole mess of the +// gl/dri/drm etc. world. and handle graceful failure at runtime not +// compile time +static int +_dri_drm_link(void) +{ + const char *drm_libs[] = + { + "libdrm.so.2", + "libdrm.so.1", + "libdrm.so.0", + "libdrm.so", + NULL, + }; + const char *dri_libs[] = + { + "libdri2.so.2", + "libdri2.so.1", + "libdri2.so.0", + "libdri2.so", + "libGL.so.4", + "libGL.so.3", + "libGL.so.2", + "libGL.so.1", + "libGL.so.0", + "libGL.so", + NULL, + }; + int i, fail; +#define SYM(lib, xx) \ + do { \ + sym_ ## xx = dlsym(lib, #xx); \ + if (!(sym_ ## xx)) { \ + fprintf(stderr, "%s\n", dlerror()); \ + fail = 1; \ + } \ + } while (0) + + if (dri_lib) return 1; + for (i = 0; drm_libs[i]; i++) + { + drm_lib = dlopen(drm_libs[i], RTLD_LOCAL | RTLD_LAZY); + if (drm_lib) + { + fail = 0; + SYM(drm_lib, drmClose); + SYM(drm_lib, drmWaitVBlank); + SYM(drm_lib, drmHandleEvent); + if (fail) + { + dlclose(drm_lib); + drm_lib = NULL; + } + else break; + } + } + if (!drm_lib) return 0; + for (i = 0; dri_libs[i]; i++) + { + dri_lib = dlopen(dri_libs[i], RTLD_LOCAL | RTLD_LAZY); + if (dri_lib) + { + fail = 0; + SYM(dri_lib, DRI2QueryExtension); + SYM(dri_lib, DRI2QueryVersion); + SYM(dri_lib, DRI2Connect); + SYM(dri_lib, DRI2Authenticate); + if (fail) + { + dlclose(dri_lib); + dri_lib = NULL; + } + else break; + } + } + if (!dri_lib) + { + dlclose(drm_lib); + drm_lib = NULL; + return 0; + } + return 1; +} + +static int +_dri_drm_init(void) +{ + if (!sym_DRI2QueryExtension(_ecore_x_disp, &dri2_event, &dri2_error)) + return 0; + if (!sym_DRI2QueryVersion(_ecore_x_disp, &dri2_major, &dri2_minor)) + return 0; + if (dri2_major < 2) + return 0; + if (!sym_DRI2Connect(_ecore_x_disp, dri_drm_vsync_root, &driver_name, &device_name)) + return 0; + drm_fd = open(device_name, O_RDWR); + if (drm_fd < 0) + return 0; + sym_drmGetMagic(drm_fd, &drm_magic); + if (!sym_DRI2Authenticate(_ecore_x_disp, dri_drm_vsync_root, drm_magic)) + { + close(drm_fd); + drm_fd = -1; + return 0; + } + memset(&drm_evctx, 0, sizeof(drm_evctx)); + drm_evctx.version = DRM_EVENT_CONTEXT_VERSION; + drm_evctx.vblank_handler = _dri_drm_vblank_handler; + drm_evctx.page_flip_handler = NULL; + + dri_drm_fdh = ecore_main_fd_handler_add(drm_fd, ECORE_FD_READ, + _dri_drm_cb, NULL, NULL, NULL); + if (!dri_drm_fdh) + { + close(drm_fd); + drm_fd = -1; + return 0; + } + return 1; +} + +static void +_dri_drm_shutdown(void) +{ + if (drm_fd >= 0) + { + close(drm_fd); + drm_fd = -1; + } + if (dri_drm_fdh) + { + ecore_main_fd_handler_del(dri_drm_fdh); + dri_drm_fdh = NULL; + } +} + +#endif + +EAPI Eina_Bool +ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win) +{ +#ifdef ECORE_X_VSYNC_DRI2 + Ecore_X_Window root; + + root = ecore_x_window_root_get(win); + if (root != dri_drm_vsync_root) + { + dri_drm_vsync_root = root; + if (dri_drm_vsync_root) + { + if (!_dri_drm_link()) + { + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + _dri_drm_shutdown(); + if (!_dri_drm_init()) + { + dri_drm_vsync_root = 0; + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + return EINA_FALSE; + } + ecore_animator_custom_source_tick_begin_callback_set + (_dri_drm_tick_begin, NULL); + ecore_animator_custom_source_tick_end_callback_set + (_dri_drm_tick_end, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); + } + else + { + if (drm_fd >= 0) + { + _dri_drm_shutdown(); + ecore_animator_custom_source_tick_begin_callback_set + (NULL, NULL); + ecore_animator_custom_source_tick_end_callback_set + (NULL, NULL); + ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); + } + } + } + return EINA_TRUE; +#else + return EINA_FALSE; + win = 0; +#endif +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_window.c b/src/lib/ecore_x/xlib/ecore_x_window.c new file mode 100644 index 0000000000..36fc5cc53a --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_window.c @@ -0,0 +1,1727 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include +#include +#include + +#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_Group + */ +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, cnt; + Ecore_X_Window *t; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (ignore) + { + if (ignore_list) + { + for (i = 0; i < ignore_num; i++) + { + if (win == ignore_list[i]) + return; + } + t = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window)); + if (!t) return; + ignore_list = t; + ignore_list[ignore_num++] = win; + } + else + { + ignore_num = 0; + ignore_list = malloc(sizeof(Ecore_X_Window)); + if (ignore_list) + ignore_list[ignore_num++] = win; + } + } + else + { + if (!ignore_list) + return; + + for (cnt = ignore_num, i = 0, j = 0; i < cnt; i++) + { + if (win != ignore_list[i]) + ignore_list[j++] = ignore_list[i]; + else + ignore_num--; + } + + if (ignore_num <= 0) + { + free(ignore_list); + ignore_list = NULL; + return; + } + t = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window)); + if (t) ignore_list = t; + } +} + +/** + * 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); + + XUnmapWindow(_ecore_x_disp, win); + 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); +} + +/** + * @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 window that has focus. + * @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. + * + * Note that the x & y coordinates are relative to your parent. In + * particular for reparenting window managers - relative to you window border. + * If you want screen coordinates either walk the window tree to the root, + * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary + * applications can use elm_win_screen_position_get(). + * + * @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); +} + +/** + * @brief Show the cursor on a window of type Ecore_X_Window. + * @param win The window for which the cursor will be showed. + * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE. + */ +EAPI void +ecore_x_window_cursor_show(Ecore_X_Window win, + Eina_Bool 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 int +_inside_rects(Shadow *s, + int x, + int y, + int bx, + int by, + Ecore_X_Rectangle *rects, + int num) +{ + int i, inside; + + if (!rects) return 0; + inside = 0; + for (i = 0; i < num; i++) + { + if ((x >= s->x + bx + rects[i].x) && + (y >= s->y + by + rects[i].y) && + (x < (int)(s->x + bx + rects[i].x + rects[i].width)) && + (y < (int)(s->y + by + rects[i].y + rects[i].height))) + { + inside = 1; + break; + } + } + free(rects); + return inside; +} + +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; + + /* FIXME: get shape */ + { + int num; + Ecore_X_Rectangle *rects; + + num = 0; + rects = ecore_x_window_shape_rectangles_get(s->win, &num); + if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0; + num = 0; + rects = ecore_x_window_shape_input_rectangles_get(s->win, &num); + if (!_inside_rects(s, x, y, bx, by, rects, num)) 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. + * @param skip The list of windows to be skipped. + * @param skip_num The number of windows to be skipped. + * @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 EINA_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. + * @param skip The list of windows to be skipped. + * @param skip_num The number of windows to be skipped. + * @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, + Eina_Bool 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, + Eina_Bool override, + Eina_Bool 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) + 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 /* ifdef ECORE_XRENDER */ + +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 /* ifdef ECORE_XRENDER */ + return 0; +#endif /* ifdef ECORE_XRENDER */ +} + +/** + * 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 /* ifdef ECORE_XRENDER */ + return 0; +#endif /* ifdef ECORE_XRENDER */ +} + +/** + * 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 /* ifdef ECORE_XRENDER */ + return 0; +#endif /* ifdef ECORE_XRENDER */ +} + +/** + * 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 /* ifdef ECORE_XRENDER */ + return 0; +#endif /* ifdef ECORE_XRENDER */ +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_window_prop.c b/src/lib/ecore_x/xlib/ecore_x_window_prop.c new file mode 100644 index 0000000000..535c521941 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_window_prop.c @@ -0,0 +1,760 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include +#include + +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" +#include +#include + +#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 /* if SIZEOF_INT == SIZEOF_LONG */ + 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 /* if SIZEOF_INT == SIZEOF_LONG */ +} + +/* + * 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)); + if (!val) + { + if (prop_ret) XFree(prop_ret); + return -1; + } + 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 /* if SIZEOF_INT == SIZEOF_LONG */ + 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 /* if SIZEOF_INT == SIZEOF_LONG */ +} + +/* + * 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); +} + +EAPI Ecore_X_Atom +ecore_x_window_prop_any_type(void) +{ + return AnyPropertyType; +} + +/** + * @brief Set a property of Ecore_X_Window. + * @param win The window for which the property will be set. + * @param property The property of the window to be set. + * @param type The type of the property that will be set. + * @param size The size of the property that will be set. + * @param data The data of the property that will be set. + * @param number The size of data. + */ +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); + } + } +} + +/** + * @brief Get a property of Ecore_X_Window. + * @note If there aren't any data to be got the function return NULL. + * If the function can't allocate the memory then 0 is returned. + * @param win The window for which the property will be got. + * @param property The property of the window that will be gotten. + * @param type The type of the property that will be gotten. + * @param size This parameter isn't in use. + * @param data The data of the property that will be gotten. + * @param num The size of property. + * @return size_ret The size of array that contains the property. + */ +EAPI int +ecore_x_window_prop_property_get(Ecore_X_Window win, + Ecore_X_Atom property, + Ecore_X_Atom type, + int size EINA_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 /* ifdef X_HAVE_UTF8_STRING */ + s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp, + &list, &items); +#endif /* ifdef X_HAVE_UTF8_STRING */ + 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 Eina_Bool +ecore_x_window_prop_protocol_isset(Ecore_X_Window win, + Ecore_X_WM_Protocol protocol) +{ + Atom proto, *protos = NULL; + int i, protos_count = 0; + Eina_Bool ret = EINA_FALSE; + + /* check for invalid values */ + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) + return EINA_FALSE; + + 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 = EINA_TRUE; + break; + } + + XFree(protos); + + return ret; +} + +/** + * @brief Get a array containing the protocols of @a win + * @note If there aren't any properties to be counted or any protocols to get + * then the function returns NULL. + * @param win The window for which protocol list will be got. + * @param num_ret Contains the number of elements of the array to be returned. + * @return The array that contains the protocols. + */ +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; +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_window_shape.c b/src/lib/ecore_x/xlib/ecore_x_window_shape.c new file mode 100644 index 0000000000..71718cfa3a --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_window_shape.c @@ -0,0 +1,658 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include + +#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); +} + +/** + * Sets the input shape of the given window to that given by the pixmap @p mask. + * @param win The given window. + * @param mask A 1-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 /* ifdef ShapeInput */ + return; + win = mask = 0; +#endif /* ifdef ShapeInput */ +} + +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_input_window_set(Ecore_X_Window win, + Ecore_X_Window shape_win) +{ +#ifdef ShapeInput + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XShapeCombineShape(_ecore_x_disp, + win, + ShapeInput, + 0, + 0, + shape_win, + ShapeInput, + ShapeSet); +#else + return; + win = shape_win = 0; +#endif +} + +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_input_window_set_xy(Ecore_X_Window win, + Ecore_X_Window shape_win, + int x, + int y) +{ +#ifdef ShapeInput + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XShapeCombineShape(_ecore_x_disp, + win, + ShapeInput, + x, + y, + shape_win, + ShapeInput, + ShapeSet); +#else + return; + win = shape_win = x = y = 0; +#endif +} + +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_input_rectangle_set(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ShapeInput + XRectangle rect; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeInput, + 0, + 0, + &rect, + 1, + ShapeSet, + Unsorted); +#else + return; + win = x = y = w = h = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangles_set(Ecore_X_Window win, + Ecore_X_Rectangle *rects, + int num) +{ +#ifdef ShapeInput + XRectangle *rect = NULL; + int i; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!rects) return; + if (num > 0) + { + rect = malloc(sizeof(XRectangle) * num); + if (!rect) return; + 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; + } + } + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeBounding, + 0, + 0, + rect, + num, + ShapeSet, + Unsorted); + if (rect) free(rect); +#else + return; + win = rects = num = 0; +#endif +} + +EAPI void +ecore_x_window_shape_input_rectangles_set(Ecore_X_Window win, + Ecore_X_Rectangle *rects, + int num) +{ +#ifdef ShapeInput + XRectangle *rect = NULL; + int i; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!rects) return; + if (num > 0) + { + rect = malloc(sizeof(XRectangle) * num); + if (!rect) return; + 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; + } + } + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeInput, + 0, + 0, + rect, + num, + ShapeSet, + Unsorted); + if (rect) free(rect); +#else + return; + win = rects = num = 0; +#endif +} + +EAPI void +ecore_x_window_shape_rectangle_subtract(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, + ShapeSubtract, + Unsorted); +} + +EAPI void +ecore_x_window_shape_input_rectangle_subtract(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ShapeInput + XRectangle rect; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeInput, + 0, + 0, + &rect, + 1, + ShapeSubtract, + Unsorted); +#else + return; + win = x = y = w = h = 0; +#endif +} + +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_input_window_add_xy(Ecore_X_Window win, + Ecore_X_Window shape_win, + int x, + int y) +{ +#ifdef ShapeInput + LOGFN(__FILE__, __LINE__, __FUNCTION__); + XShapeCombineShape(_ecore_x_disp, + win, + ShapeInput, + x, + y, + shape_win, + ShapeInput, + ShapeUnion); +#else + return; + win = shape_win = x = y = 0; +#endif +} + +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_input_rectangle_add(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ShapeInput + XRectangle rect; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeInput, + 0, + 0, + &rect, + 1, + ShapeUnion, + Unsorted); +#else + return; + win = x = y = w = h = 0; +#endif +} + +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_input_rectangle_clip(Ecore_X_Window win, + int x, + int y, + int w, + int h) +{ +#ifdef ShapeInput + XRectangle rect; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeInput, + 0, + 0, + &rect, + 1, + ShapeIntersect, + Unsorted); +#else + return; + win = x = y = w = h = 0; +#endif +} + +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) return; + 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; + } + } + + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeBounding, + 0, + 0, + rect, + num, + ShapeUnion, + Unsorted); + if (rect) free(rect); +} + +EAPI void +ecore_x_window_shape_input_rectangles_add(Ecore_X_Window win, + Ecore_X_Rectangle *rects, + int num) +{ +#ifdef ShapeInput + XRectangle *rect = NULL; + int i; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (num > 0) + { + rect = malloc(sizeof(XRectangle) * num); + if (!rect) return; + 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; + } + } + + XShapeCombineRectangles(_ecore_x_disp, + win, + ShapeInput, + 0, + 0, + rect, + num, + ShapeUnion, + Unsorted); + if (rect) free(rect); +#else + return; + win = rects = num = 0; +#endif +} + +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) + { + if (num < 1) + { + XFree(rect); + if (num_ret) *num_ret = 0; + return NULL; + } + rects = malloc(sizeof(Ecore_X_Rectangle) * num); + if (!rects) + { + XFree(rect); + if (num_ret) *num_ret = 0; + return NULL; + } + 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 Ecore_X_Rectangle * +ecore_x_window_shape_input_rectangles_get(Ecore_X_Window win, + int *num_ret) +{ + Ecore_X_Rectangle *rects = NULL; +#ifdef ShapeInput + XRectangle *rect; + int i, num = 0, ord; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeInput, &num, &ord); + if (rect) + { + if (num < 1) + { + XFree(rect); + if (num_ret) *num_ret = 0; + return NULL; + } + rects = malloc(sizeof(Ecore_X_Rectangle) * num); + if (!rects) + { + XFree(rect); + if (num_ret) *num_ret = 0; + return NULL; + } + 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; +#else + // have to return fake shape input rect of size of window + Window dw; + unsigned int di; + + if (num_ret) *num_ret = 0; + rects = malloc(sizeof(Ecore_X_Rectangle)); + if (!rects) return NULL; + if (!XGetGeometry(_ecore_x_disp, win, &dw, + &(rects[0].x), &(rects[0].y), + &(rects[0].width), &(rects[0].height), + &di, &di)) + { + free(rects); + return NULL; + } + if (num_ret) *num_ret = 1; + return rects; +#endif +} + +EAPI void +ecore_x_window_shape_events_select(Ecore_X_Window win, + Eina_Bool on) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (on) + XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask); + else + XShapeSelectInput(_ecore_x_disp, win, 0); +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_xi2.c b/src/lib/ecore_x/xlib/ecore_x_xi2.c new file mode 100644 index 0000000000..04d1023ec7 --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_xi2.c @@ -0,0 +1,336 @@ +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#include + +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" + +#ifdef ECORE_XI2 +#include "Ecore_Input.h" +#endif /* ifdef ECORE_XI2 */ + +int _ecore_x_xi2_opcode = -1; + +#ifndef XIPointerEmulated +#define XIPointerEmulated (1 << 16) +#endif + +#ifdef ECORE_XI2 +static XIDeviceInfo *_ecore_x_xi2_devs = NULL; +static int _ecore_x_xi2_num = 0; +#endif /* ifdef ECORE_XI2 */ + +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 /* ifdef ECORE_XI2 */ +} + +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 /* ifdef ECORE_XI2 */ +} + +void +_ecore_x_input_handler(XEvent *xevent) +{ +#ifdef ECORE_XI2 + XIDeviceEvent *evd = (XIDeviceEvent *)(xevent->xcookie.data); + /* XIRawEvent *evr = (XIRawEvent *)(xevent->xcookie.data); */ + int devid = evd->deviceid; + int i; + + /* No filter for this events */ + switch (xevent->xcookie.evtype) + { +#ifdef XI_RawButtonPress + case XI_RawButtonPress: + ecore_event_add(ECORE_X_RAW_BUTTON_PRESS, NULL, NULL, NULL); + break; +#endif +#ifdef XI_RawButtonRelease + case XI_RawButtonRelease: + ecore_event_add(ECORE_X_RAW_BUTTON_RELEASE, NULL, NULL, NULL); + break; +#endif +#ifdef XI_RawMotion + case XI_RawMotion: + ecore_event_add(ECORE_X_RAW_MOTION, NULL, NULL, NULL); + break; +#endif + } + + if (_ecore_x_xi2_devs) + { + for (i = 0; i < _ecore_x_xi2_num; i++) + { + XIDeviceInfo *dev = &(_ecore_x_xi2_devs[i]); + + if (devid == dev->deviceid) + { + if (dev->use == XIMasterPointer) return; + if ((dev->use == XISlavePointer) && + (evd->flags & XIPointerEmulated)) return; + } + } + } + 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; + +#ifdef XI_TouchUpdate + case XI_TouchUpdate: + _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; + +#endif +#ifdef XI_TouchBegin + case XI_TouchBegin: + _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; + +#endif +#ifdef XI_TouchEnd + case XI_TouchEnd: + _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 + default: + break; + } +#endif /* ifdef ECORE_XI2 */ +} + +EAPI Eina_Bool +ecore_x_input_multi_select(Ecore_X_Window win) +{ +#ifdef ECORE_XI2 + int i; + Eina_Bool find = EINA_FALSE; + + 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[4] = { 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 = EINA_TRUE; + } + else if (dev->use == XISlavePointer) + { + XIDeviceInfo *atdev = NULL; + int j; + + for (j = 0; j < _ecore_x_xi2_num; j++) + { + if (_ecore_x_xi2_devs[j].deviceid == dev->attachment) + atdev = &(_ecore_x_xi2_devs[j]); + } + if (((atdev) && (atdev->use != XIMasterPointer)) || + (!atdev)) + { + XIEventMask eventmask; + unsigned char mask[4] = { 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); +# ifdef XI_TouchUpdate + XISetMask(mask, XI_TouchUpdate); +# endif +# ifdef XI_TouchBegin + XISetMask(mask, XI_TouchBegin); +# endif +# ifdef XI_TouchEnd + XISetMask(mask, XI_TouchEnd); +# endif + XISelectEvents(_ecore_x_disp, win, &eventmask, 1); + find = EINA_TRUE; + } + } + } + + return find; +#else /* ifdef ECORE_XI2 */ + return EINA_FALSE; +#endif /* ifdef ECORE_XI2 */ +} + +EAPI Eina_Bool +ecore_x_input_raw_select(Ecore_X_Window win) +{ +#ifdef ECORE_XI2 + XIEventMask emask; + unsigned char mask[4] = { 0 }; + + if (!_ecore_x_xi2_devs) + return EINA_FALSE; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + emask.deviceid = XIAllMasterDevices; + emask.mask_len = sizeof(mask); + emask.mask = mask; +#ifdef XI_RawButtonPress + XISetMask(emask.mask, XI_RawButtonPress); +#endif +#ifdef XI_RawButtonRelease + XISetMask(emask.mask, XI_RawButtonRelease); +#endif +#ifdef XI_RawMotion + XISetMask(emask.mask, XI_RawMotion); +#endif + + XISelectEvents(_ecore_x_disp, win, &emask, 1); + + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + diff --git a/src/lib/ecore_x/xlib/ecore_x_xinerama.c b/src/lib/ecore_x/xlib/ecore_x_xinerama.c new file mode 100644 index 0000000000..f49a4d348f --- /dev/null +++ b/src/lib/ecore_x/xlib/ecore_x_xinerama.c @@ -0,0 +1,91 @@ +/* + * Xinerama code + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* ifdef HAVE_CONFIG_H */ + +#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 /* ifdef ECORE_XINERAMA */ + +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 /* ifdef ECORE_XINERAMA */ + return 0; +} + +EAPI Eina_Bool +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 EINA_TRUE; + } + } + } + +#endif /* ifdef ECORE_XINERAMA */ + 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 EINA_FALSE; + screen = 0; +} + diff --git a/src/lib/escape/Escape.h b/src/lib/escape/Escape.h new file mode 100644 index 0000000000..ca728b50b7 --- /dev/null +++ b/src/lib/escape/Escape.h @@ -0,0 +1,52 @@ +#ifndef __ESCAPE_H__ +#define __ESCAPE_H__ + +#ifndef EAPI +#define EAPI +#endif /* EAPI */ +#define __UNUSED__ __attribute__((unused)) + +#include + +#ifdef CLOCK_REALTIME +#undef CLOCK_REALTIME +#endif +#ifdef CLOCK_PROF +#undef CLOCK_PROF +#endif +#ifdef CLOCK_PROCESS_CPUTIME_ID +#undef CLOCK_PROCESS_CPUTIME_ID +#endif + +/** + * @mainpage Escape + * @image html e_big.png + * @author Youness Alaoui + * @date 2011 + * + * @section intro_sec Introduction + * + * The Escape library is a library that acts implements some of the missing + * function from the PS3 GameOS system that are needed for the proper + * functioning of the EFL. + * + * @section escape_sec Escape API Documentation + * + * Take a look at the documentation of @ref mmap/munmap. + * + */ + +#include "escape_libgen.h" +#include "escape_unistd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Nothing to see here */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESCAPE_H__ */ diff --git a/src/lib/escape/escape_libgen.c b/src/lib/escape/escape_libgen.c new file mode 100644 index 0000000000..796708978e --- /dev/null +++ b/src/lib/escape/escape_libgen.c @@ -0,0 +1,90 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include + +#include "Escape.h" + +static char _escape_basename_buf[PATH_MAX]; +static char _escape_dirname_buf[PATH_MAX]; + +char * +escape_basename(char *path) +{ + char *p1; + char *p2; + size_t length; + + /* path must begin by "?:\" or "?:/" */ + if (!path || strlen(path) <= 1) + { + memcpy(_escape_basename_buf, path, PATH_MAX); + return _escape_basename_buf; + } + + length = strlen(path); + p1 = strdup(path); + if (!p1) + { + memcpy(_escape_basename_buf, path, PATH_MAX); + return _escape_basename_buf; + } + + /* remove trailing backslashes */ + p2 = p1 + (length - 1); + if (*p2 == '/') + { + while (*p2 == '/') + p2--; + } + *(p2 + 1) = '\0'; + + p2 = strrchr(p1, '/'); + memcpy(_escape_basename_buf, p2 + 1, (p1 + length + 1) - p2); + + free(p1); + + return _escape_basename_buf; +} + +char * +escape_dirname(char *path) +{ + char *p1; + char *p2; + size_t length; + + /* path must begin by "?:\" or "?:/" */ + if (!path || strlen(path) <= 1) + { + memcpy(_escape_dirname_buf, path, PATH_MAX); + return _escape_dirname_buf; + } + + length = strlen(path); + p1 = strdup(path); + if (!p1) + { + memcpy(_escape_dirname_buf, path, PATH_MAX); + return _escape_dirname_buf; + } + /* remove trailing backslashes */ + p2 = p1 + (length - 1); + if (*p2 == '/') + { + while (*p2 == '/') + p2--; + } + *(p2 + 1) = '\0'; + + p2 = strrchr(p1, '/'); + *p2 = '\0'; + memcpy(_escape_dirname_buf, p1, strlen(p1) + 1); + + free(p1); + + return _escape_dirname_buf; +} + diff --git a/src/lib/escape/escape_libgen.h b/src/lib/escape/escape_libgen.h new file mode 100644 index 0000000000..0c23a76821 --- /dev/null +++ b/src/lib/escape/escape_libgen.h @@ -0,0 +1,32 @@ +#ifndef __ESCAPE_LIBGEN_H__ +#define __ESCAPE_LIBGEN_H__ + +/** + * @file escape_libgen.h + * @brief The file that provides functions ported from Unix in libgen.h. + * @defgroup Escape_Libgen_Group Libgen.h functions. + * + * This header provides functions ported from Unix in libgen.h. + * + * @{ + */ + +EAPI char *escape_basename(char *path); + +#ifdef basename +#undef basename +#endif +#define basename(p) escape_basename(p) + +EAPI char *escape_dirname(char *path); + +#ifdef dirname +#undef dirname +#endif +#define dirname(p) escape_dirname(p) + +/** + * @} + */ + +#endif /* __ESCAPE_LIBGEN_H__ */ diff --git a/src/lib/escape/escape_mman.c b/src/lib/escape/escape_mman.c new file mode 100644 index 0000000000..995c72e7f4 --- /dev/null +++ b/src/lib/escape/escape_mman.c @@ -0,0 +1,67 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include + +#include "sys/mman.h" + +/***** API *****/ + +void * +mmap(void *addr __UNUSED__, + size_t len, + int prot, + int flags, + int fd, + off_t offset) +{ + void *data; + size_t size; + + data = malloc(len); + if (!data) + { + fprintf (stderr, "[Escape] [mmap] malloc failed\n"); + return MAP_FAILED; + } + + size = read(fd, data, len); + if (size != len) + { + fprintf (stderr, "[Escape] [mmap] read failed\n"); + free(data); + return MAP_FAILED; + } + + if (lseek(fd, -len, SEEK_CUR) == -1) + { + fprintf (stderr, "[Escape] [mmap] lseek failed\n"); + free(data); + return MAP_FAILED; + } + + return data; +} + +int +munmap(void *addr, + size_t len __UNUSED__) +{ + if (addr && (addr != MAP_FAILED)) + free(addr); + + return 0; +} + +int +madvise(void *addr __UNUSED__, + size_t length __UNUSED__, + int advice __UNUSED__) +{ + return 0; +} + diff --git a/src/lib/escape/escape_unistd.c b/src/lib/escape/escape_unistd.c new file mode 100644 index 0000000000..5dbbb18634 --- /dev/null +++ b/src/lib/escape/escape_unistd.c @@ -0,0 +1,186 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_ERRNO_H +#include +#endif /* HAVE_ERRNO_H */ + +#include /* See NOTES */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Escape.h" + +char * +escape_realpath(const char *path, char *resolved_path) +{ + char *real = lrealpath (path); + + if (real) + { + if (resolved_path) + { + memcpy (resolved_path, real, PATH_MAX); + free (real); + return resolved_path; + } + else + { + return real; + } + } + + return NULL; +} + +int +escape_access(const char *pathname, int mode) +{ + struct stat stat_buf; + + if (stat(pathname, &stat_buf) != 0) + return -1; + + if (mode == F_OK) + return 0; + if (mode == R_OK) + { + if (stat_buf.st_mode & S_IRUSR) + return 0; + errno = EACCES; + return -1; + } + if (mode == W_OK) + { + if (stat_buf.st_mode & S_IWUSR) + return 0; + errno = EROFS; + return -1; + } + if (mode == X_OK) + { + if (stat_buf.st_mode & S_IXUSR) + return 0; + errno = EACCES; + return -1; + } + + return 0; +} + +EAPI ssize_t +escape_readlink(const char *path, + char *buf, + size_t bufsize) +{ + errno = EINVAL; + return -1; +} + +EAPI int +escape_symlink(const char *path1, const char *path2) +{ + errno = EINVAL; + return -1; +} + +/* + * The code of the following functions has been kindly offered + * by Tor Lillqvist. + */ +int +escape_pipe(int *fds) +{ + struct sockaddr_in saddr; + int temp; + int socket1 = -1; + int socket2 = -1; + fd_set read_set; + fd_set write_set; + int len; + + temp = socket (AF_INET, SOCK_STREAM, 0); + + if (temp == -1) + goto out0; + + memset (&saddr, 0, sizeof (saddr)); + saddr.sin_family = AF_INET; + saddr.sin_port = 0; + saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + if (bind (temp, (struct sockaddr *)&saddr, sizeof (saddr))) + goto out0; + + if (listen (temp, 1) == -1) + goto out0; + + len = sizeof (saddr); + if (getsockname (temp, (struct sockaddr *)&saddr, &len)) + goto out0; + + socket1 = socket (AF_INET, SOCK_STREAM, 0); + + if (socket1 == -1) + goto out0; + + if ((connect (socket1, (struct sockaddr *)&saddr, len) == -1) && + (errno != EAGAIN)) + goto out1; + + FD_ZERO (&read_set); + FD_SET (temp, &read_set); + + if (select (0, &read_set, NULL, NULL, NULL) == -1) + goto out1; + + if (!FD_ISSET (temp, &read_set)) + goto out1; + + socket2 = accept (temp, (struct sockaddr *)&saddr, &len); + if (socket2 == -1) + goto out1; + + FD_ZERO (&write_set); + FD_SET (socket1, &write_set); + + if (select (0, NULL, &write_set, NULL, NULL) == -1) + goto out2; + + if (!FD_ISSET (socket1, &write_set)) + goto out2; + + fds[0] = socket1; + fds[1] = socket2; + + closesocket (temp); + + return 0; + +out2: + closesocket (socket2); +out1: + closesocket (socket1); +out0: + closesocket (temp); + + fds[0] = -1; + fds[1] = -1; + + return -1; +} + +#undef access +int +access(const char *pathname, int mode) +{ + return escape_access (pathname, mode); +} + diff --git a/src/lib/escape/escape_unistd.h b/src/lib/escape/escape_unistd.h new file mode 100644 index 0000000000..0e96d3f3cb --- /dev/null +++ b/src/lib/escape/escape_unistd.h @@ -0,0 +1,107 @@ +#ifndef __ESCAPE_UNISTD_H__ +#define __ESCAPE_UNISTD_H__ + +/** + * @file escape_unistd.h + * @brief The file that provides functions ported from Unix in unistd.h. + * @defgroup Escape_Unistd_Group Unistd.h functions + * + * This header provides functions ported from Unix in unistd.h. + * + * @{ + */ + +#include + +/* Path function */ +/** + * @brief return the canonicalized absolute pathname + * + * @param path A path to canonicalize + * @param resolved_path A pointer of size PATH_MAX where to store the result + * + * realpath() expands all symbolic links and resolves references to /./, /../ + * and extra '/' characters in the null-terminated string named by path to + * produce a canonicalized absolute pathname. The resulting pathname is + * stored as a null-terminated string, up to a maximum of PATH_MAX bytes, + * in the buffer pointed to by resolved_path. The resulting path will have + * no symbolic link, /./ or /../ components. + * + * If resolved_path is specified as NULL, then realpath() uses malloc(3) + * to allocate a buffer of up to PATH_MAX bytes to hold the resolved pathname, + * and returns a pointer to this buffer. + * The caller should deallocate this buffer using free(3). + * + */ +EAPI char *escape_realpath(const char *path, char *resolved_path); +#ifdef realpath +#undef realpath +#endif +#define realpath escape_realpath + +EAPI ssize_t +escape_readlink(const char *path, + char *buf, + size_t bufsize); +#ifdef readlink +#undef readlink +#endif +#define readlink escape_readlink + +EAPI int +escape_symlink(const char *path1, const char *path2); +#ifdef symlink +#undef symlink +#endif +#define symlink escape_symlink + +/** + * @brief check real user's permissions for a file + * + * @param pathname The path to check + * @param mode the permission to check + * + * access() checks whether the calling process can access the file pathname. + * If pathname is a symbolic link, it is dereferenced. + * The mode specifies the accessibility check(s) to be performed, and is either + * the value F_OK, or a mask consisting of the bitwise OR of one or more + * of R_OK, W_OK, and X_OK. F_OK tests for the existence of the file. + * R_OK, W_OK, and X_OK test whether the file exists and grants read, write, + * and execute permissions, respectively. + * + */ +EAPI int +escape_access(const char *pathname, int mode); +#ifdef access +#undef access +#endif +#define access escape_access + +/** + * @brief Create a pair of sockets. + * + * @param fds A pointer that contains two sockets. + * + * Create a pair of sockets that can be use with select(). + * Contrary to Unix, that functions does not + * create a pair of file descriptors. + * + * Conformity: Not applicable. + */ +EAPI int +escape_pipe(int *fds); + +/** + * @def pipe(fds) + * + * Wrapper around escape_pipe(). + */ +#define pipe(fds) escape_pipe(fds) + +//#define sync() + +/** + * @} + */ + +#endif /* __ESCAPE_UNISTD_H__ */ diff --git a/src/lib/escape/sys/mman.h b/src/lib/escape/sys/mman.h new file mode 100644 index 0000000000..98ef7fa5fc --- /dev/null +++ b/src/lib/escape/sys/mman.h @@ -0,0 +1,179 @@ +#ifndef __ESCAPE_SYS_MMAN_H__ +#define __ESCAPE_SYS_MMAN_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @def PROT_NONE + * Data can not be accessed. + */ + +/** + * @def PROT_READ + * Data can be read. + */ + +/** + * @def PROT_WRITE + * Data can be written. + */ + +/** + * @def PROT_EXEC + * Data can be executed. + */ + +#define PROT_NONE 0x00 +#define PROT_READ 0x01 +#define PROT_WRITE 0x02 +#define PROT_EXEC 0x04 + +/** + * @def MAP_SHARED + * Changes are shared. + */ + +/** + * @def MAP_PRIVATE + * Changes are private. + */ + +/** + * @def MAP_FIXED + * Interpret the address (addr) exactly. + */ + +/** + * @def MAP_FAILED + * Error return from mmap(). + */ + +#define MAP_SHARED 0x0001 +#define MAP_PRIVATE 0x0002 +#define MAP_FIXED 0x0010 + +#define MAP_FAILED ((void *)-1) + +/** + * @file mman.h + * @brief The file that provides the memory map functions + * @defgroup Mman Functions that manage memory mappping. + * + * This header provides the meomry map functions mmap and munmap. + * + */ + +/** + * Creates or opens a named or unnamed file mapping object for a + * specified file and maps a view of a file mapping into the + * address space of a calling process. + * + * @param addr Unused + * @param len Number of bytes to be mapped. + * @param prot Protections. + * @param flags Type of the mapped object. + * @param fd File descriptor that describes the object to map. + * @param offset Number of bytes from which to start the mapping. + * @return The starting address of the mapped view on success, -1 otherwise. + * + * Create or open an unnamed file mapping object for a specified + * file described by the file descriptor @p fd. The number of + * bytes that are mapped is given by @p len and start after + * @p offset bytes. The parameter @p addr is unused. + * + * The only type of the mapped object that is supported is + * @c MAP_SHARED. If another value if given, -1 is returned. + * + * @p prot specifies the protection of the mapped region. If + * PROT_EXEC is used, it set the execute access. If PROT_READ + * is used, it sets the read access. If PROT_WRITE is used, it + * sets the write access. + * + * If the map view of file can not be created, -1 is returned. + * If the mappping can not be done, -1 is returned. + * + * If no error occured, the starting address of the mapped view + * is returned. + * + * Conformity: None. + * + * @ingroup Mman + */ +EAPI void *mmap(void *addr, + size_t len, + int prot, + int flags, + int fd, + off_t offset); + +/** + * Unmaps a mapped view of a file from the calling process's + * address space. + * + * @param addr Pointer to the base address. + * @param len Unused. + * @return 0 on success, -1 otherwise. + * + * Unmaps a mapped view of a file from the calling process's + * address space. @p addr is the pointer to the base address. + * This value must be identical to the value returned by a + * previous call to mmap(). The parameter @p len is unsed. + * + * Conformity: None. + * + * @ingroup Mman + */ +EAPI int +munmap(void *addr, + size_t len); + +# define MADV_NORMAL 0 /* No further special treatment. */ +# define MADV_RANDOM 1 /* Expect random page references. */ +# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */ +# define MADV_WILLNEED 3 /* Will need these pages. */ +# define MADV_DONTNEED 4 /* Don't need these pages. */ +# define MADV_REMOVE 9 /* Remove these pages and resources. */ +# define MADV_DONTFORK 10 /* Do not inherit across fork. */ +# define MADV_DOFORK 11 /* Do inherit across fork. */ +# define MADV_MERGEABLE 12 /* KSM may merge identical pages. */ +# define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages. */ +# define MADV_HUGEPAGE 14 /* Worth backing with hugepages. */ +# define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages. */ +# define MADV_HWPOISON 100 /* Poison a page for testing. */ + +/** + * give advice about use of memory + * + * @param addr Unused. + * @param length Unused. + * @param advice Unused. + * @return 0 on success, -1 otherwise. + * + * The madvise() system call advises the kernel about how to handle + * paging input/output in the address range beginning at address addr and + * with size length bytes. It allows an application to tell the kernel + * how it expects to use some mapped or shared memory areas, so that + * the kernel can choose appropriate read-ahead and caching techniques. + * This call does not influence the semantics of the application (except + * in the case of MADV_DONTNEED), but may influence its performance. + * The kernel is free to ignore the advice. + + * Conformity: None. + * + * @ingroup Mman + */ +EAPI int +madvise(void *addr, + size_t length, + int advice); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESCAPE_SYS_MMAN_H__ */ + diff --git a/src/modules/ecore/immodules/ibus/ibus_imcontext.c b/src/modules/ecore/immodules/ibus/ibus_imcontext.c new file mode 100644 index 0000000000..02f4fce9c1 --- /dev/null +++ b/src/modules/ecore/immodules/ibus/ibus_imcontext.c @@ -0,0 +1,822 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include "ibus_imcontext.h" + +struct _IBusIMContext +{ + /* instance members */ + Ecore_IMF_Context *ctx; + + /* enabled */ + Eina_Bool enable; + IBusInputContext *ibuscontext; + + /* preedit status */ + char *preedit_string; + Eina_List *preedit_attrs; + int preedit_cursor_pos; + Eina_Bool preedit_visible; + + int cursor_x; + int cursor_y; + int cursor_w; + int cursor_h; + + Eina_Bool has_focus; + + Ecore_X_Window client_window; + Evas *client_canvas; + + int caps; +}; + +typedef struct _KeyEvent KeyEvent; + +struct _KeyEvent +{ + int keysym; + int state; +}; + +static Eina_Bool _use_sync_mode = EINA_FALSE; + +static Ecore_IMF_Context *_focus_im_context = NULL; +static IBusBus *_bus = NULL; + +/* functions prototype */ +/* static methods*/ +static void _create_input_context (IBusIMContext *context); +static void _set_cursor_location_internal +(Ecore_IMF_Context *ctx); +static void _bus_connected_cb (IBusBus *bus, + IBusIMContext *context); +static XKeyEvent createXKeyEvent (Window win, Eina_Bool press, int keysym, int modifiers); + +static void +_window_to_screen_geometry_get(Ecore_X_Window client_win, int *x, int *y) +{ + Ecore_X_Window root_window, win; + int win_x, win_y; + int sum_x = 0, sum_y = 0; + + root_window = ecore_x_window_root_get(client_win); + win = client_win; + + while (root_window != win) + { + ecore_x_window_geometry_get(win, &win_x, &win_y, NULL, NULL); + sum_x += win_x; + sum_y += win_y; + win = ecore_x_window_parent_get(win); + } + + if (x) + *x = sum_x; + if (y) + *y = sum_y; +} + +static unsigned int +_ecore_imf_modifier_to_ibus_modifier(unsigned int modifier) +{ + unsigned int state = 0; + + /**< "Control" is pressed */ + if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) + state |= IBUS_CONTROL_MASK; + + /**< "Alt" is pressed */ + if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_ALT) + state |= IBUS_MOD1_MASK; + + /**< "Shift" is pressed */ + if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) + state |= IBUS_SHIFT_MASK; + + /**< "Win" (between "Ctrl" and "Alt") */ + if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_WIN) + state |= IBUS_SUPER_MASK; + + /**< "AltGr" is pressed */ + if (modifier & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) + state |= IBUS_MOD5_MASK; + + return state; +} + +static void +key_event_put(int keysym, int state) +{ + // Find the window which has the current keyboard focus. + Window winFocus = 0; + int revert = RevertToParent; + + XGetInputFocus(ecore_x_display_get(), &winFocus, &revert); + + XKeyEvent event; + if (state & IBUS_RELEASE_MASK) + { + event = createXKeyEvent(winFocus, EINA_FALSE, keysym, state); + XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event); + } + else + { + event = createXKeyEvent(winFocus, EINA_TRUE, keysym, state); + XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); + } +} + +static KeyEvent * +key_event_copy(int keysym, int state) +{ + KeyEvent *kev = calloc(1, sizeof(KeyEvent)); + kev->keysym = keysym; + kev->state = state; + + return kev; +} + +IBusIMContext * +ibus_im_context_new(void) +{ + EINA_LOG_DBG("%s", __FUNCTION__); + + IBusIMContext *context = calloc(1, sizeof(IBusIMContext)); + + /* init bus object */ + if (_bus == NULL) + { + char *display_name = NULL; + + if ((display_name = getenv("DISPLAY"))) + ibus_set_display(display_name); + else + ibus_set_display(":0.0"); + + _bus = ibus_bus_new(); + } + + return context; +} + +static void +_process_key_event_done(GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + IBusInputContext *context = (IBusInputContext *)object; + KeyEvent *event = (KeyEvent *)user_data; + + GError *error = NULL; + Eina_Bool retval = ibus_input_context_process_key_event_async_finish(context, + res, + &error); + + if (error != NULL) + { + g_warning("Process Key Event failed: %s.", error->message); + g_error_free(error); + } + + if (retval == EINA_FALSE) + { + key_event_put(event->keysym, event->state); + } + free(event); +} + +EAPI void +ibus_im_context_add(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("%s", __FUNCTION__); + + char *s = NULL; + IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + ibusimcontext->client_window = 0; + + // Init ibus status + ibusimcontext->enable = EINA_FALSE; + + // Init preedit status + ibusimcontext->preedit_string = NULL; + ibusimcontext->preedit_attrs = NULL; + ibusimcontext->preedit_cursor_pos = 0; + ibusimcontext->preedit_visible = EINA_FALSE; + + // Init cursor area + ibusimcontext->cursor_x = -1; + ibusimcontext->cursor_y = -1; + ibusimcontext->cursor_w = 0; + ibusimcontext->cursor_h = 0; + + ibusimcontext->ibuscontext = NULL; + ibusimcontext->has_focus = EINA_FALSE; + ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT; + ibusimcontext->ctx = ctx; + + s = getenv("IBUS_ENABLE_SYNC_MODE"); + if (s) + _use_sync_mode = !!atoi(s); + + if (ibus_bus_is_connected(_bus)) + _create_input_context (ibusimcontext); + + g_signal_connect(_bus, "connected", G_CALLBACK (_bus_connected_cb), ctx); +} + +EAPI void +ibus_im_context_del(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("%s", __FUNCTION__); + + IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + g_signal_handlers_disconnect_by_func(_bus, G_CALLBACK(_bus_connected_cb), ctx); + + if (ibusimcontext->ibuscontext) + ibus_proxy_destroy((IBusProxy *)ibusimcontext->ibuscontext); + + // release preedit + if (ibusimcontext->preedit_string) + free(ibusimcontext->preedit_string); + if (_focus_im_context == ctx) + _focus_im_context = NULL; +} + +EAPI Eina_Bool +ibus_im_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event) +{ + IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN_VAL(ibusimcontext, EINA_FALSE); + + if (type != ECORE_IMF_EVENT_KEY_UP && type != ECORE_IMF_EVENT_KEY_DOWN) + return EINA_FALSE; + + EINA_LOG_DBG("%s", __FUNCTION__); + + if (G_LIKELY(ibusimcontext->ibuscontext && ibusimcontext->has_focus)) + { + /* If context does not have focus, ibus will process key event in sync mode. + * It is a workaround for increase search in treeview. + */ + Eina_Bool retval = EINA_FALSE; + int keycode; + int keysym; + unsigned int state = 0; + + if (type == ECORE_IMF_EVENT_KEY_UP) + { + Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event; + if (ev->timestamp == 0) + return EINA_FALSE; + + keycode = ecore_x_keysym_keycode_get(ev->key); + keysym = XStringToKeysym(ev->key); + state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers) | IBUS_RELEASE_MASK; + + if (_use_sync_mode) + { + retval = ibus_input_context_process_key_event(ibusimcontext->ibuscontext, + keysym, + keycode - 8, + state); + } + else + { + ibus_input_context_process_key_event_async(ibusimcontext->ibuscontext, + keysym, + keycode - 8, + state, + -1, + NULL, + _process_key_event_done, + key_event_copy(keysym, state)); + retval = EINA_TRUE; + } + } + else if (type == ECORE_IMF_EVENT_KEY_DOWN) + { + Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; + if (ev->timestamp == 0) + return EINA_FALSE; + + keycode = ecore_x_keysym_keycode_get(ev->key); + keysym = XStringToKeysym(ev->key); + state = _ecore_imf_modifier_to_ibus_modifier(ev->modifiers); + if (_use_sync_mode) + { + retval = ibus_input_context_process_key_event(ibusimcontext->ibuscontext, + keysym, + keycode - 8, + state); + } + else + { + ibus_input_context_process_key_event_async(ibusimcontext->ibuscontext, + keysym, + keycode - 8, + state, + -1, + NULL, + _process_key_event_done, + key_event_copy(keysym, state)); + retval = EINA_TRUE; + } + } + else + retval = EINA_FALSE; + + if (retval) + return EINA_TRUE; + else + return EINA_FALSE; + } + else + return EINA_FALSE; +} + +EAPI void +ibus_im_context_focus_in(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("ctx : %p", ctx); + + IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->has_focus) + return; + + if (_focus_im_context != NULL) + ecore_imf_context_focus_out(_focus_im_context); + + ibusimcontext->has_focus = EINA_TRUE; + if (ibusimcontext->ibuscontext) + ibus_input_context_focus_in(ibusimcontext->ibuscontext); + + if (_focus_im_context != ctx) + _focus_im_context = ctx; +} + +EAPI void +ibus_im_context_focus_out(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("ctx : %p", ctx); + + IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->has_focus == EINA_FALSE) + return; + + if (_focus_im_context == ctx) + _focus_im_context = NULL; + + ibusimcontext->has_focus = EINA_FALSE; + if (ibusimcontext->ibuscontext) + ibus_input_context_focus_out(ibusimcontext->ibuscontext); +} + +EAPI void +ibus_im_context_reset(Ecore_IMF_Context *ctx) +{ + IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->ibuscontext) + ibus_input_context_reset(ibusimcontext->ibuscontext); +} + +EAPI void +ibus_im_context_preedit_string_get(Ecore_IMF_Context *ctx, + char **str, + int *cursor_pos) +{ + IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->enable && ibusimcontext->preedit_visible) + { + if (str) + *str = strdup(ibusimcontext->preedit_string ? ibusimcontext->preedit_string: ""); + + if (cursor_pos) + *cursor_pos = ibusimcontext->preedit_cursor_pos; + } + else + { + if (str) + *str = strdup(""); + + if (cursor_pos) + *cursor_pos = 0; + } + EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos); +} + +EAPI void +ibus_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, + char **str, + Eina_List **attr EINA_UNUSED, + int *cursor_pos) +{ + IBusIMContext *ibusimcontext = (IBusIMContext*)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->enable && ibusimcontext->preedit_visible) + { + if (str) + *str = strdup(ibusimcontext->preedit_string ? ibusimcontext->preedit_string: ""); + + if (cursor_pos) + *cursor_pos = ibusimcontext->preedit_cursor_pos; + } + else + { + if (str) + *str = strdup(""); + + if (cursor_pos) + *cursor_pos = 0; + } + EINA_LOG_DBG("str : %s, cursor_pos : %d", *str, *cursor_pos); +} + +EAPI void +ibus_im_context_client_window_set(Ecore_IMF_Context *ctx, void *window) +{ + EINA_LOG_DBG("canvas : %p", window); + IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (window != NULL) + ibusimcontext->client_window = (Ecore_X_Window)(Ecore_Window)window; +} + +EAPI void +ibus_im_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas) +{ + EINA_LOG_DBG("canvas : %p", canvas); + IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (canvas != NULL) + ibusimcontext->client_canvas = canvas; +} + +static void +_set_cursor_location_internal(Ecore_IMF_Context *ctx) +{ + IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); + Ecore_Evas *ee; + int canvas_x, canvas_y; + + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->ibuscontext == NULL) + return; + + if (ibusimcontext->client_canvas) + { + ee = ecore_evas_ecore_evas_get(ibusimcontext->client_canvas); + if (!ee) return; + + ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL); + } + else + { + if (ibusimcontext->client_window) + _window_to_screen_geometry_get(ibusimcontext->client_window, &canvas_x, &canvas_y); + else + return; + } + + ibus_input_context_set_cursor_location(ibusimcontext->ibuscontext, + ibusimcontext->cursor_x + canvas_x, + ibusimcontext->cursor_y + canvas_y, + ibusimcontext->cursor_w, + ibusimcontext->cursor_h); +} + +EAPI void +ibus_im_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int w, int h) +{ + EINA_LOG_DBG("x : %d, y : %d, w, %d, h :%d", x, y, w, h); + IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->cursor_x != x || + ibusimcontext->cursor_y != y || + ibusimcontext->cursor_w != w || + ibusimcontext->cursor_h != h) + { + ibusimcontext->cursor_x = x; + ibusimcontext->cursor_y = y; + ibusimcontext->cursor_w = w; + ibusimcontext->cursor_h = h; + + _set_cursor_location_internal(ctx); + } +} + +EAPI void +ibus_im_context_use_preedit_set(Ecore_IMF_Context *ctx, Eina_Bool use_preedit) +{ + EINA_LOG_DBG("preedit : %d", use_preedit); + IBusIMContext *ibusimcontext = (IBusIMContext *)ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->ibuscontext) + { + if (use_preedit) + ibusimcontext->caps |= IBUS_CAP_PREEDIT_TEXT; + else + ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT; + + ibus_input_context_set_capabilities(ibusimcontext->ibuscontext, ibusimcontext->caps); + } +} + +static void +_bus_connected_cb(IBusBus *bus EINA_UNUSED, + IBusIMContext *ibusimcontext) +{ + EINA_LOG_DBG("ibus is connected"); + + if (ibusimcontext) + _create_input_context(ibusimcontext); +} + +static void +_ibus_context_commit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED, + IBusText *text, + IBusIMContext *ibusimcontext) +{ + if (!ibusimcontext || !text) return; + char *commit_str = text->text ? text->text : ""; + + EINA_LOG_DBG("commit string : %s", commit_str); + + if (ibusimcontext->ctx) + { + ecore_imf_context_commit_event_add(ibusimcontext->ctx, text->text); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)commit_str); + } +} + +static XKeyEvent createXKeyEvent(Window win, Eina_Bool press, int keysym, int modifiers) +{ + XKeyEvent event; + Display *display = ecore_x_display_get(); + + event.display = display; + event.window = win; + event.root = ecore_x_window_root_get(win); + event.subwindow = None; + event.time = 0; + event.x = 1; + event.y = 1; + event.x_root = 1; + event.y_root = 1; + event.same_screen = EINA_TRUE; + event.state = modifiers; + event.keycode = XKeysymToKeycode(display, keysym); + if (press) + event.type = KeyPress; + else + event.type = KeyRelease; + event.send_event = EINA_FALSE; + event.serial = 0; + + return event; +} + +static void +_ibus_context_forward_key_event_cb(IBusInputContext *ibuscontext EINA_UNUSED, + guint keyval, + guint state, + IBusIMContext *ibusimcontext EINA_UNUSED) +{ + EINA_LOG_DBG("keyval : %d, state : %d", keyval, state); + + key_event_put(keyval, state); +} + +static void +_ibus_context_update_preedit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED, + IBusText *text, + gint cursor_pos, + gboolean visible, + IBusIMContext *ibusimcontext) +{ + if (!ibusimcontext || !text) return; + + const char *str; + gboolean flag; + + if (ibusimcontext->preedit_string) + free (ibusimcontext->preedit_string); + + str = text->text; + + if (str) + ibusimcontext->preedit_string = strdup(str); + else + ibusimcontext->preedit_string = strdup(""); + + ibusimcontext->preedit_cursor_pos = cursor_pos; + + EINA_LOG_DBG("string : %s, cursor : %d", ibusimcontext->preedit_string, ibusimcontext->preedit_cursor_pos); + + flag = ibusimcontext->preedit_visible != visible; + ibusimcontext->preedit_visible = visible; + + if (ibusimcontext->preedit_visible) + { + if (flag) + { + ecore_imf_context_preedit_start_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + } + + ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + else + { + if (flag) + { + ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + + ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + } +} + +static void +_ibus_context_show_preedit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED, + IBusIMContext *ibusimcontext) +{ + EINA_LOG_DBG("preedit visible : %d", ibusimcontext->preedit_visible); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->preedit_visible == EINA_TRUE) + return; + + ibusimcontext->preedit_visible = EINA_TRUE; + + // call preedit start + ecore_imf_context_preedit_start_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + + // call preedit changed + ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); +} + +static void +_ibus_context_hide_preedit_text_cb(IBusInputContext *ibuscontext EINA_UNUSED, + IBusIMContext *ibusimcontext) +{ + EINA_LOG_DBG("%s", __FUNCTION__); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + if (ibusimcontext->preedit_visible == EINA_FALSE) + return; + + ibusimcontext->preedit_visible = EINA_FALSE; + + // call preedit changed + ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + + // call preedit end + ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); +} + +static void +_ibus_context_enabled_cb(IBusInputContext *ibuscontext EINA_UNUSED, + IBusIMContext *ibusimcontext) +{ + EINA_LOG_DBG("%s", __FUNCTION__); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + ibusimcontext->enable = EINA_TRUE; +} + +static void +_ibus_context_disabled_cb(IBusInputContext *ibuscontext EINA_UNUSED, + IBusIMContext *ibusimcontext) +{ + EINA_LOG_DBG("%s", __FUNCTION__); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + ibusimcontext->enable = EINA_FALSE; + + /* clear preedit */ + ibusimcontext->preedit_visible = EINA_FALSE; + ibusimcontext->preedit_cursor_pos = 0; + free (ibusimcontext->preedit_string); + ibusimcontext->preedit_string = NULL; + + // call preedit changed + ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + + // call preedit end + ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); +} + +static void +_ibus_context_destroy_cb(IBusInputContext *ibuscontext EINA_UNUSED, + IBusIMContext *ibusimcontext) +{ + EINA_LOG_DBG("%s", __FUNCTION__); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + ibusimcontext->ibuscontext = NULL; + ibusimcontext->enable = EINA_FALSE; + + /* clear preedit */ + ibusimcontext->preedit_visible = EINA_FALSE; + ibusimcontext->preedit_cursor_pos = 0; + free (ibusimcontext->preedit_string); + ibusimcontext->preedit_string = NULL; + + // call preedit changed + ecore_imf_context_preedit_changed_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + + // call preedit end + ecore_imf_context_preedit_end_event_add(ibusimcontext->ctx); + ecore_imf_context_event_callback_call(ibusimcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); +} + +static void +_create_input_context(IBusIMContext *ibusimcontext) +{ + EINA_LOG_DBG("%s", __FUNCTION__); + EINA_SAFETY_ON_NULL_RETURN(ibusimcontext); + + ibusimcontext->ibuscontext = ibus_bus_create_input_context(_bus, "ecore"); + + g_return_if_fail(ibusimcontext->ibuscontext != NULL); + + g_signal_connect(ibusimcontext->ibuscontext, + "commit-text", + G_CALLBACK (_ibus_context_commit_text_cb), + ibusimcontext); + g_signal_connect(ibusimcontext->ibuscontext, + "forward-key-event", + G_CALLBACK (_ibus_context_forward_key_event_cb), + ibusimcontext); + g_signal_connect(ibusimcontext->ibuscontext, + "update-preedit-text", + G_CALLBACK (_ibus_context_update_preedit_text_cb), + ibusimcontext); + g_signal_connect(ibusimcontext->ibuscontext, + "show-preedit-text", + G_CALLBACK (_ibus_context_show_preedit_text_cb), + ibusimcontext); + g_signal_connect(ibusimcontext->ibuscontext, + "hide-preedit-text", + G_CALLBACK (_ibus_context_hide_preedit_text_cb), + ibusimcontext); + g_signal_connect(ibusimcontext->ibuscontext, + "enabled", + G_CALLBACK (_ibus_context_enabled_cb), + ibusimcontext); + g_signal_connect(ibusimcontext->ibuscontext, + "disabled", + G_CALLBACK (_ibus_context_disabled_cb), + ibusimcontext); + g_signal_connect(ibusimcontext->ibuscontext, "destroy", + G_CALLBACK (_ibus_context_destroy_cb), + ibusimcontext); + + ibus_input_context_set_capabilities(ibusimcontext->ibuscontext, ibusimcontext->caps); + + if (ibusimcontext->has_focus) + ibus_input_context_focus_in(ibusimcontext->ibuscontext); +} diff --git a/src/modules/ecore/immodules/ibus/ibus_imcontext.h b/src/modules/ecore/immodules/ibus/ibus_imcontext.h new file mode 100644 index 0000000000..ce5c075c3f --- /dev/null +++ b/src/modules/ecore/immodules/ibus/ibus_imcontext.h @@ -0,0 +1,36 @@ +#ifndef __IBUS_IM_CONTEXT_H_ +#define __IBUS_IM_CONTEXT_H_ + +#include + +typedef struct _IBusIMContext IBusIMContext; + +EAPI void ibus_im_context_add (Ecore_IMF_Context *ctx); +EAPI void ibus_im_context_del (Ecore_IMF_Context *ctx); +EAPI void ibus_im_context_reset (Ecore_IMF_Context *context); +EAPI void ibus_im_context_focus_in(Ecore_IMF_Context *context); +EAPI void ibus_im_context_focus_out(Ecore_IMF_Context *context); +EAPI void ibus_im_context_preedit_string_get + (Ecore_IMF_Context *context, + char **str, + int *cursor_pos); +EAPI void ibus_im_context_preedit_string_with_attributes_get + (Ecore_IMF_Context *context, + char **str, + Eina_List **attr, + int *cursor_pos); + +EAPI void ibus_im_context_cursor_location_set(Ecore_IMF_Context *context, + int x, int y, int w, int h); +EAPI void ibus_im_context_use_preedit_set(Ecore_IMF_Context *context, + Eina_Bool use_preedit); +EAPI void +ibus_im_context_client_window_set(Ecore_IMF_Context *context, void *window); +EAPI void +ibus_im_context_client_canvas_set(Ecore_IMF_Context *context, void *canvas); +EAPI Eina_Bool +ibus_im_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); + +IBusIMContext + *ibus_im_context_new (void); +#endif diff --git a/src/modules/ecore/immodules/ibus/ibus_module.c b/src/modules/ecore/immodules/ibus/ibus_module.c new file mode 100644 index 0000000000..a6e175c3ca --- /dev/null +++ b/src/modules/ecore/immodules/ibus/ibus_module.c @@ -0,0 +1,109 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include + +#include +#include "ibus_imcontext.h" + +#define IBUS_LOCALDIR "" +static const Ecore_IMF_Context_Info ibus_im_info = { + "ibus", + "IBus (Intelligent Input Bus)", + "*", + NULL, + 0 +}; + +static Ecore_IMF_Context_Class ibus_imf_class = { + ibus_im_context_add, /* add */ + ibus_im_context_del, /* del */ + ibus_im_context_client_window_set, /* client_window_set */ + ibus_im_context_client_canvas_set, /* client_canvas_set */ + NULL, /* input_panel_show */ + NULL, /* input_panel_hide */ + ibus_im_context_preedit_string_get, /* get_preedit_string */ + ibus_im_context_focus_in, /* focus_in */ + ibus_im_context_focus_out, /* focus_out */ + ibus_im_context_reset, /* reset */ + NULL, /* cursor_position_set */ + ibus_im_context_use_preedit_set, /* use_preedit_set */ + NULL, /* input_mode_set */ + ibus_im_context_filter_event, /* filter_event */ + ibus_im_context_preedit_string_with_attributes_get, /* preedit_string_with_attribute_get */ + NULL, /* prediction_allow_set */ + NULL, /* autocapital_type_set */ + NULL, /* control panel show */ + NULL, /* control panel hide */ + NULL, /* input_panel_layout_set */ + NULL, /* ibus_im_context_input_panel_layout_get, */ + NULL, /* ibus_im_context_input_panel_language_set, */ + NULL, /* ibus_im_context_input_panel_language_get, */ + ibus_im_context_cursor_location_set, /* cursor_location_set */ + NULL, /* input_panel_imdata_set */ + NULL, /* input_panel_imdata_get */ + NULL, /* input_panel_return_key_type_set */ + NULL, /* input_panel_return_key_disabled_set */ + NULL, /* input_panel_caps_lock_mode_set */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +static Ecore_IMF_Context *im_module_create (void); +static Ecore_IMF_Context *im_module_exit (void); + +static Eina_Bool +im_module_init(void) +{ + ecore_main_loop_glib_integrate(); + ibus_init(); + ecore_imf_module_register(&ibus_im_info, im_module_create, im_module_exit); + + return EINA_TRUE; +} + +static void im_module_shutdown(void) +{ +} + +static Ecore_IMF_Context * +im_module_exit(void) +{ + return NULL; +} + +static Ecore_IMF_Context * +im_module_create() +{ + Ecore_IMF_Context *ctx = NULL; + IBusIMContext *ctxd = NULL; + + ctxd = ibus_im_context_new(); + if (!ctxd) + { + return NULL; + } + + ctx = ecore_imf_context_new(&ibus_imf_class); + if (!ctx) + { + free(ctxd); + return NULL; + } + + ecore_imf_context_data_set(ctx, ctxd); + + return ctx; +} + +EINA_MODULE_INIT(im_module_init); +EINA_MODULE_SHUTDOWN(im_module_shutdown); + diff --git a/src/modules/ecore/immodules/scim/scim_imcontext.cpp b/src/modules/ecore/immodules/scim/scim_imcontext.cpp new file mode 100644 index 0000000000..d4d20b161a --- /dev/null +++ b/src/modules/ecore/immodules/scim/scim_imcontext.cpp @@ -0,0 +1,2900 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#define Uses_SCIM_DEBUG +#define Uses_SCIM_BACKEND +#define Uses_SCIM_IMENGINE_MODULE +#define Uses_SCIM_HOTKEY +#define Uses_SCIM_PANEL_CLIENT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include "scim_imcontext.h" + +using namespace scim; + +struct _EcoreIMFContextISFImpl +{ + EcoreIMFContextISF *parent; + IMEngineInstancePointer si; + Ecore_X_Window client_window; + Evas *client_canvas; + Ecore_IMF_Input_Mode input_mode; + WideString preedit_string; + AttributeList preedit_attrlist; + Ecore_IMF_Autocapital_Type autocapital_type; + int preedit_caret; + int cursor_x; + int cursor_y; + int cursor_pos; + bool use_preedit; + bool is_on; + bool shared_si; + bool preedit_started; + bool preedit_updating; + bool need_commit_preedit; + bool uppercase; + bool prediction_allow; + + EcoreIMFContextISFImpl *next; +}; + +/* Input Context handling functions. */ +static EcoreIMFContextISFImpl *new_ic_impl (EcoreIMFContextISF *parent); +static void delete_ic_impl (EcoreIMFContextISFImpl *impl); +static void delete_all_ic_impl (void); + +static EcoreIMFContextISF *find_ic (int id); + + +/* private functions */ +static void panel_slot_reload_config (int context); +static void panel_slot_exit (int context); +static void panel_slot_update_lookup_table_page_size(int context, + int page_size); +static void panel_slot_lookup_table_page_up (int context); +static void panel_slot_lookup_table_page_down (int context); +static void panel_slot_trigger_property (int context, + const String &property); +static void panel_slot_process_helper_event (int context, + const String &target_uuid, + const String &helper_uuid, + const Transaction &trans); +static void panel_slot_move_preedit_caret (int context, + int caret_pos); +static void panel_slot_select_candidate (int context, + int cand_index); +static void panel_slot_process_key_event (int context, + const KeyEvent &key); +static void panel_slot_commit_string (int context, + const WideString &wstr); +static void panel_slot_forward_key_event (int context, + const KeyEvent &key); +static void panel_slot_request_help (int context); +static void panel_slot_request_factory_menu (int context); +static void panel_slot_change_factory (int context, + const String &uuid); + +static void panel_req_focus_in (EcoreIMFContextISF *ic); +static void panel_req_update_factory_info (EcoreIMFContextISF *ic); +static void panel_req_update_spot_location (EcoreIMFContextISF *ic); +static void panel_req_show_help (EcoreIMFContextISF *ic); +static void panel_req_show_factory_menu (EcoreIMFContextISF *ic); + +/* Panel iochannel handler*/ +static bool panel_initialize (void); +static void panel_finalize (void); +static Eina_Bool panel_iochannel_handler (void *data, + Ecore_Fd_Handler *fd_handler); + +/* utility functions */ +static bool filter_hotkeys (EcoreIMFContextISF *ic, + const KeyEvent &key); +static void turn_on_ic (EcoreIMFContextISF *ic); +static void turn_off_ic (EcoreIMFContextISF *ic); +static void set_ic_capabilities (EcoreIMFContextISF *ic); + +static void initialize (void); +static void finalize (void); + +static void open_next_factory (EcoreIMFContextISF *ic); +static void open_previous_factory (EcoreIMFContextISF *ic); +static void open_specific_factory (EcoreIMFContextISF *ic, + const String &uuid); +static void initialize_modifier_bits (Display *display); +static unsigned int scim_x11_keymask_scim_to_x11 (Display *display, uint16 scimkeymask); +static XKeyEvent createKeyEvent (Display *display, Window &win, + Window &winRoot, bool press, + int keycode, int modifiers); +static void _x_send_key_event (const KeyEvent &key); + +static void attach_instance (const IMEngineInstancePointer &si); + +/* slot functions */ +static void slot_show_preedit_string (IMEngineInstanceBase *si); +static void slot_show_aux_string (IMEngineInstanceBase *si); +static void slot_show_lookup_table (IMEngineInstanceBase *si); + +static void slot_hide_preedit_string (IMEngineInstanceBase *si); +static void slot_hide_aux_string (IMEngineInstanceBase *si); +static void slot_hide_lookup_table (IMEngineInstanceBase *si); + +static void slot_update_preedit_caret (IMEngineInstanceBase *si, + int caret); +static void slot_update_preedit_string (IMEngineInstanceBase *si, + const WideString &str, + const AttributeList &attrs); +static void slot_update_aux_string (IMEngineInstanceBase *si, + const WideString &str, + const AttributeList &attrs); +static void slot_commit_string (IMEngineInstanceBase *si, + const WideString &str); +static void slot_forward_key_event (IMEngineInstanceBase *si, + const KeyEvent &key); +static void slot_update_lookup_table (IMEngineInstanceBase *si, + const LookupTable &table); + +static void slot_register_properties (IMEngineInstanceBase *si, + const PropertyList &properties); +static void slot_update_property (IMEngineInstanceBase *si, + const Property &property); +static void slot_beep (IMEngineInstanceBase *si); +static void slot_start_helper (IMEngineInstanceBase *si, + const String &helper_uuid); +static void slot_stop_helper (IMEngineInstanceBase *si, + const String &helper_uuid); +static void slot_send_helper_event (IMEngineInstanceBase *si, + const String &helper_uuid, + const Transaction &trans); +static bool slot_get_surrounding_text (IMEngineInstanceBase *si, + WideString &text, + int &cursor, + int maxlen_before, + int maxlen_after); +static bool slot_delete_surrounding_text (IMEngineInstanceBase *si, + int offset, + int len); + +static void reload_config_callback (const ConfigPointer &config); + +static void fallback_commit_string_cb (IMEngineInstanceBase *si, + const WideString &str); + +static void caps_mode_check (Ecore_IMF_Context *ctx, Eina_Bool force); + +/* Local variables declaration */ +static String _language; +static EcoreIMFContextISFImpl *_used_ic_impl_list = 0; +static EcoreIMFContextISFImpl *_free_ic_impl_list = 0; +static EcoreIMFContextISF *_ic_list = 0; + +static KeyboardLayout _keyboard_layout = SCIM_KEYBOARD_Default; +static int _valid_key_mask = SCIM_KEY_AllMasks; + +static FrontEndHotkeyMatcher _frontend_hotkey_matcher; +static IMEngineHotkeyMatcher _imengine_hotkey_matcher; + +static IMEngineInstancePointer _default_instance; + +static ConfigModule *_config_module = 0; +static ConfigPointer _config; +static BackEndPointer _backend; + +static EcoreIMFContextISF *_focused_ic = 0; + +static bool _scim_initialized = false; + +static int _instance_count = 0; +static int _context_count = 0; + +static IMEngineFactoryPointer _fallback_factory; +static IMEngineInstancePointer _fallback_instance; +static PanelClient _panel_client; + +static Ecore_Fd_Handler *_panel_iochannel_read_handler = 0; +static Ecore_Fd_Handler *_panel_iochannel_err_handler = 0; + +static Ecore_X_Window _client_window = 0; + +static bool _on_the_spot = true; +static bool _shared_input_method = false; + +static Eina_Bool autocap_allow = EINA_FALSE; + +static Display *__current_display = 0; +static int __current_alt_mask = Mod1Mask; +static int __current_meta_mask = 0; +static int __current_super_mask = 0; +static int __current_hyper_mask = 0; +static int __current_numlock_mask = Mod2Mask; + +// A hack to shutdown the immodule cleanly even if im_module_exit() is not called when exiting. +class FinalizeHandler +{ +public: + FinalizeHandler() + { + SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::FinalizeHandler()\n"; + } + ~FinalizeHandler() + { + SCIM_DEBUG_FRONTEND(1) << "FinalizeHandler::~FinalizeHandler()\n"; + isf_imf_context_shutdown(); + } +}; + +static FinalizeHandler _finalize_handler; + +static unsigned int +utf8_offset_to_index(const char *str, int offset) +{ + int index = 0; + int i; + for (i = 0; i < offset; i++) + { + eina_unicode_utf8_get_next(str, &index); + } + + return index; +} + +static unsigned int +get_time(void) +{ + unsigned int tint; + struct timeval tv; + struct timezone tz; /* is not used since ages */ + gettimeofday(&tv, &tz); + tint = tv.tv_sec * 1000; + tint = tint / 1000 * 1000; + tint = tint + tv.tv_usec / 1000; + return tint; +} + +/* Function Implementations */ +static EcoreIMFContextISFImpl * +new_ic_impl(EcoreIMFContextISF *parent) +{ + EcoreIMFContextISFImpl *impl = NULL; + + if (_free_ic_impl_list != NULL) + { + impl = _free_ic_impl_list; + _free_ic_impl_list = _free_ic_impl_list->next; + } + else + { + impl = new EcoreIMFContextISFImpl; + if (impl == NULL) + return NULL; + } + + impl->uppercase = false; + impl->autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE; + impl->next = _used_ic_impl_list; + _used_ic_impl_list = impl; + + impl->parent = parent; + + return impl; +} + +static void +delete_ic_impl(EcoreIMFContextISFImpl *impl) +{ + EcoreIMFContextISFImpl *rec = _used_ic_impl_list, *last = 0; + + for (; rec != 0; last = rec, rec = rec->next) + { + if (rec == impl) + { + if (last != 0) + last->next = rec->next; + else + _used_ic_impl_list = rec->next; + + rec->next = _free_ic_impl_list; + _free_ic_impl_list = rec; + + rec->parent = 0; + rec->si.reset(); + rec->client_window = 0; + rec->preedit_string = WideString(); + rec->preedit_attrlist.clear(); + + return; + } + } +} + +static void +delete_all_ic_impl(void) +{ + EcoreIMFContextISFImpl *it = _used_ic_impl_list; + + while (it != 0) + { + _used_ic_impl_list = it->next; + delete it; + it = _used_ic_impl_list; + } + + it = _free_ic_impl_list; + while (it != 0) + { + _free_ic_impl_list = it->next; + delete it; + it = _free_ic_impl_list; + } +} + +static EcoreIMFContextISF * +find_ic(int id) +{ + EcoreIMFContextISFImpl *rec = _used_ic_impl_list; + + while (rec != 0) + { + if (rec->parent && rec->parent->id == id) + return rec->parent; + rec = rec->next; + } + + return 0; +} + +static Eina_Bool +analyze_surrounding_text(Ecore_IMF_Context *ctx) +{ + char *plain_str = NULL; + char *markup_str = NULL; + const char *puncs[] = {". ", "! ", "? "}; + Eina_Bool ret = EINA_FALSE; + int cursor_pos = 0; + int i = 0; + Eina_Unicode *tail = NULL; + Eina_Unicode *ustr = NULL; + const int punc_num = sizeof(puncs) / sizeof(puncs[0]); + Eina_Unicode *uni_puncs[punc_num]; + EcoreIMFContextISF *context_scim; + + if (!ctx) return EINA_FALSE; + context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + if (!context_scim || !context_scim->impl) return EINA_FALSE; + + switch (context_scim->impl->autocapital_type) + { + case ECORE_IMF_AUTOCAPITAL_TYPE_NONE: + return EINA_FALSE; + case ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER: + return EINA_TRUE; + default: + break; + } + + for (i = 0; i < punc_num; i++) + uni_puncs[i] = eina_unicode_utf8_to_unicode(puncs[i], NULL); + + ecore_imf_context_surrounding_get(ctx, &markup_str, &cursor_pos); + if (!markup_str) goto done; + + if (cursor_pos == 0) + { + ret = EINA_TRUE; + goto done; + } + + // Convert into plain string + plain_str = evas_textblock_text_markup_to_utf8(NULL, markup_str); + if (!plain_str) goto done; + + // Convert string from UTF-8 to unicode + ustr = eina_unicode_utf8_to_unicode(plain_str, NULL); + if (!ustr) goto done; + + if (cursor_pos >= 1) + { + if (context_scim->impl->autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_WORD) + { + if (ustr[cursor_pos-1] == ' ') + { + ret = EINA_TRUE; + goto done; + } + } + + // Check paragraph separator and carriage return
+ if ((ustr[cursor_pos-1] == 0x2029) || (ustr[cursor_pos-1] == '\n')) + { + ret = EINA_TRUE; + goto done; + } + } + + // check punctuation + if (cursor_pos >= 2) + { + tail = eina_unicode_strndup(ustr+cursor_pos-2, 2); + + if (tail) + { + for (i = 0; i < punc_num; i++) + { + if (!eina_unicode_strcmp(tail, uni_puncs[i])) + { + ret = EINA_TRUE; + break; + } + } + free(tail); + tail = NULL; + } + } + +done: + if (ustr) free(ustr); + if (markup_str) free(markup_str); + if (plain_str) free(plain_str); + + for (i = 0; i < punc_num; i++) + if (uni_puncs[i]) free(uni_puncs[i]); + + return ret; +} + +static void +caps_mode_check(Ecore_IMF_Context *ctx, Eina_Bool force) +{ + Eina_Bool uppercase; + EcoreIMFContextISF *context_scim; + + if (!ctx) return; + context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (autocap_allow == EINA_FALSE) + return; + + // Check autocapital type + if (!context_scim || !context_scim->impl) + return; + + if (analyze_surrounding_text(ctx)) + uppercase = EINA_TRUE; + else + uppercase = EINA_FALSE; + + if (force) + context_scim->impl->uppercase = uppercase; + else + if (context_scim->impl->uppercase != uppercase) + context_scim->impl->uppercase = uppercase; +} + +static void +feed_key_event(Evas *evas, const char *str, Eina_Bool fake) +{ + char key_string[128] = {0}; + unsigned int timestamp = 0; + + if (!fake) + timestamp = get_time(); + + if (strncmp(str, "KeyRelease+", 11) == 0) + { + strncpy(key_string, str + 11, strlen(str)-11); + evas_event_feed_key_up(evas, key_string, key_string, NULL, NULL, timestamp, NULL); + SCIM_DEBUG_FRONTEND(1) << " evas_event_feed_key_up()...\n"; + } + else + { + strncpy(key_string, str, strlen(str)); + evas_event_feed_key_down(evas, key_string, key_string, NULL, NULL, timestamp, NULL); + SCIM_DEBUG_FRONTEND(1) << " evas_event_feed_key_down()...\n"; + } +} + +static void +window_to_screen_geometry_get(Ecore_X_Window client_win, int *x, int *y) +{ + Ecore_X_Window root_window, win; + int win_x, win_y; + int sum_x = 0, sum_y = 0; + + root_window = ecore_x_window_root_get(client_win); + win = client_win; + + while (root_window != win) + { + ecore_x_window_geometry_get(win, &win_x, &win_y, NULL, NULL); + sum_x += win_x; + sum_y += win_y; + win = ecore_x_window_parent_get(win); + } + + if (x) + *x = sum_x; + if (y) + *y = sum_y; +} + +/* Public functions */ +/** + * isf_imf_context_new + * + * This function will be called by Ecore IMF. + * Create a instance of type EcoreIMFContextISF. + * + * Return value: A pointer to the newly created EcoreIMFContextISF instance + */ +EAPI EcoreIMFContextISF * +isf_imf_context_new(void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + char *env; + + EcoreIMFContextISF *context_scim = new EcoreIMFContextISF; + if (context_scim == NULL) + { + std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n"; + return NULL; + } + + context_scim->id = _context_count++; + + if (!_scim_initialized) + { + initialize(); + _scim_initialized = true; + } + + env = getenv("ECORE_IMF_AUTOCAPITAL_ALLOW"); + if (env) + autocap_allow = !!atoi(env); + + return context_scim; +} + +/** + * isf_imf_context_shutdown + * + * It will be called when the scim im module is unloaded by ecore. It will do some + * cleanup job. + */ +EAPI void +isf_imf_context_shutdown(void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (_scim_initialized) + { + _scim_initialized = false; + finalize(); + } +} + +EAPI void +isf_imf_context_add(Ecore_IMF_Context *ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + + if (!context_scim) return; + + context_scim->impl = NULL; + + if (_backend.null()) + return; + + IMEngineInstancePointer si; + + // Use the default instance if "shared input method" mode is enabled. + if (_shared_input_method && !_default_instance.null()) + { + si = _default_instance; + SCIM_DEBUG_FRONTEND(2) << "use default instance: " << si->get_id() << " " << si->get_factory_uuid() << "\n"; + } + + // Not in "shared input method" mode, or no default instance, create an instance. + if (si.null()) + { + IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8"); + if (factory.null()) return; + si = factory->create_instance("UTF-8", _instance_count++); + if (si.null()) return; + attach_instance(si); + SCIM_DEBUG_FRONTEND(2) << "create new instance: " << si->get_id() << " " << si->get_factory_uuid() << "\n"; + } + + // If "shared input method" mode is enabled, and there is no default instance, + // then store this instance as default one. + if (_shared_input_method && _default_instance.null()) + { + SCIM_DEBUG_FRONTEND(2) << "update default instance.\n"; + _default_instance = si; + } + + context_scim->ctx = ctx; + context_scim->impl = new_ic_impl(context_scim); + if (context_scim->impl == NULL) + { + std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n"; + return; + } + + context_scim->impl->si = si; + context_scim->impl->client_window = 0; + context_scim->impl->client_canvas = NULL; + context_scim->impl->preedit_caret = 0; + context_scim->impl->cursor_x = 0; + context_scim->impl->cursor_y = 0; + context_scim->impl->cursor_pos = -1; + context_scim->impl->is_on = false; + context_scim->impl->shared_si = _shared_input_method; + context_scim->impl->use_preedit = _on_the_spot; + context_scim->impl->preedit_started = false; + context_scim->impl->preedit_updating = false; + context_scim->impl->need_commit_preedit = false; + + if (!_ic_list) + context_scim->next = NULL; + else + context_scim->next = _ic_list; + _ic_list = context_scim; + + if (_shared_input_method) + context_scim->impl->is_on = _config->read(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on); + + _panel_client.prepare(context_scim->id); + _panel_client.register_input_context(context_scim->id, si->get_factory_uuid()); + set_ic_capabilities(context_scim); + _panel_client.send(); + + SCIM_DEBUG_FRONTEND(2) << "input context created: id = " << context_scim->id << "\n"; +} + +EAPI void +isf_imf_context_del(Ecore_IMF_Context *ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (!_ic_list) return; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + + if (context_scim) + { + if (context_scim->id != _ic_list->id) + { + EcoreIMFContextISF * pre = _ic_list; + EcoreIMFContextISF * cur = _ic_list->next; + while (cur != NULL) + { + if (cur->id == context_scim->id) + { + pre->next = cur->next; + break; + } + pre = cur; + cur = cur->next; + } + } + else + _ic_list = _ic_list->next; + } + + if (context_scim && context_scim->impl) + { + _panel_client.prepare(context_scim->id); + + if (context_scim == _focused_ic) + context_scim->impl->si->focus_out(); + + // Delete the instance. + EcoreIMFContextISF *old_focused = _focused_ic; + _focused_ic = context_scim; + context_scim->impl->si.reset(); + _focused_ic = old_focused; + + if (context_scim == _focused_ic) + { + _panel_client.turn_off(context_scim->id); + _panel_client.focus_out(context_scim->id); + } + + _panel_client.remove_input_context(context_scim->id); + _panel_client.send(); + + if (context_scim->impl->client_window) + isf_imf_context_client_window_set(ctx, NULL); + + if (context_scim->impl) + { + delete_ic_impl(context_scim->impl); + context_scim->impl = 0; + } + } + + if (context_scim == _focused_ic) + _focused_ic = 0; + + if (context_scim) + { + delete context_scim; + context_scim = 0; + } +} + +/** + * isf_imf_context_client_canvas_set + * @ctx: a #Ecore_IMF_Context + * @canvas: the client canvas + * + * This function will be called by Ecore IMF. + * + * 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. + */ +EAPI void +isf_imf_context_client_canvas_set(Ecore_IMF_Context *ctx, void *canvas) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (context_scim && context_scim->impl && context_scim->impl->client_canvas != (Evas*) canvas) + context_scim->impl->client_canvas = (Evas*)canvas; +} + +/** + * isf_imf_context_client_window_set + * @ctx: a #Ecore_IMF_Context + * @window: the client window + * + * This function will be called by Ecore IMF. + * + * 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. + */ +EAPI void +isf_imf_context_client_window_set(Ecore_IMF_Context *ctx, void *window) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (context_scim && context_scim->impl && context_scim->impl->client_window != (Ecore_X_Window)((Ecore_Window)window)) + { + context_scim->impl->client_window = (Ecore_X_Window)((Ecore_Window)window); + + if ((context_scim->impl->client_window != 0) && + (context_scim->impl->client_window != _client_window)) + _client_window = context_scim->impl->client_window; + } +} + +/** + * isf_imf_context_reset + * @ctx: a #Ecore_IMF_Context + * + * This function will be called by Ecore IMF. + * + * 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. + */ +EAPI void +isf_imf_context_reset(Ecore_IMF_Context *ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (context_scim && context_scim->impl && context_scim == _focused_ic) + { + WideString wstr = context_scim->impl->preedit_string; + + _panel_client.prepare(context_scim->id); + context_scim->impl->si->reset(); + _panel_client.send(); + + if (context_scim->impl->need_commit_preedit) + { + if (wstr.length()) + { + ecore_imf_context_commit_event_add(context_scim->ctx, utf8_wcstombs(wstr).c_str()); + ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); + } + _panel_client.prepare(context_scim->id); + _panel_client.send(); + } + } +} + +/** + * isf_imf_context_focus_in + * @ctx: a #Ecore_IMF_Context + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that the widget to which its correspond has gained focus. + */ +EAPI void +isf_imf_context_focus_in(Ecore_IMF_Context *ctx) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (!context_scim) + return; + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__<< "(" << context_scim->id << ")...\n"; + + if (_focused_ic) + { + if (_focused_ic == context_scim) + { + SCIM_DEBUG_FRONTEND(1) << "It's already focused.\n"; + return; + } + SCIM_DEBUG_FRONTEND(1) << "Focus out previous IC first: " << _focused_ic->id << "\n"; + if (_focused_ic->ctx) + isf_imf_context_focus_out(_focused_ic->ctx); + } + + bool need_cap = false; + bool need_reset = false; + bool need_reg = false; + + if (context_scim && context_scim->impl) + { + _focused_ic = context_scim; + _panel_client.prepare(context_scim->id); + + // Handle the "Shared Input Method" mode. + if (_shared_input_method) + { + SCIM_DEBUG_FRONTEND(2) << "shared input method.\n"; + IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8"); + if (!factory.null()) + { + if (_default_instance.null() || _default_instance->get_factory_uuid() != factory->get_uuid()) + { + _default_instance = factory->create_instance("UTF-8", _default_instance.null() ? _instance_count++ : _default_instance->get_id()); + attach_instance(_default_instance); + SCIM_DEBUG_FRONTEND(2) << "create new default instance: " << _default_instance->get_id() << " " << _default_instance->get_factory_uuid() << "\n"; + } + + context_scim->impl->shared_si = true; + context_scim->impl->si = _default_instance; + + context_scim->impl->is_on = _config->read(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on); + context_scim->impl->preedit_string.clear(); + context_scim->impl->preedit_attrlist.clear(); + context_scim->impl->preedit_caret = 0; + context_scim->impl->preedit_started = false; + need_cap = true; + need_reset = true; + need_reg = true; + } + } + else if (context_scim->impl->shared_si) + { + SCIM_DEBUG_FRONTEND(2) << "exit shared input method.\n"; + IMEngineFactoryPointer factory = _backend->get_default_factory(_language, "UTF-8"); + if (!factory.null()) + { + context_scim->impl->si = factory->create_instance("UTF-8", _instance_count++); + context_scim->impl->preedit_string.clear(); + context_scim->impl->preedit_attrlist.clear(); + context_scim->impl->preedit_caret = 0; + context_scim->impl->preedit_started = false; + attach_instance(context_scim->impl->si); + need_cap = true; + need_reg = true; + context_scim->impl->shared_si = false; + SCIM_DEBUG_FRONTEND(2) << "create new instance: " << context_scim->impl->si->get_id() << " " << context_scim->impl->si->get_factory_uuid() << "\n"; + } + } + + context_scim->impl->si->set_frontend_data(static_cast (context_scim)); + + if (need_reg) _panel_client.register_input_context(context_scim->id, context_scim->impl->si->get_factory_uuid()); + if (need_cap) set_ic_capabilities(context_scim); + if (need_reset) context_scim->impl->si->reset(); + + panel_req_focus_in(context_scim); + panel_req_update_spot_location(context_scim); + panel_req_update_factory_info(context_scim); + + if (context_scim->impl->is_on) + { + _panel_client.turn_on(context_scim->id); + _panel_client.hide_preedit_string(context_scim->id); + _panel_client.hide_aux_string(context_scim->id); + _panel_client.hide_lookup_table(context_scim->id); + context_scim->impl->si->focus_in(); + } + else + { + _panel_client.turn_off(context_scim->id); + } + + _panel_client.send(); + } + + if (ecore_imf_context_input_panel_enabled_get(ctx)) + ecore_imf_context_input_panel_show(ctx); +} + +/** + * isf_imf_context_focus_out + * @ctx: a #Ecore_IMF_Context + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that the widget to which its correspond has lost focus. + */ +EAPI void +isf_imf_context_focus_out(Ecore_IMF_Context *ctx) +{ + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (!context_scim) return; + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "(" << context_scim->id << ")...\n"; + + if (context_scim && context_scim->impl && context_scim == _focused_ic) + { + WideString wstr = context_scim->impl->preedit_string; + + if (context_scim->impl->need_commit_preedit) + { + if (wstr.length()) + { + ecore_imf_context_commit_event_add(context_scim->ctx, utf8_wcstombs(wstr).c_str()); + ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); + } + _panel_client.prepare(context_scim->id); + _panel_client.send(); + } + + _panel_client.prepare(context_scim->id); + context_scim->impl->si->focus_out(); + context_scim->impl->si->reset(); + _panel_client.turn_off(context_scim->id); + _panel_client.focus_out(context_scim->id); + _panel_client.send(); + _focused_ic = 0; + } + + if (ecore_imf_context_input_panel_enabled_get(ctx)) + ecore_imf_context_input_panel_hide(ctx); +} + +/** + * isf_imf_context_cursor_location_set + * @ctx: a #Ecore_IMF_Context + * @x: x position of New cursor. + * @y: y position of New cursor. + * @w: the width of New cursor. + * @h: the height of New cursor. + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that a change in the cursor location has been made. + */ +EAPI void +isf_imf_context_cursor_location_set(Ecore_IMF_Context *ctx, int cx, int cy, int cw, int ch) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + Ecore_Evas *ee; + int canvas_x, canvas_y; + int new_cursor_x, new_cursor_y; + + if (cw == 0 && ch == 0) + return; + + if (context_scim && context_scim->impl && context_scim == _focused_ic) + { + if (context_scim->impl->client_canvas) + { + ee = ecore_evas_ecore_evas_get(context_scim->impl->client_canvas); + if (!ee) return; + + ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL); + } + else + { + if (context_scim->impl->client_window) + window_to_screen_geometry_get(context_scim->impl->client_window, &canvas_x, &canvas_y); + else + return; + } + + new_cursor_x = canvas_x + cx; + new_cursor_y = canvas_y + cy + ch; + + // Don't update spot location while updating preedit string. + if (context_scim->impl->preedit_updating && (context_scim->impl->cursor_y == new_cursor_y)) + return; + + if (context_scim->impl->cursor_x != new_cursor_x || context_scim->impl->cursor_y != new_cursor_y) + { + context_scim->impl->cursor_x = new_cursor_x; + context_scim->impl->cursor_y = new_cursor_y; + _panel_client.prepare(context_scim->id); + panel_req_update_spot_location(context_scim); + _panel_client.send(); + SCIM_DEBUG_FRONTEND(2) << "new cursor location = " << context_scim->impl->cursor_x << "," << context_scim->impl->cursor_y << "\n"; + } + } +} + +/** + * isf_imf_context_use_preedit_set + * @ctx: a #Ecore_IMF_Context + * @use_preedit: Whether the IM context should use the preedit string. + * + * This function will be called by Ecore IMF. + * + * Set whether the IM context should use the preedit string to display feedback. + * If 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. + */ +EAPI void +isf_imf_context_use_preedit_set(Ecore_IMF_Context* ctx, Eina_Bool use_preedit) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (use_preedit ? "true" : "false") << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + + if (!_on_the_spot) return; + + if (context_scim && context_scim->impl) + { + bool old = context_scim->impl->use_preedit; + context_scim->impl->use_preedit = use_preedit; + if (context_scim == _focused_ic) + { + _panel_client.prepare(context_scim->id); + + if (old != use_preedit) + set_ic_capabilities(context_scim); + + if (context_scim->impl->preedit_string.length()) + slot_show_preedit_string(context_scim->impl->si); + + _panel_client.send(); + } + } +} + +EAPI void +isf_imf_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + + if (context_scim && context_scim->impl && context_scim->impl->is_on) + { + String mbs = utf8_wcstombs(context_scim->impl->preedit_string); + + if (str) + { + if (mbs.length()) + *str = strdup(mbs.c_str()); + else + *str = strdup(""); + } + + if (cursor_pos) + { + *cursor_pos = context_scim->impl->preedit_caret; + } + + if (attrs) + { + if (mbs.length()) + { + int start_index, end_index; + int wlen = context_scim->impl->preedit_string.length(); + + Ecore_IMF_Preedit_Attr *attr = NULL; + AttributeList::const_iterator i; + bool *attrs_flag = new bool [mbs.length()]; + memset(attrs_flag, 0, mbs.length() *sizeof(bool)); + + for (i = context_scim->impl->preedit_attrlist.begin(); + i != context_scim->impl->preedit_attrlist.end(); ++i) + { + start_index = i->get_start(); + end_index = i->get_end(); + + if (end_index <= wlen && start_index < end_index && i->get_type() != SCIM_ATTR_DECORATE_NONE) + { + start_index = utf8_offset_to_index(mbs.c_str(), i->get_start()); + end_index = utf8_offset_to_index(mbs.c_str(), i->get_end()); + + if (i->get_type() == SCIM_ATTR_DECORATE) + { + attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr)); + if (attr == NULL) + continue; + attr->start_index = start_index; + attr->end_index = end_index; + + if (i->get_value() == SCIM_ATTR_DECORATE_UNDERLINE) + { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1; + *attrs = eina_list_append(*attrs, (void *)attr); + } + else if (i->get_value() == SCIM_ATTR_DECORATE_REVERSE) + { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; + *attrs = eina_list_append(*attrs, (void *)attr); + } + else if (i->get_value() == SCIM_ATTR_DECORATE_HIGHLIGHT) + { + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3; + *attrs = eina_list_append(*attrs, (void *)attr); + } + else + { + free(attr); + } + + switch(i->get_value()) + { + case SCIM_ATTR_DECORATE_UNDERLINE: + case SCIM_ATTR_DECORATE_REVERSE: + case SCIM_ATTR_DECORATE_HIGHLIGHT: + // Record which character has attribute. + for (int pos = start_index; pos < end_index; ++pos) + attrs_flag [pos] = 1; + break; + default: + break; + } + } + else if (i->get_type() == SCIM_ATTR_FOREGROUND) + { + SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_FOREGROUND\n"; + } + else if (i->get_type() == SCIM_ATTR_BACKGROUND) + { + SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_BACKGROUND\n"; + } + } + } + + // Add underline for all characters which don't have attribute. + for (unsigned int pos = 0; pos < mbs.length(); ++pos) + { + if (!attrs_flag [pos]) + { + int begin_pos = pos; + + while (pos < mbs.length() && !attrs_flag[pos]) + ++pos; + + // use REVERSE style as default + attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr)); + if (attr == NULL) + continue; + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; + attr->start_index = begin_pos; + attr->end_index = pos; + *attrs = eina_list_append(*attrs, (void *)attr); + } + } + + delete [] attrs_flag; + } + } + } + else + { + if (str) + *str = strdup(""); + + if (cursor_pos) + *cursor_pos = 0; + + if (attrs) + *attrs = NULL; + } +} + +/** + * isf_imf_context_preedit_string_get + * @ctx: a #Ecore_IMF_Context + * @str: the preedit string + * @cursor_pos: the cursor position + * + * This function will be called by Ecore IMF. + * + * To get the preedit string of the input method. + */ +EAPI void +isf_imf_context_preedit_string_get(Ecore_IMF_Context *ctx, char** str, int *cursor_pos) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + + if (context_scim && context_scim->impl && context_scim->impl->is_on) + { + String mbs = utf8_wcstombs(context_scim->impl->preedit_string); + + if (str) + { + if (mbs.length()) + *str = strdup(mbs.c_str()); + else + *str = strdup(""); + } + + if (cursor_pos) + *cursor_pos = context_scim->impl->preedit_caret; + } + else + { + if (str) + *str = strdup(""); + + if (cursor_pos) + *cursor_pos = 0; + } +} + +/** + * isf_imf_context_cursor_position_set + * @ctx: a #Ecore_IMF_Context + * @cursor_pos: New cursor position in characters. + * + * This function will be called by Ecore IMF. + * + * Notify the Input Method Context that a change in the cursor position has been made. + */ +EAPI void +isf_imf_context_cursor_position_set(Ecore_IMF_Context *ctx, int cursor_pos) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (context_scim && context_scim->impl && context_scim == _focused_ic) + { + // Don't update spot location while updating preedit string. + if (context_scim->impl->preedit_updating) + return; + + if (context_scim->impl->cursor_pos != cursor_pos) + { + context_scim->impl->cursor_pos = cursor_pos; + caps_mode_check(ctx, EINA_FALSE); + } + } +} + +/** + * isf_imf_context_input_mode_set + * @ctx: a #Ecore_IMF_Context + * @input_mode: the input mode + * + * This function will be called by Ecore IMF. + * + * To set the input mode of input method. The definition of Ecore_IMF_Input_Mode + * is in Ecore_IMF.h. + */ +EAPI void +isf_imf_context_input_mode_set(Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + if (context_scim && context_scim->impl) + context_scim->impl->input_mode = input_mode; +} + +/** + * isf_imf_context_prediction_allow_set + * @ctx: a #Ecore_IMF_Context + * @use_prediction: Whether the IM context should use the prediction. + * + * This function will be called by Ecore IMF. + * + * Set whether the IM context should use the prediction. + */ +EAPI void +isf_imf_context_prediction_allow_set(Ecore_IMF_Context* ctx, Eina_Bool prediction) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << (prediction ? "true" : "false") << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (context_scim && context_scim->impl && context_scim->impl->prediction_allow != prediction) + context_scim->impl->prediction_allow = prediction; +} + +EAPI void +isf_imf_context_autocapital_type_set(Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " = " << autocapital_type << "...\n"; + + EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get(ctx); + + if (context_scim && context_scim->impl && context_scim->impl->autocapital_type != autocapital_type) + context_scim->impl->autocapital_type = autocapital_type; +} + +/** + * isf_imf_context_filter_event + * @ctx: a #Ecore_IMF_Context + * @type: The type of event defined by Ecore_IMF_Event_Type. + * @event: The event itself. + * Return value: %TRUE if the input method handled the key event. + * + * This function will be called by Ecore IMF. + * + * 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. + */ +EAPI Eina_Bool +isf_imf_context_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + Eina_Bool ret = EINA_FALSE; + + if (ic == NULL || ic->impl == NULL) + return ret; + + KeyEvent key; + + if (type == ECORE_IMF_EVENT_KEY_DOWN) + { + Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; + scim_string_to_key(key, ev->key); + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask; + if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask; + if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask; + } + else if (type == ECORE_IMF_EVENT_KEY_UP) + { + Ecore_IMF_Event_Key_Up *ev = (Ecore_IMF_Event_Key_Up *)event; + scim_string_to_key(key, ev->key); + key.mask = SCIM_KEY_ReleaseMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) key.mask |=SCIM_KEY_ShiftMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) key.mask |=SCIM_KEY_ControlMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT) key.mask |=SCIM_KEY_AltMask; + if (ev->modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) key.mask |=SCIM_KEY_Mod5Mask; + if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_CAPS) key.mask |=SCIM_KEY_CapsLockMask; + if (ev->locks & ECORE_IMF_KEYBOARD_LOCK_NUM) key.mask |=SCIM_KEY_NumLockMask; + } + else + { + return ret; + } + + key.mask &= _valid_key_mask; + + _panel_client.prepare(ic->id); + + ret = EINA_TRUE; + if (!filter_hotkeys(ic, key)) + { + if (!_focused_ic || !_focused_ic->impl->is_on || + !_focused_ic->impl->si->process_key_event(key)) + ret = EINA_FALSE; + } + + _panel_client.send(); + + return ret; +} + +EAPI void +isf_imf_context_input_panel_show(Ecore_IMF_Context *ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + if (ic == NULL || ic->impl == NULL) + return; + + ecore_x_e_virtual_keyboard_state_set + (ic->impl->client_window, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON); +} + +EAPI void +isf_imf_context_input_panel_hide(Ecore_IMF_Context *ctx) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = (EcoreIMFContextISF*)ecore_imf_context_data_get(ctx); + if (ic == NULL || ic->impl == NULL) + return; + + ecore_x_e_virtual_keyboard_state_set + (ic->impl->client_window, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF); +} + +/* Panel Slot functions */ +static void +panel_slot_reload_config(int context __UNUSED__) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + _config->reload(); +} + +static void +panel_slot_exit(int /* context */) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + finalize(); +} + +static void +panel_slot_update_lookup_table_page_size(int context, int page_size) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " page_size=" << page_size << " ic=" << ic << "\n"; + if (ic && ic->impl) + { + _panel_client.prepare(ic->id); + ic->impl->si->update_lookup_table_page_size(page_size); + _panel_client.send(); + } +} + +static void +panel_slot_lookup_table_page_up(int context) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) + { + _panel_client.prepare(ic->id); + ic->impl->si->lookup_table_page_up(); + _panel_client.send(); + } +} + +static void +panel_slot_lookup_table_page_down(int context) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + if (ic && ic->impl) + { + _panel_client.prepare(ic->id); + ic->impl->si->lookup_table_page_down(); + _panel_client.send(); + } +} + +static void +panel_slot_trigger_property(int context, const String &property) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " property=" << property << " ic=" << ic << "\n"; + if (ic && ic->impl) + { + _panel_client.prepare(ic->id); + ic->impl->si->trigger_property(property); + _panel_client.send(); + } +} + +static void +panel_slot_process_helper_event(int context, const String &target_uuid, const String &helper_uuid, const Transaction &trans) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " target=" << target_uuid + << " helper=" << helper_uuid << " ic=" << ic << " ic->impl=" << (ic ? ic->impl : 0) << " ic-uuid=" + << ((ic && ic->impl) ? ic->impl->si->get_factory_uuid() : "" ) << "\n"; + if (ic && ic->impl && ic->impl->si->get_factory_uuid() == target_uuid) + { + _panel_client.prepare(ic->id); + SCIM_DEBUG_FRONTEND(2) << "call process_helper_event\n"; + ic->impl->si->process_helper_event(helper_uuid, trans); + _panel_client.send(); + } +} + +static void +panel_slot_move_preedit_caret(int context, int caret_pos) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " caret=" << caret_pos << " ic=" << ic << "\n"; + if (ic && ic->impl) + { + _panel_client.prepare(ic->id); + ic->impl->si->move_preedit_caret(caret_pos); + _panel_client.send(); + } +} + +static void +panel_slot_select_candidate(int context, int cand_index) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " candidate=" << cand_index << " ic=" << ic << "\n"; + if (ic && ic->impl) + { + _panel_client.prepare(ic->id); + ic->impl->si->select_candidate(cand_index); + _panel_client.send(); + } +} + +static void +panel_slot_process_key_event(int context, const KeyEvent &key) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string() << " ic=" << ic << "\n"; + + if (key.is_key_press()) + ecore_x_test_fake_key_press(key.get_key_string().c_str()); +} + +static void +panel_slot_commit_string(int context, const WideString &wstr) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " str=" << utf8_wcstombs(wstr) << " ic=" << ic << "\n"; + + if (ic && ic->impl) + { + if (_focused_ic != ic) + return; + + ecore_imf_context_commit_event_add(ic->ctx, utf8_wcstombs(wstr).c_str()); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); + } +} + +static void +panel_slot_forward_key_event(int context, const KeyEvent &key) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string() << " ic=" << ic << "\n"; + + if (ic && ic->impl && ic->impl->client_canvas) + feed_key_event(ic->impl->client_canvas, key.get_key_string().c_str(), EINA_TRUE); +} + +static void +panel_slot_request_help(int context) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + + if (ic && ic->impl) + { + _panel_client.prepare(ic->id); + panel_req_show_help(ic); + _panel_client.send(); + } +} + +static void +panel_slot_request_factory_menu(int context) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " ic=" << ic << "\n"; + + if (ic && ic->impl) + { + _panel_client.prepare(ic->id); + panel_req_show_factory_menu(ic); + _panel_client.send(); + } +} + +static void +panel_slot_change_factory(int context, const String &uuid) +{ + EcoreIMFContextISF *ic = find_ic(context); + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " factory=" << uuid << " ic=" << ic << "\n"; + + if (ic && ic->impl) + { + ic->impl->si->reset(); + _panel_client.prepare(ic->id); + open_specific_factory(ic, uuid); + _panel_client.send(); + } +} + +/* Panel Requestion functions. */ +static void +panel_req_show_help(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + String help; + + help = String("Smart Common Input Method platform ") + + //String(SCIM_VERSION) + + String("\n(C) 2002-2005 James Su \n\n"); + + if (ic && ic->impl) + { + IMEngineFactoryPointer sf = _backend->get_factory(ic->impl->si->get_factory_uuid()); + if (sf) + { + help += utf8_wcstombs(sf->get_name()); + help += String(":\n\n"); + + help += utf8_wcstombs(sf->get_help()); + help += String("\n\n"); + + help += utf8_wcstombs(sf->get_credits()); + } + _panel_client.show_help(ic->id, help); + } +} + +static void +panel_req_show_factory_menu(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + std::vector factories; + std::vector menu; + + _backend->get_factories_for_encoding(factories, "UTF-8"); + + for (size_t i = 0; i < factories.size(); ++ i) + { + menu.push_back(PanelFactoryInfo( + factories [i]->get_uuid(), + utf8_wcstombs(factories [i]->get_name()), + factories [i]->get_language(), + factories [i]->get_icon_file())); + } + + if (menu.size()) + _panel_client.show_factory_menu(ic->id, menu); +} + +static void +panel_req_update_factory_info(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (ic && ic->impl && ic == _focused_ic) + { + PanelFactoryInfo info; + if (ic->impl->is_on) + { + IMEngineFactoryPointer sf = _backend->get_factory(ic->impl->si->get_factory_uuid()); + if (sf) + info = PanelFactoryInfo(sf->get_uuid(), utf8_wcstombs(sf->get_name()), sf->get_language(), sf->get_icon_file()); + } + else + { + info = PanelFactoryInfo(String(""), String("English/Keyboard"), String("C"), ""); + } + _panel_client.update_factory_info(ic->id, info); + } +} + +static void +panel_req_focus_in(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _panel_client.focus_in(ic->id, ic->impl->si->get_factory_uuid()); +} + +static void +panel_req_update_spot_location(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _panel_client.update_spot_location(ic->id, ic->impl->cursor_x, ic->impl->cursor_y); +} + +static bool +filter_hotkeys(EcoreIMFContextISF *ic, const KeyEvent &key) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + bool ret = false; + + _frontend_hotkey_matcher.push_key_event(key); + _imengine_hotkey_matcher.push_key_event(key); + + FrontEndHotkeyAction hotkey_action = _frontend_hotkey_matcher.get_match_result(); + + if (hotkey_action == SCIM_FRONTEND_HOTKEY_TRIGGER) + { + if (!ic->impl->is_on) + turn_on_ic(ic); + else + turn_off_ic(ic); + ret = true; + } + else if (hotkey_action == SCIM_FRONTEND_HOTKEY_ON) + { + if (!ic->impl->is_on) + turn_on_ic(ic); + ret = true; + } + else if (hotkey_action == SCIM_FRONTEND_HOTKEY_OFF) + { + if (ic->impl->is_on) + turn_off_ic(ic); + ret = true; + } + else if (hotkey_action == SCIM_FRONTEND_HOTKEY_NEXT_FACTORY) + { + open_next_factory(ic); + ret = true; + } + else if (hotkey_action == SCIM_FRONTEND_HOTKEY_PREVIOUS_FACTORY) + { + open_previous_factory(ic); + ret = true; + } + else if (hotkey_action == SCIM_FRONTEND_HOTKEY_SHOW_FACTORY_MENU) + { + panel_req_show_factory_menu(ic); + ret = true; + } + else if (_imengine_hotkey_matcher.is_matched()) + { + String sfid = _imengine_hotkey_matcher.get_match_result(); + open_specific_factory(ic, sfid); + ret = true; + } + return ret; +} + +static bool +panel_initialize(void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + String display_name; + { + const char *p = getenv("DISPLAY"); + if (p) display_name = String(p); + } + + if (_panel_client.open_connection(_config->get_name(), display_name) >= 0) + { + int fd = _panel_client.get_connection_number(); + + _panel_iochannel_read_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, panel_iochannel_handler, NULL, NULL, NULL); + + SCIM_DEBUG_FRONTEND(2) << " Panel FD= " << fd << "\n"; + + return true; + } + std::cerr << "panel_initialize() failed!!!\n"; + return false; +} + +static void +panel_finalize(void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _panel_client.close_connection(); + + if (_panel_iochannel_read_handler) + { + ecore_main_fd_handler_del(_panel_iochannel_read_handler); + _panel_iochannel_read_handler = 0; + } + + if (_panel_iochannel_err_handler) + { + ecore_main_fd_handler_del(_panel_iochannel_err_handler); + _panel_iochannel_err_handler = 0; + } +} + +static Eina_Bool +panel_iochannel_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (fd_handler == _panel_iochannel_read_handler) + { + if (!_panel_client.filter_event()) + { + panel_finalize(); + panel_initialize(); + return ECORE_CALLBACK_CANCEL; + } + } + else if (fd_handler == _panel_iochannel_err_handler) + { + panel_finalize(); + panel_initialize(); + return ECORE_CALLBACK_CANCEL; + } + return ECORE_CALLBACK_RENEW; +} + +static void +turn_on_ic(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (ic && ic->impl && !ic->impl->is_on) + { + ic->impl->is_on = true; + + if (ic == _focused_ic) + { + panel_req_focus_in(ic); + panel_req_update_spot_location(ic); + panel_req_update_factory_info(ic); + _panel_client.turn_on(ic->id); + _panel_client.hide_preedit_string(ic->id); + _panel_client.hide_aux_string(ic->id); + _panel_client.hide_lookup_table(ic->id); + ic->impl->si->focus_in(); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), true); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length()) + { + ecore_imf_context_preedit_start_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ecore_imf_context_preedit_changed_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ic->impl->preedit_started = true; + } + } +} + +static void +turn_off_ic(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (ic && ic->impl && ic->impl->is_on) + { + ic->impl->is_on = false; + + if (ic == _focused_ic) + { + ic->impl->si->focus_out(); + + panel_req_update_factory_info(ic); + _panel_client.turn_off(ic->id); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length()) + { + ecore_imf_context_preedit_changed_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ecore_imf_context_preedit_end_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + ic->impl->preedit_started = false; + } + } +} + +static void +set_ic_capabilities(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (ic && ic->impl) + { + unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES; + + if (!_on_the_spot || !ic->impl->use_preedit) + cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT; + + ic->impl->si->update_client_capabilities(cap); + } +} + +static bool +check_socket_frontend(void) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + SocketAddress address; + SocketClient client; + + uint32 magic; + + address.set_address(scim_get_default_socket_frontend_address()); + + if (!client.connect(address)) + return false; + + if (!scim_socket_open_connection(magic, + String("ConnectionTester"), + String("SocketFrontEnd"), + client, + 1000)) + return false; + + return true; +} + +void +initialize(void) +{ + std::vector config_list; + std::vector engine_list; + std::vector load_engine_list; + + std::vector::iterator it; + + bool manual = false; + + bool socket = true; + + String config_module_name = "simple"; + + printf("Initializing Ecore SCIM IMModule...\n"); + + SCIM_DEBUG_FRONTEND(1) << "Initializing Ecore SCIM IMModule...\n"; + + // Get system language. + _language = scim_get_locale_language(scim_get_current_locale()); + + if (socket) + { + // If no Socket FrontEnd is running, then launch one. + // And set manual to false. + bool check_result = check_socket_frontend(); + if (!check_result) + { + std::cerr << "Launching a SCIM daemon with Socket FrontEnd...\n"; + //get modules list + scim_get_imengine_module_list(engine_list); + + for (it = engine_list.begin(); it != engine_list.end(); it++) + { + if (*it != "socket") + load_engine_list.push_back(*it); + } + + const char *new_argv [] = { "--no-stay", 0 }; + scim_launch(true, + config_module_name, + (load_engine_list.size() ? scim_combine_string_list(load_engine_list, ',') : "none"), + "socket", + (char **)new_argv); + manual = false; + } + + // If there is one Socket FrontEnd running and it's not manual mode, + // then just use this Socket Frontend. + if (!manual) + { + for (int i = 0; i < 200; ++i) + { + if (check_result) + { + config_module_name = "socket"; + load_engine_list.clear(); + load_engine_list.push_back("socket"); + break; + } + scim_usleep(50000); + check_result = check_socket_frontend(); + } + } + } + + if (config_module_name != "dummy") + { + //load config module + SCIM_DEBUG_FRONTEND(1) << "Loading Config module: " << config_module_name << "...\n"; + _config_module = new ConfigModule(config_module_name); + + //create config instance + if (_config_module != NULL && _config_module->valid()) + _config = _config_module->create_config(); + } + + if (_config.null()) + { + SCIM_DEBUG_FRONTEND(1) << "Config module cannot be loaded, using dummy Config.\n"; + + if (_config_module) delete _config_module; + _config_module = NULL; + + _config = new DummyConfig(); + config_module_name = "dummy"; + } + + reload_config_callback(_config); + _config->signal_connect_reload(slot(reload_config_callback)); + + // create backend + _backend = new CommonBackEnd(_config, load_engine_list.size() ? load_engine_list : engine_list); + + if (_backend.null()) + std::cerr << "Cannot create BackEnd Object!\n"; + else + _fallback_factory = _backend->get_factory(SCIM_COMPOSE_KEY_FACTORY_UUID); + + if (_fallback_factory.null()) + _fallback_factory = new DummyIMEngineFactory(); + + _fallback_instance = _fallback_factory->create_instance(String("UTF-8"), 0); + _fallback_instance->signal_connect_commit_string(slot(fallback_commit_string_cb)); + + // Attach Panel Client signal. + _panel_client.signal_connect_reload_config (slot(panel_slot_reload_config)); + _panel_client.signal_connect_exit (slot(panel_slot_exit)); + _panel_client.signal_connect_update_lookup_table_page_size(slot(panel_slot_update_lookup_table_page_size)); + _panel_client.signal_connect_lookup_table_page_up (slot(panel_slot_lookup_table_page_up)); + _panel_client.signal_connect_lookup_table_page_down (slot(panel_slot_lookup_table_page_down)); + _panel_client.signal_connect_trigger_property (slot(panel_slot_trigger_property)); + _panel_client.signal_connect_process_helper_event (slot(panel_slot_process_helper_event)); + _panel_client.signal_connect_move_preedit_caret (slot(panel_slot_move_preedit_caret)); + _panel_client.signal_connect_select_candidate (slot(panel_slot_select_candidate)); + _panel_client.signal_connect_process_key_event (slot(panel_slot_process_key_event)); + _panel_client.signal_connect_commit_string (slot(panel_slot_commit_string)); + _panel_client.signal_connect_forward_key_event (slot(panel_slot_forward_key_event)); + _panel_client.signal_connect_request_help (slot(panel_slot_request_help)); + _panel_client.signal_connect_request_factory_menu (slot(panel_slot_request_factory_menu)); + _panel_client.signal_connect_change_factory (slot(panel_slot_change_factory)); + + if (!panel_initialize()) + std::cerr << "Ecore IM Module: Cannot connect to Panel!\n"; +} + +static void +finalize(void) +{ + SCIM_DEBUG_FRONTEND(1) << "Finalizing Ecore ISF IMModule...\n"; + + // Reset this first so that the shared instance could be released correctly afterwards. + _default_instance.reset(); + + SCIM_DEBUG_FRONTEND(2) << "Finalize all IC partially.\n"; + while (_used_ic_impl_list) + { + // In case in "shared input method" mode, + // all contexts share only one instance, + // so we need point the reference pointer correctly before finalizing. + _used_ic_impl_list->si->set_frontend_data(static_cast (_used_ic_impl_list->parent)); + isf_imf_context_del(_used_ic_impl_list->parent->ctx); + } + + delete_all_ic_impl(); + + _fallback_instance.reset(); + _fallback_factory.reset(); + + SCIM_DEBUG_FRONTEND(2) << " Releasing BackEnd...\n"; + _backend.reset(); + + SCIM_DEBUG_FRONTEND(2) << " Releasing Config...\n"; + _config.reset(); + + if (_config_module) + { + SCIM_DEBUG_FRONTEND(2) << " Deleting _config_module...\n"; + delete _config_module; + _config_module = 0; + } + + _focused_ic = NULL; + _ic_list = NULL; + + _scim_initialized = false; + + panel_finalize(); +} + +static void +open_next_factory(EcoreIMFContextISF *ic) +{ + SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; + IMEngineFactoryPointer sf = _backend->get_next_factory("", "UTF-8", ic->impl->si->get_factory_uuid()); + + if (!sf.null()) + { + turn_off_ic(ic); + ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id()); + ic->impl->si->set_frontend_data(static_cast (ic)); + ic->impl->preedit_string = WideString(); + ic->impl->preedit_caret = 0; + attach_instance(ic->impl->si); + _backend->set_default_factory(_language, sf->get_uuid()); + _panel_client.register_input_context(ic->id, sf->get_uuid()); + set_ic_capabilities(ic); + turn_on_ic(ic); + + if (_shared_input_method) + { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + } +} + +static void +open_previous_factory(EcoreIMFContextISF *ic) +{ + if (ic == NULL) + return; + + SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; + IMEngineFactoryPointer sf = _backend->get_previous_factory("", "UTF-8", ic->impl->si->get_factory_uuid()); + + if (!sf.null()) + { + turn_off_ic(ic); + ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id()); + ic->impl->si->set_frontend_data(static_cast (ic)); + ic->impl->preedit_string = WideString(); + ic->impl->preedit_caret = 0; + attach_instance(ic->impl->si); + _backend->set_default_factory(_language, sf->get_uuid()); + _panel_client.register_input_context(ic->id, sf->get_uuid()); + set_ic_capabilities(ic); + turn_on_ic(ic); + + if (_shared_input_method) + { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + } +} + +static void +open_specific_factory(EcoreIMFContextISF *ic, + const String &uuid) +{ + if (ic == NULL) + return; + + SCIM_DEBUG_FRONTEND(2) << __FUNCTION__ << " context=" << ic->id << "\n"; + + // The same input method is selected, just turn on the IC. + if (ic->impl->si->get_factory_uuid() == uuid) + { + turn_on_ic(ic); + return; + } + + IMEngineFactoryPointer sf = _backend->get_factory(uuid); + + if (uuid.length() && !sf.null()) + { + turn_off_ic(ic); + ic->impl->si = sf->create_instance("UTF-8", ic->impl->si->get_id()); + ic->impl->si->set_frontend_data(static_cast (ic)); + ic->impl->preedit_string = WideString(); + ic->impl->preedit_caret = 0; + attach_instance(ic->impl->si); + _backend->set_default_factory(_language, sf->get_uuid()); + _panel_client.register_input_context(ic->id, sf->get_uuid()); + set_ic_capabilities(ic); + turn_on_ic(ic); + + if (_shared_input_method) + { + _default_instance = ic->impl->si; + ic->impl->shared_si = true; + } + } + else + { + // turn_off_ic comment out panel_req_update_factory_info() + turn_off_ic(ic); + if (ic && ic->impl->is_on) + { + ic->impl->is_on = false; + + if (ic == _focused_ic) + { + ic->impl->si->focus_out(); + + panel_req_update_factory_info(ic); + _panel_client.turn_off(ic->id); + } + + //Record the IC on/off status + if (_shared_input_method) + _config->write(String(SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), false); + + if (ic->impl->use_preedit && ic->impl->preedit_string.length()) + { + ecore_imf_context_preedit_changed_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ecore_imf_context_preedit_end_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + ic->impl->preedit_started = false; + } + } + } +} + +static void initialize_modifier_bits(Display *display) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (__current_display == display) + return; + + __current_display = display; + + if (display == 0) + { + __current_alt_mask = Mod1Mask; + __current_meta_mask = ShiftMask | Mod1Mask; + __current_super_mask = 0; + __current_hyper_mask = 0; + __current_numlock_mask = Mod2Mask; + return; + } + + XModifierKeymap *mods = NULL; + + ::KeyCode ctrl_l = XKeysymToKeycode(display, XK_Control_L); + ::KeyCode ctrl_r = XKeysymToKeycode(display, XK_Control_R); + ::KeyCode meta_l = XKeysymToKeycode(display, XK_Meta_L); + ::KeyCode meta_r = XKeysymToKeycode(display, XK_Meta_R); + ::KeyCode alt_l = XKeysymToKeycode(display, XK_Alt_L); + ::KeyCode alt_r = XKeysymToKeycode(display, XK_Alt_R); + ::KeyCode super_l = XKeysymToKeycode(display, XK_Super_L); + ::KeyCode super_r = XKeysymToKeycode(display, XK_Super_R); + ::KeyCode hyper_l = XKeysymToKeycode(display, XK_Hyper_L); + ::KeyCode hyper_r = XKeysymToKeycode(display, XK_Hyper_R); + ::KeyCode numlock = XKeysymToKeycode(display, XK_Num_Lock); + + int i, j; + + mods = XGetModifierMapping(display); + if (mods == NULL) + return; + + __current_alt_mask = 0; + __current_meta_mask = 0; + __current_super_mask = 0; + __current_hyper_mask = 0; + __current_numlock_mask = 0; + + /* We skip the first three sets for Shift, Lock, and Control. The + remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */ + for (i = 3; i < 8; i++) + { + for (j = 0; j < mods->max_keypermod; j++) + { + ::KeyCode code = mods->modifiermap [i * mods->max_keypermod + j]; + if (! code) continue; + if (code == alt_l || code == alt_r) + __current_alt_mask |= (1 << i); + else if (code == meta_l || code == meta_r) + __current_meta_mask |= (1 << i); + else if (code == super_l || code == super_r) + __current_super_mask |= (1 << i); + else if (code == hyper_l || code == hyper_r) + __current_hyper_mask |= (1 << i); + else if (code == numlock) + __current_numlock_mask |= (1 << i); + } + } + + /* Check whether there is a combine keys mapped to Meta */ + if (__current_meta_mask == 0) + { + char buf [32]; + XKeyEvent xkey; + KeySym keysym_l, keysym_r; + + xkey.type = KeyPress; + xkey.display = display; + xkey.serial = 0L; + xkey.send_event = False; + xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0; + xkey.time = 0; + xkey.same_screen = False; + xkey.subwindow = None; + xkey.window = None; + xkey.root = DefaultRootWindow(display); + xkey.state = ShiftMask; + + xkey.keycode = meta_l; + XLookupString(&xkey, buf, 32, &keysym_l, 0); + xkey.keycode = meta_r; + XLookupString(&xkey, buf, 32, &keysym_r, 0); + + if ((meta_l == alt_l && keysym_l == XK_Meta_L) || (meta_r == alt_r && keysym_r == XK_Meta_R)) + __current_meta_mask = ShiftMask + __current_alt_mask; + else if ((meta_l == ctrl_l && keysym_l == XK_Meta_L) || (meta_r == ctrl_r && keysym_r == XK_Meta_R)) + __current_meta_mask = ShiftMask + ControlMask; + } + + XFreeModifiermap(mods); +} + +static unsigned int scim_x11_keymask_scim_to_x11(Display *display, uint16 scimkeymask) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + unsigned int state = 0; + + initialize_modifier_bits(display); + + if (scimkeymask & SCIM_KEY_ShiftMask) state |= ShiftMask; + if (scimkeymask & SCIM_KEY_CapsLockMask) state |= LockMask; + if (scimkeymask & SCIM_KEY_ControlMask) state |= ControlMask; + if (scimkeymask & SCIM_KEY_AltMask) state |= __current_alt_mask; + if (scimkeymask & SCIM_KEY_MetaMask) state |= __current_meta_mask; + if (scimkeymask & SCIM_KEY_SuperMask) state |= __current_super_mask; + if (scimkeymask & SCIM_KEY_HyperMask) state |= __current_hyper_mask; + if (scimkeymask & SCIM_KEY_NumLockMask) state |= __current_numlock_mask; + + return state; +} + +static XKeyEvent createKeyEvent(Display *display, Window &win, + Window &winRoot, bool press, + int keycode, int modifiers) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + XKeyEvent event; + + event.display = display; + event.window = win; + event.root = winRoot; + event.subwindow = None; + event.time = CurrentTime; + event.x = 1; + event.y = 1; + event.x_root = 1; + event.y_root = 1; + event.same_screen = EINA_TRUE; + event.state = modifiers; + event.keycode = XKeysymToKeycode(display, keycode); + if (press) + event.type = KeyPress; + else + event.type = KeyRelease; + event.send_event = EINA_FALSE; + event.serial = 0; + + return event; +} + +static void _x_send_key_event(const KeyEvent &key) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + // Obtain the X11 display. + Display *display = XOpenDisplay(NULL); + if (display == NULL) + { + std::cerr << "XOpenDisplay failed\n"; + return; + } + + // Get the root window for the current display. + Window winRoot = 0; + + // Find the window which has the current keyboard focus. + Window winFocus = 0; + int revert = RevertToParent; + + XGetInputFocus(display, &winFocus, &revert); + + // Send a fake key press event to the window. + XSelectInput(display, winFocus, FocusChangeMask|KeyPressMask|KeyReleaseMask); + XMapWindow(display, winFocus); + + unsigned int modifier = scim_x11_keymask_scim_to_x11(display, key.mask); + XKeyEvent event; + if (key.is_key_press()) + { + event = createKeyEvent(display, winFocus, winRoot, true, key.code, modifier); + XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event); + } + else + { + event = createKeyEvent(display, winFocus, winRoot, false, key.code, modifier); + XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *)&event); + } + + XCloseDisplay(display); +} + +static void +attach_instance(const IMEngineInstancePointer &si) +{ + si->signal_connect_show_preedit_string( + slot(slot_show_preedit_string)); + si->signal_connect_show_aux_string( + slot(slot_show_aux_string)); + si->signal_connect_show_lookup_table( + slot(slot_show_lookup_table)); + + si->signal_connect_hide_preedit_string( + slot(slot_hide_preedit_string)); + si->signal_connect_hide_aux_string( + slot(slot_hide_aux_string)); + si->signal_connect_hide_lookup_table( + slot(slot_hide_lookup_table)); + + si->signal_connect_update_preedit_caret( + slot(slot_update_preedit_caret)); + si->signal_connect_update_preedit_string( + slot(slot_update_preedit_string)); + si->signal_connect_update_aux_string( + slot(slot_update_aux_string)); + si->signal_connect_update_lookup_table( + slot(slot_update_lookup_table)); + + si->signal_connect_commit_string( + slot(slot_commit_string)); + + si->signal_connect_forward_key_event( + slot(slot_forward_key_event)); + + si->signal_connect_register_properties( + slot(slot_register_properties)); + + si->signal_connect_update_property( + slot(slot_update_property)); + + si->signal_connect_beep( + slot(slot_beep)); + + si->signal_connect_start_helper( + slot(slot_start_helper)); + + si->signal_connect_stop_helper( + slot(slot_stop_helper)); + + si->signal_connect_send_helper_event( + slot(slot_send_helper_event)); + + si->signal_connect_get_surrounding_text( + slot(slot_get_surrounding_text)); + + si->signal_connect_delete_surrounding_text( + slot(slot_delete_surrounding_text)); +} + +// Implementation of slot functions +static void +slot_show_preedit_string(IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + { + if (ic->impl->use_preedit) + { + if (!ic->impl->preedit_started) + { + ecore_imf_context_preedit_start_event_add(_focused_ic->ctx); + ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + } + } + else + _panel_client.show_preedit_string(ic->id); + } +} + +static void +slot_show_aux_string(IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.show_aux_string(ic->id); +} + +static void +slot_show_lookup_table(IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.show_lookup_table(ic->id); +} + +static void +slot_hide_preedit_string(IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + { + bool emit = false; + if (ic->impl->preedit_string.length()) + { + ic->impl->preedit_string = WideString(); + ic->impl->preedit_caret = 0; + ic->impl->preedit_attrlist.clear(); + emit = true; + } + if (ic->impl->use_preedit) + { + if (emit) + { + ecore_imf_context_preedit_changed_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + if (ic->impl->preedit_started) + { + ecore_imf_context_preedit_end_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + ic->impl->preedit_started = false; + } + } + else + _panel_client.hide_preedit_string(ic->id); + } +} + +static void +slot_hide_aux_string(IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.hide_aux_string(ic->id); +} + +static void +slot_hide_lookup_table(IMEngineInstanceBase *si) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.hide_lookup_table(ic->id); +} + +static void +slot_update_preedit_caret(IMEngineInstanceBase *si, int caret) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret) + { + ic->impl->preedit_caret = caret; + if (ic->impl->use_preedit) + { + if (!ic->impl->preedit_started) + { + ecore_imf_context_preedit_start_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + } + ecore_imf_context_preedit_changed_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + else + _panel_client.update_preedit_caret(ic->id, caret); + } +} + +static void +slot_update_preedit_string(IMEngineInstanceBase *si, + const WideString & str, + const AttributeList & attrs) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic && (ic->impl->preedit_string != str || str.length())) + { + ic->impl->preedit_string = str; + ic->impl->preedit_attrlist = attrs; + if (ic->impl->use_preedit) + { + if (!ic->impl->preedit_started) + { + ecore_imf_context_preedit_start_event_add(_focused_ic->ctx); + ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + ic->impl->preedit_started = true; + } + ic->impl->preedit_caret = str.length(); + ic->impl->preedit_updating = true; + ecore_imf_context_preedit_changed_event_add(ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + ic->impl->preedit_updating = false; + } + else + { + _panel_client.update_preedit_string(ic->id, str, attrs); + } + } +} + +static void +slot_update_aux_string(IMEngineInstanceBase *si, + const WideString & str, + const AttributeList & attrs) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_aux_string(ic->id, str, attrs); +} + +static void +slot_commit_string(IMEngineInstanceBase *si, + const WideString & str) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->ctx) + { + ecore_imf_context_commit_event_add(ic->ctx, utf8_wcstombs(str).c_str()); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str()); + } +} + +static void +slot_forward_key_event(IMEngineInstanceBase *si, + const KeyEvent & key) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && _focused_ic == ic) + { + if (!_fallback_instance->process_key_event(key)) + _x_send_key_event(key); + } +} + +static void +slot_update_lookup_table(IMEngineInstanceBase *si, + const LookupTable & table) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_lookup_table(ic->id, table); +} + +static void +slot_register_properties(IMEngineInstanceBase *si, + const PropertyList & properties) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.register_properties(ic->id, properties); +} + +static void +slot_update_property(IMEngineInstanceBase *si, + const Property & property) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + _panel_client.update_property(ic->id, property); +} + +static void +slot_beep(IMEngineInstanceBase *si __UNUSED__) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; +} + +static void +slot_start_helper(IMEngineInstanceBase *si, + const String &helper_uuid) +{ + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" + << (ic ? ic->id : -1) << " ic=" << ic + << " ic-uuid=" << ((ic ) ? ic->impl->si->get_factory_uuid() : "") << "...\n"; + + if (ic && ic->impl) + _panel_client.start_helper(ic->id, helper_uuid); +} + +static void +slot_stop_helper(IMEngineInstanceBase *si, + const String &helper_uuid) +{ + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" << (ic ? ic->id : -1) << " ic=" << ic << "...\n"; + + if (ic && ic->impl) + _panel_client.stop_helper(ic->id, helper_uuid); +} + +static void +slot_send_helper_event(IMEngineInstanceBase *si, + const String &helper_uuid, + const Transaction &trans) +{ + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " helper= " << helper_uuid << " context=" + << (ic ? ic->id : -1) << " ic=" << ic + << " ic-uuid=" << ((ic) ? ic->impl->si->get_factory_uuid() : "") << "...\n"; + + if (ic && ic->impl) + _panel_client.send_helper_event(ic->id, helper_uuid, trans); +} + +static bool +slot_get_surrounding_text(IMEngineInstanceBase *si, + WideString &text, + int &cursor, + int maxlen_before, + int maxlen_after) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + { + char *surrounding = NULL; + int cursor_index; + if (ecore_imf_context_surrounding_get(_focused_ic->ctx, &surrounding, &cursor_index)) + { + SCIM_DEBUG_FRONTEND(2) << "Surrounding text: " << surrounding <<"\n"; + SCIM_DEBUG_FRONTEND(2) << "Cursor Index : " << cursor_index <<"\n"; + WideString before(utf8_mbstowcs(String(surrounding, surrounding + cursor_index))); + WideString after(utf8_mbstowcs(String(surrounding + cursor_index))); + if (maxlen_before > 0 && ((unsigned int)maxlen_before) < before.length()) + before = WideString(before.begin() + (before.length() - maxlen_before), before.end()); + else if (maxlen_before == 0) before = WideString(); + if (maxlen_after > 0 && ((unsigned int)maxlen_after) < after.length()) + after = WideString(after.begin(), after.begin() + maxlen_after); + else if (maxlen_after == 0) after = WideString(); + text = before + after; + cursor = before.length(); + return true; + } + } + return false; +} + +static bool +slot_delete_surrounding_text(IMEngineInstanceBase *si, + int offset, + int len) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + EcoreIMFContextISF *ic = static_cast(si->get_frontend_data()); + + if (ic && ic->impl && _focused_ic == ic) + { + Ecore_IMF_Event_Delete_Surrounding ev; + ev.ctx = _focused_ic->ctx; + ev.n_chars = len; + ev.offset = offset; + ecore_imf_context_delete_surrounding_event_add(_focused_ic->ctx, offset, len); + ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev); + return true; + } + return false; +} + +static void +reload_config_callback(const ConfigPointer &config) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + _frontend_hotkey_matcher.load_hotkeys(config); + _imengine_hotkey_matcher.load_hotkeys(config); + + KeyEvent key; + + scim_string_to_key(key, + config->read(String(SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK), + String("Shift+Control+Alt+Lock"))); + + _valid_key_mask = (key.mask > 0)?(key.mask):0xFFFF; + _valid_key_mask |= SCIM_KEY_ReleaseMask; + // Special treatment for two backslash keys on jp106 keyboard. + _valid_key_mask |= SCIM_KEY_QuirkKanaRoMask; + + _on_the_spot = config->read(String(SCIM_CONFIG_FRONTEND_ON_THE_SPOT), _on_the_spot); + _shared_input_method = config->read(String(SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), _shared_input_method); + + // Get keyboard layout setting + // Flush the global config first, in order to load the new configs from disk. + scim_global_config_flush(); + + _keyboard_layout = scim_get_default_keyboard_layout(); +} + +static void +fallback_commit_string_cb(IMEngineInstanceBase *si __UNUSED__, + const WideString &str) +{ + SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; + + if (_focused_ic && _focused_ic->impl) + { + ecore_imf_context_commit_event_add(_focused_ic->ctx, utf8_wcstombs(str).c_str()); + ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str()); + } +} + diff --git a/src/modules/ecore/immodules/scim/scim_imcontext.h b/src/modules/ecore/immodules/scim/scim_imcontext.h new file mode 100644 index 0000000000..72533e245d --- /dev/null +++ b/src/modules/ecore/immodules/scim/scim_imcontext.h @@ -0,0 +1,42 @@ +#ifndef __ISF_IMF_CONTEXT_H +#define __ISF_IMF_CONTEXT_H + +#include + +typedef struct _EcoreIMFContextISF EcoreIMFContextISF; +typedef struct _EcoreIMFContextISFImpl EcoreIMFContextISFImpl; + +struct _EcoreIMFContextISF { + Ecore_IMF_Context *ctx; + + EcoreIMFContextISFImpl *impl; + + int id; /* Input Context id*/ + struct _EcoreIMFContextISF *next; +}; + +void isf_imf_context_add (Ecore_IMF_Context *ctx); +void isf_imf_context_del (Ecore_IMF_Context *ctx); +void isf_imf_context_client_window_set (Ecore_IMF_Context *ctx, void *window); +void isf_imf_context_client_canvas_set (Ecore_IMF_Context *ctx, void *window); +void isf_imf_context_focus_in (Ecore_IMF_Context *ctx); +void isf_imf_context_focus_out (Ecore_IMF_Context *ctx); +void isf_imf_context_reset (Ecore_IMF_Context *ctx); +void isf_imf_context_cursor_position_set (Ecore_IMF_Context *ctx, int cursor_pos); +void isf_imf_context_cursor_location_set (Ecore_IMF_Context *ctx, int x, int y, int w, int h); +void isf_imf_context_input_mode_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Mode input_mode); +void isf_imf_context_preedit_string_get (Ecore_IMF_Context *ctx, char** str, int *cursor_pos); +void isf_imf_context_preedit_string_with_attributes_get (Ecore_IMF_Context *ctx, char** str, Eina_List **attrs, int *cursor_pos); +void isf_imf_context_use_preedit_set (Ecore_IMF_Context* ctx, Eina_Bool use_preedit); +Eina_Bool isf_imf_context_filter_event (Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event); +void isf_imf_context_prediction_allow_set (Ecore_IMF_Context* ctx, Eina_Bool prediction); +void isf_imf_context_autocapital_type_set (Ecore_IMF_Context* ctx, Ecore_IMF_Autocapital_Type autocapital_type); +void isf_imf_context_input_panel_layout_set (Ecore_IMF_Context* ctx, Ecore_IMF_Input_Panel_Layout layout); +void isf_imf_context_input_panel_show(Ecore_IMF_Context *ctx); +void isf_imf_context_input_panel_hide(Ecore_IMF_Context *ctx); + +EcoreIMFContextISF* isf_imf_context_new (void); +void isf_imf_context_shutdown (void); + +#endif /* __ISF_IMF_CONTEXT_H */ + diff --git a/src/modules/ecore/immodules/scim/scim_module.cpp b/src/modules/ecore/immodules/scim/scim_module.cpp new file mode 100644 index 0000000000..d77fb11f3a --- /dev/null +++ b/src/modules/ecore/immodules/scim/scim_module.cpp @@ -0,0 +1,104 @@ +#include +#include "scim_imcontext.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + static const Ecore_IMF_Context_Info isf_imf_info = { + "scim", /* ID */ + "SCIM immodule for Ecore", /* Description */ + "*", /* Default locales */ + NULL, /* Canvas type */ + 0 /* Canvas required */ + }; + + static Ecore_IMF_Context_Class isf_imf_class = { + isf_imf_context_add, /* add */ + isf_imf_context_del, /* del */ + isf_imf_context_client_window_set, /* client_window_set */ + isf_imf_context_client_canvas_set, /* client_canvas_set */ + isf_imf_context_input_panel_show, /* input_panel_show, - show */ + isf_imf_context_input_panel_hide, /* input_panel_hide, - hide */ + isf_imf_context_preedit_string_get, /* get_preedit_string */ + isf_imf_context_focus_in, /* focus_in */ + isf_imf_context_focus_out, /* focus_out */ + isf_imf_context_reset, /* reset */ + isf_imf_context_cursor_position_set, /* cursor_position_set */ + isf_imf_context_use_preedit_set, /* use_preedit_set */ + isf_imf_context_input_mode_set, /* input_mode_set */ + isf_imf_context_filter_event, /* filter_event */ + isf_imf_context_preedit_string_with_attributes_get, /* preedit_string_with_attribute_get */ + isf_imf_context_prediction_allow_set, /* prediction_allow_set */ + isf_imf_context_autocapital_type_set, /* autocapital_type_set */ + NULL, /* control panel show */ + NULL, /* control panel hide */ + NULL, /* input_panel_layout_set */ + NULL, /* isf_imf_context_input_panel_layout_get, */ + NULL, /* isf_imf_context_input_panel_language_set, */ + NULL, /* isf_imf_context_input_panel_language_get, */ + isf_imf_context_cursor_location_set, /* cursor_location_set */ + NULL, /* input_panel_imdata_set */ + NULL, /* input_panel_imdata_get */ + NULL, /* input_panel_return_key_type_set */ + NULL, /* input_panel_return_key_disabled_set */ + NULL, /* input_panel_caps_lock_mode_set */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + }; + + static Ecore_IMF_Context *imf_module_create (void); + static Ecore_IMF_Context *imf_module_exit (void); + + static Eina_Bool imf_module_init (void) + { + ecore_imf_module_register (&isf_imf_info, imf_module_create, imf_module_exit); + return EINA_TRUE; + } + + static void imf_module_shutdown (void) + { + isf_imf_context_shutdown (); + } + + static Ecore_IMF_Context *imf_module_create (void) + { + Ecore_IMF_Context *ctx = NULL; + EcoreIMFContextISF *ctxd = NULL; + + ctxd = isf_imf_context_new (); + if (!ctxd) + { + printf ("isf_imf_context_new () failed!!!\n"); + return NULL; + } + + ctx = ecore_imf_context_new (&isf_imf_class); + if (!ctx) + { + delete ctxd; + return NULL; + } + + ecore_imf_context_data_set (ctx, ctxd); + + return ctx; + } + + static Ecore_IMF_Context *imf_module_exit (void) + { + return NULL; + } + + EINA_MODULE_INIT(imf_module_init); + EINA_MODULE_SHUTDOWN(imf_module_shutdown); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + diff --git a/src/modules/ecore/immodules/xim/ecore_imf_xim.c b/src/modules/ecore/immodules/xim/ecore_imf_xim.c new file mode 100644 index 0000000000..64fc46c122 --- /dev/null +++ b/src/modules/ecore/immodules/xim/ecore_imf_xim.c @@ -0,0 +1,1555 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLAMP(x, low, high) (x > high) ? high : (x < low) ? low : x +#define _(x) x + +#ifdef ENABLE_XIM +static Eina_List *open_ims = NULL; +#endif + +#define FEEDBACK_MASK (XIMReverse | XIMUnderline | XIMHighlight) + +typedef struct _XIM_Im_Info XIM_Im_Info; + +typedef struct _Ecore_IMF_Context_Data Ecore_IMF_Context_Data; + +struct _XIM_Im_Info +{ + Ecore_X_Window win; + Ecore_IMF_Context_Data *user; + char *locale; + XIM im; + Eina_List *ics; + Eina_Bool reconnecting; + XIMStyles *xim_styles; + Eina_Bool supports_string_conversion : 1; + Eina_Bool supports_cursor : 1; +}; + +struct _Ecore_IMF_Context_Data +{ + Ecore_X_Window win; + long mask; + XIC ic; /* Input context for composed characters */ + char *locale; + XIM_Im_Info *im_info; + int preedit_length; + int preedit_cursor; + Eina_Unicode *preedit_chars; + Eina_Bool use_preedit; + Eina_Bool finalizing; + Eina_Bool has_focus; + Eina_Bool in_toplevel; + XIMFeedback *feedbacks; + + XIMCallback destroy_cb; + + XIMCallback preedit_start_cb; + XIMCallback preedit_done_cb; + XIMCallback preedit_draw_cb; + XIMCallback preedit_caret_cb; +}; + +/* prototype */ +Ecore_IMF_Context_Data *imf_context_data_new(); +void imf_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data); + +#ifdef ENABLE_XIM +static void add_feedback_attr(Eina_List **attrs, + const char *str, + XIMFeedback feedback, + int start_pos, + int end_pos); + +static void reinitialize_ic(Ecore_IMF_Context *ctx); +static void set_ic_client_window(Ecore_IMF_Context *ctx, + Ecore_X_Window window); +static int preedit_start_callback(XIC xic, + XPointer client_data, + XPointer call_data); +static void preedit_done_callback(XIC xic, + XPointer client_data, + XPointer call_data); +static int xim_text_to_utf8(Ecore_IMF_Context *ctx, + XIMText *xim_text, + char **text); +static void preedit_draw_callback(XIC xic, + XPointer client_data, + XIMPreeditDrawCallbackStruct *call_data); +static void preedit_caret_callback(XIC xic, + XPointer client_data, + XIMPreeditCaretCallbackStruct *call_data); +static XVaNestedList preedit_callback_set(Ecore_IMF_Context *ctx); +static XIC get_ic(Ecore_IMF_Context *ctx); +static XIM_Im_Info *get_im(Ecore_X_Window window, + char *locale); +static void xim_info_try_im(XIM_Im_Info *info); +static void xim_info_display_closed(Ecore_X_Display *display, + int is_error, + XIM_Im_Info *info); +static void xim_instantiate_callback(Display *display, + XPointer client_data, + XPointer call_data); +static void setup_im(XIM_Im_Info *info); +static void xim_destroy_callback(XIM xim, + XPointer client_data, + XPointer call_data); +#endif + +#ifdef ENABLE_XIM +static unsigned int +utf8_offset_to_index(const char *str, int offset) +{ + int idx = 0; + int i; + for (i = 0; i < offset; i++) + { + eina_unicode_utf8_get_next(str, &idx); + } + + return idx; +} + +#endif + +static void +_ecore_imf_context_xim_add(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("in"); +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data = NULL; + + imf_context_data = imf_context_data_new(); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + imf_context_data->use_preedit = EINA_TRUE; + imf_context_data->finalizing = EINA_FALSE; + imf_context_data->has_focus = EINA_FALSE; + imf_context_data->in_toplevel = EINA_FALSE; + + ecore_imf_context_data_set(ctx, imf_context_data); +#else + (void)ctx; +#endif +} + +static void +_ecore_imf_context_xim_del(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("in"); +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + imf_context_data->finalizing = EINA_TRUE; + if (imf_context_data->im_info && !imf_context_data->im_info->ics->next) + { + if (imf_context_data->im_info->reconnecting == EINA_TRUE) + { + Ecore_X_Display *dsp; + dsp = ecore_x_display_get(); + XUnregisterIMInstantiateCallback(dsp, + NULL, NULL, NULL, + xim_instantiate_callback, + (XPointer)imf_context_data->im_info); + } + else if (imf_context_data->im_info->im) + { + XIMCallback im_destroy_callback; + im_destroy_callback.client_data = NULL; + im_destroy_callback.callback = NULL; + XSetIMValues(imf_context_data->im_info->im, + XNDestroyCallback, &im_destroy_callback, + NULL); + } + } + + set_ic_client_window(ctx, 0); + + imf_context_data_destroy(imf_context_data); +#else + (void)ctx; +#endif +} + +static void +_ecore_imf_context_xim_client_window_set(Ecore_IMF_Context *ctx, + void *window) +{ + EINA_LOG_DBG("in"); +#ifdef ENABLE_XIM + set_ic_client_window(ctx, (Ecore_X_Window)((Ecore_Window)window)); +#else + (void)ctx; + (void)window; +#endif +} + +static void +_ecore_imf_context_xim_preedit_string_get(Ecore_IMF_Context *ctx, + char **str, + int *cursor_pos) +{ + EINA_LOG_DBG("in"); +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data; + char *utf8; + int len; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + if (imf_context_data->preedit_chars) + { + utf8 = eina_unicode_unicode_to_utf8(imf_context_data->preedit_chars, + &len); + if (str) + *str = utf8; + else + free(utf8); + } + else + { + if (str) + *str = NULL; + if (cursor_pos) + *cursor_pos = 0; + } + + if (cursor_pos) + *cursor_pos = imf_context_data->preedit_cursor; +#else + (void)ctx; + if (str) + *str = NULL; + if (cursor_pos) + *cursor_pos = 0; +#endif +} + +static void +_ecore_imf_context_xim_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx, + char **str, + Eina_List **attrs, + int *cursor_pos) +{ + EINA_LOG_DBG("in"); + +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); + + _ecore_imf_context_xim_preedit_string_get(ctx, str, cursor_pos); + + if (!attrs) return; + if (!imf_context_data || !imf_context_data->feedbacks) return; + + int i = 0; + XIMFeedback last_feedback = 0; + int start = -1; + + for (i = 0; i < imf_context_data->preedit_length; i++) + { + XIMFeedback new_feedback = imf_context_data->feedbacks[i] & FEEDBACK_MASK; + + if (new_feedback != last_feedback) + { + if (start >= 0) + add_feedback_attr(attrs, *str, last_feedback, start, i); + + last_feedback = new_feedback; + start = i; + } + } + + if (start >= 0) + add_feedback_attr(attrs, *str, last_feedback, start, i); +#else + (void)ctx; + if (str) + *str = NULL; + if (attrs) + *attrs = NULL; + if (cursor_pos) + *cursor_pos = 0; +#endif +} + +static void +_ecore_imf_context_xim_focus_in(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("in"); +#ifdef ENABLE_XIM + XIC ic; + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + ic = imf_context_data->ic; + imf_context_data->has_focus = EINA_TRUE; + + if (ecore_imf_context_input_panel_enabled_get(ctx)) + ecore_imf_context_input_panel_show(ctx); + + if (ic) + { + char *str; + +#ifdef X_HAVE_UTF8_STRING + if ((str = Xutf8ResetIC(ic))) +#else + if ((str = XmbResetIC(ic))) +#endif + XFree(str); + + XSetICFocus(ic); + } +#else + (void)ctx; +#endif +} + +static void +_ecore_imf_context_xim_focus_out(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("%s in", __FUNCTION__); +#ifdef ENABLE_XIM + XIC ic; + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + if (imf_context_data->has_focus == EINA_TRUE) + { + imf_context_data->has_focus = EINA_FALSE; + ic = imf_context_data->ic; + if (ic) + XUnsetICFocus(ic); + + if (ecore_imf_context_input_panel_enabled_get(ctx)) + ecore_imf_context_input_panel_hide(ctx); + } +#else + (void)ctx; +#endif +} + +static void +_ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("%s in", __FUNCTION__); +#ifdef ENABLE_XIM + XIC ic; + Ecore_IMF_Context_Data *imf_context_data; + char *result; + + /* restore conversion state after resetting ic later */ + XIMPreeditState preedit_state = XIMPreeditUnKnown; + XVaNestedList preedit_attr; + Eina_Bool have_preedit_state = EINA_FALSE; + + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + ic = imf_context_data->ic; + if (!ic) + return; + + if (imf_context_data->preedit_length == 0) + return; + + preedit_attr = XVaCreateNestedList(0, + XNPreeditState, &preedit_state, + NULL); + if (!XGetICValues(ic, + XNPreeditAttributes, preedit_attr, + NULL)) + have_preedit_state = EINA_TRUE; + + XFree(preedit_attr); + + result = XmbResetIC(ic); + + preedit_attr = XVaCreateNestedList(0, + XNPreeditState, preedit_state, + NULL); + if (have_preedit_state) + XSetICValues(ic, + XNPreeditAttributes, preedit_attr, + NULL); + + XFree(preedit_attr); + + if (imf_context_data->feedbacks) + { + free(imf_context_data->feedbacks); + imf_context_data->feedbacks = NULL; + } + + if (imf_context_data->preedit_length) + { + imf_context_data->preedit_length = 0; + free(imf_context_data->preedit_chars); + imf_context_data->preedit_chars = NULL; + + ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + + if (result) + { + char *result_utf8 = strdup(result); + if (result_utf8) + { + ecore_imf_context_commit_event_add(ctx, result_utf8); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, result_utf8); + free(result_utf8); + } + } + + XFree(result); +#else + (void)ctx; +#endif +} + +static void +_ecore_imf_context_xim_use_preedit_set(Ecore_IMF_Context *ctx, + Eina_Bool use_preedit) +{ + EINA_LOG_DBG("in"); +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + use_preedit = use_preedit != EINA_FALSE; + + if (imf_context_data->use_preedit != use_preedit) + { + imf_context_data->use_preedit = use_preedit; + reinitialize_ic(ctx); + } +#else + (void)ctx; + (void)use_preedit; +#endif +} + +#ifdef ENABLE_XIM +static void +add_feedback_attr(Eina_List **attrs, + const char *str, + XIMFeedback feedback, + int start_pos, + int end_pos) +{ + Ecore_IMF_Preedit_Attr *attr = NULL; + + unsigned int start_index = utf8_offset_to_index(str, start_pos); + unsigned int end_index = utf8_offset_to_index(str, end_pos); + + if (feedback & FEEDBACK_MASK) + { + attr = (Ecore_IMF_Preedit_Attr *)calloc(1, sizeof(Ecore_IMF_Preedit_Attr)); + attr->start_index = start_index; + attr->end_index = end_index; + *attrs = eina_list_append(*attrs, (void *)attr); + } + + if (feedback & XIMUnderline) + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1; + + if (feedback & XIMReverse) + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2; + + if (feedback & XIMHighlight) + attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3; +} + +#endif + +static void +_ecore_imf_context_xim_cursor_location_set(Ecore_IMF_Context *ctx, + int x, int y, int w, int h) +{ + EINA_LOG_DBG("%s in", __FUNCTION__); + +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data; + XIC ic; + XVaNestedList preedit_attr; + XPoint spot; + + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + ic = imf_context_data->ic; + if (!ic) + return; + + spot.x = x; + spot.y = y + h; + + preedit_attr = XVaCreateNestedList(0, + XNSpotLocation, &spot, + NULL); + XSetICValues(ic, + XNPreeditAttributes, preedit_attr, + NULL); + + XFree(preedit_attr); +#else + (void)ctx; + (void)x; + (void)y; + (void)h; +#endif + (void)(w); // yes w is unused, but only a bi-product of the algorithm +} + +static void +_ecore_imf_context_xim_input_panel_show(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("%s in", __FUNCTION__); + +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + ecore_x_e_virtual_keyboard_state_set + (imf_context_data->win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON); +#else + (void)ctx; +#endif +} + +static void +_ecore_imf_context_xim_input_panel_hide(Ecore_IMF_Context *ctx) +{ + EINA_LOG_DBG("%s in", __FUNCTION__); + +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + ecore_x_e_virtual_keyboard_state_set + (imf_context_data->win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF); +#else + (void)ctx; +#endif +} + +#ifdef ENABLE_XIM +static unsigned int +_ecore_x_event_reverse_modifiers(unsigned int state) +{ + unsigned int modifiers = 0; + + /**< "Control" is pressed */ + if (state & ECORE_IMF_KEYBOARD_MODIFIER_CTRL) + modifiers |= ECORE_X_MODIFIER_CTRL; + + /**< "Alt" is pressed */ + if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALT) + modifiers |= ECORE_X_MODIFIER_ALT; + + /**< "Shift" is pressed */ + if (state & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT) + modifiers |= ECORE_X_MODIFIER_SHIFT; + + /**< "Win" (between "Ctrl" and "Alt") is pressed */ + if (state & ECORE_IMF_KEYBOARD_MODIFIER_WIN) + modifiers |= ECORE_X_MODIFIER_WIN; + + /**< "AltGr" is pressed */ + if (state & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR) + modifiers |= ECORE_X_MODIFIER_ALTGR; + + return modifiers; +} + +static unsigned int +_ecore_x_event_reverse_locks(unsigned int state) +{ + unsigned int locks = 0; + + /**< "Num" lock is active */ + if (state & ECORE_IMF_KEYBOARD_LOCK_NUM) + locks |= ECORE_X_LOCK_NUM; + + if (state & ECORE_IMF_KEYBOARD_LOCK_CAPS) + locks |= ECORE_X_LOCK_CAPS; + + if (state & ECORE_IMF_KEYBOARD_LOCK_SCROLL) + locks |= ECORE_X_LOCK_SCROLL; + + return locks; +} + +static KeyCode +_keycode_get(Ecore_X_Display *dsp, + const char *keyname) +{ + KeyCode keycode; + + // EINA_LOG_DBG("keyname:%s keysym:%lu", keyname, XStringToKeysym(keyname)); + if (strcmp(keyname, "Keycode-0") == 0) + keycode = 0; + else + keycode = XKeysymToKeycode(dsp, XStringToKeysym(keyname)); + + return keycode; +} + +#endif + +static Eina_Bool +_ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, + Ecore_IMF_Event_Type type, + Ecore_IMF_Event *event) +{ + EINA_LOG_DBG("%s in", __FUNCTION__); +#ifdef ENABLE_XIM + Ecore_IMF_Context_Data *imf_context_data; + XIC ic; + + Ecore_X_Display *dsp; + Ecore_X_Window win; + + int val; + char compose_buffer[256]; + KeySym sym; + char *compose = NULL; + char *tmp = NULL; + Eina_Bool result = EINA_FALSE; + + imf_context_data = ecore_imf_context_data_get(ctx); + if (!imf_context_data) return EINA_FALSE; + ic = imf_context_data->ic; + if (!ic) + ic = get_ic(ctx); + + if (type == ECORE_IMF_EVENT_KEY_DOWN) + { + XKeyPressedEvent xev; + Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; + EINA_LOG_DBG("ECORE_IMF_EVENT_KEY_DOWN"); + + dsp = ecore_x_display_get(); + win = imf_context_data->win; + + xev.type = KeyPress; + xev.serial = 0; /* hope it doesn't matter */ + xev.send_event = 0; + xev.display = dsp; + xev.window = win; + xev.root = ecore_x_window_root_get(win); + xev.subwindow = win; + xev.time = ev->timestamp; + xev.x = xev.x_root = 0; + xev.y = xev.y_root = 0; + xev.state = 0; + xev.state |= _ecore_x_event_reverse_modifiers(ev->modifiers); + xev.state |= _ecore_x_event_reverse_locks(ev->locks); + xev.keycode = _keycode_get(dsp, ev->keyname); + xev.same_screen = True; + + if (ic) + { + Status mbstatus; +#ifdef X_HAVE_UTF8_STRING + val = Xutf8LookupString(ic, + &xev, + compose_buffer, + sizeof(compose_buffer) - 1, + &sym, + &mbstatus); +#else /* ifdef X_HAVE_UTF8_STRING */ + val = XmbLookupString(ic, + &xev, + compose_buffer, + sizeof(compose_buffer) - 1, + &sym, + &mbstatus); +#endif /* ifdef X_HAVE_UTF8_STRING */ + if (mbstatus == XBufferOverflow) + { + tmp = malloc(sizeof (char) * (val + 1)); + if (!tmp) + return EINA_FALSE; + + compose = tmp; + +#ifdef X_HAVE_UTF8_STRING + val = Xutf8LookupString(ic, + &xev, + tmp, + val, + &sym, + &mbstatus); +#else /* ifdef X_HAVE_UTF8_STRING */ + val = XmbLookupString(ic, + &xev, + tmp, + val, + &sym, + &mbstatus); +#endif /* ifdef X_HAVE_UTF8_STRING */ + 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 /* ifndef X_HAVE_UTF8_STRING */ + } + else + compose = NULL; + } + else if (val > 0) + { + compose_buffer[val] = '\0'; +#ifdef X_HAVE_UTF8_STRING + compose = strdup(compose_buffer); +#else /* ifdef X_HAVE_UTF8_STRING */ + compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", + compose_buffer); +#endif /* ifdef X_HAVE_UTF8_STRING */ + } + } + else + { + compose = strdup(ev->compose); + } + + if (compose) + { + Eina_Unicode *unicode; + int len; + unicode = eina_unicode_utf8_to_unicode(compose, &len); + if (!unicode) abort(); + if (unicode[0] >= 0x20 && unicode[0] != 0x7f) + { + ecore_imf_context_commit_event_add(ctx, compose); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, compose); + result = EINA_TRUE; + } + free(compose); + free(unicode); + } + } + + return result; +#else + (void)ctx; + (void)type; + (void)event; + return EINA_FALSE; +#endif +} + +static const Ecore_IMF_Context_Info xim_info = { + .id = "xim", + .description = _("X input method"), + .default_locales = "ko:ja:th:zh", + .canvas_type = "evas", + .canvas_required = 1, +}; + +static Ecore_IMF_Context_Class xim_class = { + .add = _ecore_imf_context_xim_add, + .del = _ecore_imf_context_xim_del, + .client_window_set = _ecore_imf_context_xim_client_window_set, + .client_canvas_set = NULL, + .show = _ecore_imf_context_xim_input_panel_show, + .hide = _ecore_imf_context_xim_input_panel_hide, + .preedit_string_get = _ecore_imf_context_xim_preedit_string_get, + .focus_in = _ecore_imf_context_xim_focus_in, + .focus_out = _ecore_imf_context_xim_focus_out, + .reset = _ecore_imf_context_xim_reset, + .cursor_position_set = NULL, + .use_preedit_set = _ecore_imf_context_xim_use_preedit_set, + .input_mode_set = NULL, + .filter_event = _ecore_imf_context_xim_filter_event, + .preedit_string_with_attributes_get = _ecore_imf_context_xim_preedit_string_with_attributes_get, + .prediction_allow_set = NULL, + .autocapital_type_set = NULL, + .control_panel_show = NULL, + .control_panel_hide = NULL, + .input_panel_layout_set = NULL, + .input_panel_layout_get = NULL, + .input_panel_language_set = NULL, + .input_panel_language_get = NULL, + .cursor_location_set = _ecore_imf_context_xim_cursor_location_set, + .input_panel_imdata_set = NULL, + .input_panel_imdata_get = NULL, + .input_panel_return_key_type_set = NULL, + .input_panel_return_key_disabled_set = NULL, + .input_panel_caps_lock_mode_set = NULL +}; + +static Ecore_IMF_Context * +xim_imf_module_create(void) +{ + EINA_LOG_DBG("%s in", __FUNCTION__); + Ecore_IMF_Context *ctx = NULL; + + ctx = ecore_imf_context_new(&xim_class); + if (!ctx) + goto error; + + return ctx; + +error: + free(ctx); + return NULL; +} + +static Ecore_IMF_Context * +xim_imf_module_exit(void) +{ + return NULL; +} + +Eina_Bool +ecore_imf_xim_init(void) +{ + EINA_LOG_DBG("%s in", __FUNCTION__); + eina_init(); + ecore_x_init(NULL); + ecore_imf_module_register(&xim_info, + xim_imf_module_create, + xim_imf_module_exit); + + return EINA_TRUE; +} + +void +ecore_imf_xim_shutdown(void) +{ +#ifdef ENABLE_XIM + while (open_ims) + { + XIM_Im_Info *info = open_ims->data; + Ecore_X_Display *display = ecore_x_display_get(); + + xim_info_display_closed(display, EINA_FALSE, info); + } +#endif + + ecore_x_shutdown(); + eina_shutdown(); +} + +EINA_MODULE_INIT(ecore_imf_xim_init); +EINA_MODULE_SHUTDOWN(ecore_imf_xim_shutdown); + +#ifdef ENABLE_XIM +/* + * internal functions + */ +Ecore_IMF_Context_Data * +imf_context_data_new() +{ + Ecore_IMF_Context_Data *imf_context_data = NULL; + char *locale; + + locale = setlocale(LC_CTYPE, ""); + if (!locale) return NULL; + + if (!XSupportsLocale()) return NULL; + + imf_context_data = calloc(1, sizeof(Ecore_IMF_Context_Data)); + EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, NULL); + + imf_context_data->locale = strdup(locale); + if (!imf_context_data->locale) goto error; + + return imf_context_data; +error: + imf_context_data_destroy(imf_context_data); + return NULL; +} + +void +imf_context_data_destroy(Ecore_IMF_Context_Data *imf_context_data) +{ + if (!imf_context_data) + return; + + if (imf_context_data->ic) + XDestroyIC(imf_context_data->ic); + + free(imf_context_data->preedit_chars); + + if (imf_context_data->feedbacks) + { + free(imf_context_data->feedbacks); + imf_context_data->feedbacks = NULL; + } + + free(imf_context_data->locale); + free(imf_context_data); +} + +static int +preedit_start_callback(XIC xic EINA_UNUSED, + XPointer client_data, + XPointer call_data EINA_UNUSED) +{ + EINA_LOG_DBG("in"); + Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + if (!imf_context_data) return -1; + + if (imf_context_data->finalizing == EINA_FALSE) + { + ecore_imf_context_preedit_start_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + } + return -1; +} + +static void +preedit_done_callback(XIC xic EINA_UNUSED, + XPointer client_data, + XPointer call_data EINA_UNUSED) +{ + EINA_LOG_DBG("in"); + Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + if (imf_context_data->preedit_length) + { + imf_context_data->preedit_length = 0; + free(imf_context_data->preedit_chars); + imf_context_data->preedit_chars = NULL; + ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + + if (imf_context_data->finalizing == EINA_FALSE) + { + ecore_imf_context_preedit_end_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + } +} + +/* FIXME */ +static int +xim_text_to_utf8(Ecore_IMF_Context *ctx EINA_UNUSED, + XIMText *xim_text, + char **text) +{ + int text_length = 0; + char *result = NULL; + + if (xim_text && xim_text->string.multi_byte) + { + if (xim_text->encoding_is_wchar) + { + EINA_LOG_WARN("Wide character return from Xlib not currently supported"); + *text = NULL; + return 0; + } + + /* XXX Convert to UTF-8 */ + result = strdup(xim_text->string.multi_byte); + if (result) + { + text_length = eina_unicode_utf8_get_len(result); + if (text_length != xim_text->length) + { + EINA_LOG_WARN("Size mismatch when converting text from input method: supplied length = %d\n, result length = %d", xim_text->length, text_length); + } + } + else + { + EINA_LOG_WARN("Error converting text from IM to UCS-4"); + *text = NULL; + return 0; + } + + *text = result; + return text_length; + } + else + { + *text = NULL; + return 0; + } +} + +static void +preedit_draw_callback(XIC xic EINA_UNUSED, + XPointer client_data, + XIMPreeditDrawCallbackStruct *call_data) +{ + EINA_LOG_DBG("in"); + Eina_Bool ret = EINA_FALSE; + Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; + Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); + XIMText *t = call_data->text; + char *tmp; + Eina_Unicode *new_text = NULL; + Eina_UStrbuf *preedit_bufs = NULL; + int new_text_length; + int i = 0; + + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + preedit_bufs = eina_ustrbuf_new(); + if (imf_context_data->preedit_chars) + { + ret = eina_ustrbuf_append(preedit_bufs, imf_context_data->preedit_chars); + if (ret == EINA_FALSE) goto done; + } + + new_text_length = xim_text_to_utf8(ctx, t, &tmp); + if (tmp) + { + int tmp_len; + new_text = eina_unicode_utf8_to_unicode((const char *)tmp, &tmp_len); + free(tmp); + } + + if (t == NULL) + { + /* delete string */ + ret = eina_ustrbuf_remove(preedit_bufs, + call_data->chg_first, call_data->chg_length); + } + else if (call_data->chg_length == 0) + { + /* insert string */ + ret = eina_ustrbuf_insert(preedit_bufs, new_text, call_data->chg_first); + } + else if (call_data->chg_length > 0) + { + /* replace string */ + ret = eina_ustrbuf_remove(preedit_bufs, + call_data->chg_first, call_data->chg_length); + if (ret == EINA_FALSE) goto done; + + ret = eina_ustrbuf_insert_n(preedit_bufs, new_text, + new_text_length, call_data->chg_first); + if (ret == EINA_FALSE) goto done; + } + else + { + ret = EINA_FALSE; + } + +done: + if (ret == EINA_TRUE) + { + free(imf_context_data->preedit_chars); + imf_context_data->preedit_chars = + eina_ustrbuf_string_steal(preedit_bufs); + imf_context_data->preedit_length = + eina_unicode_strlen(imf_context_data->preedit_chars); + + if (imf_context_data->feedbacks) + { + free(imf_context_data->feedbacks); + imf_context_data->feedbacks = NULL; + } + + if (imf_context_data->preedit_length > 0) + { + imf_context_data->feedbacks = calloc(imf_context_data->preedit_length, sizeof(XIMFeedback)); + + for (i = 0; i < imf_context_data->preedit_length; i++) + imf_context_data->feedbacks[i] = t->feedback[i]; + } + + ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + + free(new_text); + eina_ustrbuf_free(preedit_bufs); +} + +static void +preedit_caret_callback(XIC xic EINA_UNUSED, + XPointer client_data, + XIMPreeditCaretCallbackStruct *call_data) +{ + EINA_LOG_DBG("in"); + Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + if (call_data->direction == XIMAbsolutePosition) + { + // printf("call_data->position:%d\n", call_data->position); + imf_context_data->preedit_cursor = call_data->position; + if (imf_context_data->finalizing == EINA_FALSE) + { + ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + } +} + +static XVaNestedList +preedit_callback_set(Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + + imf_context_data->preedit_start_cb.client_data = (XPointer)ctx; + imf_context_data->preedit_start_cb.callback = (XIMProc)preedit_start_callback; + + imf_context_data->preedit_done_cb.client_data = (XPointer)ctx; + imf_context_data->preedit_done_cb.callback = (XIMProc)preedit_done_callback; + + imf_context_data->preedit_draw_cb.client_data = (XPointer)ctx; + imf_context_data->preedit_draw_cb.callback = (XIMProc)preedit_draw_callback; + + imf_context_data->preedit_caret_cb.client_data = (XPointer)ctx; + imf_context_data->preedit_caret_cb.callback = (XIMProc)preedit_caret_callback; + + return XVaCreateNestedList(0, + XNPreeditStartCallback, + &imf_context_data->preedit_start_cb, + XNPreeditDoneCallback, + &imf_context_data->preedit_done_cb, + XNPreeditDrawCallback, + &imf_context_data->preedit_draw_cb, + XNPreeditCaretCallback, + &imf_context_data->preedit_caret_cb, + NULL); +} + +static XIC +get_ic(Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Context_Data *imf_context_data; + XIC ic; + imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, NULL); + + ic = imf_context_data->ic; + if (!ic) + { + XIM_Im_Info *im_info = imf_context_data->im_info; + XVaNestedList preedit_attr = NULL; + XIMStyle im_style = 0; + XPoint spot = { 0, 0 }; + char *name = NULL; + + if (!im_info) + { + EINA_LOG_WARN("Doesn't open XIM."); + return NULL; + } + + // supported styles +#if 0 + int i; + if (im_info->xim_styles) + { + for (i = 0; i < im_info->xim_styles->count_styles; i++) + { + printf("%i: ", i); + if (im_info->xim_styles->supported_styles[i] & XIMPreeditCallbacks) + printf("XIMPreeditCallbacks | "); + if (im_info->xim_styles->supported_styles[i] & XIMPreeditPosition) + printf("XIMPreeditPosition | "); + if (im_info->xim_styles->supported_styles[i] & XIMPreeditArea) + printf("XIMPreeditArea | "); + if (im_info->xim_styles->supported_styles[i] & XIMPreeditNothing) + printf("XIMPreeditNothing | "); + if (im_info->xim_styles->supported_styles[i] & XIMPreeditNone) + printf("XIMPreeditNone | "); + if (im_info->xim_styles->supported_styles[i] & XIMStatusArea) + printf("XIMStatusArea | "); + if (im_info->xim_styles->supported_styles[i] & XIMStatusCallbacks) + printf("XIMStatusCallbacks | "); + if (im_info->xim_styles->supported_styles[i] & XIMStatusNothing) + printf("XIMStatusNothing | "); + if (im_info->xim_styles->supported_styles[i] & XIMStatusNone) + printf("XIMStatusNone | "); + printf("\n"); + } + } +#endif + // "OverTheSpot" = XIMPreeditPosition | XIMStatusNothing + // "OffTheSpot" = XIMPreeditArea | XIMStatusArea + // "Root" = XIMPreeditNothing | XIMStatusNothing + + if (imf_context_data->use_preedit == EINA_TRUE) + { + if (im_info->supports_cursor) + { + // kinput2 DOES do this... + XFontSet fs; + char **missing_charset_list; + int missing_charset_count; + char *def_string; + + im_style |= XIMPreeditPosition; + im_style |= XIMStatusNothing; + fs = XCreateFontSet(ecore_x_display_get(), + "fixed", + &missing_charset_list, + &missing_charset_count, + &def_string); + preedit_attr = XVaCreateNestedList(0, + XNSpotLocation, &spot, + XNFontSet, fs, + NULL); + } + else + { + im_style |= XIMPreeditCallbacks; + im_style |= XIMStatusNothing; + preedit_attr = preedit_callback_set(ctx); + } + name = XNPreeditAttributes; + } + else + { + im_style |= XIMPreeditNothing; + im_style |= XIMStatusNothing; + } + + if (!im_info->xim_styles) + { + EINA_LOG_WARN("No XIM styles supported! Wanted %#llx", + (unsigned long long)im_style); + im_style = 0; + } + else + { + XIMStyle fallback = 0; + int i; + + for (i = 0; i < im_info->xim_styles->count_styles; i++) + { + XIMStyle cur = im_info->xim_styles->supported_styles[i]; + if (cur == im_style) + break; + else if (cur == (XIMPreeditNothing | XIMStatusNothing)) + /* TODO: fallback is just that or the anyone? */ + fallback = cur; + } + + if (i == im_info->xim_styles->count_styles) + { + if (fallback) + { + EINA_LOG_WARN("Wanted XIM style %#llx not found, " + "using fallback %#llx instead.", + (unsigned long long)im_style, + (unsigned long long)fallback); + im_style = fallback; + } + else + { + EINA_LOG_WARN("Wanted XIM style %#llx not found, " + "no fallback supported.", + (unsigned long long)im_style); + im_style = 0; + } + } + } + + if ((im_info->im) && (im_style)) + { + ic = XCreateIC(im_info->im, + XNInputStyle, im_style, + XNClientWindow, imf_context_data->win, + name, preedit_attr, NULL); + } + XFree(preedit_attr); + if (ic) + { + unsigned long mask = 0xaaaaaaaa; + XGetICValues(ic, + XNFilterEvents, &mask, + NULL); + imf_context_data->mask = mask; + ecore_x_event_mask_set(imf_context_data->win, mask); + } + + imf_context_data->ic = ic; + if (ic && imf_context_data->has_focus == EINA_TRUE) + XSetICFocus(ic); + } + + return ic; +} + +static void +reinitialize_ic(Ecore_IMF_Context *ctx) +{ + Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + XIC ic = imf_context_data->ic; + if (ic) + { + XDestroyIC(ic); + imf_context_data->ic = NULL; + if (imf_context_data->preedit_length) + { + imf_context_data->preedit_length = 0; + free(imf_context_data->preedit_chars); + imf_context_data->preedit_chars = NULL; + ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } + } +} + +static void +set_ic_client_window(Ecore_IMF_Context *ctx, + Ecore_X_Window window) +{ + EINA_LOG_DBG("in"); + Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); + Ecore_X_Window old_win; + + EINA_SAFETY_ON_NULL_RETURN(imf_context_data); + + /* reinitialize IC */ + reinitialize_ic(ctx); + + old_win = imf_context_data->win; + EINA_LOG_DBG("old_win:%d window:%d ", old_win, window); + if (old_win != 0 && old_win != window) /* XXX how do check window... */ + { + XIM_Im_Info *info; + info = imf_context_data->im_info; + info->ics = eina_list_remove(info->ics, imf_context_data); + if (imf_context_data->im_info) + imf_context_data->im_info->user = NULL; + imf_context_data->im_info = NULL; + } + + imf_context_data->win = window; + + if (window) /* XXX */ + { + XIM_Im_Info *info = NULL; + info = get_im(window, imf_context_data->locale); + imf_context_data->im_info = info; + imf_context_data->im_info->ics = + eina_list_prepend(imf_context_data->im_info->ics, + imf_context_data); + if (imf_context_data->im_info) + imf_context_data->im_info->user = imf_context_data; + } +} + +static XIM_Im_Info * +get_im(Ecore_X_Window window, + char *locale) +{ + EINA_LOG_DBG("in"); + + Eina_List *l; + XIM_Im_Info *im_info = NULL; + XIM_Im_Info *info = NULL; + EINA_LIST_FOREACH (open_ims, l, im_info) + { + if (strcmp(im_info->locale, locale) == 0) + { + if (im_info->im) + { + return im_info; + } + else + { + info = im_info; + break; + } + } + } + + if (!info) + { + info = calloc(1, sizeof(XIM_Im_Info)); + if (!info) return NULL; + open_ims = eina_list_prepend(open_ims, info); + info->win = window; + info->locale = strdup(locale); + info->reconnecting = EINA_FALSE; + } + + xim_info_try_im(info); + return info; +} + +/* initialize info->im */ +static void +xim_info_try_im(XIM_Im_Info *info) +{ + Ecore_X_Display *dsp; + + assert(info->im == NULL); + if (info->reconnecting == EINA_TRUE) + return; + + if (XSupportsLocale()) + { + if (!XSetLocaleModifiers("")) + EINA_LOG_WARN("Unable to set locale modifiers with XSetLocaleModifiers()"); + dsp = ecore_x_display_get(); + info->im = XOpenIM(dsp, NULL, NULL, NULL); + if (!info->im) + { + XRegisterIMInstantiateCallback(dsp, + NULL, NULL, NULL, + xim_instantiate_callback, + (XPointer)info); + info->reconnecting = EINA_TRUE; + return; + } + setup_im(info); + } +} + +static void +xim_info_display_closed(Ecore_X_Display *display EINA_UNUSED, + int is_error EINA_UNUSED, + XIM_Im_Info *info) +{ + Eina_List *ics, *tmp_list; + Ecore_IMF_Context *ctx; + + open_ims = eina_list_remove(open_ims, info); + + ics = info->ics; + info->ics = NULL; + + EINA_LIST_FOREACH (ics, tmp_list, ctx) + set_ic_client_window(ctx, 0); + + EINA_LIST_FREE (ics, ctx) + { + Ecore_IMF_Context_Data *imf_context_data; + imf_context_data = ecore_imf_context_data_get(ctx); + imf_context_data_destroy(imf_context_data); + } + + free(info->locale); + + if (info->im) + XCloseIM(info->im); + + free(info); +} + +static void +xim_instantiate_callback(Display *display, + XPointer client_data, + XPointer call_data EINA_UNUSED) +{ + XIM_Im_Info *info = (XIM_Im_Info *)client_data; + XIM im = NULL; + + im = XOpenIM(display, NULL, NULL, NULL); + + if (!im) + { + fprintf(stderr, "Failed to connect to IM\n"); + return; + } + + info->im = im; + setup_im(info); + + XUnregisterIMInstantiateCallback(display, NULL, NULL, NULL, + xim_instantiate_callback, + (XPointer)info); + info->reconnecting = EINA_FALSE; +} + +static void +setup_im(XIM_Im_Info *info) +{ + XIMValuesList *ic_values = NULL; + XIMCallback im_destroy_callback; + + if (!info->im) + return; + + im_destroy_callback.client_data = (XPointer)info; + im_destroy_callback.callback = (XIMProc)xim_destroy_callback; + XSetIMValues(info->im, + XNDestroyCallback, &im_destroy_callback, + NULL); + + XGetIMValues(info->im, + XNQueryInputStyle, &info->xim_styles, + XNQueryICValuesList, &ic_values, + NULL); + + if (ic_values) + { + int i; + + for (i = 0; i < ic_values->count_values; i++) + { + if (!strcmp(ic_values->supported_values[i], + XNStringConversionCallback)) + info->supports_string_conversion = EINA_TRUE; + if (!strcmp(ic_values->supported_values[i], + XNCursor)) + info->supports_cursor = EINA_TRUE; + } +#if 0 + printf("values........\n"); + for (i = 0; i < ic_values->count_values; i++) + printf("%s\n", ic_values->supported_values[i]); + printf("styles........\n"); + for (i = 0; i < info->xim_styles->count_styles; i++) + printf("%lx\n", info->xim_styles->supported_styles[i]); +#endif + XFree(ic_values); + } +} + +static void +xim_destroy_callback(XIM xim EINA_UNUSED, + XPointer client_data, + XPointer call_data EINA_UNUSED) +{ + XIM_Im_Info *info = (XIM_Im_Info *)client_data; + + if (info->user) info->user->ic = NULL; + info->im = NULL; +// reinitialize_ic(ctx); + xim_info_try_im(info); + + return; +} + +#endif /* ENABLE_XIM */ diff --git a/src/utils/ecore/makekeys.c b/src/utils/ecore/makekeys.c new file mode 100644 index 0000000000..a057fa2c65 --- /dev/null +++ b/src/utils/ecore/makekeys.c @@ -0,0 +1,326 @@ +/* Portions of this code are Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +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 OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#include +#include +#include +#include + +#define TBLNUM 4000 +#define MIN_REHASH 15 +#define MATCHES 10 + +typedef struct _Info Info; +static struct _Info +{ + char *name; + long unsigned int val; +} info[TBLNUM]; + +/* local function prototypes */ +static int _parseline(const char *buf, char *key, long unsigned int *val, char *prefix); + +/* local variables */ +static char tab[TBLNUM]; +static unsigned short offsets[TBLNUM]; +static unsigned short indexes[TBLNUM]; +static long unsigned int values[TBLNUM]; +static char buf[1024]; +static int ksnum = 0; + +int +main(int argc, char **argv) +{ + int max_rehash = 0; + unsigned long sig; + int i = 0, j = 0, k = 0, l = 0, z = 0; + FILE *fptr; + char *name = NULL, c; + int first = 0, num_found = 0; + int best_max_rehash = 0, best_z = 0; + long unsigned int val; + char key[128], prefix[128]; + + for (l = 1; l < argc; l++) + { + if (!(fptr = fopen(argv[l], "r"))) + { + fprintf(stderr, "Could not open %s\n", argv[l]); + continue; + } + + while (fgets(buf, sizeof(buf), fptr)) + { + if (!_parseline(buf, key, &val, prefix)) + continue; + + if (val == XK_VoidSymbol) val = 0; + if (val > 0x1fffffff) + { + fprintf(stderr, "Ignoring illegal keysym (%s %lx)\n", + key, val); + continue; + } + + if (!(name = malloc(strlen(prefix) + strlen(key) + 1))) + { + fprintf(stderr, "Makekeys: Out Of Memory !!\n"); + exit(EXIT_FAILURE); + } + + sprintf(name, "%s%s", prefix, key); + info[ksnum].name = name; + info[ksnum].val = val; + ksnum++; + if (ksnum == TBLNUM) + { + fprintf(stderr, "Makekeys: Too Many Keysyms!!\n"); + exit(EXIT_FAILURE); + } + } + + fclose(fptr); + } + + printf("/* This file is generated from keysymdef.h. */\n"); + printf("/* Do Not Edit !! */\n\n"); + + best_max_rehash = ksnum; + num_found = 0; + for (z = ksnum; z < TBLNUM; z++) + { + max_rehash = 0; + for (name = tab, i = z; --i >= 0;) + *name++ = 0; + for (i = 0; i < ksnum; i++) + { + name = info[i].name; + sig = 0; + while ((c = *name++)) + sig = (sig << 1) + c; + first = j = sig % z; + for (k = 0; tab[j]; k++) + { + j += (first + 1); + if (j >= z) j -= z; + if (j == first) goto next1; + } + tab[j] = 1; + if (k > max_rehash) max_rehash = k; + } + if (max_rehash < MIN_REHASH) + { + if (max_rehash < best_max_rehash) + { + best_max_rehash = max_rehash; + best_z = z; + } + num_found++; + if (num_found >= MATCHES) + break; + } +next1: ; + } + + z = best_z; + if (z == 0) + { + fprintf(stderr, "Makekeys: Failed to find small enough hash !!\n" + "Try increasing TBLNUM in makekeys.c\n"); + exit(EXIT_FAILURE); + } + + printf("#ifdef NEED_KEYSYM_TABLE\n"); + printf("const unsigned char _ecore_xcb_keytable[] = {\n"); + printf("0,\n"); + k = 1; + for (i = 0; i < ksnum; i++) + { + name = info[i].name; + sig = 0; + while ((c = *name++)) + sig = (sig << 1) + c; + first = j = sig % z; + while (offsets[j]) + { + j += (first + 1); + if (j >= z) j -= z; + } + offsets[j] = k; + indexes[i] = k; + val = info[i].val; + printf("0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, 0x%.2lx, ", + (sig >> 8) & 0xff, sig & 0xff, + (val >> 24) & 0xff, (val >> 16) & 0xff, + (val >> 8) & 0xff, val & 0xff); + for (name = info[i].name, k += 7; (c = *name++); k++) + printf("'%c',", c); + printf((i == (ksnum - 1)) ? "0\n" : "0,\n"); + } + + printf("};\n\n"); + printf("#define KTABLESIZE %d\n", z); + printf("#define KMAXHASH %d\n", (best_max_rehash + 1)); + printf("\n"); + printf("static const unsigned short hashString[KTABLESIZE] = {\n"); + + for (i = 0; i < z;) + { + printf("0x%.4x", offsets[i]); + i++; + if (i == z) break; + printf((i & 7) ? ", " : ",\n"); + } + + printf("\n"); + printf("};\n"); + printf("#endif\n"); + + best_max_rehash = ksnum; + num_found = 0; + for (z = ksnum; z < TBLNUM; z++) + { + max_rehash = 0; + for (name = tab, i = z; --i >= 0;) + *name++ = 0; + for (i = 0; i < ksnum; i++) + { + val = info[i].val; + first = j = val % z; + for (k = 0; tab[j]; k++) + { + if (values[j] == val) goto skip1; + j += (first + 1); + if (j >= z) j -= z; + if (j == first) goto next2; + } + tab[j] = 1; + values[j] = val; + if (k > max_rehash) max_rehash = k; +skip1: ; + } + if (max_rehash < MIN_REHASH) + { + if (max_rehash < best_max_rehash) + { + best_max_rehash = max_rehash; + best_z = z; + } + num_found++; + if (num_found >= MATCHES) break; + } +next2: ; + } + + z = best_z; + if (z == 0) + { + fprintf(stderr, "Makekeys: Failed to find small enough hash !!\n" + "Try increasing TBLNUM in makekeys.c\n"); + exit(EXIT_FAILURE); + } + for (i = z; --i >= 0;) + offsets[i] = 0; + + for (i = 0; i < ksnum; i++) + { + val = info[i].val; + first = j = val % z; + while (offsets[j]) + { + if (values[j] == val) goto skip2; + j += (first + 1); + if (j >= z) j -= z; + } + offsets[j] = indexes[i] + 2; + values[j] = val; +skip2: ; + } + + printf("\n"); + printf("#ifdef NEED_VTABLE\n"); + printf("#define VTABLESIZE %d\n", z); + printf("#define VMAXHASH %d\n", best_max_rehash + 1); + printf("\n"); + printf("static const unsigned short hashKeysym[VTABLESIZE] = {\n"); + for (i = 0; i < z;) + { + printf("0x%.4x", offsets[i]); + i++; + if (i == z) break; + printf((i & 7) ? ", " : ",\n"); + } + printf("\n"); + printf("};\n"); + printf("#endif\n"); + + return 0; +} + +/* local functions */ +static int +_parseline(const char *buf, char *key, long unsigned int *val, char *prefix) +{ + int i = 0; + char alias[128]; + char *tmp = NULL, *tmpa = NULL; + + /* try to match XK_foo first */ + i = sscanf(buf, "#define %127s 0x%lx", key, val); + if ((i == 2) && (tmp = strstr(key, "XK_"))) + { + memcpy(prefix, key, (tmp - key)); + prefix[tmp - key] = '\0'; + tmp += 3; + memmove(key, tmp, strlen(tmp) + 1); + return 1; + } + + /* try to match an alias */ + i = sscanf(buf, "#define %127s %127s", key, alias); + if (((i == 2) && (tmp = strstr(key, "XK_"))) && + (tmpa = strstr(alias, "XK_"))) + { + memcpy(prefix, key, (tmp - key)); + prefix[tmp - key] = '\0'; + tmp += 3; + memmove(key, tmp, strlen(tmp) + 1); + memmove(tmpa, tmpa + 3, strlen(tmpa + 3) + 1); + + for (i = ksnum - 1; i >= 0; i--) + { + if (!strcmp(info[i].name, alias)) + { + *val = info[i].val; + return 1; + } + } + fprintf(stderr, "Cannot find matching definition %s for keysym %s%s\n", + alias, prefix, key); + } + + return 0; +} diff --git a/src/utils/ecore/mkks.sh b/src/utils/ecore/mkks.sh new file mode 100755 index 0000000000..666924258a --- /dev/null +++ b/src/utils/ecore/mkks.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +cat $* | awk 'BEGIN { \ + printf "/*\n * This file is generated from %s. Do not edit.\n */\n", \ + "$(INCLUDESRC)/keysymdef.h";\ +} \ +/^#define/ { \ + len = length($2)-3; \ + printf("{ \"%s\", %s },\n", substr($2,4,len), $3); \ +}'