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
This commit is contained in:
Christopher Michael 2011-12-26 23:27:20 +00:00
parent 26fcca18b7
commit 627d39bfa2
16 changed files with 2359 additions and 12 deletions

View File

@ -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

View File

@ -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}"

View File

@ -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@

View File

@ -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

View File

@ -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.
*

View File

@ -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 \

View File

@ -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... :) */

View File

@ -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)

View File

@ -79,9 +79,17 @@
# include <Evas_Engine_Gl_Cocoa.h>
#endif
/**
Log domain macros and variable
**/
#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
# include "Ecore_Wayland.h"
# include <Evas_Engine_Wayland_Shm.h>
#endif
#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
# include "Ecore_Wayland.h"
# include <Evas_Engine_Wayland_Egl.h>
#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 {

View File

@ -0,0 +1,342 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
# define LOGFNS 1
# ifdef LOGFNS
# include <stdio.h>
# define LOGFN(fl, ln, fn) \
printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
# else
# define LOGFN(fl, ln, fn)
# endif
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/mman.h>
# include <Eina.h>
# include <Evas.h>
# include <Ecore.h>
# include "ecore_evas_private.h"
# include "Ecore_Evas.h"
#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
# include <Evas_Engine_Wayland_Egl.h>
# include <Ecore_Wayland.h>
#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

View File

@ -0,0 +1,727 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#define LOGFNS 1
#ifdef LOGFNS
# include <stdio.h>
# define LOGFN(fl, ln, fn) \
printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
#else
# define LOGFN(fl, ln, fn)
#endif
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/mman.h>
# include <Eina.h>
# include <Evas.h>
# include <Ecore.h>
# include "ecore_evas_private.h"
# include "Ecore_Evas.h"
#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
# include <Evas_Engine_Wayland_Shm.h>
# include <Ecore_Wayland.h>
#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

View File

@ -0,0 +1,134 @@
#ifndef _ECORE_WAYLAND_H_
# define _ECORE_WAYLAND_H_
# include <Eina.h>
# include <wayland-client.h>
# 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

View File

@ -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

View File

@ -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 <linux/input.h>
#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 <X11/extensions/XKBcommon.h>
/* 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);
}

View File

@ -0,0 +1,47 @@
#ifndef _ECORE_WAYLAND_PRIVATE_H
# define _ECORE_WAYLAND_PRIVATE_H
# include <limits.h>
# define LOGFNS 1
# ifdef LOGFNS
# include <stdio.h>
# 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

View File

@ -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);
}