EFL_INTERNAL_DEPEND_PKG([ECORE_WL2], [eina])
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])
dist_installed_ecorewl2mainheaders_DATA = lib/ecore_wl2/Ecore_Wl2.h
lib_ecore_wl2_libecore_wl2_la_SOURCES = \
-lib/ecore_wl2/session-recovery-client-protocol.h \
-lib/ecore_wl2/session-recovery-protocol.c \
+lib/ecore_wl2/session-recovery.h \
+lib/ecore_wl2/session-recovery.c \
lib/ecore_wl2/subsurface-client-protocol.h \
lib/ecore_wl2/subsurface-protocol.c \
lib/ecore_wl2/xdg-shell-client-protocol.h \
ECORE_WL2_DRAG_ACTION_ASK = 4,
} 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
{
Eina_Stringshare *interface;
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);
+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_REMOVED; /** @since 1.17 */
EAPI extern int ECORE_WL2_EVENT_FOCUS_IN; /** @since 1.17 */
static int _ecore_wl2_init_count = 0;
/* external variables */
+Eina_Bool no_session_recovery;
int _ecore_wl2_log_dom = -1;
/* 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_REMOVED = 0;
EAPI int ECORE_WL2_EVENT_FOCUS_IN = 0;
/* handle creating new Ecore_Wl2 event types */
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_REMOVED = ecore_event_type_new();
ECORE_WL2_EVENT_FOCUS_IN = ecore_event_type_new();
_ecore_wl2_event_window_www = 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;
if (--_ecore_wl2_init_count != 0) return _ecore_wl2_init_count;
/* reset events */
+ ECORE_WL2_EVENT_CONNECT = 0;
+ ECORE_WL2_EVENT_DISCONNECT = 0;
ECORE_WL2_EVENT_GLOBAL_ADDED = 0;
ECORE_WL2_EVENT_GLOBAL_REMOVED = 0;
ECORE_WL2_EVENT_FOCUS_IN = 0;
#include <sys/param.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 *_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
_ecore_wl2_display_signal_exit(void)
{
_ecore_wl2_window_www_surface_init(window);
}
else if ((!strcmp(interface, "zwp_e_session_recovery")) &&
- (getenv("EFL_WAYLAND_SESSION_RECOVERY")))
+ (!no_session_recovery))
{
ewd->wl.session_recovery =
wl_registry_bind(registry, id,
};
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;
- 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);
static void
_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);
}
-static Eina_Bool
-_cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
+static Eina_Bool
+_recovery_timer(Ecore_Wl2_Display *ewd)
{
- Ecore_Wl2_Display *ewd;
- int ret = 0;
+ if (!_ecore_wl2_display_connect(ewd, 1))
+ return EINA_TRUE;
- ewd = data;
+ ewd->recovery_timer = NULL;
+ return EINA_FALSE;
+}
- if (_fatal_error) return ECORE_CALLBACK_CANCEL;
+static void
+_recovery_timer_add(Ecore_Wl2_Display *ewd)
+{
+ Eina_Inlist *tmp;
+ Ecore_Wl2_Output *output;
+ Ecore_Wl2_Input *input;
+ Ecore_Wl2_Window *window;
- if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR))
- {
- ERR("Received Fatal Error on Wayland Display");
+ eina_hash_free_buckets(ewd->globals);
+ ecore_idle_enterer_del(ewd->idle_enterer);
+ ewd->idle_enterer = NULL;
- _fatal_error = EINA_TRUE;
- _ecore_wl2_display_signal_exit();
+ ecore_main_fd_handler_del(ewd->fd_hdl);
+ ewd->fd_hdl = NULL;
- return ECORE_CALLBACK_CANCEL;
- }
+ 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
+_cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
+{
+ Ecore_Wl2_Display *ewd = data;
+ int ret = 0;
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
{
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();
-
- return ECORE_CALLBACK_CANCEL;
- }
+ if ((ret < 0) && (errno != EAGAIN)) goto err;
}
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
if (ret == 0)
ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
- if ((ret < 0) && (errno != EAGAIN))
- {
- ERR("Received Fatal Error on Wayland Display");
-
- _fatal_error = EINA_TRUE;
- _ecore_wl2_display_signal_exit();
-
- return ECORE_CALLBACK_CANCEL;
- }
+ if ((ret < 0) && (errno != EAGAIN)) goto err;
}
return ECORE_CALLBACK_RENEW;
+
+err:
+ ewd->fd_hdl = NULL;
+ _begin_recovery_maybe(ewd);
+
+ return ECORE_CALLBACK_CANCEL;
}
static void
static Eina_Bool
_cb_connect_idle(void *data)
{
- Ecore_Wl2_Display *ewd;
+ Ecore_Wl2_Display *ewd = data;
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;
err:
if ((ret < 0) && (errno != EAGAIN))
{
- ERR("Wayland Socket Error: %s", strerror(errno));
-
- _fatal_error = EINA_TRUE;
- _ecore_wl2_display_signal_exit();
+ ewd->idle_enterer = NULL;
+ _begin_recovery_maybe(ewd);
return ECORE_CALLBACK_CANCEL;
}
_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
_ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
{
ecore_wl2_display_connect(const char *name)
{
Ecore_Wl2_Display *ewd;
- Eina_Bool sync = EINA_TRUE;
- struct wl_callback *cb;
const char *n;
Eina_Bool hash_create = !_client_displays;
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", 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);
+ /* check server display hash and match on pid. If match, skip sync */
+ if (!_ecore_wl2_display_connect(ewd, _ecore_wl2_display_sync_get()))
+ goto connect_err;
ewd->xkb_context = xkb_context_new(0);
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 */
eina_hash_add(_client_displays, ewd->name, ewd);
/* remove this client display from hash */
eina_hash_del_by_key(_server_displays, display->name);
+ ecore_timer_del(display->recovery_timer);
free(display->name);
free(display);
# define _ECORE_WL2_PRIVATE_H
# include <unistd.h>
-# include <uuid/uuid.h>
# include "Ecore_Wl2.h"
# include "Ecore_Input.h"
# include "www-protocol.h"
# include "xdg-shell-client-protocol.h"
# define XDG_VERSION 5
-# include "session-recovery-client-protocol.h"
+# include "session-recovery.h"
extern int _ecore_wl2_log_dom;
+extern Eina_Bool no_session_recovery;
# ifdef EAPI
# undef EAPI
Ecore_Fd_Handler *fd_hdl;
Eina_Hash *globals;
+ Ecore_Timer *recovery_timer;
Eina_Inlist *windows;
Eina_Inlist *outputs;
struct xdg_popup *xdg_popup;
struct www_surface *www_surface;
- uuid_t uuid;
+ Eina_Stringshare *uuid;
uint32_t configure_serial;
void (*configure_ack)(struct xdg_surface *surface, uint32_t serial);
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_unmap(Ecore_Wl2_Subsurface *subsurf);
void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf);
void _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window);
#include "ecore_wl2_private.h"
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;
- char str[37];
+ Ecore_Wl2_Window *win = data;
- win = data;
- 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);
+ eina_stringshare_replace(&win->uuid, uuid);
}
static const struct zwp_e_session_recovery_listener _session_listener =
{
- _session_recovery_uuid,
+ _session_recovery_create_uuid,
};
static void
window->configure_ack = xdg_surface_ack_configure;
_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))
{
window->surface_id =
wl_proxy_get_id((struct wl_proxy *)window->surface);
- if ((window->display->wl.session_recovery) &&
- (getenv("EFL_WAYLAND_SESSION_RECOVERY")))
- {
- 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);
- }
- }
+ if (window->display->wl.session_recovery)
+ zwp_e_session_recovery_add_listener(window->display->wl.session_recovery,
+ &_session_listener, window);
}
return window->surface;
EAPI void
ecore_wl2_window_hide(Ecore_Wl2_Window *window)
{
+ Ecore_Wl2_Subsurface *subsurf;
+ Eina_Inlist *tmp;
EINA_SAFETY_ON_NULL_RETURN(window);
if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface);
www_surface_destroy(window->www_surface);
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);
window->surface = NULL;
+
+ window->configure_serial = 0;
+ window->configure_ack = NULL;
}
EAPI void
_ecore_wl2_subsurf_free(subsurf);
ecore_wl2_window_hide(window);
+ eina_stringshare_replace(&window->uuid, NULL);
if (window->title) eina_stringshare_del(window->title);
if (window->class) eina_stringshare_del(window->class);
+++ /dev/null
-#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
#include <stdint.h>
#include "wayland-util.h"
+extern const struct wl_interface wl_surface_interface;
static const struct wl_interface *types[] = {
+ &wl_surface_interface,
+ &wl_surface_interface,
+ NULL,
+ &wl_surface_interface,
+ NULL,
+ &wl_surface_interface,
NULL,
};
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[] = {
- { "uuid", "s", types + 0 },
+ { "create_uuid", "os", types + 5 },
};
WL_EXPORT const struct wl_interface zwp_e_session_recovery_interface = {
"zwp_e_session_recovery", 1,
- 1, zwp_e_session_recovery_requests,
+ 3, zwp_e_session_recovery_requests,
1, zwp_e_session_recovery_events,
};
--- /dev/null
+#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
static const char *interface_wl_name = "wayland";
static const int interface_wl_version = 1;
+Eina_List *ee_list;
+
/* local structures for the frame smart object */
typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data;
struct _EE_Wl_Smart_Data
/* local variables */
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 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
_ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Evas *ee;
_ecore_evas_wl_event_hdls[6] =
ecore_event_handler_add(_ecore_wl2_event_window_www_drag,
_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();
return _ecore_evas_wl_init_count;
if (!ee) return;
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);
wdata->anim_callback = NULL;
+ ecore_event_handler_del(wdata->sync_handler);
+
if (wdata->win) ecore_wl2_window_free(wdata->win);
wdata->win = NULL;
# endif
#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 */
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);
/* 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
_ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
{
einfo->info.rotation = ee->rotation;
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
{
einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
if (einfo)
{
- struct wl_surface *surf;
-
- 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);
- }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
einfo->www_avail = !!wdata->win->www_surface;
einfo->just_mapped = EINA_TRUE;
}
wdata->sync_done = EINA_FALSE;
wdata->parent = p;
wdata->display = ewd;
+ wdata->display_unset = _ee_egl_display_unset;
wdata->win = ecore_wl2_window_new(ewd, p, x, y, w + fw, h + fh);
ee->prop.window = ecore_wl2_window_id_get(wdata->win);
(Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_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;
struct _Ecore_Evas_Engine_Wl_Data
{
Ecore_Wl2_Display *display;
+ void (*display_unset)(Ecore_Evas*);
+ Eina_List *regen_objs;
Ecore_Wl2_Window *parent, *win;
+ Ecore_Event_Handler *sync_handler;
Evas_Object *frame;
int fx, fy, fw, fh;
#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
Eina_Bool sync_done : 1;
Eina_Bool defer_show : 1;
+ Eina_Bool reset_pending : 1;
};
Ecore_Evas_Interface_Wayland *_ecore_evas_wl_interface_new(void);
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
void _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location);
void _ecore_evas_wayland_shm_resize_edge_set(Ecore_Evas *ee, int edge);
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_dmabuf = ecore_wl2_display_dmabuf_get(wdata->display);
einfo->info.wl_shm = ecore_wl2_display_shm_get(wdata->display);
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (wdata->win)
- {
-
- 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);
- }
- }
- }
+ evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
if (wdata->frame)
{
(Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_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;