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:
commit
55c6441f6c
|
@ -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
|
||||
|
|
41
configure.ac
41
configure.ac
|
@ -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
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
/ecore-psl1ght.pc
|
||||
/ecore-sdl.pc
|
||||
/ecore-wayland.pc
|
||||
/ecore-wl2.pc
|
||||
/ecore-win32.pc
|
||||
/ecore-x.pc
|
||||
/ecore.pc
|
||||
|
|
|
@ -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@
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -67,6 +67,4 @@ Eina_Bool _ecore_cocoa_window_init(void);
|
|||
|
||||
Eina_Bool _ecore_cocoa_feed_events(void *anEvent);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
};
|
||||
|
||||
|
|
|
@ -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 =
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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,
|
||||
};
|
|
@ -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
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue