ecore: Add a new wayland module

This is a merge of branch 'devs/devilhorns/ecore_wl2' that improves on
the existing ecore_wayland module. Improvements include support for
mulitple wayland displays (nested compositor scenario), Improved time
to first frame, reduced input latency, and better support for xdg window
geometry.

@feature
This commit is contained in:
Chris Michael 2015-12-03 12:18:16 -05:00
commit 55c6441f6c
41 changed files with 7156 additions and 149 deletions

View File

@ -244,6 +244,10 @@ if HAVE_ECORE_WAYLAND
pkgconfig_DATA += pc/ecore-wayland.pc
endif
if HAVE_ECORE_WL2
pkgconfig_DATA += pc/ecore-wl2.pc
endif
if HAVE_WIN32
pkgconfig_DATA += pc/ecore-win32.pc
endif

View File

@ -3026,6 +3026,45 @@ EFL_EVAL_PKGS([ECORE_WAYLAND])
EFL_LIB_END_OPTIONAL([Ecore_Wayland])
#### End of Ecore_Wayland
#### Ecore_Wl2
EFL_LIB_START_OPTIONAL([Ecore_Wl2], [test "${want_wayland}" = "yes"])
if test "x${want_wayland_ivi_shell}" = "xyes" ; then
AC_DEFINE(USE_IVI_SHELL, 1, [Ecore_Wl2 IVI-Shell Support])
fi
### Additional options to configure
### Default values
### Checks for programs
### Checks for libraries
EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [ecore-input])
EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [ecore])
EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [eo])
EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [eina])
EFL_DEPEND_PKG([ECORE_WL2], [WAYLAND],
[wayland-server >= 1.8.0 wayland-client >= 1.8.0 wayland-cursor >= 1.8.0 xkbcommon >= 0.5.0])
EFL_EVAL_PKGS([ECORE_WL2])
### Checks for header files
### Checks for types
### Checks for structures
### Checks for compiler characteristics
### Checks for linker characteristics
### Checks for library functions
EFL_LIB_END_OPTIONAL([Ecore_Wl2])
#### End of Ecore_Wl2
#### Eldbus
EFL_LIB_START([Eldbus])
@ -4795,6 +4834,7 @@ pc/ecore-fb.pc
pc/ecore-psl1ght.pc
pc/ecore-sdl.pc
pc/ecore-wayland.pc
pc/ecore-wl2.pc
pc/ecore-win32.pc
pc/ecore-x.pc
pc/ecore-evas.pc
@ -4964,6 +5004,7 @@ echo "Ecore_IMF.......: yes (${features_ecore_imf})"
echo "Ecore_X.........: ${with_x11} (${features_ecore_x})"
echo "Ecore_SDL.......: $want_sdl"
echo "Ecore_Wayland...: $want_wayland"
echo "Ecore_Wl2.......: $want_wayland"
echo "IVI-Shell.......: $want_wayland_ivi_shell"
echo "Ecore_Buffer....: $want_ecore_buffer (${features_ecore_buffer})"
if test "${have_linux}" = "yes"; then

1
pc/.gitignore vendored
View File

@ -14,6 +14,7 @@
/ecore-psl1ght.pc
/ecore-sdl.pc
/ecore-wayland.pc
/ecore-wl2.pc
/ecore-win32.pc
/ecore-x.pc
/ecore.pc

12
pc/ecore-wl2.pc.in Normal file
View File

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: ecore-wl2
Description: E core library, Wayland module
Requires.private: @requirements_pc_ecore_wl2@
Version: @VERSION@
Libs: -L${libdir} -lecore_wl2
Libs.private: @requirements_libs_ecore_wl2@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/ecore-wl2-@VMAJ@

View File

@ -40,6 +40,7 @@ include Makefile_Ecore_FB.am
include Makefile_Ecore_Psl1ght.am
include Makefile_Ecore_SDL.am
include Makefile_Ecore_Wayland.am
include Makefile_Ecore_Wl2.am
include Makefile_Ecore_Win32.am
include Makefile_Ecore_X.am
include Makefile_Ecore_IMF.am

View File

@ -7,7 +7,8 @@ lib_LTLIBRARIES += lib/ecore_cocoa/libecore_cocoa.la
installed_ecorecocoamainheadersdir = $(includedir)/ecore-cocoa-@VMAJ@
dist_installed_ecorecocoamainheaders_DATA = \
lib/ecore_cocoa/Ecore_Cocoa.h \
lib/ecore_cocoa/Ecore_Cocoa_Cursor.h
lib/ecore_cocoa/Ecore_Cocoa_Cursor.h \
lib/ecore_cocoa/Ecore_Cocoa_Keys.h
lib_ecore_cocoa_libecore_cocoa_la_SOURCES = \
lib/ecore_cocoa/ecore_cocoa.m \

View File

@ -187,15 +187,19 @@ modules_ecore_evas_engines_wayland_module_la_SOURCES = $(WAYLANDSOURCES)
modules_ecore_evas_engines_wayland_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
@ECORE_EVAS_CFLAGS@ \
@ECORE_WAYLAND_CFLAGS@ \
@ECORE_WL2_CFLAGS@ \
-I$(top_srcdir)/src/modules/evas/engines/wayland_shm \
-I$(top_srcdir)/src/modules/evas/engines/wayland_egl \
@ECORE_WAYLAND_CFLAGS@
@ECORE_WAYLAND_CFLAGS@ \
@ECORE_WL2_CFLAGS@
modules_ecore_evas_engines_wayland_module_la_LIBADD = \
@USE_ECORE_EVAS_LIBS@ \
@USE_ECORE_WAYLAND_LIBS@
@USE_ECORE_WAYLAND_LIBS@ \
@USE_ECORE_WL2_LIBS@
modules_ecore_evas_engines_wayland_module_la_DEPENDENCIES = \
@USE_ECORE_EVAS_INTERNAL_LIBS@ \
@USE_ECORE_WAYLAND_INTERNAL_LIBS@
@USE_ECORE_WAYLAND_INTERNAL_LIBS@ \
@USE_ECORE_WL2_INTERNAL_LIBS@
modules_ecore_evas_engines_wayland_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
modules_ecore_evas_engines_wayland_module_la_LIBTOOLFLAGS = --tag=disable-static
endif

View File

@ -139,15 +139,15 @@ modules/ecore_imf/wayland/text-protocol.c
modules_ecore_imf_wayland_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
@ECORE_IMF_CFLAGS@ \
@ECORE_EVAS_CFLAGS@ \
@ECORE_WAYLAND_CFLAGS@
@ECORE_WL2_CFLAGS@
modules_ecore_imf_wayland_module_la_LIBADD = \
@USE_ECORE_IMF_LIBS@ \
@USE_ECORE_EVAS_LIBS@ \
@USE_ECORE_WAYLAND_LIBS@
@USE_ECORE_WL2_LIBS@
modules_ecore_imf_wayland_module_la_DEPENDENCIES = \
@USE_ECORE_IMF_INTERNAL_LIBS@ \
@USE_ECORE_EVAS_INTERNAL_LIBS@ \
@USE_ECORE_WAYLAND_INTERNAL_LIBS@
@USE_ECORE_WL2_INTERNAL_LIBS@
modules_ecore_imf_wayland_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
modules_ecore_imf_wayland_module_la_LIBTOOLFLAGS = --tag=disable-static
endif

30
src/Makefile_Ecore_Wl2.am Normal file
View File

@ -0,0 +1,30 @@
if HAVE_ECORE_WL2
### Library
lib_LTLIBRARIES += lib/ecore_wl2/libecore_wl2.la
installed_ecorewl2mainheadersdir = $(includedir)/ecore-wl2-@VMAJ@
dist_installed_ecorewl2mainheaders_DATA = lib/ecore_wl2/Ecore_Wl2.h
lib_ecore_wl2_libecore_wl2_la_SOURCES = \
lib/ecore_wl2/subsurface-client-protocol.h \
lib/ecore_wl2/subsurface-protocol.c \
lib/ecore_wl2/xdg-shell-client-protocol.h \
lib/ecore_wl2/xdg-shell-protocol.c \
lib/ecore_wl2/ecore_wl2_seat.c \
lib/ecore_wl2/ecore_wl2_subsurf.c \
lib/ecore_wl2/ecore_wl2_dnd.c \
lib/ecore_wl2/ecore_wl2_window.c \
lib/ecore_wl2/ecore_wl2_input.c \
lib/ecore_wl2/ecore_wl2_output.c \
lib/ecore_wl2/ecore_wl2_display.c \
lib/ecore_wl2/ecore_wl2.c \
lib/ecore_wl2/ecore_wl2_private.h
lib_ecore_wl2_libecore_wl2_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_WL2_CFLAGS@
lib_ecore_wl2_libecore_wl2_la_LIBADD = @ECORE_WL2_LIBS@
lib_ecore_wl2_libecore_wl2_la_DEPENDENCIES = @ECORE_WL2_INTERNAL_LIBS@
lib_ecore_wl2_libecore_wl2_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
endif

View File

@ -282,6 +282,10 @@ EAPI void *ecore_cocoa_selection_clipboard_get(int *size, Ecore_Cocoa_Cnp_Type t
EAPI void ecore_cocoa_selection_clipboard_clear(void);
EAPI void ecore_cocoa_window_cursor_set(Ecore_Cocoa_Window *win, Ecore_Cocoa_Cursor c);
EAPI void ecore_cocoa_window_cursor_show(Ecore_Cocoa_Window *win, Eina_Bool show);
EAPI void ecore_cocoa_window_cursor_set(Ecore_Cocoa_Window *win, Ecore_Cocoa_Cursor c);
EAPI void ecore_cocoa_window_cursor_show(Ecore_Cocoa_Window *win, Eina_Bool show);

View File

@ -67,6 +67,4 @@ Eina_Bool _ecore_cocoa_window_init(void);
Eina_Bool _ecore_cocoa_feed_events(void *anEvent);
#endif

View File

@ -578,3 +578,50 @@ _ecore_cocoa_window_init(void)
return EINA_TRUE;
}
EAPI void
ecore_cocoa_window_cursor_set(Ecore_Cocoa_Window *win,
Ecore_Cocoa_Cursor c)
{
EINA_SAFETY_ON_NULL_RETURN(win);
EINA_SAFETY_ON_FALSE_RETURN((c >= 0) && (c <= __ECORE_COCOA_CURSOR_LAST));
NSCursor *cursor = _cursors[c];
DBG("Setting cursor %i (%s)", c, [[cursor description] UTF8String]);
[cursor set];
}
EAPI void
ecore_cocoa_window_cursor_show(Ecore_Cocoa_Window *win,
Eina_Bool show)
{
EINA_SAFETY_ON_NULL_RETURN(win);
if (show) [NSCursor unhide];
else [NSCursor hide];
}
Eina_Bool
_ecore_cocoa_window_init(void)
{
_cursors[ECORE_COCOA_CURSOR_ARROW] = [NSCursor arrowCursor];
_cursors[ECORE_COCOA_CURSOR_CONTEXTUAL_MENU] = [NSCursor contextualMenuCursor];
_cursors[ECORE_COCOA_CURSOR_CLOSED_HAND] = [NSCursor closedHandCursor];
_cursors[ECORE_COCOA_CURSOR_CROSSHAIR] = [NSCursor crosshairCursor];
_cursors[ECORE_COCOA_CURSOR_DISAPPEARING_ITEM] = [NSCursor disappearingItemCursor];
_cursors[ECORE_COCOA_CURSOR_DRAG_COPY] = [NSCursor dragCopyCursor];
_cursors[ECORE_COCOA_CURSOR_DRAG_LINK] = [NSCursor dragLinkCursor];
_cursors[ECORE_COCOA_CURSOR_IBEAM] = [NSCursor IBeamCursor];
_cursors[ECORE_COCOA_CURSOR_OPEN_HAND] = [NSCursor openHandCursor];
_cursors[ECORE_COCOA_CURSOR_OPERATION_NOT_ALLOWED] = [NSCursor operationNotAllowedCursor];
_cursors[ECORE_COCOA_CURSOR_POINTING_HAND] = [NSCursor pointingHandCursor];
_cursors[ECORE_COCOA_CURSOR_RESIZE_DOWN] = [NSCursor resizeDownCursor];
_cursors[ECORE_COCOA_CURSOR_RESIZE_LEFT] = [NSCursor resizeLeftCursor];
_cursors[ECORE_COCOA_CURSOR_RESIZE_LEFT_RIGHT] = [NSCursor resizeLeftRightCursor];
_cursors[ECORE_COCOA_CURSOR_RESIZE_RIGHT] = [NSCursor resizeRightCursor];
_cursors[ECORE_COCOA_CURSOR_RESIZE_UP] = [NSCursor resizeUpCursor];
_cursors[ECORE_COCOA_CURSOR_RESIZE_UP_DOWN] = [NSCursor resizeUpDownCursor];
_cursors[ECORE_COCOA_CURSOR_IBEAM_VERTICAL] = [NSCursor IBeamCursorForVerticalLayout];
return EINA_TRUE;
}

View File

@ -1316,6 +1316,7 @@ EAPI void ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y);
EAPI void ecore_evas_wayland_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y);
EAPI void ecore_evas_wayland_type_set(Ecore_Evas *ee, int type);
EAPI Ecore_Wl_Window *ecore_evas_wayland_window_get(const Ecore_Evas *ee);
EAPI Ecore_Wl2_Window *ecore_evas_wayland_window_get2(const Ecore_Evas *ee);
EAPI Ecore_Cocoa_Window *ecore_evas_cocoa_window_get(const Ecore_Evas *ee);

View File

@ -48,6 +48,11 @@ typedef void (*Ecore_Evas_Event_Cb) (Ecore_Evas *ee); /**< Callback used for s
typedef struct _Ecore_Wl_Window Ecore_Wl_Window;
#endif
#ifndef _ECORE_WL2_H_
#define _ECORE_WAYLAND_WINDOW_PREDEF
typedef struct _Ecore_Wl2_Window Ecore_Wl2_Window;
#endif
#ifndef _ECORE_GETOPT_PREDEF
typedef struct _Ecore_Getopt Ecore_Getopt;
#define _ECORE_GETOPT_PREDEF 1

View File

@ -3993,6 +3993,25 @@ ecore_evas_cocoa_window_get(const Ecore_Evas *ee)
return iface->window_get(ee);
}
EAPI Ecore_Wl2_Window *
ecore_evas_wayland_window_get2(const Ecore_Evas *ee)
{
Ecore_Evas_Interface_Wayland *iface;
iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
return iface->window_get2(ee);
}
EAPI Ecore_Cocoa_Window *
ecore_evas_cocoa_window_get(const Ecore_Evas *ee)
{
Ecore_Evas_Interface_Cocoa *iface;
iface = (Ecore_Evas_Interface_Cocoa *)_ecore_evas_interface_get(ee, "opengl_cocoa");
EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
return iface->window_get(ee);
}
EAPI Ecore_Evas *
ecore_evas_drm_new(const char *disp_name, unsigned int parent,
int x, int y, int w, int h)

View File

@ -12,6 +12,7 @@ struct _Ecore_Evas_Interface_Wayland
void (*pointer_set)(Ecore_Evas *ee, int hot_x, int hot_y);
void (*type_set)(Ecore_Evas *ee, int type);
Ecore_Wl_Window* (*window_get)(const Ecore_Evas *ee);
Ecore_Wl2_Window *(*window_get2)(const Ecore_Evas *ee);
void (*pre_post_swap_callback_set)(const Ecore_Evas *ee, void *data, void (*pre_cb) (void *data, Evas *e), void (*post_cb) (void *data, Evas *e));
};

View File

@ -43,7 +43,7 @@ static void _ecore_wl_init_callback(void *data, struct wl_callback *callback, ui
static int _ecore_wl_init_count = 0;
static Eina_Bool _ecore_wl_animator_busy = EINA_FALSE;
static Eina_Bool _ecore_wl_fatal_error = EINA_FALSE;
static Eina_Bool _ecore_wl_server_mode = EINA_FALSE;
Eina_Bool _ecore_wl_server_mode = EINA_FALSE;
static const struct wl_registry_listener _ecore_wl_registry_listener =
{

View File

@ -22,6 +22,7 @@
# endif
extern int _ecore_wl_log_dom;
extern Eina_Bool _ecore_wl_server_mode;
# ifdef ECORE_WL_DEFAULT_LOG_COLOR
# undef ECORE_WL_DEFAULT_LOG_COLOR

View File

@ -227,6 +227,7 @@ ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buf
win->class_name = NULL;
eina_hash_add(_windows, _ecore_wl_window_id_str_get(win->id), win);
return win;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ecore_wl2_private.h"
/* local variables */
static int _ecore_wl2_init_count = 0;
/* external variables */
int _ecore_wl2_log_dom = -1;
/* public API variables */
EAPI int ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
EAPI int ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
EAPI int ECORE_WL2_EVENT_FOCUS_IN = 0;
EAPI int ECORE_WL2_EVENT_FOCUS_OUT = 0;
EAPI int ECORE_WL2_EVENT_DND_ENTER = 0;
EAPI int ECORE_WL2_EVENT_DND_LEAVE = 0;
EAPI int ECORE_WL2_EVENT_DND_MOTION = 0;
EAPI int ECORE_WL2_EVENT_DND_DROP = 0;
EAPI int ECORE_WL2_EVENT_DND_END = 0;
EAPI int ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED = 0;
EAPI int ECORE_WL2_EVENT_DATA_SOURCE_TARGET = 0;
EAPI int ECORE_WL2_EVENT_DATA_SOURCE_SEND = 0;
EAPI int ECORE_WL2_EVENT_SELECTION_DATA_READY = 0;
EAPI int ECORE_WL2_EVENT_WINDOW_CONFIGURE = 0;
/* public API functions */
EAPI int
ecore_wl2_init(void)
{
if (++_ecore_wl2_init_count != 1) return _ecore_wl2_init_count;
/* try to initialize Eina */
if (!eina_init()) return --_ecore_wl2_init_count;
/* try to create Eina logging domain */
_ecore_wl2_log_dom =
eina_log_domain_register("ecore_wl2", ECORE_WL2_DEFAULT_LOG_COLOR);
if (_ecore_wl2_log_dom < 0)
{
EINA_LOG_ERR("Cannot create a log domain for Ecore Wl2");
goto eina_err;
}
/* try to initialize Ecore */
if (!ecore_init())
{
ERR("Could not initialize Ecore");
goto ecore_err;
}
/* try to initialize Ecore_Event */
if (!ecore_event_init())
{
ERR("Could not initialize Ecore_Event");
goto ecore_event_err;
}
/* handle creating new Ecore_Wl2 event types */
if (!ECORE_WL2_EVENT_GLOBAL_ADDED)
{
ECORE_WL2_EVENT_GLOBAL_ADDED = ecore_event_type_new();
ECORE_WL2_EVENT_GLOBAL_REMOVED = ecore_event_type_new();
ECORE_WL2_EVENT_FOCUS_IN = ecore_event_type_new();
ECORE_WL2_EVENT_FOCUS_OUT = ecore_event_type_new();
ECORE_WL2_EVENT_DND_ENTER = ecore_event_type_new();
ECORE_WL2_EVENT_DND_LEAVE = ecore_event_type_new();
ECORE_WL2_EVENT_DND_MOTION = ecore_event_type_new();
ECORE_WL2_EVENT_DND_DROP = ecore_event_type_new();
ECORE_WL2_EVENT_DND_END = ecore_event_type_new();
ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED = ecore_event_type_new();
ECORE_WL2_EVENT_DATA_SOURCE_TARGET = ecore_event_type_new();
ECORE_WL2_EVENT_DATA_SOURCE_SEND = ecore_event_type_new();
ECORE_WL2_EVENT_SELECTION_DATA_READY = ecore_event_type_new();
ECORE_WL2_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
}
return _ecore_wl2_init_count;
ecore_event_err:
ecore_shutdown();
ecore_err:
eina_log_domain_unregister(_ecore_wl2_log_dom);
_ecore_wl2_log_dom = -1;
eina_err:
eina_shutdown();
return --_ecore_wl2_init_count;
}
EAPI int
ecore_wl2_shutdown(void)
{
if (_ecore_wl2_init_count < 1)
{
ERR("Ecore_Wl2 shutdown called without Ecore_Wl2 Init");
return 0;
}
if (--_ecore_wl2_init_count != 0) return _ecore_wl2_init_count;
/* reset events */
ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
ECORE_WL2_EVENT_FOCUS_IN = 0;
ECORE_WL2_EVENT_FOCUS_OUT = 0;
ECORE_WL2_EVENT_DND_ENTER = 0;
ECORE_WL2_EVENT_DND_LEAVE = 0;
ECORE_WL2_EVENT_DND_MOTION = 0;
ECORE_WL2_EVENT_DND_DROP = 0;
ECORE_WL2_EVENT_DND_END = 0;
ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED = 0;
ECORE_WL2_EVENT_DATA_SOURCE_TARGET = 0;
ECORE_WL2_EVENT_DATA_SOURCE_SEND = 0;
ECORE_WL2_EVENT_SELECTION_DATA_READY = 0;
ECORE_WL2_EVENT_WINDOW_CONFIGURE = 0;
/* shutdown Ecore_Event */
ecore_event_shutdown();
/* shutdown Ecore */
ecore_shutdown();
/* unregister logging domain */
eina_log_domain_unregister(_ecore_wl2_log_dom);
_ecore_wl2_log_dom = -1;
/* shutdown eina */
eina_shutdown();
return _ecore_wl2_init_count;
}

View File

@ -0,0 +1,745 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ecore_wl2_private.h"
static Eina_Bool _fatal_error = EINA_FALSE;
static Eina_Hash *_server_displays = NULL;
static Eina_Hash *_client_displays = NULL;
static void
_ecore_wl2_display_signal_exit(void)
{
Ecore_Event_Signal_Exit *ev;
ev = calloc(1, sizeof(Ecore_Event_Signal_Exit));
if (!ev) return;
ev->quit = EINA_TRUE;
ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, ev, NULL, NULL);
}
static void
_xdg_shell_cb_ping(void *data EINA_UNUSED, struct xdg_shell *shell, uint32_t serial)
{
xdg_shell_pong(shell, serial);
}
static const struct xdg_shell_listener _xdg_shell_listener =
{
_xdg_shell_cb_ping
};
static void
_cb_global_event_free(void *data EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Global *ev;
ev = event;
eina_stringshare_del(ev->interface);
free(ev);
}
static void
_cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version)
{
Ecore_Wl2_Display *ewd;
Ecore_Wl2_Event_Global *ev;
ewd = data;
/* test to see if we have already added this global to our hash */
if (!eina_hash_find(ewd->globals, &id))
{
Ecore_Wl2_Global *global;
/* allocate space for new global */
global = calloc(1, sizeof(Ecore_Wl2_Global));
if (!global) return;
global->id = id;
global->interface = eina_stringshare_add(interface);
global->version = version;
/* add this global to our hash */
if (!eina_hash_add(ewd->globals, &global->id, global))
{
eina_stringshare_del(global->interface);
free(global);
}
}
else
goto event;
if (!strcmp(interface, "wl_compositor"))
{
ewd->wl.compositor =
wl_registry_bind(registry, id, &wl_compositor_interface, 3);
}
else if (!strcmp(interface, "wl_subcompositor"))
{
ewd->wl.subcompositor =
wl_registry_bind(registry, id, &wl_subcompositor_interface, 1);
}
else if (!strcmp(interface, "wl_shm"))
{
ewd->wl.shm =
wl_registry_bind(registry, id, &wl_shm_interface, 1);
}
else if (!strcmp(interface, "wl_data_device_manager"))
{
ewd->wl.data_device_manager =
wl_registry_bind(registry, id, &wl_data_device_manager_interface, 1);
}
else if (!strcmp(interface, "wl_shell"))
{
ewd->wl.wl_shell =
wl_registry_bind(registry, id, &wl_shell_interface, 1);
}
else if ((!strcmp(interface, "xdg_shell")) &&
(!getenv("EFL_WAYLAND_DONT_USE_XDG_SHELL")))
{
ewd->wl.xdg_shell =
wl_registry_bind(registry, id, &xdg_shell_interface, 1);
xdg_shell_use_unstable_version(ewd->wl.xdg_shell, XDG_VERSION);
xdg_shell_add_listener(ewd->wl.xdg_shell, &_xdg_shell_listener, NULL);
}
else if (!strcmp(interface, "wl_output"))
_ecore_wl2_output_add(ewd, id);
else if (!strcmp(interface, "wl_seat"))
_ecore_wl2_input_add(ewd, id, version);
event:
/* allocate space for event structure */
ev = calloc(1, sizeof(Ecore_Wl2_Event_Global));
if (!ev) return;
ev->id = id;
ev->display = ewd;
ev->version = version;
ev->interface = eina_stringshare_add(interface);
/* raise an event saying a new global has been added */
ecore_event_add(ECORE_WL2_EVENT_GLOBAL_ADDED, ev,
_cb_global_event_free, NULL);
}
static void
_cb_global_remove(void *data, struct wl_registry *registry EINA_UNUSED, unsigned int id)
{
Ecore_Wl2_Display *ewd;
Ecore_Wl2_Global *global;
Ecore_Wl2_Event_Global *ev;
ewd = data;
/* try to find this global in our hash */
global = eina_hash_find(ewd->globals, &id);
if (!global) return;
/* allocate space for event structure */
ev = calloc(1, sizeof(Ecore_Wl2_Event_Global));
if (!ev) return;
ev->id = id;
ev->display = ewd;
ev->version = global->version;
ev->interface = eina_stringshare_add(global->interface);
/* raise an event saying a global has been removed */
ecore_event_add(ECORE_WL2_EVENT_GLOBAL_REMOVED, ev,
_cb_global_event_free, NULL);
/* delete this global from our hash */
if (ewd->globals) eina_hash_del_by_key(ewd->globals, &id);
}
static const struct wl_registry_listener _registry_listener =
{
_cb_global_add,
_cb_global_remove
};
static Eina_Bool
_cb_create_data(void *data, Ecore_Fd_Handler *hdl)
{
Ecore_Wl2_Display *ewd;
struct wl_event_loop *loop;
ewd = data;
if (_fatal_error) return ECORE_CALLBACK_CANCEL;
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR))
{
ERR("Received Fatal Error on Wayland Display");
_fatal_error = EINA_TRUE;
_ecore_wl2_display_signal_exit();
return ECORE_CALLBACK_CANCEL;
}
loop = wl_display_get_event_loop(ewd->wl.display);
wl_event_loop_dispatch(loop, 0);
/* wl_display_flush_clients(ewd->wl.display); */
return ECORE_CALLBACK_RENEW;
}
static void
_cb_create_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
{
Ecore_Wl2_Display *ewd;
ewd = data;
wl_display_flush_clients(ewd->wl.display);
}
static Eina_Bool
_cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
{
Ecore_Wl2_Display *ewd;
int ret = 0;
ewd = data;
if (_fatal_error) return ECORE_CALLBACK_CANCEL;
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR))
{
ERR("Received Fatal Error on Wayland Display");
_fatal_error = EINA_TRUE;
_ecore_wl2_display_signal_exit();
return ECORE_CALLBACK_CANCEL;
}
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
{
ret = wl_display_dispatch(ewd->wl.display);
if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
{
ERR("Received Fatal Error on Wayland Display");
_fatal_error = EINA_TRUE;
_ecore_wl2_display_signal_exit();
return ECORE_CALLBACK_CANCEL;
}
}
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
{
ret = wl_display_flush(ewd->wl.display);
if (ret == 0)
ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
{
ERR("Received Fatal Error on Wayland Display");
_fatal_error = EINA_TRUE;
_ecore_wl2_display_signal_exit();
return ECORE_CALLBACK_CANCEL;
}
}
return ECORE_CALLBACK_RENEW;
}
static void
_cb_globals_hash_del(void *data)
{
Ecore_Wl2_Global *global;
global = data;
eina_stringshare_del(global->interface);
free(global);
}
static Eina_Bool
_cb_connect_idle(void *data)
{
Ecore_Wl2_Display *ewd;
int ret = 0;
ewd = data;
if (!ewd) return ECORE_CALLBACK_RENEW;
if (_fatal_error) return ECORE_CALLBACK_CANCEL;
ret = wl_display_get_error(ewd->wl.display);
if (ret < 0) goto err;
ret = wl_display_dispatch_pending(ewd->wl.display);
if (ret < 0) goto err;
ret = wl_display_flush(ewd->wl.display);
if ((ret < 0) && (errno == EAGAIN))
ecore_main_fd_handler_active_set(ewd->fd_hdl,
(ECORE_FD_READ | ECORE_FD_WRITE));
return ECORE_CALLBACK_RENEW;
err:
if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
{
ERR("Wayland Socket Error: %s", strerror(errno));
_fatal_error = EINA_TRUE;
_ecore_wl2_display_signal_exit();
return ECORE_CALLBACK_CANCEL;
}
return ECORE_CALLBACK_RENEW;
}
static void
_cb_sync_done(void *data, struct wl_callback *cb, uint32_t serial EINA_UNUSED)
{
Ecore_Wl2_Display *ewd;
ewd = data;
ewd->sync_done = EINA_TRUE;
wl_callback_destroy(cb);
}
static const struct wl_callback_listener _sync_listener =
{
_cb_sync_done
};
static void
_ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
{
Ecore_Wl2_Output *output;
Ecore_Wl2_Input *input;
Eina_Inlist *tmp;
if (--ewd->refs) return;
if (ewd->xkb_context) xkb_context_unref(ewd->xkb_context);
/* free each input */
EINA_INLIST_FOREACH_SAFE(ewd->inputs, tmp, input)
_ecore_wl2_input_del(input);
/* free each output */
EINA_INLIST_FOREACH_SAFE(ewd->outputs, tmp, output)
_ecore_wl2_output_del(output);
if (ewd->idle_enterer) ecore_idle_enterer_del(ewd->idle_enterer);
if (ewd->fd_hdl) ecore_main_fd_handler_del(ewd->fd_hdl);
eina_hash_free(ewd->globals);
if (ewd->wl.xdg_shell) xdg_shell_destroy(ewd->wl.xdg_shell);
if (ewd->wl.wl_shell) wl_shell_destroy(ewd->wl.wl_shell);
if (ewd->wl.shm) wl_shm_destroy(ewd->wl.shm);
if (ewd->wl.data_device_manager)
wl_data_device_manager_destroy(ewd->wl.data_device_manager);
if (ewd->wl.compositor) wl_compositor_destroy(ewd->wl.compositor);
if (ewd->wl.subcompositor) wl_subcompositor_destroy(ewd->wl.subcompositor);
if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry);
wl_display_flush(ewd->wl.display);
if (ewd->name) free(ewd->name);
/* remove this client display from hash */
if (_client_displays) eina_hash_del(_client_displays, ewd->name, ewd);
}
Ecore_Wl2_Window *
_ecore_wl2_display_window_surface_find(Ecore_Wl2_Display *display, struct wl_surface *wl_surface)
{
Ecore_Wl2_Window *window;
if ((!display) || (!wl_surface)) return NULL;
EINA_INLIST_FOREACH(display->windows, window)
{
if ((window->surface) &&
(window->surface == wl_surface))
return window;
}
return NULL;
}
EAPI Ecore_Wl2_Display *
ecore_wl2_display_create(const char *name)
{
Ecore_Wl2_Display *ewd;
struct wl_event_loop *loop;
const char *n;
if (!_server_displays)
_server_displays = eina_hash_string_superfast_new(NULL);
if (!name)
{
/* someone wants to create a new server */
n = getenv("WAYLAND_DISPLAY");
if (n)
{
/* we have a default wayland display */
/* check hash of cached server displays for this name */
ewd = eina_hash_find(_server_displays, n);
if (ewd) goto found;
}
}
else
{
/* someone wants to create a server with a specific display */
/* check hash of cached server displays for this name */
ewd = eina_hash_find(_server_displays, name);
if (ewd) goto found;
}
/* allocate space for display structure */
ewd = calloc(1, sizeof(Ecore_Wl2_Display));
if (!ewd) return NULL;
ewd->refs++;
ewd->pid = getpid();
/* try to create new wayland display */
ewd->wl.display = wl_display_create();
if (!ewd->wl.display)
{
ERR("Could not create wayland display: %m");
goto create_err;
}
if (!name)
{
const char *n;
n = wl_display_add_socket_auto(ewd->wl.display);
if (!n)
{
ERR("Failed to add display socket: %m");
goto socket_err;
}
ewd->name = strdup(n);
}
else
{
if (wl_display_add_socket(ewd->wl.display, name))
{
ERR("Failed to add display socket: %m");
goto socket_err;
}
ewd->name = strdup(name);
}
setenv("WAYLAND_DISPLAY", ewd->name, 1);
DBG("WAYLAND_DISPLAY: %s", ewd->name);
loop = wl_display_get_event_loop(ewd->wl.display);
ewd->fd_hdl =
ecore_main_fd_handler_add(wl_event_loop_get_fd(loop),
ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR,
_cb_create_data, ewd, NULL, NULL);
ecore_main_fd_handler_prepare_callback_set(ewd->fd_hdl,
_cb_create_prepare, ewd);
/* add this new server display to hash */
eina_hash_add(_server_displays, ewd->name, ewd);
return ewd;
socket_err:
wl_display_destroy(ewd->wl.display);
create_err:
free(ewd);
return NULL;
found:
ewd->refs++;
return ewd;
}
static Eina_Bool
_ecore_wl2_display_sync_get(void)
{
Ecore_Wl2_Display *sewd;
Eina_Iterator *itr;
Eina_Bool ret = EINA_TRUE;
void *data;
if (eina_hash_population(_server_displays) < 1) return ret;
itr = eina_hash_iterator_data_new(_server_displays);
while (eina_iterator_next(itr, &data))
{
sewd = (Ecore_Wl2_Display *)data;
if (sewd->pid == getpid())
{
ret = EINA_FALSE;
break;
}
}
eina_iterator_free(itr);
return ret;
}
EAPI Ecore_Wl2_Display *
ecore_wl2_display_connect(const char *name)
{
Ecore_Wl2_Display *ewd;
Eina_Bool sync = EINA_TRUE;
struct wl_callback *cb;
const char *n;
if (!_client_displays)
_client_displays = eina_hash_string_superfast_new(NULL);
if (!name)
{
/* client wants to connect to default display */
n = getenv("WAYLAND_DISPLAY");
if (n)
{
/* we have a default wayland display */
/* check hash of cached client displays for this name */
ewd = eina_hash_find(_client_displays, n);
if (ewd) goto found;
}
}
else
{
/* client wants to connect to specific display */
/* check hash of cached client displays for this name */
ewd = eina_hash_find(_client_displays, name);
if (ewd) goto found;
}
if ((!name) && (!n))
{
ERR("No Wayland Display Running");
goto name_err;
}
/* allocate space for display structure */
ewd = calloc(1, sizeof(Ecore_Wl2_Display));
if (!ewd) return NULL;
ewd->refs++;
if (name)
ewd->name = strdup(name);
else if (n)
ewd->name = strdup(n);
ewd->globals = eina_hash_int32_new(_cb_globals_hash_del);
/* try to connect to wayland display with this name */
ewd->wl.display = wl_display_connect(ewd->name);
if (!ewd->wl.display)
{
ERR("Could not connect to display %s: %m", ewd->name);
goto connect_err;
}
ewd->fd_hdl =
ecore_main_fd_handler_add(wl_display_get_fd(ewd->wl.display),
ECORE_FD_READ | ECORE_FD_ERROR,
_cb_connect_data, ewd, NULL, NULL);
ewd->idle_enterer = ecore_idle_enterer_add(_cb_connect_idle, ewd);
ewd->wl.registry = wl_display_get_registry(ewd->wl.display);
wl_registry_add_listener(ewd->wl.registry, &_registry_listener, ewd);
ewd->xkb_context = xkb_context_new(0);
if (!ewd->xkb_context) goto context_err;
/* add this new client display to hash */
eina_hash_add(_client_displays, ewd->name, ewd);
/* check server display hash and match on pid. If match, skip sync */
sync = _ecore_wl2_display_sync_get();
cb = wl_display_sync(ewd->wl.display);
wl_callback_add_listener(cb, &_sync_listener, ewd);
if (sync)
{
/* NB: If we are connecting (as a client), then we will need to setup
* a callback for display_sync and wait for it to complete. There is no
* other option here as we need the compositor, shell, etc, to be setup
* before we can allow a user to make use of the API functions */
while (!ewd->sync_done)
wl_display_dispatch(ewd->wl.display);
}
else
{
/* this client is on same pid as server so we need to iterate
* main loop until the "server" advertises it's globals
*
* NB: DO NOT REMOVE THIS !!
*
* This is NEEDED for E's internal dialogs to function because the
* "server" and "client" are on the same PID
* and thus the "server" never advertises out it's globals
* (wl_compositor, wl_shm, etc) unless we sit here and iterate the
* main loop until it's done.
*
* If we remove this, E will never show an internal dialog as it
* just sits and waits for the globals */
while (!ewd->sync_done)
ecore_main_loop_iterate();
}
return ewd;
context_err:
ecore_main_fd_handler_del(ewd->fd_hdl);
wl_registry_destroy(ewd->wl.registry);
wl_display_disconnect(ewd->wl.display);
connect_err:
eina_hash_free(ewd->globals);
free(ewd->name);
free(ewd);
return NULL;
name_err:
eina_hash_free(_client_displays);
return NULL;
found:
ewd->refs++;
return ewd;
}
EAPI void
ecore_wl2_display_disconnect(Ecore_Wl2_Display *display)
{
EINA_SAFETY_ON_NULL_RETURN(display);
_ecore_wl2_display_cleanup(display);
if (display->refs <= 0)
{
wl_display_disconnect(display->wl.display);
free(display);
}
}
EAPI void
ecore_wl2_display_destroy(Ecore_Wl2_Display *display)
{
EINA_SAFETY_ON_NULL_RETURN(display);
_ecore_wl2_display_cleanup(display);
if (display->refs <= 0)
{
wl_display_destroy(display->wl.display);
free(display);
}
}
EAPI void
ecore_wl2_display_terminate(Ecore_Wl2_Display *display)
{
EINA_SAFETY_ON_NULL_RETURN(display);
wl_display_terminate(display->wl.display);
}
EAPI struct wl_display *
ecore_wl2_display_get(Ecore_Wl2_Display *display)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
return display->wl.display;
}
EAPI struct wl_shm *
ecore_wl2_display_shm_get(Ecore_Wl2_Display *display)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
return display->wl.shm;
}
EAPI Eina_Iterator *
ecore_wl2_display_globals_get(Ecore_Wl2_Display *display)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
return eina_hash_iterator_data_new(display->globals);
}
EAPI void
ecore_wl2_display_screen_size_get(Ecore_Wl2_Display *display, int *w, int *h)
{
Ecore_Wl2_Output *output;
int ow = 0, oh = 0;
EINA_SAFETY_ON_NULL_RETURN(display);
if (w) *w = 0;
if (h) *h = 0;
EINA_INLIST_FOREACH(display->outputs, output)
{
switch (output->transform)
{
case WL_OUTPUT_TRANSFORM_90:
case WL_OUTPUT_TRANSFORM_270:
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
ow += output->geometry.h;
oh += output->geometry.w;
break;
default:
ow += output->geometry.w;
oh += output->geometry.h;
break;
}
}
if (w) *w = ow;
if (h) *h = oh;
}
EAPI Ecore_Wl2_Window *
ecore_wl2_display_window_find(Ecore_Wl2_Display *display, unsigned int id)
{
Ecore_Wl2_Window *window;
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
EINA_INLIST_FOREACH(display->windows, window)
if (window->id == (int)id) return window;
return NULL;
}
EAPI struct wl_registry *
ecore_wl2_display_registry_get(Ecore_Wl2_Display *display)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
return display->wl.registry;
}

View File

@ -0,0 +1,627 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include "ecore_wl2_private.h"
struct _dnd_task
{
void *data;
Ecore_Fd_Cb cb;
};
struct _dnd_read_ctx
{
int epoll_fd;
struct epoll_event *ep;
};
static void
_offer_cb_offer(void *data, struct wl_data_offer *offer EINA_UNUSED, const char *type)
{
Ecore_Wl2_Dnd_Source *source;
char **t;
source = data;
if ((!source) || (!type)) return;
t = wl_array_add(&source->types, sizeof(*t));
if (t) *t = strdup(type);
}
static const struct wl_data_offer_listener _offer_listener =
{
_offer_cb_offer
};
static void
_source_cb_target_free(void *data EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Data_Source_Target *ev;
ev = event;
if (!ev) return;
free(ev->type);
free(ev);
}
static void
_source_cb_target(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type)
{
Ecore_Wl2_Input *input;
Ecore_Wl2_Event_Data_Source_Target *ev;
input = data;
if (!input) return;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Data_Source_Target));
if (!ev) return;
if (mime_type) ev->type = strdup(mime_type);
ecore_event_add(ECORE_WL2_EVENT_DATA_SOURCE_TARGET, ev,
_source_cb_target_free, NULL);
}
static void
_source_cb_send_free(void *data EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Data_Source_Send *ev;
ev = event;
if (!ev) return;
free(ev->type);
free(ev);
}
static void
_source_cb_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd)
{
Ecore_Wl2_Input *input;
Ecore_Wl2_Event_Data_Source_Send *ev;
input = data;
if (!input) return;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Data_Source_Send));
if (!ev) return;
ev->fd = fd;
ev->type = strdup(mime_type);
ecore_event_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND, ev,
_source_cb_send_free, NULL);
}
static void
_source_cb_cancelled(void *data, struct wl_data_source *source)
{
Ecore_Wl2_Input *input;
Ecore_Wl2_Event_Data_Source_Cancelled *ev;
input = data;
if (!input) return;
if (input->data.source == source) input->data.source = NULL;
wl_data_source_destroy(source);
ev = calloc(1, sizeof(Ecore_Wl2_Event_Data_Source_Cancelled));
if (!ev) return;
if (input->focus.pointer)
ev->win = input->focus.pointer->id;
if (input->focus.keyboard)
ev->source = input->focus.keyboard->id;
if (!ev->win) ev->win = ev->source;
ecore_event_add(ECORE_WL2_EVENT_DATA_SOURCE_CANCELLED, ev, NULL, NULL);
}
static const struct wl_data_source_listener _source_listener =
{
_source_cb_target,
_source_cb_send,
_source_cb_cancelled
};
static void
_selection_data_ready_cb_free(void *data EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Selection_Data_Ready *ev;
ev = event;
if (!ev) return;
free(ev->data);
free(ev);
}
static Eina_Bool
_selection_data_read(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
{
int len;
char buffer[PATH_MAX];
Ecore_Wl2_Dnd_Source *source;
Ecore_Wl2_Event_Selection_Data_Ready *event;
Eina_Bool ret;
source = data;
len = read(source->fd, buffer, sizeof buffer);
event = calloc(1, sizeof(Ecore_Wl2_Event_Selection_Data_Ready));
if (!event) return ECORE_CALLBACK_CANCEL;
if (len <= 0)
{
close(source->fd);
_ecore_wl2_dnd_del(source);
event->done = EINA_TRUE;
event->data = NULL;
event->len = 0;
ret = ECORE_CALLBACK_CANCEL;
}
else
{
event->data = malloc(len);
if (!event->data)
{
free(event);
return ECORE_CALLBACK_CANCEL;
}
memcpy(event->data, buffer, len);
event->len = len;
event->done = EINA_FALSE;
ret = ECORE_CALLBACK_RENEW;
}
ecore_event_add(ECORE_WL2_EVENT_SELECTION_DATA_READY, event,
_selection_data_ready_cb_free, NULL);
return ret;
}
static Eina_Bool
_selection_cb_idle(void *data)
{
struct _dnd_read_ctx *ctx;
struct _dnd_task *task;
int count, i;
ctx = data;
count = epoll_wait(ctx->epoll_fd, ctx->ep, 1, 0);
for (i = 0; i < count; i++)
{
task = ctx->ep->data.ptr;
if (task->cb(task->data, NULL) == ECORE_CALLBACK_CANCEL)
{
free(ctx->ep);
free(task);
free(ctx);
return ECORE_CALLBACK_CANCEL;
}
}
return ECORE_CALLBACK_RENEW;
}
static void
_selection_data_receive(Ecore_Wl2_Dnd_Source *source, const char *type)
{
int epoll_fd;
struct epoll_event *ep = NULL;
struct _dnd_task *task = NULL;
struct _dnd_read_ctx *read_ctx = NULL;
int p[2];
if (pipe2(p, O_CLOEXEC) == -1)
return;
wl_data_offer_receive(source->offer, type, p[1]);
close(p[1]);
/* Due to http://trac.enlightenment.org/e/ticket/1208,
* use epoll and idle handler instead of ecore_main_fd_handler_add() */
ep = calloc(1, sizeof(struct epoll_event));
if (!ep) goto err;
task = calloc(1, sizeof(struct _dnd_task));
if (!task) goto err;
read_ctx = calloc(1, sizeof(struct _dnd_read_ctx));
if (!read_ctx) goto err;
epoll_fd = epoll_create1(0);
if (epoll_fd < 0) goto err;
task->data = source;
task->cb = _selection_data_read;
ep->events = EPOLLIN;
ep->data.ptr = task;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err;
read_ctx->epoll_fd = epoll_fd;
read_ctx->ep = ep;
if (!ecore_idler_add(_selection_cb_idle, read_ctx)) goto err;
source->refcount++;
source->fd = p[0];
return;
err:
if (ep) free(ep);
if (task) free(task);
if (read_ctx) free(read_ctx);
close(p[0]);
return;
}
void
_ecore_wl2_dnd_add(Ecore_Wl2_Input *input, struct wl_data_offer *offer)
{
Ecore_Wl2_Dnd_Source *source;
source = calloc(1, sizeof(Ecore_Wl2_Dnd_Source));
if (!source) return;
wl_array_init(&source->types);
source->refcount = 1;
source->input = input;
source->offer = offer;
wl_data_offer_add_listener(source->offer, &_offer_listener, source);
}
void
_ecore_wl2_dnd_enter(Ecore_Wl2_Input *input, struct wl_data_offer *offer, struct wl_surface *surface, int x, int y, unsigned int timestamp)
{
Ecore_Wl2_Window *window;
Ecore_Wl2_Event_Dnd_Enter *ev;
char **types;
int num = 0;
window = _ecore_wl2_display_window_surface_find(input->display, surface);
if (!window) return;
if (offer)
{
input->drag.source = wl_data_offer_get_user_data(offer);
num = (input->drag.source->types.size / sizeof(char *));
types = input->drag.source->types.data;
}
else
{
input->drag.source = NULL;
types = NULL;
}
ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Enter));
if (!ev) return;
ev->win = window->id;
if (input->focus.keyboard)
ev->source = input->focus.keyboard->id;
if (!ev->win) ev->win = ev->source;
ev->x = x;
ev->y = y;
ev->offer = offer;
ev->serial = timestamp;
ev->num_types = num;
ev->types = types;
ecore_event_add(ECORE_WL2_EVENT_DND_ENTER, ev, NULL, NULL);
}
void
_ecore_wl2_dnd_leave(Ecore_Wl2_Input *input)
{
Ecore_Wl2_Event_Dnd_Leave *ev;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Leave));
if (!ev) return;
if (input->focus.pointer)
ev->win = input->focus.pointer->id;
if (input->focus.keyboard)
ev->source = input->focus.keyboard->id;
if (!ev->win) ev->win = ev->source;
ecore_event_add(ECORE_WL2_EVENT_DND_LEAVE, ev, NULL, NULL);
}
void
_ecore_wl2_dnd_motion(Ecore_Wl2_Input *input, int x, int y, unsigned int timestamp)
{
Ecore_Wl2_Event_Dnd_Motion *ev;
input->pointer.sx = x;
input->pointer.sy = y;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Motion));
if (!ev) return;
if (input->focus.pointer)
ev->win = input->focus.pointer->id;
if (input->focus.keyboard)
ev->source = input->focus.keyboard->id;
if (!ev->win) ev->win = ev->source;
ev->x = x;
ev->y = y;
ev->serial = timestamp;
ecore_event_add(ECORE_WL2_EVENT_DND_MOTION, ev, NULL, NULL);
}
void
_ecore_wl2_dnd_drop(Ecore_Wl2_Input *input)
{
Ecore_Wl2_Event_Dnd_Drop *ev;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Drop));
if (!ev) return;
if (input->drag.source)
{
if (input->focus.pointer)
ev->win = input->focus.pointer->id;
if (input->focus.keyboard)
ev->source = input->focus.keyboard->id;
if (!ev->win) ev->win = ev->source;
}
ev->x = input->pointer.sx;
ev->y = input->pointer.sy;
ecore_event_add(ECORE_WL2_EVENT_DND_DROP, ev, NULL, NULL);
}
void
_ecore_wl2_dnd_selection(Ecore_Wl2_Input *input, struct wl_data_offer *offer)
{
if (input->selection.source) _ecore_wl2_dnd_del(input->selection.source);
input->selection.source = NULL;
if (offer)
{
char **t;
input->selection.source = wl_data_offer_get_user_data(offer);
t = wl_array_add(&input->selection.source->types, sizeof(*t));
*t = NULL;
}
}
void
_ecore_wl2_dnd_del(Ecore_Wl2_Dnd_Source *source)
{
if (!source) return;
source->refcount--;
if (source->refcount == 0)
{
wl_data_offer_destroy(source->offer);
wl_array_release(&source->types);
free(source);
}
}
EAPI void
ecore_wl2_dnd_drag_types_set(Ecore_Wl2_Input *input, const char **types)
{
struct wl_data_device_manager *manager;
const char **type;
char **t;
EINA_SAFETY_ON_NULL_RETURN(input);
EINA_SAFETY_ON_NULL_RETURN(input->display);
manager = input->display->wl.data_device_manager;
if (input->data.types.data)
{
wl_array_for_each(t, &input->data.types)
free(*t);
wl_array_release(&input->data.types);
wl_array_init(&input->data.types);
}
if (input->data.source) wl_data_source_destroy(input->data.source);
input->data.source = NULL;
input->data.source = wl_data_device_manager_create_data_source(manager);
if (!input->data.source)
{
ERR("Could not create data source: %m");
return;
}
for (type = types; *type; type++)
{
if (!*type) continue;
t = wl_array_add(&input->data.types, sizeof(*t));
if (t)
{
*t = strdup(*type);
wl_data_source_offer(input->data.source, *t);
}
}
}
EAPI void
ecore_wl2_dnd_drag_start(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, Ecore_Wl2_Window *drag_window)
{
struct wl_surface *dsurface, *osurface;
EINA_SAFETY_ON_NULL_RETURN(input);
EINA_SAFETY_ON_NULL_RETURN(input->data.source);
EINA_SAFETY_ON_NULL_RETURN(drag_window);
dsurface = ecore_wl2_window_surface_get(drag_window);
_ecore_wl2_input_ungrab(input);
wl_data_source_add_listener(input->data.source, &_source_listener, input);
osurface = ecore_wl2_window_surface_get(window);
if (osurface)
{
wl_data_device_start_drag(input->data.device, input->data.source,
osurface, dsurface, input->display->serial);
ecore_wl2_window_cursor_from_name_set(window, "move");
}
}
EAPI Eina_Bool
ecore_wl2_dnd_drag_get(Ecore_Wl2_Input *input, const char *type)
{
char **t;
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(input->drag.source, EINA_FALSE);
wl_array_for_each(t, &input->drag.source->types)
if (!strcmp(type, *t)) break;
if (!*t) return EINA_FALSE;
_selection_data_receive(input->drag.source, type);
return EINA_TRUE;
}
EAPI void
ecore_wl2_dnd_drag_end(Ecore_Wl2_Input *input)
{
Ecore_Wl2_Event_Dnd_End *ev;
EINA_SAFETY_ON_NULL_RETURN(input);
if (input->data.types.data)
{
char **t;
wl_array_for_each(t, &input->data.types)
free(*t);
wl_array_release(&input->data.types);
wl_array_init(&input->data.types);
}
if (input->data.source) wl_data_source_destroy(input->data.source);
input->data.source = NULL;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_End));
if (!ev) return;
if (input->focus.pointer)
ev->win = input->focus.pointer->id;
if (input->focus.keyboard)
ev->source = input->focus.keyboard->id;
if (!ev->win) ev->win = ev->source;
ecore_event_add(ECORE_WL2_EVENT_DND_END, ev, NULL, NULL);
}
EAPI Eina_Bool
ecore_wl2_dnd_selection_owner_has(Ecore_Wl2_Input *input)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
return (input->selection.source != NULL);
}
EAPI Eina_Bool
ecore_wl2_dnd_selection_set(Ecore_Wl2_Input *input, const char **types)
{
struct wl_data_device_manager *manager;
const char **type;
char **t;
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE);
manager = input->display->wl.data_device_manager;
if (input->data.types.data)
{
wl_array_for_each(t, &input->data.types)
free(*t);
wl_array_release(&input->data.types);
wl_array_init(&input->data.types);
}
input->data.source = NULL;
if (!types[0]) return EINA_FALSE;
input->data.source = wl_data_device_manager_create_data_source(manager);
if (!input->data.source)
{
ERR("Could not create data source: %m");
return EINA_FALSE;
}
for (type = types; *type; type++)
{
if (!*type) continue;
t = wl_array_add(&input->data.types, sizeof(*t));
if (t)
{
*t = strdup(*type);
wl_data_source_offer(input->data.source, *t);
}
}
wl_data_source_add_listener(input->data.source, &_source_listener, input);
wl_data_device_set_selection(input->data.device, input->data.source,
input->display->serial);
return EINA_TRUE;
}
EAPI Eina_Bool
ecore_wl2_dnd_selection_get(Ecore_Wl2_Input *input, const char *type)
{
char **t;
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(input->selection.source, EINA_FALSE);
for (t = input->selection.source->types.data; *t; t++)
if (!strcmp(type, *t)) break;
if (!*t) return EINA_FALSE;
_selection_data_receive(input->selection.source, type);
return EINA_TRUE;
}
EAPI Eina_Bool
ecore_wl2_dnd_selection_clear(Ecore_Wl2_Input *input)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(input->data.device, EINA_FALSE);
wl_data_device_set_selection(input->data.device,
NULL, input->display->serial);
return EINA_TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ecore_wl2_private.h"
static void
_cb_geometry(void *data, struct wl_output *wl_output EINA_UNUSED, int x, int y, int w, int h, int subpixel EINA_UNUSED, const char *make, const char *model, int transform)
{
Ecore_Wl2_Output *output;
output = data;
if (!output) return;
output->mw = w;
output->mh = h;
output->geometry.x = x;
output->geometry.y = y;
output->transform = transform;
eina_stringshare_replace(&output->make, make);
eina_stringshare_replace(&output->model, model);
}
static void
_cb_mode(void *data, struct wl_output *wl_output EINA_UNUSED, unsigned int flags, int w, int h, int refresh EINA_UNUSED)
{
Ecore_Wl2_Output *output;
output = data;
if (!output) return;
if (flags & WL_OUTPUT_MODE_CURRENT)
{
output->geometry.w = w;
output->geometry.h = h;
}
}
static void
_cb_done(void *data EINA_UNUSED, struct wl_output *output EINA_UNUSED)
{
/* NB: Use this event to raise any "output (re)configured events" */
}
static void
_cb_scale(void *data EINA_UNUSED, struct wl_output *output EINA_UNUSED, int scale EINA_UNUSED)
{
}
static const struct wl_output_listener _output_listener =
{
_cb_geometry,
_cb_mode,
_cb_done,
_cb_scale
};
void
_ecore_wl2_output_add(Ecore_Wl2_Display *display, unsigned int id)
{
Ecore_Wl2_Output *output;
output = calloc(1, sizeof(Ecore_Wl2_Output));
if (!output) return;
output->display = display;
output->wl_output =
wl_registry_bind(display->wl.registry, id, &wl_output_interface, 2);
display->outputs =
eina_inlist_append(display->outputs, EINA_INLIST_GET(output));
wl_output_add_listener(output->wl_output, &_output_listener, output);
}
void
_ecore_wl2_output_del(Ecore_Wl2_Output *output)
{
Ecore_Wl2_Display *display;
if (!output) return;
display = output->display;
if (output->wl_output) wl_output_destroy(output->wl_output);
if (output->make) eina_stringshare_del(output->make);
if (output->model) eina_stringshare_del(output->model);
display->outputs =
eina_inlist_remove(display->outputs, EINA_INLIST_GET(output));
free(output);
}
EAPI int
ecore_wl2_output_dpi_get(Ecore_Wl2_Output *output)
{
int w, mw;
EINA_SAFETY_ON_NULL_RETURN_VAL(output, 75);
mw = output->mw;
if (mw <= 0) return 75;
w = output->geometry.w;
return (((w * 254) / mw) + 5) / 10;
}

View File

@ -0,0 +1,403 @@
#ifndef _ECORE_WL2_PRIVATE_H
# define _ECORE_WL2_PRIVATE_H
# include <unistd.h>
# include "Ecore_Wl2.h"
# include "Ecore_Input.h"
/* NB: Test if subsurface protocol is part of wayland code, if not then
* include our own copy */
# ifndef WL_SUBSURFACE_ERROR_ENUM
# include "subsurface-client-protocol.h"
# endif
# include "xdg-shell-client-protocol.h"
# define XDG_VERSION 5
extern int _ecore_wl2_log_dom;
# ifdef ECORE_WL2_DEFAULT_LOG_COLOR
# undef ECORE_WL2_DEFAULT_LOG_COLOR
# endif
# define ECORE_WL2_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
# ifdef ERR
# undef ERR
# endif
# define ERR(...) EINA_LOG_DOM_ERR(_ecore_wl2_log_dom, __VA_ARGS__)
# ifdef DBG
# undef DBG
# endif
# define DBG(...) EINA_LOG_DOM_DBG(_ecore_wl2_log_dom, __VA_ARGS__)
# ifdef INF
# undef INF
# endif
# define INF(...) EINA_LOG_DOM_INFO(_ecore_wl2_log_dom, __VA_ARGS__)
# ifdef WRN
# undef WRN
# endif
# define WRN(...) EINA_LOG_DOM_WARN(_ecore_wl2_log_dom, __VA_ARGS__)
# ifdef CRI
# undef CRI
# endif
# define CRI(...) EINA_LOG_DOM_CRIT(_ecore_wl2_log_dom, __VA_ARGS__)
struct _Ecore_Wl2_Display
{
int refs;
char *name;
pid_t pid;
struct
{
struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor;
struct wl_subcompositor *subcompositor;
struct wl_data_device_manager *data_device_manager;
struct wl_shm *shm;
struct wl_shell *wl_shell;
struct xdg_shell *xdg_shell;
} wl;
uint32_t serial;
struct xkb_context *xkb_context;
Ecore_Idle_Enterer *idle_enterer;
Ecore_Fd_Handler *fd_hdl;
Eina_Hash *globals;
Eina_Inlist *windows;
Eina_Inlist *outputs;
Eina_Inlist *inputs;
Eina_Inlist *seats;
Eina_Bool sync_done : 1;
};
struct _Ecore_Wl2_Subsurface
{
EINA_INLIST;
int x, y;
Ecore_Wl2_Window *parent;
struct
{
struct wl_surface *surface;
struct wl_subsurface *subsurface;
} wl;
Eina_Bool sync : 1;
};
struct _Ecore_Wl2_Window
{
EINA_INLIST;
Ecore_Wl2_Display *display;
Ecore_Wl2_Input *input;
Ecore_Wl2_Window *parent;
int id, rotation, surface_id;
const char *title;
const char *class;
const char *cursor;
struct wl_surface *surface;
struct wl_shell_surface *wl_shell_surface;
struct xdg_surface *xdg_surface;
struct xdg_popup *xdg_popup;
Eina_Rectangle saved;
Eina_Rectangle geometry;
Eina_Rectangle opaque;
Eina_Rectangle input_rect;
Ecore_Wl2_Window_Type type;
Eina_Inlist *subsurfs;
Eina_Bool moving : 1;
Eina_Bool minimized : 1;
Eina_Bool maximized : 1;
Eina_Bool fullscreen : 1;
Eina_Bool focused : 1;
Eina_Bool resizing : 1;
Eina_Bool alpha : 1;
Eina_Bool transparent : 1;
};
struct _Ecore_Wl2_Output
{
EINA_INLIST;
Ecore_Wl2_Display *display;
struct wl_output *wl_output;
int mw, mh, transform;
const char *make, *model;
Eina_Rectangle geometry;
};
typedef struct _Ecore_Wl2_Dnd_Source
{
Ecore_Wl2_Input *input;
int refcount, fd, x, y;
struct wl_data_offer *offer;
struct wl_array types;
} Ecore_Wl2_Dnd_Source;
/** TODO: Refactor ALL Input code :(
*
* wl_seat is a GROUP of Input Devices (such as):
* keyboards, pointers, touch devices
*/
struct _Ecore_Wl2_Pointer
{
EINA_INLIST;
Ecore_Wl2_Seat *seat;
double sx, sy;
unsigned int button;
unsigned int enter_serial;
struct
{
const char *name, *theme_name;
unsigned int index, size;
struct wl_cursor *wl_cursor;
struct wl_cursor_theme *theme;
struct wl_surface *surface;
struct wl_callback *frame_cb;
Ecore_Timer *timer;
} cursor;
struct
{
unsigned int button, count, timestamp;
Ecore_Wl2_Window *window;
} grab;
Ecore_Wl2_Window *focus;
Eina_List *resources;
};
struct _Ecore_Wl2_Keyboard
{
EINA_INLIST;
Ecore_Wl2_Seat *seat;
unsigned int modifiers;
struct
{
struct xkb_keymap *keymap;
struct xkb_state *state;
xkb_mod_mask_t control_mask;
xkb_mod_mask_t alt_mask;
xkb_mod_mask_t shift_mask;
xkb_mod_mask_t win_mask;
xkb_mod_mask_t scroll_mask;
xkb_mod_mask_t num_mask;
xkb_mod_mask_t caps_mask;
xkb_mod_mask_t altgr_mask;
unsigned int mods_depressed;
unsigned int mods_latched;
unsigned int mods_locked;
unsigned int mods_group;
} xkb;
struct
{
Ecore_Timer *tmr;
unsigned int sym, key, time;
double rate, delay;
Eina_Bool enabled : 1;
} repeat;
struct
{
unsigned int button, count, timestamp;
Ecore_Wl2_Window *window;
} grab;
Ecore_Wl2_Window *focus;
Eina_List *resources;
};
struct _Ecore_Wl2_Touch
{
EINA_INLIST;
struct
{
unsigned int button, count, timestamp;
Ecore_Wl2_Window *window;
} grab;
};
struct _Ecore_Wl2_Seat
{
EINA_INLIST;
uint32_t id;
uint32_t version;
const char *name;
struct wl_global *global;
const struct wl_seat_interface *implementation;
struct
{
struct wl_global *global;
struct wl_resource *resource;
} im;
Ecore_Wl2_Bind_Cb bind_cb;
Ecore_Wl2_Unbind_Cb unbind_cb;
Ecore_Wl2_Pointer *pointer;
int pointer_count;
Ecore_Wl2_Keyboard *keyboard;
int keyboard_count;
Ecore_Wl2_Touch *touch;
int touch_count;
Eina_List *resources;
};
struct _Ecore_Wl2_Input
{
EINA_INLIST;
Ecore_Wl2_Display *display;
unsigned int timestamp;
struct
{
struct wl_seat *seat;
struct wl_pointer *pointer;
struct wl_keyboard *keyboard;
struct wl_touch *touch;
} wl;
struct
{
struct wl_data_device *device;
struct wl_data_source *source;
struct wl_array types;
} data;
struct
{
const char *name, *theme_name;
unsigned int index, size;
struct wl_cursor *wl_cursor;
struct wl_cursor_theme *theme;
struct wl_surface *surface;
struct wl_callback *frame_cb;
Ecore_Timer *timer;
} cursor;
struct
{
double sx, sy;
unsigned int button;
unsigned int enter_serial;
} pointer;
struct
{
unsigned int modifiers;
} keyboard;
struct
{
Ecore_Wl2_Window *pointer;
Ecore_Wl2_Window *keyboard;
Ecore_Wl2_Window *touch;
} focus;
struct
{
unsigned int button, count, timestamp;
Ecore_Wl2_Window *window;
} grab;
struct
{
struct xkb_keymap *keymap;
struct xkb_state *state;
xkb_mod_mask_t control_mask;
xkb_mod_mask_t alt_mask;
xkb_mod_mask_t shift_mask;
xkb_mod_mask_t win_mask;
xkb_mod_mask_t scroll_mask;
xkb_mod_mask_t num_mask;
xkb_mod_mask_t caps_mask;
xkb_mod_mask_t altgr_mask;
unsigned int mods_depressed;
unsigned int mods_latched;
unsigned int mods_locked;
unsigned int mods_group;
} xkb;
struct
{
Ecore_Timer *timer;
unsigned int sym, key, time;
double rate, delay;
Eina_Bool enabled : 1;
} repeat;
struct
{
Ecore_Wl2_Dnd_Source *source;
} drag, selection;
unsigned int seat_version;
};
Ecore_Wl2_Window *_ecore_wl2_display_window_surface_find(Ecore_Wl2_Display *display, struct wl_surface *wl_surface);
void _ecore_wl2_output_add(Ecore_Wl2_Display *display, unsigned int id);
void _ecore_wl2_output_del(Ecore_Wl2_Output *output);
void _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int version);
void _ecore_wl2_input_del(Ecore_Wl2_Input *input);
void _ecore_wl2_input_ungrab(Ecore_Wl2_Input *input);
void _ecore_wl2_input_grab(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, unsigned int button);
void _ecore_wl2_input_cursor_set(Ecore_Wl2_Input *input, const char *cursor);
void _ecore_wl2_input_cursor_update_stop(Ecore_Wl2_Input *input);
void _ecore_wl2_dnd_add(Ecore_Wl2_Input *input, struct wl_data_offer *offer);
void _ecore_wl2_dnd_enter(Ecore_Wl2_Input *input, struct wl_data_offer *offer, struct wl_surface *surface, int x, int y, unsigned int timestamp);
void _ecore_wl2_dnd_leave(Ecore_Wl2_Input *input);
void _ecore_wl2_dnd_motion(Ecore_Wl2_Input *input, int x, int y, unsigned int timestamp);
void _ecore_wl2_dnd_drop(Ecore_Wl2_Input *input);
void _ecore_wl2_dnd_selection(Ecore_Wl2_Input *input, struct wl_data_offer *offer);
void _ecore_wl2_dnd_del(Ecore_Wl2_Dnd_Source *source);
void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf);
#endif

View File

@ -0,0 +1,350 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ecore_wl2_private.h"
static void
_seat_cb_unbind(struct wl_resource *resource)
{
Ecore_Wl2_Seat *seat;
DBG("Seat Unbind");
seat = wl_resource_get_user_data(resource);
if (!seat) return;
seat->resources = eina_list_remove(seat->resources, resource);
if (seat->unbind_cb) seat->unbind_cb(resource);
}
static void
_seat_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
{
Ecore_Wl2_Seat *seat;
struct wl_resource *res;
seat = data;
seat->id = id;
DBG("Seat Bind");
res = wl_resource_create(client, &wl_seat_interface, version, id);
if (!res)
{
ERR("Failed to create seat resource: %m");
return;
}
seat->resources = eina_list_append(seat->resources, res);
wl_resource_set_implementation(res, seat->implementation, seat,
_seat_cb_unbind);
if (version >= WL_SEAT_NAME_SINCE_VERSION)
wl_seat_send_name(res, seat->name);
if (seat->bind_cb) seat->bind_cb(client, seat, version, id);
}
static void
_pointer_cb_unbind(struct wl_resource *resource)
{
Ecore_Wl2_Pointer *ptr;
DBG("Pointer Unbind");
ptr = wl_resource_get_user_data(resource);
if (!ptr) return;
ptr->resources = eina_list_remove(ptr->resources, resource);
/* wl_pointer_release(); */
}
static Ecore_Wl2_Pointer *
_ecore_wl2_seat_pointer_create(Ecore_Wl2_Seat *seat)
{
Ecore_Wl2_Pointer *ptr;
ptr = calloc(1, sizeof(Ecore_Wl2_Pointer));
if (!ptr) return NULL;
/* FIXME: Init pointer fields */
ptr->seat = seat;
return ptr;
}
static void
_ecore_wl2_seat_pointer_destroy(Ecore_Wl2_Pointer *ptr)
{
/* FIXME: Free pointer fields */
free(ptr);
}
static void
_keyboard_cb_unbind(struct wl_resource *resource)
{
Ecore_Wl2_Keyboard *kbd;
DBG("Keyboard Unbind");
kbd = wl_resource_get_user_data(resource);
if (!kbd) return;
kbd->resources = eina_list_remove(kbd->resources, resource);
/* wl_keyboard_release(); */
}
static Ecore_Wl2_Keyboard *
_ecore_wl2_seat_keyboard_create(Ecore_Wl2_Seat *seat)
{
Ecore_Wl2_Keyboard *kbd;
kbd = calloc(1, sizeof(Ecore_Wl2_Keyboard));
if (!kbd) return NULL;
/* FIXME: Init keyboard fields */
kbd->seat = seat;
return kbd;
}
static void
_ecore_wl2_seat_keyboard_destroy(Ecore_Wl2_Keyboard *kbd)
{
/* FIXME: Free keyboard fields */
free(kbd);
}
EAPI Ecore_Wl2_Seat *
ecore_wl2_seat_create(Ecore_Wl2_Display *display, const char *name, const struct wl_seat_interface *implementation, int version, Ecore_Wl2_Bind_Cb bind_cb, Ecore_Wl2_Unbind_Cb unbind_cb)
{
Ecore_Wl2_Seat *seat;
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
if (!name) name = "default";
EINA_INLIST_FOREACH(display->seats, seat)
{
if (!strcmp(seat->name, name))
return seat;
}
seat = calloc(1, sizeof(Ecore_Wl2_Seat));
if (!seat) return NULL;
seat->version = version;
seat->implementation = implementation;
seat->bind_cb = bind_cb;
seat->unbind_cb = unbind_cb;
eina_stringshare_replace(&seat->name, name);
seat->global =
wl_global_create(display->wl.display, &wl_seat_interface, seat->version,
seat, _seat_cb_bind);
if (!seat->global)
{
ERR("Could not create seat global: %m");
free(seat);
return NULL;
}
return seat;
}
EAPI void
ecore_wl2_seat_destroy(Ecore_Wl2_Seat *seat)
{
EINA_SAFETY_ON_NULL_RETURN(seat);
eina_stringshare_del(seat->name);
if (seat->pointer) _ecore_wl2_seat_pointer_destroy(seat->pointer);
if (seat->keyboard) _ecore_wl2_seat_keyboard_destroy(seat->keyboard);
/* NB: Hmmm, should we iterate and free resources here ?? */
wl_global_destroy(seat->global);
free(seat);
}
EAPI void
ecore_wl2_seat_capabilities_send(Ecore_Wl2_Seat *seat, enum wl_seat_capability caps)
{
Eina_List *l;
struct wl_resource *res;
EINA_SAFETY_ON_NULL_RETURN(seat);
EINA_LIST_FOREACH(seat->resources, l, res)
wl_seat_send_capabilities(res, caps);
}
EAPI void
ecore_wl2_seat_pointer_release(Ecore_Wl2_Seat *seat)
{
enum wl_seat_capability caps = 0;
EINA_SAFETY_ON_NULL_RETURN(seat);
seat->pointer_count--;
if (seat->pointer_count == 0)
{
if (seat->pointer_count > 0)
caps |= WL_SEAT_CAPABILITY_POINTER;
if (seat->keyboard_count > 0)
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
if (seat->touch_count > 0)
caps |= WL_SEAT_CAPABILITY_TOUCH;
ecore_wl2_seat_capabilities_send(seat, caps);
}
}
EAPI Ecore_Wl2_Pointer *
ecore_wl2_pointer_get(Ecore_Wl2_Seat *seat)
{
enum wl_seat_capability caps = 0;
EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
if (seat->pointer_count > 0)
caps |= WL_SEAT_CAPABILITY_POINTER;
if (seat->keyboard_count > 0)
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
if (seat->touch_count > 0)
caps |= WL_SEAT_CAPABILITY_TOUCH;
if (seat->pointer)
{
seat->pointer_count += 1;
if (seat->pointer_count == 1)
{
caps |= WL_SEAT_CAPABILITY_POINTER;
ecore_wl2_seat_capabilities_send(seat, caps);
}
return seat->pointer;
}
seat->pointer = _ecore_wl2_seat_pointer_create(seat);
seat->pointer_count = 1;
caps |= WL_SEAT_CAPABILITY_POINTER;
ecore_wl2_seat_capabilities_send(seat, caps);
return seat->pointer;
}
EAPI Eina_Bool
ecore_wl2_pointer_resource_create(Ecore_Wl2_Pointer *ptr, struct wl_client *client, const struct wl_pointer_interface *implementation, int version, uint32_t id)
{
struct wl_resource *res;
EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
res = wl_resource_create(client, &wl_pointer_interface, version, id);
if (!res)
{
ERR("Could not create pointer resource: %m");
wl_client_post_no_memory(client);
return EINA_FALSE;
}
wl_resource_set_implementation(res, implementation, ptr, _pointer_cb_unbind);
ptr->resources = eina_list_append(ptr->resources, res);
/* FIXME: Hmmm, should we sent a pointer_enter to ptr->focus'd surface
* here like weston does ? */
return EINA_TRUE;
}
EAPI Ecore_Wl2_Keyboard *
ecore_wl2_keyboard_get(Ecore_Wl2_Seat *seat)
{
enum wl_seat_capability caps = 0;
EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
if (seat->pointer_count > 0)
caps |= WL_SEAT_CAPABILITY_POINTER;
if (seat->keyboard_count > 0)
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
if (seat->touch_count > 0)
caps |= WL_SEAT_CAPABILITY_TOUCH;
if (seat->keyboard)
{
seat->keyboard_count += 1;
if (seat->keyboard_count == 1)
{
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
ecore_wl2_seat_capabilities_send(seat, caps);
}
return seat->keyboard;
}
seat->keyboard = _ecore_wl2_seat_keyboard_create(seat);
seat->keyboard_count = 1;
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
ecore_wl2_seat_capabilities_send(seat, caps);
return seat->keyboard;
}
EAPI Eina_Bool
ecore_wl2_keyboard_resource_create(Ecore_Wl2_Keyboard *kbd, struct wl_client *client, const struct wl_keyboard_interface *implementation, int version, uint32_t id)
{
struct wl_resource *res;
EINA_SAFETY_ON_NULL_RETURN_VAL(kbd, EINA_FALSE);
res = wl_resource_create(client, &wl_keyboard_interface, version, id);
if (!res)
{
ERR("Could not create keyboard resource: %m");
wl_client_post_no_memory(client);
return EINA_FALSE;
}
wl_resource_set_implementation(res, implementation, kbd, _keyboard_cb_unbind);
kbd->resources = eina_list_append(kbd->resources, res);
/* FIXME: Hmmm, should we sent a keyboard_enter to kbd->focus'd surface
* here like weston does ? */
return EINA_TRUE;
}
EAPI void
ecore_wl2_keyboard_repeat_info_set(Ecore_Wl2_Keyboard *kbd, double rate, double delay)
{
struct wl_resource *res;
Eina_List *l;
EINA_SAFETY_ON_NULL_RETURN(kbd);
kbd->repeat.rate = rate;
kbd->repeat.delay = delay;
EINA_LIST_FOREACH(kbd->resources, l, res)
{
if (wl_resource_get_version(res) >=
WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
wl_keyboard_send_repeat_info(res, rate, delay);
}
}

View File

@ -0,0 +1,177 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ecore_wl2_private.h"
void
_ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf)
{
Ecore_Wl2_Window *parent;
if (subsurf->wl.subsurface) wl_subsurface_destroy(subsurf->wl.subsurface);
if (subsurf->wl.surface) wl_surface_destroy(subsurf->wl.surface);
parent = subsurf->parent;
if (parent)
{
parent->subsurfs =
eina_inlist_remove(parent->subsurfs, EINA_INLIST_GET(subsurf));
}
free(subsurf);
}
EAPI Ecore_Wl2_Subsurface *
ecore_wl2_subsurface_new(Ecore_Wl2_Window *window)
{
Ecore_Wl2_Display *display;
Ecore_Wl2_Subsurface *subsurf;
EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(window->surface, NULL);
display = window->display;
EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.compositor, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.subcompositor, NULL);
subsurf = calloc(1, sizeof(Ecore_Wl2_Subsurface));
if (!subsurf) return NULL;
subsurf->parent = window;
subsurf->wl.surface = wl_compositor_create_surface(display->wl.compositor);
if (!subsurf->wl.surface)
{
ERR("Failed to create surface: %m");
goto surf_err;
}
subsurf->wl.subsurface =
wl_subcompositor_get_subsurface(display->wl.subcompositor,
subsurf->wl.surface, window->surface);
if (!subsurf->wl.subsurface)
{
ERR("Could not create subsurface: %m");
goto sub_surf_err;
}
window->subsurfs =
eina_inlist_append(window->subsurfs, EINA_INLIST_GET(subsurf));
return subsurf;
sub_surf_err:
wl_surface_destroy(subsurf->wl.surface);
surf_err:
free(subsurf);
return NULL;
}
EAPI void
ecore_wl2_subsurface_del(Ecore_Wl2_Subsurface *subsurface)
{
EINA_SAFETY_ON_NULL_RETURN(subsurface);
_ecore_wl2_subsurf_free(subsurface);
}
EAPI struct wl_surface *
ecore_wl2_subsurface_surface_get(Ecore_Wl2_Subsurface *subsurface)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(subsurface, NULL);
return subsurface->wl.surface;
}
EAPI void
ecore_wl2_subsurface_position_set(Ecore_Wl2_Subsurface *subsurface, int x, int y)
{
EINA_SAFETY_ON_NULL_RETURN(subsurface);
EINA_SAFETY_ON_NULL_RETURN(subsurface->wl.subsurface);
if ((subsurface->x == x) && (subsurface->y == y)) return;
subsurface->x = x;
subsurface->y = y;
wl_subsurface_set_position(subsurface->wl.subsurface, x, y);
}
EAPI void
ecore_wl2_subsurface_position_get(Ecore_Wl2_Subsurface *subsurface, int *x, int *y)
{
EINA_SAFETY_ON_NULL_RETURN(subsurface);
if (x) *x = subsurface->x;
if (y) *y = subsurface->y;
}
EAPI void
ecore_wl2_subsurface_place_above(Ecore_Wl2_Subsurface *subsurface, struct wl_surface *surface)
{
EINA_SAFETY_ON_NULL_RETURN(subsurface);
EINA_SAFETY_ON_NULL_RETURN(surface);
wl_subsurface_place_above(subsurface->wl.subsurface, surface);
}
EAPI void
ecore_wl2_subsurface_place_below(Ecore_Wl2_Subsurface *subsurface, struct wl_surface *surface)
{
EINA_SAFETY_ON_NULL_RETURN(subsurface);
EINA_SAFETY_ON_NULL_RETURN(surface);
wl_subsurface_place_below(subsurface->wl.subsurface, surface);
}
EAPI void
ecore_wl2_subsurface_sync_set(Ecore_Wl2_Subsurface *subsurface, Eina_Bool sync)
{
EINA_SAFETY_ON_NULL_RETURN(subsurface);
EINA_SAFETY_ON_NULL_RETURN(subsurface->wl.subsurface);
sync = !!sync;
if (subsurface->sync == sync) return;
subsurface->sync = sync;
if (subsurface->sync)
wl_subsurface_set_sync(subsurface->wl.subsurface);
else
wl_subsurface_set_desync(subsurface->wl.subsurface);
}
EAPI void
ecore_wl2_subsurface_opaque_region_set(Ecore_Wl2_Subsurface *subsurface, int x, int y, int w, int h)
{
EINA_SAFETY_ON_NULL_RETURN(subsurface);
EINA_SAFETY_ON_NULL_RETURN(subsurface->wl.subsurface);
if ((w > 0) && (h > 0))
{
Ecore_Wl2_Window *parent;
parent = subsurface->parent;
if (parent)
{
struct wl_region *region;
region =
wl_compositor_create_region(parent->display->wl.compositor);
if (!region)
{
ERR("Failed to create opaque region: %m");
return;
}
wl_region_add(region, x, y, w, h);
wl_surface_set_opaque_region(subsurface->wl.surface, region);
wl_region_destroy(region);
}
}
else
wl_surface_set_opaque_region(subsurface->wl.surface, NULL);
}

View File

@ -0,0 +1,869 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ecore_wl2_private.h"
static void
_ecore_wl2_window_configure_send(Ecore_Wl2_Window *window, int w, int h, unsigned int edges)
{
Ecore_Wl2_Event_Window_Configure *ev;
ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Configure));
if (!ev) return;
ev->win = window->id;
ev->event_win = window->id;
ev->x = window->geometry.x;
ev->y = window->geometry.y;
ev->w = w;
ev->h = h;
ev->edges = edges;
ecore_event_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL);
}
static void
_wl_shell_surface_cb_ping(void *data EINA_UNUSED, struct wl_shell_surface *shell_surface, unsigned int serial)
{
wl_shell_surface_pong(shell_surface, serial);
}
static void
_wl_shell_surface_cb_configure(void *data, struct wl_shell_surface *shell_surface EINA_UNUSED, unsigned int edges, int w, int h)
{
Ecore_Wl2_Window *win;
win = data;
if (!win) return;
if ((w <= 0) || (h <= 0)) return;
if ((w > 0) && (h > 0))
_ecore_wl2_window_configure_send(win, w, h, edges);
}
static void
_wl_shell_surface_cb_popup_done(void *data EINA_UNUSED, struct wl_shell_surface *shell_surface EINA_UNUSED)
{
Ecore_Wl2_Window *win;
win = data;
if (!win) return;
_ecore_wl2_input_ungrab(win->input);
}
static const struct wl_shell_surface_listener _wl_shell_surface_listener =
{
_wl_shell_surface_cb_ping,
_wl_shell_surface_cb_configure,
_wl_shell_surface_cb_popup_done
};
static void
_xdg_popup_cb_done(void *data, struct xdg_popup *xdg_popup EINA_UNUSED)
{
Ecore_Wl2_Window *win;
win = data;
if (!win) return;
_ecore_wl2_input_ungrab(win->input);
}
static const struct xdg_popup_listener _xdg_popup_listener =
{
_xdg_popup_cb_done,
};
static void
_xdg_surface_cb_configure(void *data, struct xdg_surface *xdg_surface EINA_UNUSED, int32_t w, int32_t h, struct wl_array *states, uint32_t serial)
{
Ecore_Wl2_Window *win;
uint32_t *s;
win = data;
if (!win) return;
win->minimized = EINA_FALSE;
win->maximized = EINA_FALSE;
win->fullscreen = EINA_FALSE;
win->focused = EINA_FALSE;
win->resizing = EINA_FALSE;
wl_array_for_each(s, states)
{
switch (*s)
{
case XDG_SURFACE_STATE_MAXIMIZED:
win->maximized = EINA_TRUE;
break;
case XDG_SURFACE_STATE_FULLSCREEN:
win->fullscreen = EINA_TRUE;
break;
case XDG_SURFACE_STATE_RESIZING:
win->resizing = EINA_TRUE;
break;
case XDG_SURFACE_STATE_ACTIVATED:
win->focused = EINA_TRUE;
win->minimized = EINA_FALSE;
default:
break;
}
}
if ((w > 0) && (h > 0))
_ecore_wl2_window_configure_send(win, w, h, 0);
xdg_surface_ack_configure(win->xdg_surface, serial);
}
static void
_xdg_surface_cb_delete(void *data, struct xdg_surface *xdg_surface EINA_UNUSED)
{
Ecore_Wl2_Window *win;
win = data;
if (!win) return;
ecore_wl2_window_free(win);
}
static const struct xdg_surface_listener _xdg_surface_listener =
{
_xdg_surface_cb_configure,
_xdg_surface_cb_delete,
};
static void
_ecore_wl2_window_type_set(Ecore_Wl2_Window *win)
{
switch (win->type)
{
case ECORE_WL2_WINDOW_TYPE_FULLSCREEN:
if (win->xdg_surface)
xdg_surface_set_fullscreen(win->xdg_surface, NULL);
else if (win->wl_shell_surface)
wl_shell_surface_set_fullscreen(win->wl_shell_surface,
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
0, NULL);
break;
case ECORE_WL2_WINDOW_TYPE_MAXIMIZED:
if (win->xdg_surface)
xdg_surface_set_maximized(win->xdg_surface);
else if (win->wl_shell_surface)
wl_shell_surface_set_maximized(win->wl_shell_surface, NULL);
break;
case ECORE_WL2_WINDOW_TYPE_TRANSIENT:
if (win->xdg_surface)
xdg_surface_set_parent(win->xdg_surface, win->parent->xdg_surface);
else if (win->wl_shell_surface)
wl_shell_surface_set_transient(win->wl_shell_surface,
win->parent->surface,
win->geometry.x, win->geometry.y, 0);
break;
case ECORE_WL2_WINDOW_TYPE_MENU:
{
Ecore_Wl2_Input *input;
input = win->input;
if ((!input) && (win->parent))
{
input = win->parent->input;
}
if ((!input) || (!input->wl.seat)) return;
if (win->xdg_surface)
{
win->xdg_popup =
xdg_shell_get_xdg_popup(win->display->wl.xdg_shell,
win->surface, win->parent->surface,
input->wl.seat,
win->display->serial,
win->geometry.x, win->geometry.y);
if (!win->xdg_popup)
{
ERR("Could not create xdg popup: %m");
return;
}
xdg_popup_set_user_data(win->xdg_popup, win);
xdg_popup_add_listener(win->xdg_popup,
&_xdg_popup_listener, win);
}
else if (win->wl_shell_surface)
{
wl_shell_surface_set_popup(win->wl_shell_surface,
input->wl.seat,
win->display->serial,
win->parent->surface,
win->geometry.x,
win->geometry.y, 0);
}
}
break;
case ECORE_WL2_WINDOW_TYPE_TOPLEVEL:
if (win->xdg_surface)
xdg_surface_set_parent(win->xdg_surface, NULL);
else if (win->wl_shell_surface)
wl_shell_surface_set_toplevel(win->wl_shell_surface);
break;
default:
break;
}
}
EAPI Ecore_Wl2_Window *
ecore_wl2_window_new(Ecore_Wl2_Display *display, Ecore_Wl2_Window *parent, int x, int y, int w, int h)
{
Ecore_Wl2_Window *win;
static int _win_id = 1;
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
/* try to allocate space for window structure */
win = calloc(1, sizeof(Ecore_Wl2_Window));
if (!win) return NULL;
win->display = display;
win->parent = parent;
win->id = _win_id++;
win->geometry.x = x;
win->geometry.y = y;
win->geometry.w = w;
win->geometry.h = h;
win->opaque.x = x;
win->opaque.y = y;
win->opaque.w = w;
win->opaque.h = h;
win->type = ECORE_WL2_WINDOW_TYPE_TOPLEVEL;
display->windows =
eina_inlist_append(display->windows, EINA_INLIST_GET(win));
return win;
}
EAPI int
ecore_wl2_window_id_get(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
return window->id;
}
EAPI struct wl_surface *
ecore_wl2_window_surface_get(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
if (!window->surface)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window->display->wl.compositor, NULL);
window->surface =
wl_compositor_create_surface(window->display->wl.compositor);
window->surface_id =
wl_proxy_get_id((struct wl_proxy *)window->surface);
}
return window->surface;
}
EAPI int
ecore_wl2_window_surface_id_get(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
return window->surface_id;
}
EAPI void
ecore_wl2_window_show(Ecore_Wl2_Window *window)
{
Ecore_Wl2_Display *disp;
EINA_SAFETY_ON_NULL_RETURN(window);
disp = window->display;
if (!window->surface)
{
window->surface =
wl_compositor_create_surface(window->display->wl.compositor);
}
if ((window->type == ECORE_WL2_WINDOW_TYPE_DND) ||
(window->type == ECORE_WL2_WINDOW_TYPE_NONE))
goto type_set;
if ((disp->wl.xdg_shell) && (!window->xdg_surface))
{
window->xdg_surface =
xdg_shell_get_xdg_surface(disp->wl.xdg_shell, window->surface);
if (!window->xdg_surface) goto surf_err;
if (window->title)
xdg_surface_set_title(window->xdg_surface, window->title);
if (window->class)
xdg_surface_set_app_id(window->xdg_surface, window->class);
xdg_surface_set_user_data(window->xdg_surface, window);
xdg_surface_add_listener(window->xdg_surface,
&_xdg_surface_listener, window);
}
else if ((disp->wl.wl_shell) && (!window->wl_shell_surface))
{
window->wl_shell_surface =
wl_shell_get_shell_surface(disp->wl.wl_shell, window->surface);
if (!window->wl_shell_surface) goto surf_err;
if (window->title)
wl_shell_surface_set_title(window->wl_shell_surface, window->title);
if (window->class)
wl_shell_surface_set_class(window->wl_shell_surface, window->class);
wl_shell_surface_add_listener(window->wl_shell_surface,
&_wl_shell_surface_listener, window);
}
type_set:
_ecore_wl2_window_type_set(window);
return;
surf_err:
ERR("Failed to create surface for window: %m");
}
EAPI void
ecore_wl2_window_hide(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface);
window->xdg_surface = NULL;
if (window->xdg_popup) xdg_popup_destroy(window->xdg_popup);
window->xdg_popup = NULL;
if (window->wl_shell_surface)
wl_shell_surface_destroy(window->wl_shell_surface);
window->wl_shell_surface = NULL;
if (window->surface) wl_surface_destroy(window->surface);
window->surface = NULL;
}
EAPI void
ecore_wl2_window_free(Ecore_Wl2_Window *window)
{
Ecore_Wl2_Display *display;
Ecore_Wl2_Input *input;
Ecore_Wl2_Subsurface *subsurf;
Eina_Inlist *tmp;
EINA_SAFETY_ON_NULL_RETURN(window);
display = window->display;
EINA_INLIST_FOREACH(display->inputs, input)
{
if ((input->focus.pointer) &&
(input->focus.pointer == window))
input->focus.pointer = NULL;
if ((input->focus.keyboard) &&
(input->focus.keyboard == window))
{
input->focus.keyboard = NULL;
ecore_timer_del(input->repeat.timer);
input->repeat.timer = NULL;
}
}
EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp, subsurf)
_ecore_wl2_subsurf_free(subsurf);
ecore_wl2_window_hide(window);
if (window->title) eina_stringshare_del(window->title);
if (window->class) eina_stringshare_del(window->class);
display->windows =
eina_inlist_remove(display->windows, EINA_INLIST_GET(window));
free(window);
}
EAPI void
ecore_wl2_window_move(Ecore_Wl2_Window *window, int x EINA_UNUSED, int y EINA_UNUSED)
{
Ecore_Wl2_Input *input;
EINA_SAFETY_ON_NULL_RETURN(window);
input = window->input;
if ((!input) && (window->parent))
{
input = window->parent->input;
}
if ((!input) || (!input->wl.seat)) return;
window->moving = EINA_TRUE;
if (window->xdg_surface)
xdg_surface_move(window->xdg_surface, input->wl.seat,
window->display->serial);
else if (window->wl_shell_surface)
wl_shell_surface_move(window->wl_shell_surface, input->wl.seat,
window->display->serial);
}
EAPI void
ecore_wl2_window_resize(Ecore_Wl2_Window *window, int w EINA_UNUSED, int h EINA_UNUSED, int location)
{
Ecore_Wl2_Input *input;
EINA_SAFETY_ON_NULL_RETURN(window);
input = window->input;
if ((!input) && (window->parent))
{
input = window->parent->input;
}
if ((!input) || (!input->wl.seat)) return;
if (window->xdg_surface)
xdg_surface_resize(window->xdg_surface, input->wl.seat,
input->display->serial, location);
else if (window->wl_shell_surface)
wl_shell_surface_resize(window->wl_shell_surface, input->wl.seat,
input->display->serial, location);
}
EAPI void
ecore_wl2_window_raise(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if (window->xdg_surface)
{
struct wl_array states;
uint32_t *s;
wl_array_init(&states);
s = wl_array_add(&states, sizeof(*s));
*s = XDG_SURFACE_STATE_ACTIVATED;
_xdg_surface_cb_configure(window, window->xdg_surface,
window->geometry.w, window->geometry.h,
&states, 0);
wl_array_release(&states);
}
else if (window->wl_shell_surface)
wl_shell_surface_set_toplevel(window->wl_shell_surface);
}
EAPI Eina_Bool
ecore_wl2_window_alpha_get(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
return window->alpha;
}
EAPI void
ecore_wl2_window_alpha_set(Ecore_Wl2_Window *window, Eina_Bool alpha)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if (window->alpha == alpha) return;
window->alpha = alpha;
if (!window->alpha)
ecore_wl2_window_opaque_region_set(window, window->opaque.x,
window->opaque.y, window->opaque.w,
window->opaque.h);
else
ecore_wl2_window_opaque_region_set(window, 0, 0, 0, 0);
}
EAPI void
ecore_wl2_window_transparent_set(Ecore_Wl2_Window *window, Eina_Bool transparent)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if (window->transparent == transparent) return;
window->transparent = transparent;
if (!window->transparent)
ecore_wl2_window_opaque_region_set(window, window->opaque.x,
window->opaque.y, window->opaque.w,
window->opaque.h);
else
ecore_wl2_window_opaque_region_set(window, 0, 0, 0, 0);
}
EAPI void
ecore_wl2_window_opaque_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
{
struct wl_region *region;
EINA_SAFETY_ON_NULL_RETURN(window);
window->opaque.x = x;
window->opaque.y = y;
window->opaque.w = w;
window->opaque.h = h;
if ((window->transparent) || (window->alpha)) return;
region = wl_compositor_create_region(window->display->wl.compositor);
if (!region)
{
ERR("Failed to create opaque region: %m");
return;
}
switch (window->rotation)
{
case 0:
wl_region_add(region, x, y, w, h);
break;
case 180:
wl_region_add(region, x, x + y, w, h);
break;
case 90:
wl_region_add(region, y, x, h, w);
break;
case 270:
wl_region_add(region, x + y, x, h, w);
break;
}
wl_surface_set_opaque_region(window->surface, region);
wl_region_destroy(region);
}
EAPI void
ecore_wl2_window_input_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
{
struct wl_region *region;
EINA_SAFETY_ON_NULL_RETURN(window);
window->input_rect.x = x;
window->input_rect.y = y;
window->input_rect.w = w;
window->input_rect.h = h;
if (window->type == ECORE_WL2_WINDOW_TYPE_DND) return;
region = wl_compositor_create_region(window->display->wl.compositor);
if (!region)
{
ERR("Failed to create opaque region: %m");
return;
}
switch (window->rotation)
{
case 0:
wl_region_add(region, x, y, w, h);
break;
case 180:
wl_region_add(region, x, x + y, w, h);
break;
case 90:
wl_region_add(region, y, x, h, w);
break;
case 270:
wl_region_add(region, x + y, x, h, w);
break;
}
wl_surface_set_input_region(window->surface, region);
wl_region_destroy(region);
}
EAPI Eina_Bool
ecore_wl2_window_maximized_get(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
return window->maximized;
}
EAPI void
ecore_wl2_window_maximized_set(Ecore_Wl2_Window *window, Eina_Bool maximized)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if (window->maximized == maximized) return;
if (window->type == ECORE_WL2_WINDOW_TYPE_TOPLEVEL)
{
window->saved = window->geometry;
if (window->xdg_surface)
xdg_surface_set_maximized(window->xdg_surface);
else if (window->wl_shell_surface)
wl_shell_surface_set_maximized(window->wl_shell_surface, NULL);
window->type = ECORE_WL2_WINDOW_TYPE_MAXIMIZED;
}
else if (window->type == ECORE_WL2_WINDOW_TYPE_MAXIMIZED)
{
if (window->xdg_surface)
xdg_surface_unset_maximized(window->xdg_surface);
else if (window->wl_shell_surface)
wl_shell_surface_set_toplevel(window->wl_shell_surface);
window->type = ECORE_WL2_WINDOW_TYPE_TOPLEVEL;
_ecore_wl2_window_configure_send(window, window->saved.w,
window->saved.h, 0);
}
window->maximized = maximized;
}
EAPI Eina_Bool
ecore_wl2_window_fullscreen_get(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
return window->fullscreen;
}
EAPI void
ecore_wl2_window_fullscreen_set(Ecore_Wl2_Window *window, Eina_Bool fullscreen)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if (window->fullscreen == fullscreen) return;
if (fullscreen)
{
window->saved = window->geometry;
if (window->xdg_surface)
xdg_surface_set_fullscreen(window->xdg_surface, NULL);
else if (window->wl_shell_surface)
wl_shell_surface_set_fullscreen(window->wl_shell_surface,
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
0, NULL);
window->type = ECORE_WL2_WINDOW_TYPE_FULLSCREEN;
}
else
{
if (window->xdg_surface)
xdg_surface_unset_fullscreen(window->xdg_surface);
else if (window->wl_shell_surface)
wl_shell_surface_set_toplevel(window->wl_shell_surface);
window->type = ECORE_WL2_WINDOW_TYPE_TOPLEVEL;
_ecore_wl2_window_configure_send(window, window->saved.w,
window->saved.h, 0);
}
window->fullscreen = fullscreen;
}
EAPI int
ecore_wl2_window_rotation_get(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
return window->rotation;
}
EAPI void
ecore_wl2_window_rotation_set(Ecore_Wl2_Window *window, int rotation)
{
EINA_SAFETY_ON_NULL_RETURN(window);
window->rotation = rotation;
}
EAPI void
ecore_wl2_window_title_set(Ecore_Wl2_Window *window, const char *title)
{
EINA_SAFETY_ON_NULL_RETURN(window);
eina_stringshare_replace(&window->title, title);
if (!window->title) return;
if (window->xdg_surface)
xdg_surface_set_title(window->xdg_surface, window->title);
else if (window->wl_shell_surface)
wl_shell_surface_set_title(window->wl_shell_surface, window->title);
}
EAPI void
ecore_wl2_window_class_set(Ecore_Wl2_Window *window, const char *clas)
{
EINA_SAFETY_ON_NULL_RETURN(window);
eina_stringshare_replace(&window->class, clas);
if (!window->class) return;
if (window->xdg_surface)
xdg_surface_set_app_id(window->xdg_surface, window->class);
else if (window->wl_shell_surface)
wl_shell_surface_set_class(window->wl_shell_surface, window->class);
}
EAPI void
ecore_wl2_window_geometry_get(Ecore_Wl2_Window *window, int *x, int *y, int *w, int *h)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if (x) *x = window->geometry.x;
if (y) *y = window->geometry.y;
if (w) *w = window->geometry.w;
if (h) *h = window->geometry.h;
}
EAPI void
ecore_wl2_window_geometry_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if ((window->geometry.x == x) && (window->geometry.y == y) &&
(window->geometry.w == w) && (window->geometry.h == h))
return;
window->geometry.x = x;
window->geometry.y = y;
window->geometry.w = w;
window->geometry.h = h;
if (window->xdg_surface)
xdg_surface_set_window_geometry(window->xdg_surface, x, y, w, h);
}
EAPI Eina_Bool
ecore_wl2_window_iconified_get(Ecore_Wl2_Window *window)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
return window->minimized;
}
EAPI void
ecore_wl2_window_iconified_set(Ecore_Wl2_Window *window, Eina_Bool iconified)
{
EINA_SAFETY_ON_NULL_RETURN(window);
if (window->minimized == iconified) return;
if (iconified)
{
if (window->xdg_surface)
xdg_surface_set_minimized(window->xdg_surface);
}
else
{
if (window->xdg_surface)
{
struct wl_array states;
uint32_t *s;
wl_array_init(&states);
s = wl_array_add(&states, sizeof(*s));
*s = XDG_SURFACE_STATE_ACTIVATED;
_xdg_surface_cb_configure(window, window->xdg_surface,
window->geometry.w, window->geometry.h,
&states, 0);
wl_array_release(&states);
}
window->type = ECORE_WL2_WINDOW_TYPE_TOPLEVEL;
}
window->minimized = iconified;
}
EAPI void
ecore_wl2_window_pointer_xy_get(Ecore_Wl2_Window *window, int *x, int *y)
{
Ecore_Wl2_Input *input;
EINA_SAFETY_ON_NULL_RETURN(window);
if (x) *x = 0;
if (y) *y = 0;
input = ecore_wl2_window_input_get(window);
if (!input) return;
if (x) *x = input->pointer.sx;
if (y) *y = input->pointer.sy;
}
EAPI void
ecore_wl2_window_pointer_set(Ecore_Wl2_Window *window, struct wl_surface *surface, int hot_x, int hot_y)
{
Ecore_Wl2_Input *input;
EINA_SAFETY_ON_NULL_RETURN(window);
input = ecore_wl2_window_input_get(window);
if (!input) return;
_ecore_wl2_input_cursor_update_stop(input);
if (input->wl.pointer)
wl_pointer_set_cursor(input->wl.pointer,
input->pointer.enter_serial,
surface, hot_x, hot_y);
}
EAPI void
ecore_wl2_window_cursor_from_name_set(Ecore_Wl2_Window *window, const char *cursor)
{
Ecore_Wl2_Input *input;
EINA_SAFETY_ON_NULL_RETURN(window);
eina_stringshare_replace(&window->cursor, cursor);
input = ecore_wl2_window_input_get(window);
if (!input) return;
_ecore_wl2_input_cursor_update_stop(input);
_ecore_wl2_input_cursor_set(input, cursor);
}
EAPI void
ecore_wl2_window_type_set(Ecore_Wl2_Window *window, Ecore_Wl2_Window_Type type)
{
EINA_SAFETY_ON_NULL_RETURN(window);
window->type = type;
}
EAPI Ecore_Wl2_Input *
ecore_wl2_window_input_get(Ecore_Wl2_Window *window)
{
Ecore_Wl2_Input *input;
EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(window->display, NULL);
if (window->input) return window->input;
EINA_INLIST_FOREACH(window->display->inputs, input)
{
if (input->focus.pointer) return input;
}
return NULL;
}

View File

@ -0,0 +1,167 @@
/*
* Copyright © 2012-2013 Collabora, Ltd.
*
* Permission to use, copy, modify, distribute, and sell this
* software and its documentation for any purpose is hereby granted
* without fee, provided that the above copyright notice appear in
* all copies and that both that copyright notice and this permission
* notice appear in supporting documentation, and that the name of
* the copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
* THIS SOFTWARE.
*/
#ifndef SUBSURFACE_CLIENT_PROTOCOL_H
#define SUBSURFACE_CLIENT_PROTOCOL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
struct wl_client;
struct wl_resource;
struct wl_subcompositor;
struct wl_subsurface;
extern const struct wl_interface wl_subcompositor_interface;
extern const struct wl_interface wl_subsurface_interface;
#ifndef WL_SUBCOMPOSITOR_ERROR_ENUM
#define WL_SUBCOMPOSITOR_ERROR_ENUM
enum wl_subcompositor_error {
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE = 0,
};
#endif /* WL_SUBCOMPOSITOR_ERROR_ENUM */
#define WL_SUBCOMPOSITOR_DESTROY 0
#define WL_SUBCOMPOSITOR_GET_SUBSURFACE 1
static inline void
wl_subcompositor_set_user_data(struct wl_subcompositor *wl_subcompositor, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) wl_subcompositor, user_data);
}
static inline void *
wl_subcompositor_get_user_data(struct wl_subcompositor *wl_subcompositor)
{
return wl_proxy_get_user_data((struct wl_proxy *) wl_subcompositor);
}
static inline void
wl_subcompositor_destroy(struct wl_subcompositor *wl_subcompositor)
{
wl_proxy_marshal((struct wl_proxy *) wl_subcompositor,
WL_SUBCOMPOSITOR_DESTROY);
wl_proxy_destroy((struct wl_proxy *) wl_subcompositor);
}
static inline struct wl_subsurface *
wl_subcompositor_get_subsurface(struct wl_subcompositor *wl_subcompositor, struct wl_surface *surface, struct wl_surface *parent)
{
struct wl_proxy *id;
id = wl_proxy_create((struct wl_proxy *) wl_subcompositor,
&wl_subsurface_interface);
if (!id)
return NULL;
wl_proxy_marshal((struct wl_proxy *) wl_subcompositor,
WL_SUBCOMPOSITOR_GET_SUBSURFACE, id, surface, parent);
return (struct wl_subsurface *) id;
}
#ifndef WL_SUBSURFACE_ERROR_ENUM
#define WL_SUBSURFACE_ERROR_ENUM
enum wl_subsurface_error {
WL_SUBSURFACE_ERROR_BAD_SURFACE = 0,
};
#endif /* WL_SUBSURFACE_ERROR_ENUM */
#define WL_SUBSURFACE_DESTROY 0
#define WL_SUBSURFACE_SET_POSITION 1
#define WL_SUBSURFACE_PLACE_ABOVE 2
#define WL_SUBSURFACE_PLACE_BELOW 3
#define WL_SUBSURFACE_SET_SYNC 4
#define WL_SUBSURFACE_SET_DESYNC 5
static inline void
wl_subsurface_set_user_data(struct wl_subsurface *wl_subsurface, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) wl_subsurface, user_data);
}
static inline void *
wl_subsurface_get_user_data(struct wl_subsurface *wl_subsurface)
{
return wl_proxy_get_user_data((struct wl_proxy *) wl_subsurface);
}
static inline void
wl_subsurface_destroy(struct wl_subsurface *wl_subsurface)
{
wl_proxy_marshal((struct wl_proxy *) wl_subsurface,
WL_SUBSURFACE_DESTROY);
wl_proxy_destroy((struct wl_proxy *) wl_subsurface);
}
static inline void
wl_subsurface_set_position(struct wl_subsurface *wl_subsurface, int32_t x, int32_t y)
{
wl_proxy_marshal((struct wl_proxy *) wl_subsurface,
WL_SUBSURFACE_SET_POSITION, x, y);
}
static inline void
wl_subsurface_place_above(struct wl_subsurface *wl_subsurface, struct wl_surface *sibling)
{
wl_proxy_marshal((struct wl_proxy *) wl_subsurface,
WL_SUBSURFACE_PLACE_ABOVE, sibling);
}
static inline void
wl_subsurface_place_below(struct wl_subsurface *wl_subsurface, struct wl_surface *sibling)
{
wl_proxy_marshal((struct wl_proxy *) wl_subsurface,
WL_SUBSURFACE_PLACE_BELOW, sibling);
}
static inline void
wl_subsurface_set_sync(struct wl_subsurface *wl_subsurface)
{
wl_proxy_marshal((struct wl_proxy *) wl_subsurface,
WL_SUBSURFACE_SET_SYNC);
}
static inline void
wl_subsurface_set_desync(struct wl_subsurface *wl_subsurface)
{
wl_proxy_marshal((struct wl_proxy *) wl_subsurface,
WL_SUBSURFACE_SET_DESYNC);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,70 @@
/*
* Copyright © 2012-2013 Collabora, Ltd.
*
* Permission to use, copy, modify, distribute, and sell this
* software and its documentation for any purpose is hereby granted
* without fee, provided that the above copyright notice appear in
* all copies and that both that copyright notice and this permission
* notice appear in supporting documentation, and that the name of
* the copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
* THIS SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
extern const struct wl_interface wl_subsurface_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface wl_surface_interface;
static const struct wl_interface *types[] = {
NULL,
NULL,
&wl_subsurface_interface,
&wl_surface_interface,
&wl_surface_interface,
&wl_surface_interface,
&wl_surface_interface,
};
static const struct wl_message wl_subcompositor_requests[] = {
{ "destroy", "", types + 0 },
{ "get_subsurface", "noo", types + 2 },
};
WL_EXPORT const struct wl_interface wl_subcompositor_interface = {
"wl_subcompositor", 1,
2, wl_subcompositor_requests,
0, NULL,
};
static const struct wl_message wl_subsurface_requests[] = {
{ "destroy", "", types + 0 },
{ "set_position", "ii", types + 0 },
{ "place_above", "o", types + 5 },
{ "place_below", "o", types + 6 },
{ "set_sync", "", types + 0 },
{ "set_desync", "", types + 0 },
};
WL_EXPORT const struct wl_interface wl_subsurface_interface = {
"wl_subsurface", 1,
6, wl_subsurface_requests,
0, NULL,
};

View File

@ -0,0 +1,561 @@
/*
* Copyright © 2008-2013 Kristian Høgsberg
* Copyright © 2013 Rafael Antognolli
* Copyright © 2013 Jasper St. Pierre
* Copyright © 2010-2013 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this
* software and its documentation for any purpose is hereby granted
* without fee, provided that the above copyright notice appear in
* all copies and that both that copyright notice and this permission
* notice appear in supporting documentation, and that the name of
* the copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
* THIS SOFTWARE.
*/
#ifndef XDG_SHELL_CLIENT_PROTOCOL_H
#define XDG_SHELL_CLIENT_PROTOCOL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
struct wl_client;
struct wl_resource;
struct wl_output;
struct wl_seat;
struct wl_surface;
struct xdg_popup;
struct xdg_shell;
struct xdg_surface;
extern const struct wl_interface xdg_shell_interface;
extern const struct wl_interface xdg_surface_interface;
extern const struct wl_interface xdg_popup_interface;
#ifndef XDG_SHELL_VERSION_ENUM
#define XDG_SHELL_VERSION_ENUM
/**
* xdg_shell_version - latest protocol version
* @XDG_SHELL_VERSION_CURRENT: Always the latest version
*
* The 'current' member of this enum gives the version of the protocol.
* Implementations can compare this to the version they implement using
* static_assert to ensure the protocol and implementation versions match.
*/
enum xdg_shell_version {
XDG_SHELL_VERSION_CURRENT = 5,
};
#endif /* XDG_SHELL_VERSION_ENUM */
#ifndef XDG_SHELL_ERROR_ENUM
#define XDG_SHELL_ERROR_ENUM
enum xdg_shell_error {
XDG_SHELL_ERROR_ROLE = 0,
XDG_SHELL_ERROR_DEFUNCT_SURFACES = 1,
XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP = 2,
XDG_SHELL_ERROR_INVALID_POPUP_PARENT = 3,
};
#endif /* XDG_SHELL_ERROR_ENUM */
/**
* xdg_shell - create desktop-style surfaces
* @ping: check if the client is alive
*
* xdg_shell allows clients to turn a wl_surface into a "real window"
* which can be dragged, resized, stacked, and moved around by the user.
* Everything about this interface is suited towards traditional desktop
* environments.
*/
struct xdg_shell_listener {
/**
* ping - check if the client is alive
* @serial: pass this to the pong request
*
* The ping event asks the client if it's still alive. Pass the
* serial specified in the event back to the compositor by sending
* a "pong" request back with the specified serial.
*
* Compositors can use this to determine if the client is still
* alive. It's unspecified what will happen if the client doesn't
* respond to the ping request, or in what timeframe. Clients
* should try to respond in a reasonable amount of time.
*
* A compositor is free to ping in any way it wants, but a client
* must always respond to any xdg_shell object it created.
*/
void (*ping)(void *data,
struct xdg_shell *xdg_shell,
uint32_t serial);
};
static inline int
xdg_shell_add_listener(struct xdg_shell *xdg_shell,
const struct xdg_shell_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) xdg_shell,
(void (**)(void)) listener, data);
}
#define XDG_SHELL_DESTROY 0
#define XDG_SHELL_USE_UNSTABLE_VERSION 1
#define XDG_SHELL_GET_XDG_SURFACE 2
#define XDG_SHELL_GET_XDG_POPUP 3
#define XDG_SHELL_PONG 4
static inline void
xdg_shell_set_user_data(struct xdg_shell *xdg_shell, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) xdg_shell, user_data);
}
static inline void *
xdg_shell_get_user_data(struct xdg_shell *xdg_shell)
{
return wl_proxy_get_user_data((struct wl_proxy *) xdg_shell);
}
static inline void
xdg_shell_destroy(struct xdg_shell *xdg_shell)
{
wl_proxy_marshal((struct wl_proxy *) xdg_shell,
XDG_SHELL_DESTROY);
wl_proxy_destroy((struct wl_proxy *) xdg_shell);
}
static inline void
xdg_shell_use_unstable_version(struct xdg_shell *xdg_shell, int32_t version)
{
wl_proxy_marshal((struct wl_proxy *) xdg_shell,
XDG_SHELL_USE_UNSTABLE_VERSION, version);
}
static inline struct xdg_surface *
xdg_shell_get_xdg_surface(struct xdg_shell *xdg_shell, struct wl_surface *surface)
{
struct wl_proxy *id;
id = wl_proxy_marshal_constructor((struct wl_proxy *) xdg_shell,
XDG_SHELL_GET_XDG_SURFACE, &xdg_surface_interface, NULL, surface);
return (struct xdg_surface *) id;
}
static inline struct xdg_popup *
xdg_shell_get_xdg_popup(struct xdg_shell *xdg_shell, struct wl_surface *surface, struct wl_surface *parent, struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y)
{
struct wl_proxy *id;
id = wl_proxy_marshal_constructor((struct wl_proxy *) xdg_shell,
XDG_SHELL_GET_XDG_POPUP, &xdg_popup_interface, NULL, surface, parent, seat, serial, x, y);
return (struct xdg_popup *) id;
}
static inline void
xdg_shell_pong(struct xdg_shell *xdg_shell, uint32_t serial)
{
wl_proxy_marshal((struct wl_proxy *) xdg_shell,
XDG_SHELL_PONG, serial);
}
#ifndef XDG_SURFACE_RESIZE_EDGE_ENUM
#define XDG_SURFACE_RESIZE_EDGE_ENUM
/**
* xdg_surface_resize_edge - edge values for resizing
* @XDG_SURFACE_RESIZE_EDGE_NONE: (none)
* @XDG_SURFACE_RESIZE_EDGE_TOP: (none)
* @XDG_SURFACE_RESIZE_EDGE_BOTTOM: (none)
* @XDG_SURFACE_RESIZE_EDGE_LEFT: (none)
* @XDG_SURFACE_RESIZE_EDGE_TOP_LEFT: (none)
* @XDG_SURFACE_RESIZE_EDGE_BOTTOM_LEFT: (none)
* @XDG_SURFACE_RESIZE_EDGE_RIGHT: (none)
* @XDG_SURFACE_RESIZE_EDGE_TOP_RIGHT: (none)
* @XDG_SURFACE_RESIZE_EDGE_BOTTOM_RIGHT: (none)
*
* These values are used to indicate which edge of a surface is being
* dragged in a resize operation. The server may use this information to
* adapt its behavior, e.g. choose an appropriate cursor image.
*/
enum xdg_surface_resize_edge {
XDG_SURFACE_RESIZE_EDGE_NONE = 0,
XDG_SURFACE_RESIZE_EDGE_TOP = 1,
XDG_SURFACE_RESIZE_EDGE_BOTTOM = 2,
XDG_SURFACE_RESIZE_EDGE_LEFT = 4,
XDG_SURFACE_RESIZE_EDGE_TOP_LEFT = 5,
XDG_SURFACE_RESIZE_EDGE_BOTTOM_LEFT = 6,
XDG_SURFACE_RESIZE_EDGE_RIGHT = 8,
XDG_SURFACE_RESIZE_EDGE_TOP_RIGHT = 9,
XDG_SURFACE_RESIZE_EDGE_BOTTOM_RIGHT = 10,
};
#endif /* XDG_SURFACE_RESIZE_EDGE_ENUM */
#ifndef XDG_SURFACE_STATE_ENUM
#define XDG_SURFACE_STATE_ENUM
/**
* xdg_surface_state - types of state on the surface
* @XDG_SURFACE_STATE_MAXIMIZED: the surface is maximized
* @XDG_SURFACE_STATE_FULLSCREEN: the surface is fullscreen
* @XDG_SURFACE_STATE_RESIZING: (none)
* @XDG_SURFACE_STATE_ACTIVATED: (none)
*
* The different state values used on the surface. This is designed for
* state values like maximized, fullscreen. It is paired with the configure
* event to ensure that both the client and the compositor setting the
* state can be synchronized.
*
* States set in this way are double-buffered. They will get applied on the
* next commit.
*
* Desktop environments may extend this enum by taking up a range of values
* and documenting the range they chose in this description. They are not
* required to document the values for the range that they chose. Ideally,
* any good extensions from a desktop environment should make its way into
* standardization into this enum.
*
* The current reserved ranges are:
*
* 0x0000 - 0x0FFF: xdg-shell core values, documented below. 0x1000 -
* 0x1FFF: GNOME
*/
enum xdg_surface_state {
XDG_SURFACE_STATE_MAXIMIZED = 1,
XDG_SURFACE_STATE_FULLSCREEN = 2,
XDG_SURFACE_STATE_RESIZING = 3,
XDG_SURFACE_STATE_ACTIVATED = 4,
};
#endif /* XDG_SURFACE_STATE_ENUM */
/**
* xdg_surface - A desktop window
* @configure: suggest a surface change
* @close: surface wants to be closed
*
* An interface that may be implemented by a wl_surface, for
* implementations that provide a desktop-style user interface.
*
* It provides requests to treat surfaces like windows, allowing to set
* properties like maximized, fullscreen, minimized, and to move and resize
* them, and associate metadata like title and app id.
*
* The client must call wl_surface.commit on the corresponding wl_surface
* for the xdg_surface state to take effect. Prior to committing the new
* state, it can set up initial configuration, such as maximizing or
* setting a window geometry.
*
* Even without attaching a buffer the compositor must respond to initial
* committed configuration, for instance sending a configure event with
* expected window geometry if the client maximized its surface during
* initialization.
*
* For a surface to be mapped by the compositor the client must have
* committed both an xdg_surface state and a buffer.
*/
struct xdg_surface_listener {
/**
* configure - suggest a surface change
* @width: (none)
* @height: (none)
* @states: (none)
* @serial: (none)
*
* The configure event asks the client to resize its surface or
* to change its state.
*
* The width and height arguments specify a hint to the window
* about how its surface should be resized in window geometry
* coordinates. See set_window_geometry.
*
* If the width or height arguments are zero, it means the client
* should decide its own window dimension. This may happen when the
* compositor need to configure the state of the surface but
* doesn't have any information about any previous or expected
* dimension.
*
* The states listed in the event specify how the width/height
* arguments should be interpreted, and possibly how it should be
* drawn.
*
* Clients should arrange their surface for the new size and
* states, and then send a ack_configure request with the serial
* sent in this configure event at some point before committing the
* new surface.
*
* If the client receives multiple configure events before it can
* respond to one, it is free to discard all but the last event it
* received.
*/
void (*configure)(void *data,
struct xdg_surface *xdg_surface,
int32_t width,
int32_t height,
struct wl_array *states,
uint32_t serial);
/**
* close - surface wants to be closed
*
* The close event is sent by the compositor when the user wants
* the surface to be closed. This should be equivalent to the user
* clicking the close button in client-side decorations, if your
* application has any...
*
* This is only a request that the user intends to close your
* window. The client may choose to ignore this request, or show a
* dialog to ask the user to save their data...
*/
void (*close)(void *data,
struct xdg_surface *xdg_surface);
};
static inline int
xdg_surface_add_listener(struct xdg_surface *xdg_surface,
const struct xdg_surface_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) xdg_surface,
(void (**)(void)) listener, data);
}
#define XDG_SURFACE_DESTROY 0
#define XDG_SURFACE_SET_PARENT 1
#define XDG_SURFACE_SET_TITLE 2
#define XDG_SURFACE_SET_APP_ID 3
#define XDG_SURFACE_SHOW_WINDOW_MENU 4
#define XDG_SURFACE_MOVE 5
#define XDG_SURFACE_RESIZE 6
#define XDG_SURFACE_ACK_CONFIGURE 7
#define XDG_SURFACE_SET_WINDOW_GEOMETRY 8
#define XDG_SURFACE_SET_MAXIMIZED 9
#define XDG_SURFACE_UNSET_MAXIMIZED 10
#define XDG_SURFACE_SET_FULLSCREEN 11
#define XDG_SURFACE_UNSET_FULLSCREEN 12
#define XDG_SURFACE_SET_MINIMIZED 13
static inline void
xdg_surface_set_user_data(struct xdg_surface *xdg_surface, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) xdg_surface, user_data);
}
static inline void *
xdg_surface_get_user_data(struct xdg_surface *xdg_surface)
{
return wl_proxy_get_user_data((struct wl_proxy *) xdg_surface);
}
static inline void
xdg_surface_destroy(struct xdg_surface *xdg_surface)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_DESTROY);
wl_proxy_destroy((struct wl_proxy *) xdg_surface);
}
static inline void
xdg_surface_set_parent(struct xdg_surface *xdg_surface, struct xdg_surface *parent)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_SET_PARENT, parent);
}
static inline void
xdg_surface_set_title(struct xdg_surface *xdg_surface, const char *title)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_SET_TITLE, title);
}
static inline void
xdg_surface_set_app_id(struct xdg_surface *xdg_surface, const char *app_id)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_SET_APP_ID, app_id);
}
static inline void
xdg_surface_show_window_menu(struct xdg_surface *xdg_surface, struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_SHOW_WINDOW_MENU, seat, serial, x, y);
}
static inline void
xdg_surface_move(struct xdg_surface *xdg_surface, struct wl_seat *seat, uint32_t serial)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_MOVE, seat, serial);
}
static inline void
xdg_surface_resize(struct xdg_surface *xdg_surface, struct wl_seat *seat, uint32_t serial, uint32_t edges)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_RESIZE, seat, serial, edges);
}
static inline void
xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_ACK_CONFIGURE, serial);
}
static inline void
xdg_surface_set_window_geometry(struct xdg_surface *xdg_surface, int32_t x, int32_t y, int32_t width, int32_t height)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_SET_WINDOW_GEOMETRY, x, y, width, height);
}
static inline void
xdg_surface_set_maximized(struct xdg_surface *xdg_surface)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_SET_MAXIMIZED);
}
static inline void
xdg_surface_unset_maximized(struct xdg_surface *xdg_surface)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_UNSET_MAXIMIZED);
}
static inline void
xdg_surface_set_fullscreen(struct xdg_surface *xdg_surface, struct wl_output *output)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_SET_FULLSCREEN, output);
}
static inline void
xdg_surface_unset_fullscreen(struct xdg_surface *xdg_surface)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_UNSET_FULLSCREEN);
}
static inline void
xdg_surface_set_minimized(struct xdg_surface *xdg_surface)
{
wl_proxy_marshal((struct wl_proxy *) xdg_surface,
XDG_SURFACE_SET_MINIMIZED);
}
/**
* xdg_popup - short-lived, popup surfaces for menus
* @popup_done: popup interaction is done
*
* A popup surface is a short-lived, temporary surface that can be used
* to implement menus. It takes an explicit grab on the surface that will
* be dismissed when the user dismisses the popup. This can be done by the
* user clicking outside the surface, using the keyboard, or even locking
* the screen through closing the lid or a timeout.
*
* When the popup is dismissed, a popup_done event will be sent out, and at
* the same time the surface will be unmapped. The xdg_popup object is now
* inert and cannot be reactivated, so clients should destroy it.
* Explicitly destroying the xdg_popup object will also dismiss the popup
* and unmap the surface.
*
* Clients will receive events for all their surfaces during this grab
* (which is an "owner-events" grab in X11 parlance). This is done so that
* users can navigate through submenus and other "nested" popup windows
* without having to dismiss the topmost popup.
*
* Clients that want to dismiss the popup when another surface of their own
* is clicked should dismiss the popup using the destroy request.
*
* The parent surface must have either an xdg_surface or xdg_popup role.
*
* Specifying an xdg_popup for the parent means that the popups are nested,
* with this popup now being the topmost popup. Nested popups must be
* destroyed in the reverse order they were created in, e.g. the only popup
* you are allowed to destroy at all times is the topmost one.
*
* If there is an existing popup when creating a new popup, the parent must
* be the current topmost popup.
*
* A parent surface must be mapped before the new popup is mapped.
*
* When compositors choose to dismiss a popup, they will likely dismiss
* every nested popup as well. When a compositor dismisses popups, it will
* follow the same dismissing order as required from the client.
*
* The x and y arguments passed when creating the popup object specify
* where the top left of the popup should be placed, relative to the local
* surface coordinates of the parent surface. See xdg_shell.get_xdg_popup.
*
* The client must call wl_surface.commit on the corresponding wl_surface
* for the xdg_popup state to take effect.
*
* For a surface to be mapped by the compositor the client must have
* committed both the xdg_popup state and a buffer.
*/
struct xdg_popup_listener {
/**
* popup_done - popup interaction is done
*
* The popup_done event is sent out when a popup is dismissed by
* the compositor. The client should destroy the xdg_popup object
* at this point.
*/
void (*popup_done)(void *data,
struct xdg_popup *xdg_popup);
};
static inline int
xdg_popup_add_listener(struct xdg_popup *xdg_popup,
const struct xdg_popup_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) xdg_popup,
(void (**)(void)) listener, data);
}
#define XDG_POPUP_DESTROY 0
static inline void
xdg_popup_set_user_data(struct xdg_popup *xdg_popup, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) xdg_popup, user_data);
}
static inline void *
xdg_popup_get_user_data(struct xdg_popup *xdg_popup)
{
return wl_proxy_get_user_data((struct wl_proxy *) xdg_popup);
}
static inline void
xdg_popup_destroy(struct xdg_popup *xdg_popup)
{
wl_proxy_marshal((struct wl_proxy *) xdg_popup,
XDG_POPUP_DESTROY);
wl_proxy_destroy((struct wl_proxy *) xdg_popup);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,125 @@
/*
* Copyright © 2008-2013 Kristian Høgsberg
* Copyright © 2013 Rafael Antognolli
* Copyright © 2013 Jasper St. Pierre
* Copyright © 2010-2013 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this
* software and its documentation for any purpose is hereby granted
* without fee, provided that the above copyright notice appear in
* all copies and that both that copyright notice and this permission
* notice appear in supporting documentation, and that the name of
* the copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
* THIS SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface xdg_popup_interface;
extern const struct wl_interface xdg_surface_interface;
static const struct wl_interface *types[] = {
NULL,
NULL,
NULL,
NULL,
&xdg_surface_interface,
&wl_surface_interface,
&xdg_popup_interface,
&wl_surface_interface,
&wl_surface_interface,
&wl_seat_interface,
NULL,
NULL,
NULL,
&xdg_surface_interface,
&wl_seat_interface,
NULL,
NULL,
NULL,
&wl_seat_interface,
NULL,
&wl_seat_interface,
NULL,
NULL,
&wl_output_interface,
};
static const struct wl_message xdg_shell_requests[] = {
{ "destroy", "", types + 0 },
{ "use_unstable_version", "i", types + 0 },
{ "get_xdg_surface", "no", types + 4 },
{ "get_xdg_popup", "nooouii", types + 6 },
{ "pong", "u", types + 0 },
};
static const struct wl_message xdg_shell_events[] = {
{ "ping", "u", types + 0 },
};
WL_EXPORT const struct wl_interface xdg_shell_interface = {
"xdg_shell", 1,
5, xdg_shell_requests,
1, xdg_shell_events,
};
static const struct wl_message xdg_surface_requests[] = {
{ "destroy", "", types + 0 },
{ "set_parent", "?o", types + 13 },
{ "set_title", "s", types + 0 },
{ "set_app_id", "s", types + 0 },
{ "show_window_menu", "ouii", types + 14 },
{ "move", "ou", types + 18 },
{ "resize", "ouu", types + 20 },
{ "ack_configure", "u", types + 0 },
{ "set_window_geometry", "iiii", types + 0 },
{ "set_maximized", "", types + 0 },
{ "unset_maximized", "", types + 0 },
{ "set_fullscreen", "?o", types + 23 },
{ "unset_fullscreen", "", types + 0 },
{ "set_minimized", "", types + 0 },
};
static const struct wl_message xdg_surface_events[] = {
{ "configure", "iiau", types + 0 },
{ "close", "", types + 0 },
};
WL_EXPORT const struct wl_interface xdg_surface_interface = {
"xdg_surface", 1,
14, xdg_surface_requests,
2, xdg_surface_events,
};
static const struct wl_message xdg_popup_requests[] = {
{ "destroy", "", types + 0 },
};
static const struct wl_message xdg_popup_events[] = {
{ "popup_done", "", types + 0 },
};
WL_EXPORT const struct wl_interface xdg_popup_interface = {
"xdg_popup", 1,
1, xdg_popup_requests,
1, xdg_popup_events,
};

View File

@ -37,6 +37,9 @@ static Ecore_Event_Handler *ecore_evas_event_handlers[4];
static const char *_iface_name = "opengl_cocoa";
static const int _iface_version = 1;
static const char *_iface_name = "opengl_cocoa";
static const int _iface_version = 1;
static int
_render_updates_process(Ecore_Evas *ee, Eina_List *updates)
{

View File

@ -80,7 +80,7 @@ static Eina_Bool
_ecore_evas_wl_common_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Evas *ee;
Ecore_Wl_Event_Mouse_In *ev;
Ecore_Event_Mouse_IO *ev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
@ -102,7 +102,7 @@ static Eina_Bool
_ecore_evas_wl_common_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Evas *ee;
Ecore_Wl_Event_Mouse_Out *ev;
Ecore_Event_Mouse_IO *ev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
@ -127,14 +127,14 @@ static Eina_Bool
_ecore_evas_wl_common_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Evas *ee;
Ecore_Wl_Event_Focus_In *ev;
Ecore_Wl2_Event_Focus_In *ev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ev = event;
ee = ecore_event_window_match(ev->win);
ee = ecore_event_window_match(ev->window);
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
if (ee->prop.focused) return ECORE_CALLBACK_PASS_ON;
ee->prop.focused = EINA_TRUE;
evas_focus_in(ee->evas);
@ -146,14 +146,14 @@ static Eina_Bool
_ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Evas *ee;
Ecore_Wl_Event_Focus_In *ev;
Ecore_Wl2_Event_Focus_Out *ev;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ev = event;
ee = ecore_event_window_match(ev->win);
ee = ecore_event_window_match(ev->window);
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
if (!ee->prop.focused) return ECORE_CALLBACK_PASS_ON;
evas_focus_out(ee->evas);
ee->prop.focused = EINA_FALSE;
@ -166,7 +166,7 @@ _ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_
{
Ecore_Evas *ee;
Ecore_Evas_Engine_Wl_Data *wdata;
Ecore_Wl_Event_Window_Configure *ev;
Ecore_Wl2_Event_Window_Configure *ev;
int nw = 0, nh = 0;
int fw = 0, fh = 0;
Eina_Bool prev_max, prev_full;
@ -198,7 +198,10 @@ _ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_
(prev_full != ee->prop.fullscreen))
_ecore_evas_wl_common_state_update(ee);
/* NB: We receive window configure sizes based on xdg surface
* window geometry, so we need to subtract framespace here */
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (ECORE_EVAS_PORTRAIT(ee))
{
nw -= fw;
@ -232,7 +235,7 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
if (rot_dif < 0) rot_dif = -rot_dif;
/* set ecore_wayland window rotation */
ecore_wl_window_rotation_set(wdata->win, rotation);
ecore_wl2_window_rotation_set(wdata->win, rotation);
/* check if rotation is just a flip */
if (rot_dif != 180)
@ -253,8 +256,8 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
if (!ee->prop.fullscreen)
{
/* resize the ecore_wayland window */
ecore_wl_window_resize(wdata->win,
ee->req.h + fw, ee->req.w + fh, 0);
ecore_wl2_window_resize(wdata->win,
ee->req.h + fw, ee->req.w + fh, 0);
}
else
{
@ -262,8 +265,8 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
if ((rotation == 0) || (rotation == 180))
{
/* resize the ecore_wayland window */
ecore_wl_window_resize(wdata->win,
ee->req.w, ee->req.h, 0);
ecore_wl2_window_resize(wdata->win,
ee->req.w, ee->req.h, 0);
/* resize the canvas */
evas_output_size_set(ee->evas, ee->req.w, ee->req.h);
@ -273,8 +276,8 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
else
{
/* resize the ecore_wayland window */
ecore_wl_window_resize(wdata->win,
ee->req.h, ee->req.w, 0);
ecore_wl2_window_resize(wdata->win,
ee->req.h, ee->req.w, 0);
/* resize the canvas */
evas_output_size_set(ee->evas, ee->req.h, ee->req.w);
@ -346,7 +349,7 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
else
{
/* resize the ecore_wayland window */
ecore_wl_window_resize(wdata->win, ee->w, ee->h, 0);
ecore_wl2_window_resize(wdata->win, ee->w, ee->h, 0);
/* record the current rotation of the ecore_evas */
ee->rotation = rotation;
@ -391,19 +394,19 @@ _ecore_evas_wl_common_init(void)
return _ecore_evas_wl_init_count;
_ecore_evas_wl_event_hdls[0] =
ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
ecore_event_handler_add(ECORE_EVENT_MOUSE_IN,
_ecore_evas_wl_common_cb_mouse_in, NULL);
_ecore_evas_wl_event_hdls[1] =
ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
ecore_event_handler_add(ECORE_EVENT_MOUSE_OUT,
_ecore_evas_wl_common_cb_mouse_out, NULL);
_ecore_evas_wl_event_hdls[2] =
ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_IN,
_ecore_evas_wl_common_cb_focus_in, NULL);
_ecore_evas_wl_event_hdls[3] =
ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_OUT,
_ecore_evas_wl_common_cb_focus_out, NULL);
_ecore_evas_wl_event_hdls[4] =
ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE,
_ecore_evas_wl_common_cb_window_configure, NULL);
ecore_event_evas_init();
@ -452,30 +455,40 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!ee) return;
wdata = ee->engine.data;
if (wdata->anim_callback)
wl_callback_destroy(wdata->anim_callback);
if (wdata->win) ecore_wl_window_free(wdata->win);
if (wdata->anim_callback) wl_callback_destroy(wdata->anim_callback);
wdata->anim_callback = NULL;
if (wdata->win) ecore_wl2_window_free(wdata->win);
wdata->win = NULL;
ecore_wl2_display_disconnect(wdata->display);
free(wdata);
ecore_event_window_unregister(ee->prop.window);
ecore_evas_input_event_unregister(ee);
_ecore_evas_wl_common_shutdown();
ecore_wl_shutdown();
ecore_wl2_shutdown();
}
void
_ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h)
{
Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
Ecore_Evas_Engine_Wl_Data *wdata;
int orig_w, orig_h;
int ow, oh;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!ee) return;
wdata = ee->engine.data;
if (!wdata) return;
if (w < 1) w = 1;
if (h < 1) h = 1;
@ -636,11 +649,16 @@ _ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h)
if (wdata->frame)
evas_object_resize(wdata->frame, w, h);
if (wdata->win)
{
if (ECORE_EVAS_PORTRAIT(ee))
ecore_wl2_window_geometry_set(wdata->win, 0, 0, w, h);
else
ecore_wl2_window_geometry_set(wdata->win, 0, 0, h, w);
}
if (ee->func.fn_resize) ee->func.fn_resize(ee);
}
if (wdata->win)
ecore_wl_window_update_size(wdata->win, w, h);
}
void
@ -936,11 +954,14 @@ _ecore_evas_wl_common_frame_border_size_get(Evas_Object *obj, int *fx, int *fy,
}
void
_ecore_evas_wl_common_pointer_xy_get(const Ecore_Evas *ee EINA_UNUSED, Evas_Coord *x, Evas_Coord *y)
_ecore_evas_wl_common_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
{
Ecore_Evas_Engine_Wl_Data *wdata;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ecore_wl_pointer_xy_get(x, y);
wdata = ee->engine.data;
ecore_wl2_window_pointer_xy_get(wdata->win, x, y);
}
void
@ -952,7 +973,7 @@ _ecore_evas_wl_common_raise(Ecore_Evas *ee)
if ((!ee) || (!ee->visible)) return;
wdata = ee->engine.data;
ecore_wl_window_raise(wdata->win);
ecore_wl2_window_raise(wdata->win);
}
void
@ -977,7 +998,7 @@ _ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title)
}
if (ee->prop.title)
ecore_wl_window_title_set(wdata->win, ee->prop.title);
ecore_wl2_window_title_set(wdata->win, ee->prop.title);
}
void
@ -1001,8 +1022,9 @@ _ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *
ee->prop.clas = NULL;
if (c) ee->prop.clas = strdup(c);
}
if (ee->prop.clas)
ecore_wl_window_class_name_set(wdata->win, ee->prop.clas);
ecore_wl2_window_class_set(wdata->win, ee->prop.clas);
}
void
@ -1088,14 +1110,15 @@ void
_ecore_evas_wl_common_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
{
int x, y, fx, fy;
Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
Ecore_Evas_Engine_Wl_Data *wdata;
Evas_Object *old;
if (!ee) return;
wdata = ee->engine.data;
old = ee->prop.cursor.object;
if (obj == NULL)
{
ecore_wl_window_pointer_set(wdata->win, NULL, 0, 0);
ecore_wl2_window_pointer_set(wdata->win, NULL, 0, 0);
ee->prop.cursor.object = NULL;
ee->prop.cursor.layer = 0;
ee->prop.cursor.hot.x = 0;
@ -1112,7 +1135,7 @@ _ecore_evas_wl_common_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int la
if (obj != old)
{
ecore_wl_window_pointer_set(wdata->win, NULL, 0, 0);
ecore_wl2_window_pointer_set(wdata->win, NULL, 0, 0);
evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
evas_object_pass_events_set(ee->prop.cursor.object, 1);
if (evas_pointer_inside_get(ee->evas))
@ -1158,7 +1181,7 @@ _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, Eina_Bool on)
ee->prop.iconified = on;
wdata = ee->engine.data;
ecore_wl_window_iconified_set(wdata->win, on);
ecore_wl2_window_iconified_set(wdata->win, on);
}
static void
@ -1208,9 +1231,9 @@ _ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, Eina_Bool on)
if (!ee) return;
if (ee->prop.maximized == on) return;
wdata = ee->engine.data;
ecore_wl_window_maximized_set(wdata->win, on);
// _ecore_evas_wl_common_state_update(ee);
ecore_wl2_window_maximized_set(wdata->win, on);
}
void
@ -1222,9 +1245,9 @@ _ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
if (!ee) return;
if (ee->prop.fullscreen == on) return;
wdata = ee->engine.data;
ecore_wl_window_fullscreen_set(wdata->win, on);
// _ecore_evas_wl_common_state_update(ee);
ecore_wl2_window_fullscreen_set(wdata->win, on);
}
void
@ -1291,7 +1314,7 @@ _ecore_evas_wl_common_render_pre(void *data, Evas *evas EINA_UNUSED, void *event
wdata = ee->engine.data;
wdata->anim_callback =
wl_surface_frame(ecore_wl_window_surface_get(wdata->win));
wl_surface_frame(ecore_wl2_window_surface_get(wdata->win));
wl_callback_add_listener(wdata->anim_callback, &_anim_listener, ee);
ecore_evas_manual_render_set(ee, 1);
}
@ -1306,8 +1329,6 @@ _ecore_evas_wl_common_render_updates(void *data, Evas *evas EINA_UNUSED, void *e
ee->in_async_render = EINA_FALSE;
_ecore_evas_wl_common_render_updates_process(ee, ev->updated_area);
if (ee->delayed.alpha_changed)
{
_ecore_evas_wayland_alpha_do(ee, ee->delayed.alpha);
@ -1323,6 +1344,8 @@ _ecore_evas_wl_common_render_updates(void *data, Evas *evas EINA_UNUSED, void *e
_rotation_do(ee, ee->delayed.rotation, ee->delayed.rotation_resize);
ee->delayed.rotation_changed = EINA_FALSE;
}
_ecore_evas_wl_common_render_updates_process(ee, ev->updated_area);
}
void
@ -1340,12 +1363,10 @@ _ecore_evas_wl_common_render(Ecore_Evas *ee)
int rend = 0;
Eina_List *l;
Ecore_Evas *ee2;
Ecore_Wl_Window *win = NULL;
Ecore_Evas_Engine_Wl_Data *wdata;
if (!ee) return 0;
if (!(wdata = ee->engine.data)) return 0;
if (!(win = wdata->win)) return 0;
/* TODO: handle comp no sync */
@ -1403,13 +1424,17 @@ _ecore_evas_wl_common_withdrawn_set(Ecore_Evas *ee, Eina_Bool on)
}
void
_ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h)
_ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
{
Ecore_Evas_Engine_Wl_Data *wdata;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (x) *x = 0;
if (y) *y = 0;
ecore_wl_screen_size_get(w, h);
wdata = ee->engine.data;
ecore_wl2_display_screen_size_get(wdata->display, w, h);
}
void
@ -1421,8 +1446,11 @@ _ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee EINA_UNUSED, int *xdpi
if (xdpi) *xdpi = 0;
if (ydpi) *ydpi = 0;
/* FIXME: Ideally this needs to get the DPI from a specific screen */
dpi = ecore_wl_dpi_get();
/* TODO */
/* dpi = ecore_wl_dpi_get(); */
if (xdpi) *xdpi = dpi;
if (ydpi) *ydpi = dpi;
}
@ -1479,7 +1507,7 @@ _ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y)
{
wdata = ee->engine.data;
if (wdata->win)
ecore_wl_window_move(wdata->win, x, y);
ecore_wl2_window_move(wdata->win, x, y);
}
}
@ -1490,10 +1518,11 @@ _ecore_evas_wayland_type_set(Ecore_Evas *ee, int type)
if (!ee) return;
wdata = ee->engine.data;
ecore_wl_window_type_set(wdata->win, type);
ecore_wl2_window_type_set(wdata->win, type);
}
static Ecore_Wl_Window *
static Ecore_Wl2_Window *
_ecore_evas_wayland_window_get(const Ecore_Evas *ee)
{
Ecore_Evas_Engine_Wl_Data *wdata;
@ -1505,7 +1534,6 @@ _ecore_evas_wayland_window_get(const Ecore_Evas *ee)
return wdata->win;
}
#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
static void
_ecore_evas_wayland_pre_post_swap_callback_set(const Ecore_Evas *ee, void *data, void (*pre_cb) (void *data, Evas *e), void (*post_cb) (void *data, Evas *e))
@ -1525,11 +1553,11 @@ _ecore_evas_wayland_pre_post_swap_callback_set(const Ecore_Evas *ee, void *data,
}
#endif
static void
_ecore_evas_wayland_pointer_set(Ecore_Evas *ee EINA_UNUSED, int hot_x EINA_UNUSED, int hot_y EINA_UNUSED)
{
/* static void */
/* _ecore_evas_wayland_pointer_set(Ecore_Evas *ee EINA_UNUSED, int hot_x EINA_UNUSED, int hot_y EINA_UNUSED) */
/* { */
}
/* } */
Ecore_Evas_Interface_Wayland *
_ecore_evas_wl_interface_new(void)
@ -1544,9 +1572,9 @@ _ecore_evas_wl_interface_new(void)
iface->resize = _ecore_evas_wayland_resize;
iface->move = _ecore_evas_wayland_move;
iface->pointer_set = _ecore_evas_wayland_pointer_set;
/* iface->pointer_set = _ecore_evas_wayland_pointer_set; */
iface->type_set = _ecore_evas_wayland_type_set;
iface->window_get = _ecore_evas_wayland_window_get;
iface->window_get2 = _ecore_evas_wayland_window_get;
#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
iface->pre_post_swap_callback_set =

View File

@ -119,12 +119,13 @@ EAPI Ecore_Evas *
ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
int x, int y, int w, int h, Eina_Bool frame)
{
Ecore_Wl_Window *p = NULL;
Ecore_Wl2_Display *ewd;
Ecore_Wl2_Window *p = NULL;
Evas_Engine_Info_Wayland_Egl *einfo;
Ecore_Evas_Interface_Wayland *iface;
Ecore_Evas_Engine_Wl_Data *wdata;
Ecore_Evas *ee;
int method = 0, count = 0;
int method = 0;
int fx = 0, fy = 0, fw = 0, fh = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
@ -135,10 +136,37 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
return NULL;
}
count = ecore_wl_init(disp_name);
if (!count)
if (!ecore_wl2_init())
{
ERR("Failed to initialize Ecore_Wayland");
ERR("Failed to initialize Ecore_Wl2");
return NULL;
}
ewd = ecore_wl2_display_connect(disp_name);
if (!ewd)
{
ERR("Failed to connect to Wayland Display %s", disp_name);
return NULL;
}
ewd = ecore_wl2_display_connect(disp_name);
if (!ewd)
{
ERR("Failed to connect to Wayland Display %s", disp_name);
return NULL;
}
ewd = ecore_wl2_display_connect(disp_name);
if (!ewd)
{
ERR("Failed to connect to Wayland Display %s", disp_name);
return NULL;
}
ewd = ecore_wl2_display_connect(disp_name);
if (!ewd)
{
ERR("Failed to connect to Wayland Display %s", disp_name);
return NULL;
}
@ -194,7 +222,7 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
/* if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER")) */
ee->can_async_render = 0;
/* else */
/* ee->can_async_render = 1; */
/* ee->can_async_render = 1; */
/* frame offset and size */
if (ee->prop.draw_frame)
@ -207,15 +235,14 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
if (parent)
{
p = ecore_wl_window_find(parent);
ee->alpha = ecore_wl_window_alpha_get(p);
p = ecore_wl2_display_window_find(ewd, parent);
ee->alpha = ecore_wl2_window_alpha_get(p);
}
wdata->parent = p;
wdata->win =
ecore_wl_window_new(p, x, y, w + fw, h + fh,
ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW);
ee->prop.window = ecore_wl_window_id_get(wdata->win);
wdata->display = ewd;
wdata->win = ecore_wl2_window_new(ewd, p, x, y, w + fw, h + fh);
ee->prop.window = ecore_wl2_window_id_get(wdata->win);
ee->evas = evas_new();
evas_data_attach_set(ee->evas, ee);
@ -236,11 +263,11 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas)))
{
einfo->info.display = ecore_wl_display_get();
einfo->info.display = ecore_wl2_display_get(ewd);
einfo->info.destination_alpha = EINA_TRUE;
einfo->info.rotation = ee->rotation;
einfo->info.depth = 32;
einfo->info.surface = ecore_wl_window_surface_create(wdata->win);
einfo->info.surface = ecore_wl2_window_surface_get(wdata->win);
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
{
ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
@ -253,7 +280,7 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
goto err;
}
/* ecore_wl_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); */
/* ecore_wl2_display_animator_source_set(ewd, ECORE_ANIMATOR_SOURCE_CUSTOM); */
ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free);
@ -335,15 +362,16 @@ _ecore_evas_wl_show(Ecore_Evas *ee)
wdata = ee->engine.data;
if (wdata->win)
{
ecore_wl_window_show(wdata->win);
ecore_wl_window_alpha_set(wdata->win, ee->alpha);
ecore_wl2_window_show(wdata->win);
ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
/* ecore_wl_window_update_size(wdata->win, ee->w + fw, ee->h + fh); */
einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
if (einfo)
{
struct wl_surface *surf;
surf = ecore_wl_window_surface_get(wdata->win);
surf = ecore_wl2_window_surface_get(wdata->win);
if ((!einfo->info.surface) || (einfo->info.surface != surf))
{
einfo->info.surface = surf;
@ -390,7 +418,7 @@ _ecore_evas_wl_hide(Ecore_Evas *ee)
}
if (wdata->win)
ecore_wl_window_hide(wdata->win);
ecore_wl2_window_hide(wdata->win);
if (ee->prop.override)
{
@ -420,7 +448,7 @@ _ecore_evas_wayland_egl_alpha_do(Ecore_Evas *ee, int alpha)
ee->alpha = alpha;
wdata = ee->engine.data;
if (wdata->win) ecore_wl_window_alpha_set(wdata->win, ee->alpha);
if (wdata->win) ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
@ -461,7 +489,7 @@ _ecore_evas_wayland_egl_transparent_do(Ecore_Evas *ee, int transparent)
wdata = ee->engine.data;
if (wdata->win)
ecore_wl_window_transparent_set(wdata->win, ee->transparent);
ecore_wl2_window_transparent_set(wdata->win, ee->transparent);
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
@ -501,9 +529,9 @@ _ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location)
_ecore_evas_wayland_egl_resize_edge_set(ee, location);
if (ECORE_EVAS_PORTRAIT(ee))
ecore_wl_window_resize(wdata->win, ee->w, ee->h, location);
ecore_wl2_window_resize(wdata->win, ee->w, ee->h, location);
else
ecore_wl_window_resize(wdata->win, ee->w, ee->h, location);
ecore_wl2_window_resize(wdata->win, ee->w, ee->h, location);
}
}

View File

@ -20,6 +20,7 @@
#include <Ecore_Input.h>
#include <Ecore_Input_Evas.h>
#include <Ecore_Wayland.h>
#include <Ecore_Wl2.h>
#include <Ecore_Evas.h>
#include "ecore_evas_private.h"
@ -29,7 +30,8 @@ typedef struct _Ecore_Evas_Engine_Wl_Data Ecore_Evas_Engine_Wl_Data;
struct _Ecore_Evas_Engine_Wl_Data
{
Ecore_Wl_Window *parent, *win;
Ecore_Wl2_Display *display;
Ecore_Wl2_Window *parent, *win;
Evas_Object *frame;
int fx, fy, fw, fh;
#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL

View File

@ -118,7 +118,8 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
EAPI Ecore_Evas *
ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame)
{
Ecore_Wl_Window *p = NULL;
Ecore_Wl2_Display *ewd;
Ecore_Wl2_Window *p = NULL;
Evas_Engine_Info_Wayland_Shm *einfo;
Ecore_Evas_Engine_Wl_Data *wdata;
Ecore_Evas_Interface_Wayland *iface;
@ -134,9 +135,37 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
return NULL;
}
if (!ecore_wl_init(disp_name))
if (!ecore_wl2_init())
{
ERR("Failed to initialize Ecore_Wayland");
ERR("Failed to initialize Ecore_Wl2");
return NULL;
}
ewd = ecore_wl2_display_connect(disp_name);
if (!ewd)
{
ERR("Failed to connect to Wayland Display %s", disp_name);
return NULL;
}
ewd = ecore_wl2_display_connect(disp_name);
if (!ewd)
{
ERR("Failed to connect to Wayland Display %s", disp_name);
return NULL;
}
ewd = ecore_wl2_display_connect(disp_name);
if (!ewd)
{
ERR("Failed to connect to Wayland Display %s", disp_name);
return NULL;
}
ewd = ecore_wl2_display_connect(disp_name);
if (!ewd)
{
ERR("Failed to connect to Wayland Display %s", disp_name);
return NULL;
}
@ -202,15 +231,14 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
if (parent)
{
p = ecore_wl_window_find(parent);
ee->alpha = ecore_wl_window_alpha_get(p);
p = ecore_wl2_display_window_find(ewd, parent);
ee->alpha = ecore_wl2_window_alpha_get(p);
}
wdata->parent = p;
wdata->win =
ecore_wl_window_new(p, x, y, w + fw, h + fh,
ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
ee->prop.window = ecore_wl_window_id_get(wdata->win);
wdata->display = ewd;
wdata->win = ecore_wl2_window_new(ewd, p, x, y, w + fw, h + fh);
ee->prop.window = ecore_wl2_window_id_get(wdata->win);
ee->evas = evas_new();
evas_data_attach_set(ee->evas, ee);
@ -231,11 +259,11 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
{
einfo->info.wl_disp = ecore_wl_display_get();
einfo->info.wl_shm = ecore_wl_shm_get();
einfo->info.wl_disp = ecore_wl2_display_get(ewd);
einfo->info.wl_shm = ecore_wl2_display_shm_get(ewd);
einfo->info.destination_alpha = EINA_TRUE;
einfo->info.rotation = ee->rotation;
einfo->info.wl_surface = ecore_wl_window_surface_create(wdata->win);
einfo->info.wl_surface = ecore_wl2_window_surface_get(wdata->win);
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
{
ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
@ -248,7 +276,7 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
goto err;
}
/* ecore_wl_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); */
/* ecore_wl2_display_animator_source_set(ewd, ECORE_ANIMATOR_SOURCE_CUSTOM); */
ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free);
@ -278,7 +306,8 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
return NULL;
ee_err:
ecore_wl_shutdown();
ecore_wl2_display_disconnect(ewd);
ecore_wl2_shutdown();
return NULL;
}
@ -330,15 +359,17 @@ _ecore_evas_wl_show(Ecore_Evas *ee)
if (wdata->win)
{
ecore_wl_window_show(wdata->win);
ecore_wl_window_alpha_set(wdata->win, ee->alpha);
ecore_wl2_window_show(wdata->win);
ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
/* TODO: Needed ?? */
/* ecore_wl_window_update_size(wdata->win, ee->w + fw, ee->h + fh); */
einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
if (einfo)
{
struct wl_surface *surf;
surf = ecore_wl_window_surface_get(wdata->win);
surf = ecore_wl2_window_surface_get(wdata->win);
if ((!einfo->info.wl_surface) || (einfo->info.wl_surface != surf))
{
einfo->info.wl_surface = surf;
@ -385,7 +416,7 @@ _ecore_evas_wl_hide(Ecore_Evas *ee)
}
if (wdata->win)
ecore_wl_window_hide(wdata->win);
ecore_wl2_window_hide(wdata->win);
if (ee->prop.override)
{
@ -415,7 +446,7 @@ _ecore_evas_wayland_shm_alpha_do(Ecore_Evas *ee, int alpha)
ee->alpha = alpha;
wdata = ee->engine.data;
if (wdata->win) ecore_wl_window_alpha_set(wdata->win, ee->alpha);
if (wdata->win) ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
@ -455,7 +486,7 @@ _ecore_evas_wayland_shm_transparent_do(Ecore_Evas *ee, int transparent)
wdata = ee->engine.data;
if (wdata->win)
ecore_wl_window_transparent_set(wdata->win, ee->transparent);
ecore_wl2_window_transparent_set(wdata->win, ee->transparent);
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
@ -494,9 +525,9 @@ _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location)
_ecore_evas_wayland_shm_resize_edge_set(ee, location);
if (ECORE_EVAS_PORTRAIT(ee))
ecore_wl_window_resize(wdata->win, ee->w, ee->h, location);
ecore_wl2_window_resize(wdata->win, ee->w, ee->h, location);
else
ecore_wl_window_resize(wdata->win, ee->w, ee->h, location);
ecore_wl2_window_resize(wdata->win, ee->w, ee->h, location);
}
}

View File

@ -27,7 +27,7 @@
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Ecore_Input.h>
#include <Ecore_Wayland.h>
#include <Ecore_Wl2.h>
#include "wayland_imcontext.h"
@ -38,9 +38,9 @@ struct _WaylandIMContext
struct wl_text_input_manager *text_input_manager;
struct wl_text_input *text_input;
Ecore_Wl_Window *window;
Ecore_Wl_Input *input;
Evas *canvas;
Ecore_Wl2_Window *window;
Ecore_Wl2_Input *input;
Evas *canvas;
char *preedit_text;
char *preedit_commit;
@ -292,17 +292,17 @@ static Eina_Bool
show_input_panel(Ecore_IMF_Context *ctx)
{
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
Ecore_Wl_Input *input;
Ecore_Wl2_Input *input;
struct wl_seat *seat;
if ((!imcontext) || (!imcontext->window) || (!imcontext->text_input))
return EINA_FALSE;
input = ecore_wl_window_keyboard_get(imcontext->window);
input = ecore_wl2_window_input_get(imcontext->window);
if (!input)
return EINA_FALSE;
seat = ecore_wl_input_seat_get(input);
seat = ecore_wl2_input_seat_get(input);
if (!seat)
return EINA_FALSE;
@ -312,7 +312,7 @@ show_input_panel(Ecore_IMF_Context *ctx)
{
wl_text_input_show_input_panel(imcontext->text_input);
wl_text_input_activate(imcontext->text_input, seat,
ecore_wl_window_surface_get(imcontext->window));
ecore_wl2_window_surface_get(imcontext->window));
wl_text_input_set_content_type(imcontext->text_input,
imcontext->content_hint,
@ -531,8 +531,8 @@ text_input_keysym(void *data,
strcpy((char *)e->key, key);
strcpy((char *)e->string, string);
e->window = ecore_wl_window_id_get(imcontext->window);
e->event_window = ecore_wl_window_id_get(imcontext->window);
e->window = ecore_wl2_window_id_get(imcontext->window);
e->event_window = ecore_wl2_window_id_get(imcontext->window);
e->timestamp = time;
e->modifiers = 0;
@ -692,7 +692,7 @@ wayland_im_context_focus_out(Ecore_IMF_Context *ctx)
wl_text_input_hide_input_panel(imcontext->text_input);
wl_text_input_deactivate(imcontext->text_input,
ecore_wl_input_seat_get(imcontext->input));
ecore_wl2_input_seat_get(imcontext->input));
}
imcontext->input = NULL;
@ -776,7 +776,10 @@ wayland_im_context_client_window_set(Ecore_IMF_Context *ctx,
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "client window set (window: %p)", window);
if (window != NULL)
imcontext->window = ecore_wl_window_find((Ecore_Window)window);
{
imcontext->window =
ecore_wl2_display_window_find(ewd, (Ecore_Window)window);
}
}
EAPI void

View File

@ -24,8 +24,12 @@
#define __WAYLAND_IM_CONTEXT_H_
#include <Ecore_IMF.h>
#include <Ecore_Wl2.h>
#include "text-client-protocol.h"
extern Ecore_Wl2_Display *ewd;
typedef struct _WaylandIMContext WaylandIMContext;
EAPI void wayland_im_context_add (Ecore_IMF_Context *ctx);

View File

@ -26,13 +26,14 @@
#include <Ecore.h>
#include <Ecore_IMF.h>
#include <Ecore_Wayland.h>
#include <Ecore_Wl2.h>
#include <stdio.h>
#include "wayland_imcontext.h"
#include "text-client-protocol.h"
int _ecore_imf_wayland_log_dom = -1;
Ecore_Wl2_Display *ewd;
static const Ecore_IMF_Context_Info wayland_im_info =
{
@ -100,27 +101,28 @@ im_module_create()
if (!text_input_manager)
{
Ecore_Wl_Global *global;
struct wl_registry *registry;
Eina_Inlist *globals;
Eina_Iterator *itr;
if (!(registry = ecore_wl_registry_get()))
return NULL;
if (!(globals = ecore_wl_globals_get()))
return NULL;
EINA_INLIST_FOREACH(globals, global)
itr = ecore_wl2_display_globals_get(ewd);
if (itr)
{
if (!strcmp(global->interface, "wl_text_input_manager"))
Ecore_Wl2_Global *global;
struct wl_registry *registry;
registry = ecore_wl2_display_registry_get(ewd);
EINA_ITERATOR_FOREACH(itr, global)
{
text_input_manager =
wl_registry_bind(registry, global->id,
&wl_text_input_manager_interface, 1);
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
"bound wl_text_input_manager interface");
break;
if (!strcmp(global->interface, "wl_text_input_manager"))
{
text_input_manager =
wl_registry_bind(registry, global->id,
&wl_text_input_manager_interface, 1);
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
"bound wl_text_input_manager interface");
break;
}
}
eina_iterator_free(itr);
}
if (!text_input_manager)
@ -156,21 +158,29 @@ im_module_init(void)
if (strcmp(s, "wl")) return EINA_FALSE;
}
if (!ecore_wl_init(NULL))
if (!ecore_wl2_init())
return EINA_FALSE;
ewd = ecore_wl2_display_connect(NULL);
if (!ewd) goto err;
ecore_imf_module_register(&wayland_im_info, im_module_create,
im_module_exit);
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "im module initalized");
return EINA_TRUE;
err:
ecore_wl2_shutdown();
return EINA_FALSE;
}
static void
im_module_shutdown(void)
{
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "im module shutdown");
ecore_wl_shutdown();
ecore_wl2_display_disconnect(ewd);
ecore_wl2_shutdown();
}
EINA_MODULE_INIT(im_module_init);