forked from enlightenment/efl
wayland: implement session recovery
add support for reconnecting wayland applications if the compositor dies disconnect -> destroy gl ctx + image textures -> block rendering -> reconnect -> create gl ctx -> create image textures -> unblock rendering -> sprinkle special seasoning on top -> just like ma used to make #SamsungFeatures @feature
This commit is contained in:
parent
0231800b60
commit
9d5caf00b6
|
@ -3331,7 +3331,7 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [efl])
|
||||||
EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [eina])
|
EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [eina])
|
||||||
|
|
||||||
EFL_DEPEND_PKG([ECORE_WL2], [WAYLAND],
|
EFL_DEPEND_PKG([ECORE_WL2], [WAYLAND],
|
||||||
[wayland-server >= 1.10.0 wayland-client >= 1.10.0 wayland-cursor >= 1.10.0 xkbcommon >= 0.5.0 uuid])
|
[wayland-server >= 1.10.0 wayland-client >= 1.10.0 wayland-cursor >= 1.10.0 xkbcommon >= 0.5.0])
|
||||||
|
|
||||||
EFL_EVAL_PKGS([ECORE_WL2])
|
EFL_EVAL_PKGS([ECORE_WL2])
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ installed_ecorewl2mainheadersdir = $(includedir)/ecore-wl2-@VMAJ@
|
||||||
dist_installed_ecorewl2mainheaders_DATA = lib/ecore_wl2/Ecore_Wl2.h
|
dist_installed_ecorewl2mainheaders_DATA = lib/ecore_wl2/Ecore_Wl2.h
|
||||||
|
|
||||||
lib_ecore_wl2_libecore_wl2_la_SOURCES = \
|
lib_ecore_wl2_libecore_wl2_la_SOURCES = \
|
||||||
lib/ecore_wl2/session-recovery-client-protocol.h \
|
lib/ecore_wl2/session-recovery.h \
|
||||||
lib/ecore_wl2/session-recovery-protocol.c \
|
lib/ecore_wl2/session-recovery.c \
|
||||||
lib/ecore_wl2/subsurface-client-protocol.h \
|
lib/ecore_wl2/subsurface-client-protocol.h \
|
||||||
lib/ecore_wl2/subsurface-protocol.c \
|
lib/ecore_wl2/subsurface-protocol.c \
|
||||||
lib/ecore_wl2/xdg-shell-client-protocol.h \
|
lib/ecore_wl2/xdg-shell-client-protocol.h \
|
||||||
|
|
|
@ -53,6 +53,13 @@ typedef enum
|
||||||
ECORE_WL2_DRAG_ACTION_ASK = 4,
|
ECORE_WL2_DRAG_ACTION_ASK = 4,
|
||||||
} Ecore_Wl2_Drag_Action;
|
} Ecore_Wl2_Drag_Action;
|
||||||
|
|
||||||
|
struct _Ecore_Wl2_Event_Connection
|
||||||
|
{
|
||||||
|
Ecore_Wl2_Display *display;
|
||||||
|
};
|
||||||
|
typedef struct _Ecore_Wl2_Event_Connection Ecore_Wl2_Event_Connect;
|
||||||
|
typedef struct _Ecore_Wl2_Event_Connection Ecore_Wl2_Event_Disconnect;
|
||||||
|
|
||||||
typedef struct _Ecore_Wl2_Global
|
typedef struct _Ecore_Wl2_Global
|
||||||
{
|
{
|
||||||
Eina_Stringshare *interface;
|
Eina_Stringshare *interface;
|
||||||
|
@ -175,6 +182,8 @@ typedef enum _Ecore_Wl2_Window_Type
|
||||||
typedef void (*Ecore_Wl2_Bind_Cb)(struct wl_client *client, void *data, uint32_t version, uint32_t id);
|
typedef void (*Ecore_Wl2_Bind_Cb)(struct wl_client *client, void *data, uint32_t version, uint32_t id);
|
||||||
typedef void (*Ecore_Wl2_Unbind_Cb)(struct wl_resource *resource);
|
typedef void (*Ecore_Wl2_Unbind_Cb)(struct wl_resource *resource);
|
||||||
|
|
||||||
|
EAPI extern int ECORE_WL2_EVENT_DISCONNECT; /** @since 1.18 */
|
||||||
|
EAPI extern int ECORE_WL2_EVENT_CONNECT; /** @since 1.18 */
|
||||||
EAPI extern int ECORE_WL2_EVENT_GLOBAL_ADDED; /** @since 1.17 */
|
EAPI extern int ECORE_WL2_EVENT_GLOBAL_ADDED; /** @since 1.17 */
|
||||||
EAPI extern int ECORE_WL2_EVENT_GLOBAL_REMOVED; /** @since 1.17 */
|
EAPI extern int ECORE_WL2_EVENT_GLOBAL_REMOVED; /** @since 1.17 */
|
||||||
EAPI extern int ECORE_WL2_EVENT_FOCUS_IN; /** @since 1.17 */
|
EAPI extern int ECORE_WL2_EVENT_FOCUS_IN; /** @since 1.17 */
|
||||||
|
|
|
@ -8,9 +8,12 @@
|
||||||
static int _ecore_wl2_init_count = 0;
|
static int _ecore_wl2_init_count = 0;
|
||||||
|
|
||||||
/* external variables */
|
/* external variables */
|
||||||
|
Eina_Bool no_session_recovery;
|
||||||
int _ecore_wl2_log_dom = -1;
|
int _ecore_wl2_log_dom = -1;
|
||||||
|
|
||||||
/* public API variables */
|
/* public API variables */
|
||||||
|
EAPI int ECORE_WL2_EVENT_CONNECT = 0;
|
||||||
|
EAPI int ECORE_WL2_EVENT_DISCONNECT = 0;
|
||||||
EAPI int ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
|
EAPI int ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
|
||||||
EAPI int ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
|
EAPI int ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
|
||||||
EAPI int ECORE_WL2_EVENT_FOCUS_IN = 0;
|
EAPI int ECORE_WL2_EVENT_FOCUS_IN = 0;
|
||||||
|
@ -67,6 +70,8 @@ ecore_wl2_init(void)
|
||||||
/* handle creating new Ecore_Wl2 event types */
|
/* handle creating new Ecore_Wl2 event types */
|
||||||
if (!ECORE_WL2_EVENT_GLOBAL_ADDED)
|
if (!ECORE_WL2_EVENT_GLOBAL_ADDED)
|
||||||
{
|
{
|
||||||
|
ECORE_WL2_EVENT_CONNECT = ecore_event_type_new();
|
||||||
|
ECORE_WL2_EVENT_DISCONNECT = ecore_event_type_new();
|
||||||
ECORE_WL2_EVENT_GLOBAL_ADDED = ecore_event_type_new();
|
ECORE_WL2_EVENT_GLOBAL_ADDED = ecore_event_type_new();
|
||||||
ECORE_WL2_EVENT_GLOBAL_REMOVED = 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_IN = ecore_event_type_new();
|
||||||
|
@ -87,6 +92,7 @@ ecore_wl2_init(void)
|
||||||
_ecore_wl2_event_window_www = ecore_event_type_new();
|
_ecore_wl2_event_window_www = ecore_event_type_new();
|
||||||
_ecore_wl2_event_window_www_drag = ecore_event_type_new();
|
_ecore_wl2_event_window_www_drag = ecore_event_type_new();
|
||||||
}
|
}
|
||||||
|
no_session_recovery = !!getenv("EFL_NO_WAYLAND_SESSION_RECOVERY");
|
||||||
|
|
||||||
return _ecore_wl2_init_count;
|
return _ecore_wl2_init_count;
|
||||||
|
|
||||||
|
@ -114,6 +120,8 @@ ecore_wl2_shutdown(void)
|
||||||
if (--_ecore_wl2_init_count != 0) return _ecore_wl2_init_count;
|
if (--_ecore_wl2_init_count != 0) return _ecore_wl2_init_count;
|
||||||
|
|
||||||
/* reset events */
|
/* reset events */
|
||||||
|
ECORE_WL2_EVENT_CONNECT = 0;
|
||||||
|
ECORE_WL2_EVENT_DISCONNECT = 0;
|
||||||
ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
|
ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
|
||||||
ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
|
ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
|
||||||
ECORE_WL2_EVENT_FOCUS_IN = 0;
|
ECORE_WL2_EVENT_FOCUS_IN = 0;
|
||||||
|
|
|
@ -8,10 +8,24 @@
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
static Eina_Bool _fatal_error = EINA_FALSE;
|
|
||||||
static Eina_Hash *_server_displays = NULL;
|
static Eina_Hash *_server_displays = NULL;
|
||||||
static Eina_Hash *_client_displays = NULL;
|
static Eina_Hash *_client_displays = NULL;
|
||||||
|
|
||||||
|
static Eina_Bool _cb_connect_idle(void *data);
|
||||||
|
static Eina_Bool _cb_connect_data(void *data, Ecore_Fd_Handler *hdl);
|
||||||
|
static Eina_Bool _ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync);
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ecore_wl2_display_event(Ecore_Wl2_Display *ewd, int event)
|
||||||
|
{
|
||||||
|
Ecore_Wl2_Event_Connect *ev;
|
||||||
|
|
||||||
|
ev = calloc(1, sizeof(Ecore_Wl2_Event_Connect));
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(ev);
|
||||||
|
ev->display = ewd;
|
||||||
|
ecore_event_add(event, ev, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ecore_wl2_display_signal_exit(void)
|
_ecore_wl2_display_signal_exit(void)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +161,7 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const
|
||||||
_ecore_wl2_window_www_surface_init(window);
|
_ecore_wl2_window_www_surface_init(window);
|
||||||
}
|
}
|
||||||
else if ((!strcmp(interface, "zwp_e_session_recovery")) &&
|
else if ((!strcmp(interface, "zwp_e_session_recovery")) &&
|
||||||
(getenv("EFL_WAYLAND_SESSION_RECOVERY")))
|
(!no_session_recovery))
|
||||||
{
|
{
|
||||||
ewd->wl.session_recovery =
|
ewd->wl.session_recovery =
|
||||||
wl_registry_bind(registry, id,
|
wl_registry_bind(registry, id,
|
||||||
|
@ -210,25 +224,11 @@ static const struct wl_registry_listener _registry_listener =
|
||||||
};
|
};
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_cb_create_data(void *data, Ecore_Fd_Handler *hdl)
|
_cb_create_data(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Display *ewd;
|
Ecore_Wl2_Display *ewd = data;
|
||||||
struct wl_event_loop *loop;
|
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);
|
loop = wl_display_get_event_loop(ewd->wl.display);
|
||||||
wl_event_loop_dispatch(loop, 0);
|
wl_event_loop_dispatch(loop, 0);
|
||||||
|
|
||||||
|
@ -240,44 +240,83 @@ _cb_create_data(void *data, Ecore_Fd_Handler *hdl)
|
||||||
static void
|
static void
|
||||||
_cb_create_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
_cb_create_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Display *ewd;
|
Ecore_Wl2_Display *ewd = data;
|
||||||
|
|
||||||
ewd = data;
|
|
||||||
wl_display_flush_clients(ewd->wl.display);
|
wl_display_flush_clients(ewd->wl.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_recovery_timer(Ecore_Wl2_Display *ewd)
|
||||||
|
{
|
||||||
|
if (!_ecore_wl2_display_connect(ewd, 1))
|
||||||
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
ewd->recovery_timer = NULL;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_recovery_timer_add(Ecore_Wl2_Display *ewd)
|
||||||
|
{
|
||||||
|
Eina_Inlist *tmp;
|
||||||
|
Ecore_Wl2_Output *output;
|
||||||
|
Ecore_Wl2_Input *input;
|
||||||
|
Ecore_Wl2_Window *window;
|
||||||
|
|
||||||
|
eina_hash_free_buckets(ewd->globals);
|
||||||
|
ecore_idle_enterer_del(ewd->idle_enterer);
|
||||||
|
ewd->idle_enterer = NULL;
|
||||||
|
|
||||||
|
ecore_main_fd_handler_del(ewd->fd_hdl);
|
||||||
|
ewd->fd_hdl = NULL;
|
||||||
|
|
||||||
|
if (ewd->wl.session_recovery)
|
||||||
|
zwp_e_session_recovery_destroy(ewd->wl.session_recovery);
|
||||||
|
if (ewd->wl.www) www_destroy(ewd->wl.www);
|
||||||
|
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);
|
||||||
|
|
||||||
|
memset(&ewd->wl, 0, sizeof(ewd->wl));
|
||||||
|
EINA_INLIST_FOREACH_SAFE(ewd->inputs, tmp, input)
|
||||||
|
_ecore_wl2_input_del(input);
|
||||||
|
|
||||||
|
EINA_INLIST_FOREACH_SAFE(ewd->outputs, tmp, output)
|
||||||
|
_ecore_wl2_output_del(output);
|
||||||
|
|
||||||
|
EINA_INLIST_FOREACH_SAFE(ewd->windows, tmp, window)
|
||||||
|
ecore_wl2_window_hide(window);
|
||||||
|
|
||||||
|
ewd->recovery_timer = ecore_timer_add(0.5, (Ecore_Task_Cb)_recovery_timer, ewd);
|
||||||
|
_ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_DISCONNECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_begin_recovery_maybe(Ecore_Wl2_Display *ewd)
|
||||||
|
{
|
||||||
|
ERR("Wayland Socket Error: %s", strerror(errno));
|
||||||
|
if (ewd->wl.session_recovery)// && (errno == EPIPE))
|
||||||
|
_recovery_timer_add(ewd);
|
||||||
|
else
|
||||||
|
_ecore_wl2_display_signal_exit();
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
|
_cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Display *ewd;
|
Ecore_Wl2_Display *ewd = data;
|
||||||
int ret = 0;
|
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))
|
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
|
||||||
{
|
{
|
||||||
ret = wl_display_dispatch(ewd->wl.display);
|
ret = wl_display_dispatch(ewd->wl.display);
|
||||||
if ((ret < 0) && (errno != EAGAIN))
|
if ((ret < 0) && (errno != EAGAIN)) goto err;
|
||||||
{
|
|
||||||
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))
|
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
|
||||||
|
@ -286,18 +325,16 @@ _cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
|
ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
|
||||||
|
|
||||||
if ((ret < 0) && (errno != EAGAIN))
|
if ((ret < 0) && (errno != EAGAIN)) goto err;
|
||||||
{
|
|
||||||
ERR("Received Fatal Error on Wayland Display");
|
|
||||||
|
|
||||||
_fatal_error = EINA_TRUE;
|
|
||||||
_ecore_wl2_display_signal_exit();
|
|
||||||
|
|
||||||
return ECORE_CALLBACK_CANCEL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ECORE_CALLBACK_RENEW;
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
|
||||||
|
err:
|
||||||
|
ewd->fd_hdl = NULL;
|
||||||
|
_begin_recovery_maybe(ewd);
|
||||||
|
|
||||||
|
return ECORE_CALLBACK_CANCEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -315,14 +352,9 @@ _cb_globals_hash_del(void *data)
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_cb_connect_idle(void *data)
|
_cb_connect_idle(void *data)
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Display *ewd;
|
Ecore_Wl2_Display *ewd = data;
|
||||||
int ret = 0;
|
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);
|
ret = wl_display_get_error(ewd->wl.display);
|
||||||
if (ret < 0) goto err;
|
if (ret < 0) goto err;
|
||||||
|
|
||||||
|
@ -339,10 +371,8 @@ _cb_connect_idle(void *data)
|
||||||
err:
|
err:
|
||||||
if ((ret < 0) && (errno != EAGAIN))
|
if ((ret < 0) && (errno != EAGAIN))
|
||||||
{
|
{
|
||||||
ERR("Wayland Socket Error: %s", strerror(errno));
|
ewd->idle_enterer = NULL;
|
||||||
|
_begin_recovery_maybe(ewd);
|
||||||
_fatal_error = EINA_TRUE;
|
|
||||||
_ecore_wl2_display_signal_exit();
|
|
||||||
|
|
||||||
return ECORE_CALLBACK_CANCEL;
|
return ECORE_CALLBACK_CANCEL;
|
||||||
}
|
}
|
||||||
|
@ -373,6 +403,56 @@ static const struct wl_callback_listener _sync_listener =
|
||||||
_cb_sync_done
|
_cb_sync_done
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync)
|
||||||
|
{
|
||||||
|
struct wl_callback *cb;
|
||||||
|
/* 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", ewd->name);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ewd->wl.registry = wl_display_get_registry(ewd->wl.display);
|
||||||
|
wl_registry_add_listener(ewd->wl.registry, &_registry_listener, ewd);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = wl_display_dispatch(ewd->wl.display);
|
||||||
|
if ((ret < 0) && (errno != EAGAIN))
|
||||||
|
{
|
||||||
|
ERR("Received Fatal Error on Wayland Display");
|
||||||
|
|
||||||
|
wl_registry_destroy(ewd->wl.registry);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ewd->fd_hdl =
|
||||||
|
ecore_main_fd_handler_add(wl_display_get_fd(ewd->wl.display),
|
||||||
|
ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR,
|
||||||
|
_cb_connect_data, ewd, NULL, NULL);
|
||||||
|
|
||||||
|
ewd->idle_enterer = ecore_idle_enterer_add(_cb_connect_idle, ewd);
|
||||||
|
|
||||||
|
_ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_CONNECT);
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
|
_ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
|
||||||
{
|
{
|
||||||
|
@ -545,8 +625,6 @@ EAPI Ecore_Wl2_Display *
|
||||||
ecore_wl2_display_connect(const char *name)
|
ecore_wl2_display_connect(const char *name)
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Display *ewd;
|
Ecore_Wl2_Display *ewd;
|
||||||
Eina_Bool sync = EINA_TRUE;
|
|
||||||
struct wl_callback *cb;
|
|
||||||
const char *n;
|
const char *n;
|
||||||
Eina_Bool hash_create = !_client_displays;
|
Eina_Bool hash_create = !_client_displays;
|
||||||
|
|
||||||
|
@ -594,56 +672,13 @@ ecore_wl2_display_connect(const char *name)
|
||||||
|
|
||||||
ewd->globals = eina_hash_int32_new(_cb_globals_hash_del);
|
ewd->globals = eina_hash_int32_new(_cb_globals_hash_del);
|
||||||
|
|
||||||
/* try to connect to wayland display with this name */
|
/* check server display hash and match on pid. If match, skip sync */
|
||||||
ewd->wl.display = wl_display_connect(ewd->name);
|
if (!_ecore_wl2_display_connect(ewd, _ecore_wl2_display_sync_get()))
|
||||||
if (!ewd->wl.display)
|
goto connect_err;
|
||||||
{
|
|
||||||
ERR("Could not connect to display %s", 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_WRITE | 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);
|
ewd->xkb_context = xkb_context_new(0);
|
||||||
if (!ewd->xkb_context) goto context_err;
|
if (!ewd->xkb_context) goto context_err;
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = wl_display_dispatch(ewd->wl.display);
|
|
||||||
if ((ret < 0) && (errno != EAGAIN))
|
|
||||||
{
|
|
||||||
ERR("Received Fatal Error on Wayland Display");
|
|
||||||
|
|
||||||
_fatal_error = EINA_TRUE;
|
|
||||||
_ecore_wl2_display_signal_exit();
|
|
||||||
|
|
||||||
goto context_err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add this new client display to hash */
|
/* add this new client display to hash */
|
||||||
eina_hash_add(_client_displays, ewd->name, ewd);
|
eina_hash_add(_client_displays, ewd->name, ewd);
|
||||||
|
|
||||||
|
@ -703,6 +738,7 @@ ecore_wl2_display_destroy(Ecore_Wl2_Display *display)
|
||||||
|
|
||||||
/* remove this client display from hash */
|
/* remove this client display from hash */
|
||||||
eina_hash_del_by_key(_server_displays, display->name);
|
eina_hash_del_by_key(_server_displays, display->name);
|
||||||
|
ecore_timer_del(display->recovery_timer);
|
||||||
|
|
||||||
free(display->name);
|
free(display->name);
|
||||||
free(display);
|
free(display);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
# define _ECORE_WL2_PRIVATE_H
|
# define _ECORE_WL2_PRIVATE_H
|
||||||
|
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <uuid/uuid.h>
|
|
||||||
# include "Ecore_Wl2.h"
|
# include "Ecore_Wl2.h"
|
||||||
# include "Ecore_Input.h"
|
# include "Ecore_Input.h"
|
||||||
# include "www-protocol.h"
|
# include "www-protocol.h"
|
||||||
|
@ -16,9 +15,10 @@
|
||||||
# include "xdg-shell-client-protocol.h"
|
# include "xdg-shell-client-protocol.h"
|
||||||
# define XDG_VERSION 5
|
# define XDG_VERSION 5
|
||||||
|
|
||||||
# include "session-recovery-client-protocol.h"
|
# include "session-recovery.h"
|
||||||
|
|
||||||
extern int _ecore_wl2_log_dom;
|
extern int _ecore_wl2_log_dom;
|
||||||
|
extern Eina_Bool no_session_recovery;
|
||||||
|
|
||||||
# ifdef EAPI
|
# ifdef EAPI
|
||||||
# undef EAPI
|
# undef EAPI
|
||||||
|
@ -95,6 +95,7 @@ struct _Ecore_Wl2_Display
|
||||||
Ecore_Fd_Handler *fd_hdl;
|
Ecore_Fd_Handler *fd_hdl;
|
||||||
|
|
||||||
Eina_Hash *globals;
|
Eina_Hash *globals;
|
||||||
|
Ecore_Timer *recovery_timer;
|
||||||
|
|
||||||
Eina_Inlist *windows;
|
Eina_Inlist *windows;
|
||||||
Eina_Inlist *outputs;
|
Eina_Inlist *outputs;
|
||||||
|
@ -141,7 +142,7 @@ struct _Ecore_Wl2_Window
|
||||||
struct xdg_popup *xdg_popup;
|
struct xdg_popup *xdg_popup;
|
||||||
struct www_surface *www_surface;
|
struct www_surface *www_surface;
|
||||||
|
|
||||||
uuid_t uuid;
|
Eina_Stringshare *uuid;
|
||||||
|
|
||||||
uint32_t configure_serial;
|
uint32_t configure_serial;
|
||||||
void (*configure_ack)(struct xdg_surface *surface, uint32_t serial);
|
void (*configure_ack)(struct xdg_surface *surface, uint32_t serial);
|
||||||
|
@ -445,6 +446,7 @@ 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_selection(Ecore_Wl2_Input *input, struct wl_data_offer *offer);
|
||||||
void _ecore_wl2_dnd_del(Ecore_Wl2_Dnd_Source *source);
|
void _ecore_wl2_dnd_del(Ecore_Wl2_Dnd_Source *source);
|
||||||
|
|
||||||
|
void _ecore_wl2_subsurf_unmap(Ecore_Wl2_Subsurface *subsurf);
|
||||||
void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf);
|
void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf);
|
||||||
|
|
||||||
void _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window);
|
void _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window);
|
||||||
|
|
|
@ -5,22 +5,16 @@
|
||||||
#include "ecore_wl2_private.h"
|
#include "ecore_wl2_private.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_session_recovery_uuid(void *data, struct zwp_e_session_recovery *session_recovery, const char *uuid)
|
_session_recovery_create_uuid(void *data, struct zwp_e_session_recovery *session_recovery EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, const char *uuid)
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Window *win;
|
Ecore_Wl2_Window *win = data;
|
||||||
char str[37];
|
|
||||||
|
|
||||||
win = data;
|
eina_stringshare_replace(&win->uuid, uuid);
|
||||||
if (!win) return;
|
|
||||||
if (!session_recovery) return;
|
|
||||||
uuid_parse(uuid, win->uuid);
|
|
||||||
uuid_unparse(win->uuid, str);
|
|
||||||
DBG("UUID event received from compositor with UUID: %s\n", str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct zwp_e_session_recovery_listener _session_listener =
|
static const struct zwp_e_session_recovery_listener _session_listener =
|
||||||
{
|
{
|
||||||
_session_recovery_uuid,
|
_session_recovery_create_uuid,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -300,6 +294,22 @@ _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window)
|
||||||
|
|
||||||
window->configure_ack = xdg_surface_ack_configure;
|
window->configure_ack = xdg_surface_ack_configure;
|
||||||
_ecore_wl2_window_type_set(window);
|
_ecore_wl2_window_type_set(window);
|
||||||
|
if (window->display->wl.session_recovery)
|
||||||
|
{
|
||||||
|
if (window->uuid)
|
||||||
|
{
|
||||||
|
zwp_e_session_recovery_set_uuid(window->display->wl.session_recovery,
|
||||||
|
window->surface, window->uuid);
|
||||||
|
xdg_surface_set_window_geometry(window->xdg_surface,
|
||||||
|
window->geometry.x, window->geometry.y,
|
||||||
|
window->geometry.w, window->geometry.h);
|
||||||
|
ecore_wl2_window_opaque_region_set(window,
|
||||||
|
window->opaque.x, window->opaque.y,
|
||||||
|
window->opaque.w, window->opaque.h);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
zwp_e_session_recovery_get_uuid(window->display->wl.session_recovery, window->surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ((window->display->wl.wl_shell) && (!window->wl_shell_surface))
|
else if ((window->display->wl.wl_shell) && (!window->wl_shell_surface))
|
||||||
{
|
{
|
||||||
|
@ -380,19 +390,9 @@ ecore_wl2_window_surface_get(Ecore_Wl2_Window *window)
|
||||||
window->surface_id =
|
window->surface_id =
|
||||||
wl_proxy_get_id((struct wl_proxy *)window->surface);
|
wl_proxy_get_id((struct wl_proxy *)window->surface);
|
||||||
|
|
||||||
if ((window->display->wl.session_recovery) &&
|
if (window->display->wl.session_recovery)
|
||||||
(getenv("EFL_WAYLAND_SESSION_RECOVERY")))
|
zwp_e_session_recovery_add_listener(window->display->wl.session_recovery,
|
||||||
{
|
&_session_listener, window);
|
||||||
char uuid[37];
|
|
||||||
|
|
||||||
zwp_e_session_recovery_add_listener(window->display->wl.session_recovery,
|
|
||||||
&_session_listener, window);
|
|
||||||
if (!uuid_is_null(window->uuid))
|
|
||||||
{
|
|
||||||
uuid_unparse(window->uuid, uuid);
|
|
||||||
zwp_e_session_recovery_provide_uuid(window->display->wl.session_recovery, uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return window->surface;
|
return window->surface;
|
||||||
|
@ -432,6 +432,8 @@ ecore_wl2_window_show(Ecore_Wl2_Window *window)
|
||||||
EAPI void
|
EAPI void
|
||||||
ecore_wl2_window_hide(Ecore_Wl2_Window *window)
|
ecore_wl2_window_hide(Ecore_Wl2_Window *window)
|
||||||
{
|
{
|
||||||
|
Ecore_Wl2_Subsurface *subsurf;
|
||||||
|
Eina_Inlist *tmp;
|
||||||
EINA_SAFETY_ON_NULL_RETURN(window);
|
EINA_SAFETY_ON_NULL_RETURN(window);
|
||||||
|
|
||||||
if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface);
|
if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface);
|
||||||
|
@ -448,8 +450,18 @@ ecore_wl2_window_hide(Ecore_Wl2_Window *window)
|
||||||
www_surface_destroy(window->www_surface);
|
www_surface_destroy(window->www_surface);
|
||||||
window->www_surface = NULL;
|
window->www_surface = NULL;
|
||||||
|
|
||||||
|
EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp, subsurf)
|
||||||
|
_ecore_wl2_subsurf_unmap(subsurf);
|
||||||
|
|
||||||
|
if (window->uuid && window->surface && window->display->wl.session_recovery)
|
||||||
|
zwp_e_session_recovery_destroy_uuid(window->display->wl.session_recovery,
|
||||||
|
window->surface, window->uuid);
|
||||||
|
|
||||||
if (window->surface) wl_surface_destroy(window->surface);
|
if (window->surface) wl_surface_destroy(window->surface);
|
||||||
window->surface = NULL;
|
window->surface = NULL;
|
||||||
|
|
||||||
|
window->configure_serial = 0;
|
||||||
|
window->configure_ack = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
|
@ -482,6 +494,7 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window)
|
||||||
_ecore_wl2_subsurf_free(subsurf);
|
_ecore_wl2_subsurf_free(subsurf);
|
||||||
|
|
||||||
ecore_wl2_window_hide(window);
|
ecore_wl2_window_hide(window);
|
||||||
|
eina_stringshare_replace(&window->uuid, NULL);
|
||||||
|
|
||||||
if (window->title) eina_stringshare_del(window->title);
|
if (window->title) eina_stringshare_del(window->title);
|
||||||
if (window->class) eina_stringshare_del(window->class);
|
if (window->class) eina_stringshare_del(window->class);
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
#ifndef E_SESSION_RECOVERY_CLIENT_PROTOCOL_H
|
|
||||||
#define E_SESSION_RECOVERY_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 zwp_e_session_recovery;
|
|
||||||
|
|
||||||
extern const struct wl_interface zwp_e_session_recovery_interface;
|
|
||||||
|
|
||||||
struct zwp_e_session_recovery_listener {
|
|
||||||
/**
|
|
||||||
* uuid - (none)
|
|
||||||
* @uuid: (none)
|
|
||||||
*/
|
|
||||||
void (*uuid)(void *data,
|
|
||||||
struct zwp_e_session_recovery *zwp_e_session_recovery,
|
|
||||||
const char *uuid);
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
zwp_e_session_recovery_add_listener(struct zwp_e_session_recovery *zwp_e_session_recovery,
|
|
||||||
const struct zwp_e_session_recovery_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
return wl_proxy_add_listener((struct wl_proxy *) zwp_e_session_recovery,
|
|
||||||
(void (**)(void)) listener, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ZWP_E_SESSION_RECOVERY_PROVIDE_UUID 0
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
zwp_e_session_recovery_set_user_data(struct zwp_e_session_recovery *zwp_e_session_recovery, void *user_data)
|
|
||||||
{
|
|
||||||
wl_proxy_set_user_data((struct wl_proxy *) zwp_e_session_recovery, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
zwp_e_session_recovery_get_user_data(struct zwp_e_session_recovery *zwp_e_session_recovery)
|
|
||||||
{
|
|
||||||
return wl_proxy_get_user_data((struct wl_proxy *) zwp_e_session_recovery);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
zwp_e_session_recovery_destroy(struct zwp_e_session_recovery *zwp_e_session_recovery)
|
|
||||||
{
|
|
||||||
wl_proxy_destroy((struct wl_proxy *) zwp_e_session_recovery);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
zwp_e_session_recovery_provide_uuid(struct zwp_e_session_recovery *zwp_e_session_recovery, const char *uuid)
|
|
||||||
{
|
|
||||||
wl_proxy_marshal((struct wl_proxy *) zwp_e_session_recovery,
|
|
||||||
ZWP_E_SESSION_RECOVERY_PROVIDE_UUID, uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -2,22 +2,31 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "wayland-util.h"
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
|
||||||
static const struct wl_interface *types[] = {
|
static const struct wl_interface *types[] = {
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_surface_interface,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wl_message zwp_e_session_recovery_requests[] = {
|
static const struct wl_message zwp_e_session_recovery_requests[] = {
|
||||||
{ "provide_uuid", "s", types + 0 },
|
{ "get_uuid", "o", types + 0 },
|
||||||
|
{ "set_uuid", "os", types + 1 },
|
||||||
|
{ "destroy_uuid", "os", types + 3 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wl_message zwp_e_session_recovery_events[] = {
|
static const struct wl_message zwp_e_session_recovery_events[] = {
|
||||||
{ "uuid", "s", types + 0 },
|
{ "create_uuid", "os", types + 5 },
|
||||||
};
|
};
|
||||||
|
|
||||||
WL_EXPORT const struct wl_interface zwp_e_session_recovery_interface = {
|
WL_EXPORT const struct wl_interface zwp_e_session_recovery_interface = {
|
||||||
"zwp_e_session_recovery", 1,
|
"zwp_e_session_recovery", 1,
|
||||||
1, zwp_e_session_recovery_requests,
|
3, zwp_e_session_recovery_requests,
|
||||||
1, zwp_e_session_recovery_events,
|
1, zwp_e_session_recovery_events,
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
#ifndef E_SESSION_RECOVERY_CLIENT_PROTOCOL_H
|
||||||
|
#define E_SESSION_RECOVERY_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_surface;
|
||||||
|
struct zwp_e_session_recovery;
|
||||||
|
|
||||||
|
extern const struct wl_interface zwp_e_session_recovery_interface;
|
||||||
|
|
||||||
|
struct zwp_e_session_recovery_listener {
|
||||||
|
/**
|
||||||
|
* create_uuid - (none)
|
||||||
|
* @surface: (none)
|
||||||
|
* @uuid: (none)
|
||||||
|
*/
|
||||||
|
void (*create_uuid)(void *data,
|
||||||
|
struct zwp_e_session_recovery *zwp_e_session_recovery,
|
||||||
|
struct wl_surface *surface,
|
||||||
|
const char *uuid);
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
zwp_e_session_recovery_add_listener(struct zwp_e_session_recovery *zwp_e_session_recovery,
|
||||||
|
const struct zwp_e_session_recovery_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zwp_e_session_recovery,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZWP_E_SESSION_RECOVERY_GET_UUID 0
|
||||||
|
#define ZWP_E_SESSION_RECOVERY_SET_UUID 1
|
||||||
|
#define ZWP_E_SESSION_RECOVERY_DESTROY_UUID 2
|
||||||
|
|
||||||
|
#define ZWP_E_SESSION_RECOVERY_GET_UUID_SINCE_VERSION 1
|
||||||
|
#define ZWP_E_SESSION_RECOVERY_SET_UUID_SINCE_VERSION 1
|
||||||
|
#define ZWP_E_SESSION_RECOVERY_DESTROY_UUID_SINCE_VERSION 1
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
zwp_e_session_recovery_set_user_data(struct zwp_e_session_recovery *zwp_e_session_recovery, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwp_e_session_recovery, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
zwp_e_session_recovery_get_user_data(struct zwp_e_session_recovery *zwp_e_session_recovery)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwp_e_session_recovery);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwp_e_session_recovery_get_version(struct zwp_e_session_recovery *zwp_e_session_recovery)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwp_e_session_recovery);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
zwp_e_session_recovery_destroy(struct zwp_e_session_recovery *zwp_e_session_recovery)
|
||||||
|
{
|
||||||
|
wl_proxy_destroy((struct wl_proxy *) zwp_e_session_recovery);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
zwp_e_session_recovery_get_uuid(struct zwp_e_session_recovery *zwp_e_session_recovery, struct wl_surface *surface)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwp_e_session_recovery,
|
||||||
|
ZWP_E_SESSION_RECOVERY_GET_UUID, surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
zwp_e_session_recovery_set_uuid(struct zwp_e_session_recovery *zwp_e_session_recovery, struct wl_surface *surface, const char *uuid)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwp_e_session_recovery,
|
||||||
|
ZWP_E_SESSION_RECOVERY_SET_UUID, surface, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
zwp_e_session_recovery_destroy_uuid(struct zwp_e_session_recovery *zwp_e_session_recovery, struct wl_surface *surface, const char *uuid)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwp_e_session_recovery,
|
||||||
|
ZWP_E_SESSION_RECOVERY_DESTROY_UUID, surface, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,6 +12,8 @@
|
||||||
static const char *interface_wl_name = "wayland";
|
static const char *interface_wl_name = "wayland";
|
||||||
static const int interface_wl_version = 1;
|
static const int interface_wl_version = 1;
|
||||||
|
|
||||||
|
Eina_List *ee_list;
|
||||||
|
|
||||||
/* local structures for the frame smart object */
|
/* local structures for the frame smart object */
|
||||||
typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data;
|
typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data;
|
||||||
struct _EE_Wl_Smart_Data
|
struct _EE_Wl_Smart_Data
|
||||||
|
@ -34,7 +36,7 @@ EVAS_SMART_SUBCLASS_NEW(_smart_frame_type, _ecore_evas_wl_frame,
|
||||||
|
|
||||||
/* local variables */
|
/* local variables */
|
||||||
static int _ecore_evas_wl_init_count = 0;
|
static int _ecore_evas_wl_init_count = 0;
|
||||||
static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[7];
|
static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[8];
|
||||||
|
|
||||||
static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location);
|
static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location);
|
||||||
|
|
||||||
|
@ -161,6 +163,30 @@ _ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED,
|
||||||
return ECORE_CALLBACK_PASS_ON;
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_ecore_evas_wl_common_cb_disconnect(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||||
|
{
|
||||||
|
Ecore_Wl2_Event_Disconnect *ev = event;
|
||||||
|
Eina_List *l;
|
||||||
|
Ecore_Evas *ee;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(ee_list, l, ee)
|
||||||
|
{
|
||||||
|
Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
|
||||||
|
|
||||||
|
if (wdata->display != ev->display) continue;
|
||||||
|
if (wdata->anim_callback) wl_callback_destroy(wdata->anim_callback);
|
||||||
|
wdata->anim_callback = NULL;
|
||||||
|
wdata->sync_done = EINA_FALSE;
|
||||||
|
wdata->defer_show = EINA_TRUE;
|
||||||
|
wdata->reset_pending = 1;
|
||||||
|
ecore_evas_manual_render_set(ee, 1);
|
||||||
|
if (wdata->display_unset)
|
||||||
|
wdata->display_unset(ee);
|
||||||
|
}
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
_ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||||
{
|
{
|
||||||
|
@ -441,6 +467,9 @@ _ecore_evas_wl_common_init(void)
|
||||||
_ecore_evas_wl_event_hdls[6] =
|
_ecore_evas_wl_event_hdls[6] =
|
||||||
ecore_event_handler_add(_ecore_wl2_event_window_www_drag,
|
ecore_event_handler_add(_ecore_wl2_event_window_www_drag,
|
||||||
_ecore_evas_wl_common_cb_www_drag, NULL);
|
_ecore_evas_wl_common_cb_www_drag, NULL);
|
||||||
|
_ecore_evas_wl_event_hdls[7] =
|
||||||
|
ecore_event_handler_add(ECORE_WL2_EVENT_DISCONNECT,
|
||||||
|
_ecore_evas_wl_common_cb_disconnect, NULL);
|
||||||
ecore_event_evas_init();
|
ecore_event_evas_init();
|
||||||
|
|
||||||
return _ecore_evas_wl_init_count;
|
return _ecore_evas_wl_init_count;
|
||||||
|
@ -489,10 +518,15 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
|
||||||
if (!ee) return;
|
if (!ee) return;
|
||||||
|
|
||||||
wdata = ee->engine.data;
|
wdata = ee->engine.data;
|
||||||
|
ee_list = eina_list_remove(ee_list, ee);
|
||||||
|
|
||||||
|
eina_list_free(wdata->regen_objs);
|
||||||
|
|
||||||
if (wdata->anim_callback) wl_callback_destroy(wdata->anim_callback);
|
if (wdata->anim_callback) wl_callback_destroy(wdata->anim_callback);
|
||||||
wdata->anim_callback = NULL;
|
wdata->anim_callback = NULL;
|
||||||
|
|
||||||
|
ecore_event_handler_del(wdata->sync_handler);
|
||||||
|
|
||||||
if (wdata->win) ecore_wl2_window_free(wdata->win);
|
if (wdata->win) ecore_wl2_window_free(wdata->win);
|
||||||
wdata->win = NULL;
|
wdata->win = NULL;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
# endif
|
# endif
|
||||||
#endif /* ! _WIN32 */
|
#endif /* ! _WIN32 */
|
||||||
|
|
||||||
|
extern EAPI Eina_List *_evas_canvas_image_data_unset(Evas *eo_e);
|
||||||
|
extern EAPI void _evas_canvas_image_data_regenerate(Eina_List *list);
|
||||||
|
|
||||||
/* local function prototypes */
|
/* local function prototypes */
|
||||||
static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h);
|
static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h);
|
||||||
static void _ecore_evas_wl_show(Ecore_Evas *ee);
|
static void _ecore_evas_wl_show(Ecore_Evas *ee);
|
||||||
|
@ -117,6 +120,19 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
|
||||||
|
|
||||||
/* external variables */
|
/* external variables */
|
||||||
|
|
||||||
|
void
|
||||||
|
_ee_egl_display_unset(Ecore_Evas *ee)
|
||||||
|
{
|
||||||
|
Evas_Engine_Info_Wayland_Egl *einfo;
|
||||||
|
Ecore_Evas_Engine_Wl_Data *wdata;
|
||||||
|
|
||||||
|
einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
|
||||||
|
einfo->info.display = NULL;
|
||||||
|
wdata = ee->engine.data;
|
||||||
|
wdata->regen_objs = _evas_canvas_image_data_unset(ecore_evas_get(ee));
|
||||||
|
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
|
_ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -136,10 +152,19 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
|
||||||
einfo->info.rotation = ee->rotation;
|
einfo->info.rotation = ee->rotation;
|
||||||
einfo->info.surface = ecore_wl2_window_surface_get(wdata->win);
|
einfo->info.surface = ecore_wl2_window_surface_get(wdata->win);
|
||||||
|
|
||||||
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
|
if (wdata->reset_pending)
|
||||||
{
|
{
|
||||||
ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
|
ecore_evas_manual_render_set(ee, 0);
|
||||||
}
|
}
|
||||||
|
if (evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
|
||||||
|
{
|
||||||
|
if (wdata->reset_pending)
|
||||||
|
_evas_canvas_image_data_regenerate(wdata->regen_objs);
|
||||||
|
wdata->regen_objs = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
|
||||||
|
wdata->reset_pending = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -164,15 +189,7 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
|
||||||
einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
|
einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
|
||||||
if (einfo)
|
if (einfo)
|
||||||
{
|
{
|
||||||
struct wl_surface *surf;
|
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
|
||||||
|
|
||||||
surf = ecore_wl2_window_surface_get(wdata->win);
|
|
||||||
if ((!einfo->info.surface) || (einfo->info.surface != surf))
|
|
||||||
{
|
|
||||||
einfo->info.surface = surf;
|
|
||||||
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
|
|
||||||
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
|
|
||||||
}
|
|
||||||
einfo->www_avail = !!wdata->win->www_surface;
|
einfo->www_avail = !!wdata->win->www_surface;
|
||||||
einfo->just_mapped = EINA_TRUE;
|
einfo->just_mapped = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -362,6 +379,7 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
|
||||||
wdata->sync_done = EINA_FALSE;
|
wdata->sync_done = EINA_FALSE;
|
||||||
wdata->parent = p;
|
wdata->parent = p;
|
||||||
wdata->display = ewd;
|
wdata->display = ewd;
|
||||||
|
wdata->display_unset = _ee_egl_display_unset;
|
||||||
wdata->win = ecore_wl2_window_new(ewd, p, x, y, w + fw, h + fh);
|
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->prop.window = ecore_wl2_window_id_get(wdata->win);
|
||||||
|
|
||||||
|
@ -432,7 +450,8 @@ ecore_evas_wayland_egl_new_internal(const char *disp_name, unsigned int parent,
|
||||||
(Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
|
(Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
|
||||||
(Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
|
(Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
|
||||||
|
|
||||||
ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee);
|
wdata->sync_handler = ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee);
|
||||||
|
ee_list = eina_list_append(ee_list, ee);
|
||||||
|
|
||||||
return ee;
|
return ee;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,10 @@ typedef struct _Ecore_Evas_Engine_Wl_Data Ecore_Evas_Engine_Wl_Data;
|
||||||
struct _Ecore_Evas_Engine_Wl_Data
|
struct _Ecore_Evas_Engine_Wl_Data
|
||||||
{
|
{
|
||||||
Ecore_Wl2_Display *display;
|
Ecore_Wl2_Display *display;
|
||||||
|
void (*display_unset)(Ecore_Evas*);
|
||||||
|
Eina_List *regen_objs;
|
||||||
Ecore_Wl2_Window *parent, *win;
|
Ecore_Wl2_Window *parent, *win;
|
||||||
|
Ecore_Event_Handler *sync_handler;
|
||||||
Evas_Object *frame;
|
Evas_Object *frame;
|
||||||
int fx, fy, fw, fh;
|
int fx, fy, fw, fh;
|
||||||
#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
|
#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
|
||||||
|
@ -48,6 +51,7 @@ struct _Ecore_Evas_Engine_Wl_Data
|
||||||
|
|
||||||
Eina_Bool sync_done : 1;
|
Eina_Bool sync_done : 1;
|
||||||
Eina_Bool defer_show : 1;
|
Eina_Bool defer_show : 1;
|
||||||
|
Eina_Bool reset_pending : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ecore_Evas_Interface_Wayland *_ecore_evas_wl_interface_new(void);
|
Ecore_Evas_Interface_Wayland *_ecore_evas_wl_interface_new(void);
|
||||||
|
@ -100,6 +104,8 @@ void _ecore_evas_wl_common_frame_border_size_set(Evas_Object *obj, int fx, int f
|
||||||
|
|
||||||
void _ecore_evas_wl_common_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y);
|
void _ecore_evas_wl_common_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y);
|
||||||
|
|
||||||
|
extern Eina_List *ee_list;
|
||||||
|
|
||||||
#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
|
#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
|
||||||
void _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location);
|
void _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location);
|
||||||
void _ecore_evas_wayland_shm_resize_edge_set(Ecore_Evas *ee, int edge);
|
void _ecore_evas_wayland_shm_resize_edge_set(Ecore_Evas *ee, int edge);
|
||||||
|
|
|
@ -131,6 +131,7 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
|
||||||
|
|
||||||
if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
|
if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
|
||||||
{
|
{
|
||||||
|
ecore_evas_manual_render_set(ee, 0);
|
||||||
einfo->info.wl_disp = ecore_wl2_display_get(wdata->display);
|
einfo->info.wl_disp = ecore_wl2_display_get(wdata->display);
|
||||||
einfo->info.wl_dmabuf = ecore_wl2_display_dmabuf_get(wdata->display);
|
einfo->info.wl_dmabuf = ecore_wl2_display_dmabuf_get(wdata->display);
|
||||||
einfo->info.wl_shm = ecore_wl2_display_shm_get(wdata->display);
|
einfo->info.wl_shm = ecore_wl2_display_shm_get(wdata->display);
|
||||||
|
@ -162,22 +163,7 @@ _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
|
||||||
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
|
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
|
||||||
|
|
||||||
if (wdata->win)
|
if (wdata->win)
|
||||||
{
|
evas_damage_rectangle_add(ee->evas, 0, 0, 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_wl2_window_surface_get(wdata->win);
|
|
||||||
if ((!einfo->info.wl_surface) || (einfo->info.wl_surface != surf))
|
|
||||||
{
|
|
||||||
einfo->info.wl_surface = surf;
|
|
||||||
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
|
|
||||||
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wdata->frame)
|
if (wdata->frame)
|
||||||
{
|
{
|
||||||
|
@ -373,7 +359,8 @@ ecore_evas_wayland_shm_new_internal(const char *disp_name, unsigned int parent,
|
||||||
(Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
|
(Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
|
||||||
(Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
|
(Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
|
||||||
|
|
||||||
ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee);
|
wdata->sync_handler = ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee);
|
||||||
|
ee_list = eina_list_append(ee_list, ee);
|
||||||
|
|
||||||
return ee;
|
return ee;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue