From 627d39bfa20bb2b73e69edda06a27049d8b0729f Mon Sep 17 00:00:00 2001 From: Christopher Michael Date: Mon, 26 Dec 2011 23:27:20 +0000 Subject: [PATCH] Ecore: Add Ecore_Wayland (Wayland backend like ecore_x). Ecore_Evas: Add 'drame_frame' functions. Add ecore_evas_wayland code (for creating ecore_evas' in wayland). NB: Merry Christmas EFL !!, Here is you're gift :) SVN revision: 66542 --- legacy/ecore/Makefile.am | 5 + legacy/ecore/configure.ac | 41 + legacy/ecore/ecore-wayland.pc.in | 12 + legacy/ecore/src/lib/Makefile.am | 4 + legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h | 16 +- legacy/ecore/src/lib/ecore_evas/Makefile.am | 18 +- legacy/ecore/src/lib/ecore_evas/ecore_evas.c | 88 ++- .../ecore/src/lib/ecore_evas/ecore_evas_fb.c | 2 +- .../src/lib/ecore_evas/ecore_evas_private.h | 29 +- .../lib/ecore_evas/ecore_evas_wayland_egl.c | 342 ++++++++ .../lib/ecore_evas/ecore_evas_wayland_shm.c | 727 ++++++++++++++++++ .../src/lib/ecore_wayland/Ecore_Wayland.h | 134 ++++ .../ecore/src/lib/ecore_wayland/Makefile.am | 31 + legacy/ecore/src/lib/ecore_wayland/ecore_wl.c | 679 ++++++++++++++++ .../src/lib/ecore_wayland/ecore_wl_private.h | 47 ++ .../src/lib/ecore_wayland/ecore_wl_window.c | 196 +++++ 16 files changed, 2359 insertions(+), 12 deletions(-) create mode 100644 legacy/ecore/ecore-wayland.pc.in create mode 100644 legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c create mode 100644 legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_shm.c create mode 100644 legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h create mode 100644 legacy/ecore/src/lib/ecore_wayland/Makefile.am create mode 100644 legacy/ecore/src/lib/ecore_wayland/ecore_wl.c create mode 100644 legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h create mode 100644 legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c diff --git a/legacy/ecore/Makefile.am b/legacy/ecore/Makefile.am index 3de767395c..8a6ef9af22 100644 --- a/legacy/ecore/Makefile.am +++ b/legacy/ecore/Makefile.am @@ -106,6 +106,7 @@ ecore-cocoa.pc.in \ ecore-psl1ght.pc.in \ ecore-input.pc.in \ ecore-wince.pc.in \ +ecore-wayland.pc.in \ ecore.spec.in \ ecore.spec \ m4/ac_abstract_socket.m4 \ @@ -190,6 +191,10 @@ if BUILD_ECORE_PSL1GHT pkgconfig_DATA += ecore-psl1ght.pc endif +if BUILD_ECORE_WAYLAND +pkgconfig_DATA += ecore-wayland.pc +endif + .PHONY: doc # Documentation diff --git a/legacy/ecore/configure.ac b/legacy/ecore/configure.ac index 7b921944b3..1b1ef5a250 100644 --- a/legacy/ecore/configure.ac +++ b/legacy/ecore/configure.ac @@ -133,6 +133,7 @@ want_ecore_psl1ght="no" want_ecore_fb="no" want_ecore_directfb="no" want_ecore_wince="no" +want_ecore_wayland="no" # ecore_x options (both xlib and xcb) want_ecore_x_composite="yes" @@ -173,6 +174,8 @@ want_ecore_evas_directfb="no" want_ecore_evas_fb="no" want_ecore_evas_software_16_wince="no" want_ecore_evas_ews="yes" +want_ecore_evas_wayland_shm="no" +want_ecore_evas_wayland_egl="no" # ecore_imf modules want_ecore_imf_xim="no" @@ -225,6 +228,7 @@ case "$host_os" in want_ecore_fb="yes" want_ecore_imf="yes" want_ecore_x="yes" + want_ecore_wayland="yes" want_ecore_evas_software_x11="yes" want_ecore_evas_opengl_x11="yes" want_ecore_evas_software_16_x11="yes" @@ -235,6 +239,8 @@ case "$host_os" in 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" want_ecore_imf_xim="yes" want_ecore_imf_scim="yes" ;; @@ -265,6 +271,7 @@ requirements_ecore_win32="" requirements_ecore_wince="" requirements_ecore_imf_xim="" requirements_ecore_imf_scim="" +requirements_ecore_wayland="" AC_CHECK_DECL([MAXHOSTNAMELEN],[FOUND_MAXHOSTNAMELEN=yes]) @@ -1838,6 +1845,34 @@ ECORE_EVAS_CHECK_MODULE([psl1ght], [${have_ecore_psl1ght}], [requirements_ecore_evas="ecore-psl1ght >= 1.1.99 ${requirements_ecore_evas}"]) +### WAYLAND + +ecore_wayland_deps="no" +have_wayland="no" +if test "x${want_ecore_wayland}" = "xyes" ; then + PKG_CHECK_MODULES([WAYLAND], [wayland-client xkbcommon], [have_wayland="yes"], [have_wayland="no"]) +fi +if test "x${have_ecore_input}" = "xyes" -a "x${have_wayland}" = "xyes" ; then + ecore_wayland_deps="yes" +fi + +ECORE_CHECK_MODULE([wayland], [${want_ecore_wayland}], [Wayland], [${ecore_wayland_deps}]) +if test "x${have_ecore_wayland}" = "xyes" ; then + requirements_ecore_wayland="ecore-input >= 1.1.0 wayland-client xkbcommon ${requirements_ecore_wayland}" +fi + +ECORE_EVAS_CHECK_MODULE_FULL([wayland-shm], [wayland-shm], + [${want_ecore_evas_wayland_shm}], + [Wayland Shm], + [${have_ecore_wayland}], + [requirements_ecore_evas="ecore-wayland >= 1.1.0 ${requirements_ecore_evas}"]) + +ECORE_EVAS_CHECK_MODULE_FULL([wayland-egl], [wayland-egl], + [${want_ecore_evas_wayland_egl}], + [Wayland Egl], + [${have_ecore_wayland}], + [requirements_ecore_evas="ecore-wayland >= 1.1.0 ${requirements_ecore_evas}"]) + ### install and build examples EFL_CHECK_BUILD_EXAMPLES([enable_build_examples="yes"], [enable_build_examples="no"]) @@ -1865,6 +1900,7 @@ AC_SUBST(requirements_ecore_win32) AC_SUBST(requirements_ecore_wince) AC_SUBST(requirements_ecore_imf_xim) AC_SUBST(requirements_ecore_imf_scim) +AC_SUBST(requirements_ecore_wayland) AC_CONFIG_FILES([ Makefile @@ -1885,6 +1921,7 @@ ecore-sdl.pc ecore-cocoa.pc ecore-psl1ght.pc ecore-wince.pc +ecore-wayland.pc ecore.pc doc/ecore.dox doc/Makefile @@ -1913,6 +1950,7 @@ src/lib/ecore_wince/Makefile src/lib/ecore_x/Makefile src/lib/ecore_x/xlib/Makefile src/lib/ecore_x/xcb/Makefile +src/lib/ecore_wayland/Makefile src/examples/Makefile src/tests/Makefile src/modules/Makefile @@ -2033,6 +2071,7 @@ fi echo " Ecore_DirectFB...............: $have_ecore_directfb" echo " Ecore_WinCE..................: $have_ecore_wince" echo " Ecore_PSL1GHT................: $have_ecore_psl1ght" +echo " Ecore_Wayland................: $have_ecore_wayland" echo echo " Ecore Evas:" @@ -2066,6 +2105,8 @@ if test "x${have_ecore_evas}" = "xyes" ; then echo " Software 16bit DirectDraw..: $have_ecore_evas_software_16_ddraw" echo " Software 16bit WinCE.......: $have_ecore_evas_software_16_wince" 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" fi echo echo " Tests................: ${enable_tests}" diff --git a/legacy/ecore/ecore-wayland.pc.in b/legacy/ecore/ecore-wayland.pc.in new file mode 100644 index 0000000000..f4f5cf3a0a --- /dev/null +++ b/legacy/ecore/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 +@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/src/lib/Makefile.am b/legacy/ecore/src/lib/Makefile.am index b13bc183e9..d43ad7580b 100644 --- a/legacy/ecore/src/lib/Makefile.am +++ b/legacy/ecore/src/lib/Makefile.am @@ -46,6 +46,10 @@ if BUILD_ECORE_COCOA SUBDIRS += ecore_cocoa endif +if BUILD_ECORE_WAYLAND +SUBDIRS += ecore_wayland +endif + if BUILD_ECORE_IPC SUBDIRS += ecore_ipc endif diff --git a/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h b/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h index 46aa867001..2e398c2e81 100644 --- a/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h +++ b/legacy/ecore/src/lib/ecore_evas/Ecore_Evas.h @@ -81,6 +81,8 @@ extern "C" { #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 { @@ -104,7 +106,9 @@ typedef enum _Ecore_Evas_Engine_Type ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE, ECORE_EVAS_ENGINE_OPENGL_SDL, ECORE_EVAS_ENGINE_EWS, - ECORE_EVAS_ENGINE_PSL1GHT + 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 @@ -144,6 +148,10 @@ typedef struct _Ecore_WinCE_Window Ecore_WinCE_Window; typedef struct _Ecore_Cocoa_Window Ecore_Cocoa_Window; #endif +#ifndef _ECORE_WAYLAND_H_ +typedef struct _Ecore_Wl_Window Ecore_Wl_Window; +#endif + #ifndef _ECORE_EVAS_PRIVATE_H /* basic data types */ typedef struct _Ecore_Evas Ecore_Evas; @@ -689,6 +697,9 @@ EAPI Ecore_Evas *ecore_evas_fb_new(const char *disp_name, int rotation, int 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, int x, int y, int w, int h, int frame); +//EAPI Ecore_Evas *ecore_evas_wayland_egl_new(const char *disp_name, int x, int y, int w, int h, int frame); + /** * @brief Create a new @c Ecore_Evas canvas bound to the Evas * @b buffer engine @@ -1450,6 +1461,9 @@ EAPI Eina_Bool ecore_evas_comp_sync_get(const Ecore_Evas *ee); */ EAPI void ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h); +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. * diff --git a/legacy/ecore/src/lib/ecore_evas/Makefile.am b/legacy/ecore/src/lib/ecore_evas/Makefile.am index a3213b632f..88f036fe24 100644 --- a/legacy/ecore/src/lib/ecore_evas/Makefile.am +++ b/legacy/ecore/src/lib/ecore_evas/Makefile.am @@ -1,8 +1,8 @@ MAINTAINERCLEANFILES = Makefile.in if BUILD_ECORE_X -ECORE_X_INC = -I$(top_srcdir)/src/lib/ecore_x @x_cflags@ @ECORE_XCB_CFLAGS@ -ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la @x_libs@ @ECORE_XCB_LIBS@ +ECORE_X_INC = -I$(top_srcdir)/src/lib/ecore_x @x_cflags@ +ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la @x_libs@ else ECORE_X_INC = ECORE_X_LIB = @@ -66,6 +66,16 @@ ECORE_PSL1GHT_INC = ECORE_PSL1GHT_LIB = endif +if BUILD_ECORE_WAYLAND +ECORE_WAYLAND_INC = -I$(top_srcdir)/src/lib/ecore_wayland @WAYLAND_CFLAGS@ +ECORE_WAYLAND_LIB = $(top_builddir)/src/lib/ecore_wayland/libecore_wayland.la +ECORE_WAYLAND_LIBADD = @WAYLAND_LIBS@ $(ECORE_WAYLAND_LIB) +else +ECORE_WAYLAND_INC = +ECORE_WAYLAND_LIB = +ECORE_WAYLAND_LIBADD = +endif + if BUILD_ECORE_IPC ECORE_IPC_INC= \ -I$(top_srcdir)/src/lib/ecore_ipc \ @@ -92,6 +102,7 @@ $(ECORE_SDL_INC) \ $(ECORE_COCOA_INC) \ $(ECORE_WINCE_INC) \ $(ECORE_PSL1GHT_INC) \ +$(ECORE_WAYLAND_INC) \ $(ECORE_IPC_INC) \ @EVAS_CFLAGS@ \ @EINA_CFLAGS@ \ @@ -116,6 +127,7 @@ ecore_evas_cocoa.c \ ecore_evas_wince.c \ ecore_evas_ews.c \ ecore_evas_psl1ght.c \ +ecore_evas_wayland_shm.c \ ecore_evas_extn.c libecore_evas_la_LIBADD = \ @@ -129,6 +141,8 @@ $(ECORE_COCOA_LIB) \ $(ECORE_WINCE_LIB) \ $(ECORE_IPC_LIB) \ $(ECORE_PSL1GHT_LIB) \ +$(ECORE_WAYLAND_LIB) \ +$(ECORE_WAYLAND_LIBADD) \ $(top_builddir)/src/lib/ecore_input/libecore_input.la \ $(top_builddir)/src/lib/ecore_input_evas/libecore_input_evas.la \ $(top_builddir)/src/lib/ecore/libecore.la \ diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas.c index 073598055b..28c3e36407 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas.c @@ -200,6 +200,18 @@ ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine) 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; @@ -293,6 +305,7 @@ ecore_evas_shutdown(void) #ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE while (_ecore_evas_wince_shutdown()); #endif + if (_ecore_evas_async_events_fd) ecore_main_fd_handler_del(_ecore_evas_async_events_fd); @@ -588,6 +601,40 @@ _ecore_evas_constructor_psl1ght(int x __UNUSED__, int y __UNUSED__, int w, int h } #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 = 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); + ee = ecore_evas_wayland_shm_new(disp_name, 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 = 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); +// ee = ecore_evas_wayland_egl_new(disp_name, x, y, w, h, frame); + free(disp_name); + + return NULL; +} +#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) @@ -725,7 +772,16 @@ static const struct ecore_evas_engine _engines[] = { {"psl1ght", _ecore_evas_constructor_psl1ght}, #endif - /* Last chance to have a window */ + /* 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 @@ -2019,8 +2075,8 @@ ecore_evas_withdrawn_get(const Ecore_Evas *ee) ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_withdrawn_get"); return EINA_FALSE; - } else - return ee->prop.withdrawn ? EINA_TRUE : EINA_FALSE; + } + return ee->prop.withdrawn ? EINA_TRUE : EINA_FALSE; } /** @@ -2059,8 +2115,8 @@ ecore_evas_sticky_get(const Ecore_Evas *ee) ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_sticky_get"); return EINA_FALSE; - } else - return ee->prop.sticky ? EINA_TRUE : EINA_FALSE; + } + return ee->prop.sticky ? EINA_TRUE : EINA_FALSE; } EAPI void @@ -2181,6 +2237,28 @@ ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int 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... :) */ diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c index e85d9d85ae..1e7efad1f2 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_fb.c @@ -155,9 +155,9 @@ _ecore_evas_fb_render(Ecore_Evas *ee) 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) diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h b/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h index b77a17110a..e3f8681e53 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_private.h @@ -79,9 +79,17 @@ # include #endif -/** - Log domain macros and variable - **/ +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +# include "Ecore_Wayland.h" +# include +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +# include "Ecore_Wayland.h" +# include +#endif + +/** Log domain macros and variables **/ extern int _ecore_evas_log_dom; @@ -260,6 +268,20 @@ struct _Ecore_Evas_Engine } ews; #endif +#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL) + struct + { + Evas_Object *frame; + +# ifdef BUILD_ECORE_EVAS_WAYLAND_SHM + struct wl_surface *surface; + struct wl_shell_surface *shell_surface; + struct wl_buffer *buffer; +# endif + + } wl; +#endif + Ecore_Timer *idle_flush_timer; }; @@ -322,6 +344,7 @@ struct _Ecore_Evas char withdrawn : 1; char sticky : 1; char request_pos : 1; + char draw_frame : 1; } prop; struct { 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 new file mode 100644 index 0000000000..f33b9332dc --- /dev/null +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c @@ -0,0 +1,342 @@ +#ifdef HAVE_CONFIG_H +# include +#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 +# include +# include +# include +# include + +# include +# include +# include + +# include "ecore_evas_private.h" +# include "Ecore_Evas.h" + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +# include +# include +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +/* local function prototypes */ +static int _ecore_evas_wl_init(Ecore_Evas *ee); +static int _ecore_evas_wl_shutdown(void); +static void _ecore_evas_wl_free(Ecore_Evas *ee); +static void _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y); +static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h); +static void _ecore_evas_wl_show(Ecore_Evas *ee); +static int _ecore_evas_wl_render(Ecore_Evas *ee); + +/* local variables */ +static int _ecore_evas_init_count = 0; + +static Ecore_Evas_Engine_Func _ecore_wl_engine_func = +{ + _ecore_evas_wl_free, + NULL, // _ecore_evas_wl_callback_resize_set, + NULL, // _ecore_evas_wl_callback_move_set, + NULL, // callback show set + NULL, // callback hide set + NULL, // _ecore_evas_wl_callback_delete_request_set, + NULL, // callback destroy set + NULL, // _ecore_evas_wl_callback_focus_in_set, + NULL, // _ecore_evas_wl_callback_focus_out_set, + NULL, // callback mouse in set + NULL, // callback mouse out set + NULL, // callback sticky set + NULL, // callback unsticky set + NULL, // callback pre render set + NULL, // callback post render set + _ecore_evas_wl_move, + NULL, // func managed move + _ecore_evas_wl_resize, + NULL, // _ecore_evas_wl_move_resize, + NULL, // func rotation set + NULL, // func shaped set + _ecore_evas_wl_show, + NULL, // _ecore_evas_wl_hide, + NULL, // _ecore_evas_wl_raise, + NULL, // _ecore_evas_wl_lower, + NULL, // _ecore_evas_wl_activate, + NULL, // _ecore_evas_wl_title_set, + NULL, // _ecore_evas_wl_name_class_set, + NULL, // _ecore_evas_wl_size_min_set, + NULL, // _ecore_evas_wl_size_max_set, + NULL, // _ecore_evas_wl_size_base_set, + NULL, // _ecore_evas_wl_size_step_set, + NULL, // _ecore_evas_wl_object_cursor_set, + NULL, // _ecore_evas_wl_layer_set, + NULL, // _ecore_evas_wl_focus_set, + NULL, // func iconified set + NULL, // func borderless set + NULL, // func override set + NULL, // func maximized set + NULL, // func fullscreen set + NULL, // _ecore_evas_wl_avoid_damage_set, + NULL, // func withdrawn set + NULL, // func sticky set + NULL, // func ignore events set + NULL, // func alpha set + NULL, // func transparent set + _ecore_evas_wl_render, + NULL // _ecore_evas_wl_screen_geometry_get +}; + +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +EAPI Ecore_Evas * +ecore_evas_wayland_egl_new(const char *disp_name, int x, int y, int w, int h, int frame) +{ + Evas_Engine_Info_Wayland_Egl *einfo; + Ecore_Evas *ee; + int method = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(method = evas_render_method_lookup("wayland_egl"))) + { + ERR("Render method lookup failed for Wayland Egl"); + return NULL; + } + + if (!ecore_wl_init(disp_name)) + { + ERR("Failed to initialize Ecore Wayland"); + return NULL; + } + + if (!(ee = calloc(1, sizeof(Ecore_Evas)))) return NULL; + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_wl_init(ee); + + 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->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->rotation = 0; + + ee->engine.wl.win = + ecore_wl_window_new(ECORE_WL_WINDOW_TYPE_EGL, x, y, w, h); + ee->prop.window = ee->engine.wl.win->id; + + 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); + + if (ee->prop.draw_frame) evas_output_framespace_set(ee->evas, 4, 18, 8, 22); + + if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) + { + einfo->info.disp = ecore_wl_display_get(); + einfo->info.comp = ecore_wl_compositor_get(); + einfo->info.shell = ecore_wl_shell_get(); + einfo->info.rotation = ee->rotation; + einfo->info.debug = EINA_FALSE; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("Failed to set Evas Engine Info for '%s'.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("Failed to get Evas Engine Info for '%s'.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + + ecore_evas_input_event_register(ee); + _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); + + 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_wayland_egl_new(const char *disp_name __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, int frame __UNUSED__) +{ + return NULL; +} +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL +/* local functions */ +static int +_ecore_evas_wl_init(Ecore_Evas *ee) +{ + _ecore_evas_init_count++; + + /* TODO: Add handlers */ + + if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; + ecore_event_evas_init(); + + return _ecore_evas_init_count; +} + +static int +_ecore_evas_wl_shutdown(void) +{ + _ecore_evas_init_count--; + if (_ecore_evas_init_count == 0) + { + /* TODO: Delete handlers */ + } + if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; + return _ecore_evas_init_count; +} + +static void +_ecore_evas_wl_free(Ecore_Evas *ee) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (ee) + { + if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win); + ecore_event_window_unregister(ee->prop.window); + ecore_evas_input_event_unregister(ee); + } + _ecore_evas_wl_shutdown(); + ecore_wl_shutdown(); +} + +static void +_ecore_evas_wl_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)) return; + ee->x = x; + ee->y = y; + /* TODO: Actually move this window */ + if (!ee->should_be_visible) ee->prop.request_pos = 1; + if (ee->func.fn_move) ee->func.fn_move(ee); +} + +static void +_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + ee->req.w = w; + ee->req.h = h; + if ((ee->w == w) && (ee->h == h)) return; + + ee->w = w; + ee->h = h; + ecore_wl_window_resize(ee->engine.wl.win, w, 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); + evas_damage_rectangle_add(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); + evas_damage_rectangle_add(ee->evas, 0, 0, w, h); + } + + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_wl_show(Ecore_Evas *ee) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + ee->visible = 1; + ee->should_be_visible = 1; + + if (ee->func.fn_show) ee->func.fn_show(ee); +} + +static int +_ecore_evas_wl_render(Ecore_Evas *ee) +{ + int rend = 0; + + if (!ee) return 0; + if (ee->visible) + { + Eina_List *updates = NULL, *ll = NULL; + 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 ((updates = evas_render_updates(ee->evas))) + { + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + + 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); + } + else + evas_norender(ee->evas); + + return rend; +} + +#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 new file mode 100644 index 0000000000..970cbb7ee4 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_wayland_shm.c @@ -0,0 +1,727 @@ +#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 +# include +# include +# include +# include + +# include +# include +# include + +# include "ecore_evas_private.h" +# include "Ecore_Evas.h" + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +# include +# include +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +/* local function prototypes */ +static int _ecore_evas_wl_init(void); +static int _ecore_evas_wl_shutdown(void); +static void _ecore_evas_wl_pre_free(Ecore_Evas *ee); +static void _ecore_evas_wl_free(Ecore_Evas *ee); +static void _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +static void _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +static void _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +static void _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +static void _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)); +static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h); +static void _ecore_evas_wl_show(Ecore_Evas *ee); +static int _ecore_evas_wl_render(Ecore_Evas *ee); +static void _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h); +static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, void **dest); + +static Eina_Bool _ecore_evas_wl_event_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event); +static Eina_Bool _ecore_evas_wl_event_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event); +static Eina_Bool _ecore_evas_wl_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event); +static Eina_Bool _ecore_evas_wl_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event); +static Eina_Bool _ecore_evas_wl_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event); +static Eina_Bool _ecore_evas_wl_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event); +static Eina_Bool _ecore_evas_wl_event_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event); +static Eina_Bool _ecore_evas_wl_event_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event); + +/* local variables */ +static int _ecore_evas_wl_init_count = 0; +static Ecore_Event_Handler *_ecore_evas_wl_event_handlers[8]; + +static Ecore_Evas_Engine_Func _ecore_wl_engine_func = +{ + _ecore_evas_wl_free, + _ecore_evas_wl_callback_resize_set, + _ecore_evas_wl_callback_move_set, + NULL, // callback show set + NULL, // callback hide set + _ecore_evas_wl_callback_delete_request_set, + NULL, // callback destroy set + _ecore_evas_wl_callback_focus_in_set, + _ecore_evas_wl_callback_focus_out_set, + NULL, // callback mouse in set + NULL, // callback mouse out set + NULL, // callback sticky set + NULL, // callback unsticky set + NULL, // callback pre render set + NULL, // callback post render set + NULL, // func move + NULL, // func managed move + _ecore_evas_wl_resize, + NULL, // func move_resize + NULL, // func rotation set + NULL, // func shaped set + _ecore_evas_wl_show, + NULL, // func hide + NULL, // func raise + NULL, // func lower + NULL, // func activate + NULL, // func title set + NULL, // func name_class set + NULL, // func size min set + NULL, // func size max set + NULL, // func size base set + NULL, // func size step set + NULL, // func object cursor set + NULL, // func layer set + NULL, // func focus set + NULL, // func iconified set + NULL, // func borderless set + NULL, // func override set + NULL, // func maximized set + NULL, // func fullscreen set + NULL, // func avoid_damage set + NULL, // func withdrawn set + NULL, // func sticky set + NULL, // func ignore_events set + NULL, // func alpha set + NULL, // func transparent set + _ecore_evas_wl_render, + _ecore_evas_wl_screen_geometry_get +}; + +/* external variables */ +#endif + +#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM +EAPI Ecore_Evas * +ecore_evas_wayland_shm_new(const char *disp_name, int x, int y, int w, int h, int frame) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + Ecore_Evas *ee; + int method = 0; + static int _win_id = 1; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(method = evas_render_method_lookup("wayland_shm"))) + { + ERR("Render method lookup failed."); + return NULL; + } + + if (!(ecore_wl_init(disp_name))) + { + ERR("Failed to initialize Ecore Wayland."); + return NULL; + } + + if (!(ee = calloc(1, sizeof(Ecore_Evas)))) + { + ERR("Failed to allocate Ecore_Evas."); + ecore_wl_shutdown(); + return NULL; + } + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_wl_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->req.x = ee->x = x; + ee->req.y = ee->y = y; + ee->req.w = ee->w = w; + ee->req.h = ee->h = h; + ee->rotation = 0; + ee->prop.max.w = ee->prop.max.h = 32767; + ee->prop.layer = 4; + ee->prop.request_pos = 0; + ee->prop.sticky = 0; + ee->prop.draw_frame = frame; + ee->prop.window = _win_id++; + + 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); + + if (ee->prop.draw_frame) + evas_output_framespace_set(ee->evas, 4, 18, 8, 22); + + if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) + { + einfo->info.rotation = ee->rotation; + einfo->info.debug = EINA_FALSE; + if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) + { + ERR("Failed to set Evas Engine Info for '%s'.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + } + else + { + ERR("Failed to get Evas Engine Info for '%s'.", ee->driver); + ecore_evas_free(ee); + return NULL; + } + + /* NB: we need to be notified before 'free' so we can munmap the evas + * engine destination */ + ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free); + + ecore_evas_input_event_register(ee); + _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); + + evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + + return ee; +} + +/* local functions */ +static int +_ecore_evas_wl_init(void) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (++_ecore_evas_wl_init_count != 1) + return _ecore_evas_wl_init_count; + + _ecore_evas_wl_event_handlers[0] = + ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, + _ecore_evas_wl_event_mouse_down, NULL); + _ecore_evas_wl_event_handlers[1] = + ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, + _ecore_evas_wl_event_mouse_up, NULL); + _ecore_evas_wl_event_handlers[2] = + ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, + _ecore_evas_wl_event_mouse_move, NULL); + _ecore_evas_wl_event_handlers[3] = + ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, + _ecore_evas_wl_event_mouse_wheel, NULL); + _ecore_evas_wl_event_handlers[4] = + ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, + _ecore_evas_wl_event_mouse_in, NULL); + _ecore_evas_wl_event_handlers[5] = + ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, + _ecore_evas_wl_event_mouse_out, NULL); + _ecore_evas_wl_event_handlers[6] = + ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, + _ecore_evas_wl_event_focus_in, NULL); + _ecore_evas_wl_event_handlers[7] = + ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, + _ecore_evas_wl_event_focus_out, NULL); + + ecore_event_evas_init(); + + return _ecore_evas_wl_init_count; +} + +static int +_ecore_evas_wl_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_handlers) / sizeof(Ecore_Event_Handler *); i++) + { + if (_ecore_evas_wl_event_handlers[i]) + ecore_event_handler_del(_ecore_evas_wl_event_handlers[i]); + } + + ecore_event_evas_shutdown(); + + return _ecore_evas_wl_init_count; +} + +static void +_ecore_evas_wl_pre_free(Ecore_Evas *ee) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* get engine info */ + einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); + if ((einfo) && (einfo->info.dest)) + { + int ret = 0; + + /* munmap previous engine destination */ + ret = munmap(einfo->info.dest, ((ee->w * sizeof(int)) * ee->h)); + } +} + +static void +_ecore_evas_wl_free(Ecore_Evas *ee) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* destroy buffer */ + if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer); + ee->engine.wl.buffer = NULL; + + /* destroy shell surface */ + if (ee->engine.wl.shell_surface) + wl_shell_surface_destroy(ee->engine.wl.shell_surface); + ee->engine.wl.shell_surface = NULL; + + /* destroy surface */ + if (ee->engine.wl.surface) wl_surface_destroy(ee->engine.wl.surface); + ee->engine.wl.surface = NULL; + + ecore_event_window_unregister(ee->prop.window); + + _ecore_evas_wl_shutdown(); + ecore_wl_shutdown(); +} + +static void +_ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + ee->func.fn_resize = func; +} + +static void +_ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + ee->func.fn_move = func; +} + +static void +_ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + ee->func.fn_delete_request = func; +} + +static void +_ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + ee->func.fn_focus_in = func; +} + +static void +_ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee)) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + ee->func.fn_focus_out = func; +} + +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->w == w) && (ee->h == h)) return; + + /* get engine info */ + einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); + if (einfo->info.dest) + { + int ret = 0; + + /* munmap previous engine destination */ + ret = munmap(einfo->info.dest, ((ee->w * sizeof(int)) * ee->h)); + } + + /* free old buffer */ + if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer); + ee->engine.wl.buffer = NULL; + + ee->w = w; + ee->h = h; + + /* create buffer @ new size (also mmaps the new destination) */ + _ecore_evas_wl_buffer_new(ee, &einfo->info.dest); + + /* change evas output & viewport sizes */ + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + + /* set new engine destination */ + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + + /* flush new buffer fd */ + ecore_wl_flush(); + + /* damage buffer */ + wl_buffer_damage(ee->engine.wl.buffer, 0, 0, ee->w, ee->h); + + if (ee->visible) + { + /* if visible, attach to surface */ + wl_surface_attach(ee->engine.wl.surface, ee->engine.wl.buffer, 0, 0); + + /* damage surface */ + wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h); + } + + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_wl_show(Ecore_Evas *ee) +{ + Evas_Engine_Info_Wayland_Shm *einfo; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!ee) return; + if (ee->visible) return; + + /* get engine info */ + einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas); + + /* create new surface */ + ee->engine.wl.surface = + wl_compositor_create_surface(ecore_wl_compositor_get()); + wl_surface_set_user_data(ee->engine.wl.surface, (void *)ee->prop.window); + + /* get new shell surface */ + ee->engine.wl.shell_surface = + wl_shell_get_shell_surface(ecore_wl_shell_get(), ee->engine.wl.surface); + + /* set toplevel */ + wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface); + + /* create buffer @ new size (also mmaps the new destination) */ + _ecore_evas_wl_buffer_new(ee, &einfo->info.dest); + + /* set new engine destination */ + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + + /* flush new buffer fd */ + ecore_wl_flush(); + + /* attach buffer to surface */ + wl_surface_attach(ee->engine.wl.surface, ee->engine.wl.buffer, 0, 0); + + /* NB: No need to do a damage here. If we do, we end up w/ screen + * artifacts in the compositor */ + /* wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h); */ + + ee->visible = 1; + if (ee->func.fn_show) ee->func.fn_show(ee); +} + +static int +_ecore_evas_wl_render(Ecore_Evas *ee) +{ + int rend = 0; + + if (!ee) return 0; + if (!ee->visible) + evas_norender(ee->evas); + else + { + Eina_List *ll = NULL, *updates = NULL; + Ecore_Evas *ee2 = NULL; + + 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); + } + + if ((updates = evas_render_updates(ee->evas))) + { + Eina_List *l = NULL; + Eina_Rectangle *r; + + EINA_LIST_FOREACH(updates, l, r) + { + if (ee->engine.wl.buffer) + wl_buffer_damage(ee->engine.wl.buffer, + r->x, r->y, r->w, r->h); + + if (ee->engine.wl.surface) + wl_surface_damage(ee->engine.wl.surface, + r->x, r->y, r->w, r->h); + } + + 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); + } + + return rend; +} + +static void +_ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __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); +} + +static Eina_Bool +_ecore_evas_wl_event_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Event_Mouse_Button *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; + /* printf("Mouse Down: %d %d\t%d %d\n", */ + /* ev->x, ev->y, ev->root.x, ev->root.y); */ + evas_event_feed_mouse_down(ee->evas, ev->buttons, ev->modifiers, + ev->timestamp, NULL); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_event_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Event_Mouse_Button *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; + evas_event_feed_mouse_up(ee->evas, ev->buttons, ev->modifiers, + ev->timestamp, NULL); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Event_Mouse_Move *ev; + + 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; + ee->mouse.x = ev->x; + ee->mouse.y = ev->y; + evas_event_feed_mouse_move(ee->evas, ev->x, ev->y, ev->timestamp, NULL); + _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Event_Mouse_Wheel *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; + evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, + ev->timestamp, NULL); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_event_mouse_in(void *data __UNUSED__, int type __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->time, NULL); + _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->time); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_event_mouse_out(void *data __UNUSED__, int type __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; + ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers); + _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->time); + evas_event_feed_mouse_out(ee->evas, ev->time, NULL); + if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); + if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_ecore_evas_wl_event_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Focus_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; + 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_event_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Wl_Event_Focus_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; + 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 void +_ecore_evas_wl_buffer_new(Ecore_Evas *ee, void **dest) +{ + static unsigned int format; + char tmp[PATH_MAX]; + int fd = -1, stride = 0, size = 0; + void *ret; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (dest) *dest = NULL; + + if (!format) format = ecore_wl_format_get(); + + strcpy(tmp, "/tmp/ecore-wayland_shm-XXXXXX"); + if ((fd = mkstemp(tmp)) < 0) + { + ERR("Could not create temporary file."); + return; + } + + stride = (ee->w * sizeof(int)); + size = (stride * ee->h); + if (ftruncate(fd, size) < 0) + { + ERR("Could not truncate temporary file."); + close(fd); + return; + } + + ret = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0); + unlink(tmp); + + if (ret == MAP_FAILED) + { + ERR("mmap of temporary file failed."); + close(fd); + return; + } + + if (dest) *dest = ret; + + ee->engine.wl.buffer = + wl_shm_create_buffer(ecore_wl_shm_get(), fd, ee->w, ee->h, stride, format); + + close(fd); +} + +#else +EAPI Ecore_Evas * +ecore_evas_wayland_shm_new(const char *disp_name __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, int frame __UNUSED__) +{ + return NULL; +} +#endif diff --git a/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h b/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h new file mode 100644 index 0000000000..63d78ed926 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_wayland/Ecore_Wayland.h @@ -0,0 +1,134 @@ +#ifndef _ECORE_WAYLAND_H_ +# define _ECORE_WAYLAND_H_ + +# 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 struct _Ecore_Wl_Window Ecore_Wl_Window; +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; + +enum _Ecore_Wl_Window_Type +{ + ECORE_WL_WINDOW_TYPE_SHM, + ECORE_WL_WINDOW_TYPE_EGL +}; + +struct _Ecore_Wl_Window +{ + int id; + int x, y, w, h; + Ecore_Wl_Window_Type type; + Eina_Bool synced : 1; + + struct wl_surface *surface; + struct wl_shell_surface *shell_surface; + + struct wl_callback *callback; +}; + +struct _Ecore_Wl_Event_Mouse_In +{ + int modifiers; + int x, y; + + struct + { + int x, y; + } root; + + unsigned int window; + + unsigned int time; +}; + +struct _Ecore_Wl_Event_Mouse_Out +{ + int modifiers; + int x, y; + + struct + { + int x, y; + } root; + + unsigned int window; + + unsigned int time; +}; + +struct _Ecore_Wl_Event_Focus_In +{ + unsigned int window; + /* TODO: mode & detail */ + unsigned int time; +}; + +struct _Ecore_Wl_Event_Focus_Out +{ + unsigned int window; + /* TODO: mode & detail */ + unsigned int time; +}; + +/** + * @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 + */ + +EAPI int ecore_wl_init(const char *name); +EAPI int ecore_wl_shutdown(void); + +EAPI struct wl_display *ecore_wl_display_get(void); +EAPI struct wl_shm *ecore_wl_shm_get(void); +EAPI struct wl_compositor *ecore_wl_compositor_get(void); +EAPI struct wl_shell *ecore_wl_shell_get(void); +EAPI struct wl_input_device *ecore_wl_input_device_get(void); +EAPI void ecore_wl_screen_size_get(int *w, int *h); +EAPI unsigned int ecore_wl_format_get(void); +EAPI void ecore_wl_sync(void); +EAPI void ecore_wl_flush(void); + +EAPI Ecore_Wl_Window *ecore_wl_window_new(Ecore_Wl_Window_Type type, int x, int y, int w, int h); +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); +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_lower(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_activate(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_focus(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_fullscreen(Ecore_Wl_Window *win); +EAPI void ecore_wl_window_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer); +EAPI void ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h); +EAPI void ecore_wl_window_sync(Ecore_Wl_Window *win); + +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; + +#endif diff --git a/legacy/ecore/src/lib/ecore_wayland/Makefile.am b/legacy/ecore/src/lib/ecore_wayland/Makefile.am new file mode 100644 index 0000000000..ea005b2cf3 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_wayland/Makefile.am @@ -0,0 +1,31 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_input \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_input \ +@WAYLAND_CFLAGS@ \ +@EVAS_CFLAGS@ \ +@EINA_CFLAGS@ + +lib_LTLIBRARIES = libecore_wayland.la +includes_HEADERS = Ecore_Wayland.h +includesdir = $(includedir)/ecore-@VMAJ@ + +libecore_wayland_la_SOURCES = \ +ecore_wl.c + +## ecore_wl_window.c + +libecore_wayland_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_input/libecore_input.la \ +@WAYLAND_LIBS@ \ +@EVAS_LIBS@ \ +@EINA_LIBS@ + +libecore_wayland_la_LDFLAGS = -version-info @version_info@ @release_info@ +libecore_wayland_la_DEPENDENCIES = $(top_builddir)/src/lib/ecore/libecore.la + +EXTRA_DIST = ecore_wl_private.h diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c b/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c new file mode 100644 index 0000000000..d473b23131 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_wayland/ecore_wl.c @@ -0,0 +1,679 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Input.h" +#include "ecore_wl_private.h" +#include "Ecore_Wayland.h" + +/* 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 + +#include + +/* local function prototypes */ +static Eina_Bool _ecore_wl_shutdown(Eina_Bool close_display); +static void _ecore_wl_cb_disp_handle_global(struct wl_display *disp, uint32_t id, const char *interface, uint32_t version __UNUSED__, void *data __UNUSED__); +static int _ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__); +static void _ecore_wl_cb_shm_format_iterate(void *data __UNUSED__, struct wl_shm *shm __UNUSED__, uint32_t format); +static void _ecore_wl_cb_disp_handle_geometry(void *data __UNUSED__, struct wl_output *output __UNUSED__, int x, int y, int pw __UNUSED__, int ph __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__); +static void _ecore_wl_cb_disp_handle_mode(void *data __UNUSED__, struct wl_output *output __UNUSED__, uint32_t flags, int w, int h, int refresh __UNUSED__); +static Eina_Bool _ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__); +static void _ecore_wl_cb_handle_motion(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, int32_t x, int32_t y, int32_t sx, int32_t sy); +static void _ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state); +static void _ecore_wl_cb_handle_key(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, uint32_t key, uint32_t state); +static void _ecore_wl_cb_handle_pointer_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, int32_t x, int32_t y, int32_t sx, int32_t sy); +static void _ecore_wl_cb_handle_keyboard_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, struct wl_array *keys); +static void _ecore_wl_mouse_out_send(void); +static void _ecore_wl_mouse_in_send(void); +static void _ecore_wl_focus_out_send(void); +static void _ecore_wl_focus_in_send(void); + +/* local variables */ +static int _ecore_wl_init_count = 0; +static struct wl_display *_ecore_wl_disp = NULL; +static uint32_t _ecore_wl_disp_mask = 0; +static uint32_t _ecore_wl_disp_format = WL_SHM_FORMAT_PREMULTIPLIED_ARGB32; +static Eina_Rectangle _ecore_wl_screen; +static Ecore_Fd_Handler *_ecore_wl_fd_hdl = NULL; +static int _ecore_wl_input_x = 0; +static int _ecore_wl_input_y = 0; +static int _ecore_wl_input_sx = 0; +static int _ecore_wl_input_sy = 0; +static int _ecore_wl_input_modifiers = 0; +static struct xkb_desc *_ecore_wl_xkb; + +static struct wl_compositor *_ecore_wl_comp; +static struct wl_shm *_ecore_wl_shm; +static struct wl_shell *_ecore_wl_shell; +static struct wl_output *_ecore_wl_output; +static struct wl_input_device *_ecore_wl_input; +static struct wl_surface *_ecore_wl_input_surface; +static const struct wl_shm_listener _ecore_wl_shm_listener = +{ + _ecore_wl_cb_shm_format_iterate +}; +static const struct wl_output_listener _ecore_wl_output_listener = +{ + _ecore_wl_cb_disp_handle_geometry, + _ecore_wl_cb_disp_handle_mode +}; +static const struct wl_input_device_listener _ecore_wl_input_listener = +{ + _ecore_wl_cb_handle_motion, + _ecore_wl_cb_handle_button, + _ecore_wl_cb_handle_key, + _ecore_wl_cb_handle_pointer_focus, + _ecore_wl_cb_handle_keyboard_focus, + NULL, // touch down + NULL, // touch up + NULL, // touch motion + NULL, // touch frame + NULL, // touch cancel +}; + +/* external variables */ +int _ecore_wl_log_dom = -1; +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_init(const char *name) +{ + struct xkb_rule_names xkb_names; + int fd = 0; + + if (++_ecore_wl_init_count != 1) + return _ecore_wl_init_count; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + 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()) + { + eina_log_domain_unregister(_ecore_wl_log_dom); + _ecore_wl_log_dom = -1; + eina_shutdown(); + return --_ecore_wl_init_count; + } + + if (!ecore_event_init()) + { + 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(); + } + + /* init xkb */ + /* FIXME: Somehow make this portable to other languages/countries */ + xkb_names.rules = "evdev"; + xkb_names.model = "evdev"; + xkb_names.layout = "us"; + xkb_names.variant = ""; + xkb_names.options = ""; + if (!(_ecore_wl_xkb = xkb_compile_keymap_from_rules(&xkb_names))) + { + ERR("Could not compile keymap"); + 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; + } + + /* connect to the wayland display */ + if (!(_ecore_wl_disp = wl_display_connect(name))) + { + 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; + } + + /* setup handler for wayland interfaces */ + wl_display_add_global_listener(_ecore_wl_disp, + _ecore_wl_cb_disp_handle_global, NULL); + + /* process connection events */ + wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE); + + fd = wl_display_get_fd(_ecore_wl_disp, + _ecore_wl_cb_disp_event_mask_update, NULL); + + /* NB: DO NOT TOUCH THIS OR YOU WILL PAY THE PRICE OF FAILURE !! */ + /* Without a ECORE_FD_WRITE, then animators/timers break */ + _ecore_wl_fd_hdl = + ecore_main_fd_handler_add(fd, ECORE_FD_READ | ECORE_FD_WRITE, + _ecore_wl_cb_fd_handle, _ecore_wl_disp, + NULL, NULL); + if (!_ecore_wl_fd_hdl) + { + wl_display_destroy(_ecore_wl_disp); + _ecore_wl_disp = NULL; + 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; + } + + return _ecore_wl_init_count; +} + +EAPI int +ecore_wl_shutdown(void) +{ + return _ecore_wl_shutdown(EINA_TRUE); +} + +EAPI struct wl_display * +ecore_wl_display_get(void) +{ + return _ecore_wl_disp; +} + +EAPI struct wl_shm * +ecore_wl_shm_get(void) +{ + return _ecore_wl_shm; +} + +EAPI struct wl_compositor * +ecore_wl_compositor_get(void) +{ + return _ecore_wl_comp; +} + +EAPI struct wl_shell * +ecore_wl_shell_get(void) +{ + return _ecore_wl_shell; +} + +EAPI struct wl_input_device * +ecore_wl_input_device_get(void) +{ + return _ecore_wl_input; +} + +EAPI void +ecore_wl_screen_size_get(int *w, int *h) +{ + if (w) *w = _ecore_wl_screen.w; + if (h) *h = _ecore_wl_screen.h; +} + +EAPI unsigned int +ecore_wl_format_get(void) +{ + return _ecore_wl_disp_format; +} + +EAPI void +ecore_wl_flush(void) +{ + wl_display_flush(_ecore_wl_disp); + /* if (_ecore_wl_disp_mask & WL_DISPLAY_WRITABLE) */ + /* wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_WRITABLE); */ +} + +EAPI void +ecore_wl_sync(void) +{ + wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE); +} + +/* local functions */ +static Eina_Bool +_ecore_wl_shutdown(Eina_Bool close_display) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (--_ecore_wl_init_count != 0) + return _ecore_wl_init_count; + + if (!_ecore_wl_disp) return _ecore_wl_init_count; + + if (_ecore_wl_xkb) free(_ecore_wl_xkb); + + if (_ecore_wl_fd_hdl) ecore_main_fd_handler_del(_ecore_wl_fd_hdl); + _ecore_wl_fd_hdl = NULL; + + if (close_display) + { + if (_ecore_wl_shm) wl_shm_destroy(_ecore_wl_shm); + if (_ecore_wl_comp) wl_compositor_destroy(_ecore_wl_comp); + if (_ecore_wl_disp) wl_display_destroy(_ecore_wl_disp); + _ecore_wl_disp = NULL; + } + + 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; +} + +static void +_ecore_wl_cb_disp_handle_global(struct wl_display *disp, uint32_t id, const char *interface, uint32_t version __UNUSED__, void *data __UNUSED__) +{ +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (disp != _ecore_wl_disp) return; + if (!strcmp(interface, "wl_compositor")) + { + _ecore_wl_comp = + wl_display_bind(_ecore_wl_disp, id, &wl_compositor_interface); + } + else if (!strcmp(interface, "wl_shm")) + { + _ecore_wl_shm = + wl_display_bind(_ecore_wl_disp, id, &wl_shm_interface); + wl_shm_add_listener(_ecore_wl_shm, &_ecore_wl_shm_listener, NULL); + } + else if (!strcmp(interface, "wl_output")) + { + _ecore_wl_output = + wl_display_bind(_ecore_wl_disp, id, &wl_output_interface); + wl_output_add_listener(_ecore_wl_output, + &_ecore_wl_output_listener, NULL); + } + else if (!strcmp(interface, "wl_shell")) + { + _ecore_wl_shell = + wl_display_bind(_ecore_wl_disp, id, &wl_shell_interface); + } + else if (!strcmp(interface, "wl_input_device")) + { + _ecore_wl_input = + wl_display_bind(_ecore_wl_disp, id, &wl_input_device_interface); + wl_input_device_add_listener(_ecore_wl_input, + &_ecore_wl_input_listener, NULL); + } +} + +static int +_ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__) +{ +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + _ecore_wl_disp_mask = mask; + return 0; +} + +static void +_ecore_wl_cb_shm_format_iterate(void *data __UNUSED__, struct wl_shm *shm __UNUSED__, uint32_t format) +{ +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (_ecore_wl_disp_format < 2) return; + switch (format) + { + case WL_SHM_FORMAT_ARGB32: + /* NB: Ignore argb32. We prefer premul */ + break; + case WL_SHM_FORMAT_PREMULTIPLIED_ARGB32: + _ecore_wl_disp_format = format; + break; + case WL_SHM_FORMAT_XRGB32: + _ecore_wl_disp_format = format; + break; + default: + break; + } +} + +static void +_ecore_wl_cb_disp_handle_geometry(void *data __UNUSED__, struct wl_output *output __UNUSED__, int x, int y, int pw __UNUSED__, int ph __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__) +{ + _ecore_wl_screen.x = x; + _ecore_wl_screen.y = y; +} + +static void +_ecore_wl_cb_disp_handle_mode(void *data __UNUSED__, struct wl_output *output __UNUSED__, uint32_t flags, int w, int h, int refresh __UNUSED__) +{ + if (flags & WL_OUTPUT_MODE_CURRENT) + { + _ecore_wl_screen.w = w; + _ecore_wl_screen.h = h; + } +} + +static Eina_Bool +_ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__) +{ + struct wl_display *disp; + + if (!(disp = data)) return ECORE_CALLBACK_RENEW; + if (disp != _ecore_wl_disp) return ECORE_CALLBACK_RENEW; + +// LOGFN(__FILE__, __LINE__, __FUNCTION__); + + /* NB: This handles iterate for writable AND readable. + * DO NOT TOUCH THIS OR YOU WILL PAY THE PRICE OF FAILURE !! + * Without this, animators/timers die */ + if (_ecore_wl_disp_mask & (WL_DISPLAY_READABLE | WL_DISPLAY_WRITABLE)) + wl_display_roundtrip(_ecore_wl_disp); + + return ECORE_CALLBACK_RENEW; +} + +static void +_ecore_wl_cb_handle_motion(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, int32_t x, int32_t y, int32_t sx, int32_t sy) +{ + Ecore_Event_Mouse_Move *ev; + + if (dev != _ecore_wl_input) return; + if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return; + + _ecore_wl_input_x = x; + _ecore_wl_input_y = y; + _ecore_wl_input_sx = sx; + _ecore_wl_input_sy = sy; + + ev->timestamp = t; + ev->x = sx; + ev->y = sy; + ev->root.x = x; + ev->root.y = y; + + if (_ecore_wl_input_surface) + { + unsigned int id = 0; + + if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) + { + ev->window = id; + ev->event_window = id; + } + } + + ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL); +} + +static void +_ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state) +{ + if (dev != _ecore_wl_input) return; + + if ((btn >= BTN_SIDE) && (btn <= BTN_BACK)) + { + Ecore_Event_Mouse_Wheel *ev; + + if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return; + + ev->timestamp = t; + ev->x = _ecore_wl_input_sx; + ev->y = _ecore_wl_input_sy; + ev->root.x = _ecore_wl_input_x; + ev->root.y = _ecore_wl_input_y; + ev->modifiers = _ecore_wl_input_modifiers; + ev->direction = 0; + + if (_ecore_wl_input_surface) + { + unsigned int id = 0; + + if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) + { + ev->window = id; + ev->event_window = id; + } + } + + /* NB: (FIXME) Currently Wayland provides no measure of how much the + * wheel has scrolled (read: delta of movement). So for now, we will + * just assume that the amount scrolled is 1 */ + if ((btn == BTN_EXTRA) || (btn == BTN_FORWARD)) // down + ev->z = 1; + else if ((btn == BTN_SIDE) || (btn == BTN_BACK)) // up + ev->z = -1; + + ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); + } + else + { + Ecore_Event_Mouse_Button *ev; + + if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return; + + if (btn == BTN_LEFT) + ev->buttons = 1; + else if (btn == BTN_MIDDLE) + ev->buttons = 2; + else if (btn == BTN_RIGHT) + ev->buttons = 3; + + ev->timestamp = t; + ev->x = _ecore_wl_input_sx; + ev->y = _ecore_wl_input_sy; + ev->root.x = _ecore_wl_input_x; + ev->root.y = _ecore_wl_input_y; + ev->modifiers = _ecore_wl_input_modifiers; + + if (_ecore_wl_input_surface) + { + unsigned int id = 0; + + if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) + { + ev->window = id; + ev->event_window = id; + } + } + + if (state) + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); + else + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); + } +} + +static void +_ecore_wl_cb_handle_key(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, uint32_t key, uint32_t state) +{ + unsigned int keycode = 0; + + if (dev != _ecore_wl_input) return; + + keycode = key + _ecore_wl_xkb->min_key_code; + + if (state) + _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[keycode]; + else + _ecore_wl_input_modifiers &= ~_ecore_wl_xkb->map->modmap[keycode]; +} + +static void +_ecore_wl_cb_handle_pointer_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, int32_t x, int32_t y, int32_t sx, int32_t sy) +{ + if (dev != _ecore_wl_input) return; + + _ecore_wl_input_x = x; + _ecore_wl_input_y = y; + _ecore_wl_input_sx = sx; + _ecore_wl_input_sy = sy; + + if (surface) + { + if (_ecore_wl_input_surface) + { + if (_ecore_wl_input_surface != surface) + { + /* NB: Pointer focus in different window. Send mouse & focus + * out events for previous window */ + _ecore_wl_mouse_out_send(); + _ecore_wl_focus_out_send(); + + /* NB: Send mouse & focus in events for new window */ + _ecore_wl_input_surface = surface; + _ecore_wl_mouse_in_send(); + _ecore_wl_focus_in_send(); + } + } + else + { + _ecore_wl_input_surface = surface; + _ecore_wl_mouse_in_send(); + _ecore_wl_focus_in_send(); + /* printf("\tPointer Focus In New Window\n"); */ + } + } + else + { + if (_ecore_wl_input_surface) + { + _ecore_wl_mouse_out_send(); + _ecore_wl_focus_out_send(); + /* printf("\tPointer Focus Not On a Window\n"); */ + } + else + printf("\tUnhandled Pointer Focus Case !!!\n"); + _ecore_wl_input_surface = NULL; + } +} + +static void +_ecore_wl_cb_handle_keyboard_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, struct wl_array *keys) +{ + unsigned int *keyend = 0, *i = 0; + + if (dev != _ecore_wl_input) return; + + if ((surface) && (surface != _ecore_wl_input_surface)) + _ecore_wl_input_surface = surface; + else if (!surface) + _ecore_wl_input_surface = NULL; + + keyend = keys->data + keys->size; + _ecore_wl_input_modifiers = 0; + for (i = keys->data; i < keyend; i++) + _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[*i]; +} + +static void +_ecore_wl_mouse_out_send(void) +{ + Ecore_Wl_Event_Mouse_Out *ev; + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return; + + ev->x = _ecore_wl_input_sx; + ev->y = _ecore_wl_input_sy; + ev->root.x = _ecore_wl_input_x; + ev->root.y = _ecore_wl_input_y; + ev->modifiers = _ecore_wl_input_modifiers; + ev->time = ecore_time_get(); + + if (_ecore_wl_input_surface) + { + unsigned int id = 0; + + if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) + ev->window = id; + } + + ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL); +} + +static void +_ecore_wl_mouse_in_send(void) +{ + Ecore_Wl_Event_Mouse_In *ev; + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return; + + ev->x = _ecore_wl_input_sx; + ev->y = _ecore_wl_input_sy; + ev->root.x = _ecore_wl_input_x; + ev->root.y = _ecore_wl_input_y; + ev->modifiers = _ecore_wl_input_modifiers; + ev->time = ecore_time_get(); + + if (_ecore_wl_input_surface) + { + unsigned int id = 0; + + if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) + ev->window = id; + } + + ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL); +} + +static void +_ecore_wl_focus_out_send(void) +{ + Ecore_Wl_Event_Focus_Out *ev; + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return; + ev->time = ecore_time_get(); + if (_ecore_wl_input_surface) + { + unsigned int id = 0; + + if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) + ev->window = id; + } + ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL); +} + +static void +_ecore_wl_focus_in_send(void) +{ + Ecore_Wl_Event_Focus_In *ev; + + if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return; + ev->time = ecore_time_get(); + if (_ecore_wl_input_surface) + { + unsigned int id = 0; + + if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) + ev->window = id; + } + ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL); +} diff --git a/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h new file mode 100644 index 0000000000..3beeac5ca7 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_private.h @@ -0,0 +1,47 @@ +#ifndef _ECORE_WAYLAND_PRIVATE_H +# define _ECORE_WAYLAND_PRIVATE_H + +# include + +# 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; + +# 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__) + +#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 new file mode 100644 index 0000000000..faa660a748 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_wayland/ecore_wl_window.c @@ -0,0 +1,196 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Wayland.h" +#include "ecore_wl_private.h" + +/* local function prototypes */ +static void _ecore_wl_window_cb_frame(void *data, struct wl_callback *cb __UNUSED__, uint32_t tm __UNUSED__); + +/* local variables */ +static const struct wl_callback_listener _ecore_wl_window_frame_listener = +{ + _ecore_wl_window_cb_frame +}; + +EAPI Ecore_Wl_Window * +ecore_wl_window_new(Ecore_Wl_Window_Type type, int x, int y, int w, int h) +{ + static int _win_id = 1; + Ecore_Wl_Window *win; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!(win = calloc(1, sizeof(Ecore_Wl_Window)))) return NULL; + + win->id = _win_id++; + printf("Ecore_Wl Window Id: %d\n", win->id); + win->x = x; + win->y = y; + win->w = w; + win->h = h; + win->synced = EINA_TRUE; + win->type = type; + + return win; +} + +EAPI void +ecore_wl_window_free(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; +// ecore_wl_window_hide(win); + free(win); +} + +EAPI void +ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if ((win->x == x) && (win->y == y)) return; + win->x = x; + win->y = y; +} + +EAPI void +ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if ((win->w == w) && (win->h == h)) return; + win->w = w; + win->h = h; +} + +EAPI void +ecore_wl_window_show(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + + win->surface = wl_compositor_create_surface(ecore_wl_compositor_get()); + + win->shell_surface = + wl_shell_get_shell_surface(ecore_wl_shell_get(), win->surface); + wl_shell_surface_set_toplevel(win->shell_surface); +} + +EAPI void +ecore_wl_window_hide(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (win->callback) wl_callback_destroy(win->callback); + if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface); + if (win->surface) wl_surface_destroy(win->surface); +} + +EAPI void +ecore_wl_window_raise(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (!win->shell_surface) return; + wl_shell_surface_set_toplevel(win->shell_surface); +} + +EAPI void +ecore_wl_window_lower(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; +} + +EAPI void +ecore_wl_window_activate(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (!win->shell_surface) return; + wl_shell_surface_set_toplevel(win->shell_surface); +} + +EAPI void +ecore_wl_window_focus(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (!win->shell_surface) return; + wl_shell_surface_set_toplevel(win->shell_surface); +} + +EAPI void +ecore_wl_window_fullscreen(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if (!win->shell_surface) return; + wl_shell_surface_set_fullscreen(win->shell_surface); +} + +EAPI void +ecore_wl_window_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + if ((win->surface) && (buffer)) + wl_surface_attach(win->surface, buffer, 0, 0); +} + +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) return; + if (win->synced) + { + if (win->callback) wl_callback_destroy(win->callback); + win->callback = wl_surface_frame(win->surface); + wl_callback_add_listener(win->callback, + &_ecore_wl_window_frame_listener, win); + win->synced = EINA_FALSE; + } + wl_surface_damage(win->surface, x, y, w, h); +} + +EAPI void +ecore_wl_window_sync(Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!win) return; + ecore_wl_flush(); + while (!win->synced) + ecore_wl_sync(); +} + +/* local functions */ +static void +_ecore_wl_window_cb_frame(void *data, struct wl_callback *cb __UNUSED__, uint32_t tm __UNUSED__) +{ + Ecore_Wl_Window *win; + + if (!(win = data)) return; + win->synced = EINA_TRUE; + if (win->callback) wl_callback_destroy(win->callback); + win->callback = NULL; + wl_surface_damage(win->surface, 0, 0, win->w, win->h); +}