2015-08-18 08:56:07 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "ecore_wl2_private.h"
|
|
|
|
|
2016-04-08 13:17:00 -07:00
|
|
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
2015-12-28 06:09:04 -08:00
|
|
|
|
2015-10-23 09:03:08 -07:00
|
|
|
static Eina_Hash *_server_displays = NULL;
|
2015-10-08 12:24:56 -07:00
|
|
|
static Eina_Hash *_client_displays = NULL;
|
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-10-26 07:44:44 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-09-10 07:50:30 -07:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2016-04-08 13:17:00 -07:00
|
|
|
static void
|
|
|
|
_dmabuf_cb_format(void *data EINA_UNUSED, struct zwp_linux_dmabuf_v1 *dmabuf EINA_UNUSED, uint32_t format EINA_UNUSED)
|
|
|
|
{
|
|
|
|
/* It would be awfully nice if this actually happened */
|
|
|
|
};
|
|
|
|
|
2016-04-22 06:36:54 -07:00
|
|
|
static const struct zwp_linux_dmabuf_v1_listener _dmabuf_listener =
|
|
|
|
{
|
|
|
|
_dmabuf_cb_format
|
2016-04-08 13:17:00 -07:00
|
|
|
};
|
|
|
|
|
2017-01-04 11:20:42 -08:00
|
|
|
static void
|
|
|
|
_zxdg_shell_cb_ping(void *data EINA_UNUSED, struct zxdg_shell_v6 *shell, uint32_t serial)
|
|
|
|
{
|
|
|
|
zxdg_shell_v6_pong(shell, serial);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct zxdg_shell_v6_listener _zxdg_shell_listener =
|
|
|
|
{
|
|
|
|
_zxdg_shell_cb_ping,
|
|
|
|
};
|
|
|
|
|
2017-01-13 08:34:07 -08:00
|
|
|
static void
|
|
|
|
_session_recovery_create_uuid(void *data EINA_UNUSED, struct zwp_e_session_recovery *session_recovery EINA_UNUSED, struct wl_surface *surface, const char *uuid)
|
|
|
|
{
|
|
|
|
Ecore_Wl2_Window *win = wl_surface_get_user_data(surface);
|
|
|
|
|
|
|
|
eina_stringshare_replace(&win->uuid, uuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct zwp_e_session_recovery_listener _session_listener =
|
|
|
|
{
|
|
|
|
_session_recovery_create_uuid,
|
|
|
|
};
|
|
|
|
|
2015-08-18 12:05:05 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2015-10-20 06:53:22 -07:00
|
|
|
else
|
|
|
|
goto event;
|
2015-08-18 12:05:05 -07:00
|
|
|
|
2015-08-19 10:48:19 -07:00
|
|
|
if (!strcmp(interface, "wl_compositor"))
|
|
|
|
{
|
2017-02-10 08:25:53 -08:00
|
|
|
ewd->wl.compositor_version = MIN(version, 4);
|
2015-08-19 10:48:19 -07:00
|
|
|
ewd->wl.compositor =
|
2015-12-28 06:09:04 -08:00
|
|
|
wl_registry_bind(registry, id, &wl_compositor_interface,
|
2017-02-10 08:25:53 -08:00
|
|
|
ewd->wl.compositor_version);
|
2015-08-19 10:48:19 -07:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
2016-04-08 13:17:00 -07:00
|
|
|
else if (!strcmp(interface, "zwp_linux_dmabuf_v1"))
|
|
|
|
{
|
|
|
|
ewd->wl.dmabuf =
|
|
|
|
wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 1);
|
|
|
|
zwp_linux_dmabuf_v1_add_listener(ewd->wl.dmabuf, &_dmabuf_listener, ewd);
|
|
|
|
}
|
2015-08-19 10:48:19 -07:00
|
|
|
else if (!strcmp(interface, "wl_data_device_manager"))
|
|
|
|
{
|
2016-04-20 08:11:34 -07:00
|
|
|
ewd->wl.data_device_manager_version = MIN(version, 3);
|
2015-08-19 10:48:19 -07:00
|
|
|
ewd->wl.data_device_manager =
|
2016-04-20 08:11:34 -07:00
|
|
|
wl_registry_bind(registry, id, &wl_data_device_manager_interface, ewd->wl.data_device_manager_version);
|
2015-08-19 10:48:19 -07:00
|
|
|
}
|
2016-05-14 02:26:27 -07:00
|
|
|
else if ((eina_streq(interface, "www")) &&
|
2017-02-01 14:21:34 -08:00
|
|
|
(getenv("EFL_WAYLAND_ENABLE_WWW")))
|
2016-03-24 10:19:42 -07:00
|
|
|
{
|
|
|
|
Ecore_Wl2_Window *window;
|
2016-04-22 06:36:54 -07:00
|
|
|
|
2016-03-24 10:19:42 -07:00
|
|
|
ewd->wl.www = wl_registry_bind(registry, id, &www_interface, 1);
|
|
|
|
EINA_INLIST_FOREACH(ewd->windows, window)
|
|
|
|
_ecore_wl2_window_www_surface_init(window);
|
|
|
|
}
|
2016-04-22 06:32:45 -07:00
|
|
|
else if ((!strcmp(interface, "zwp_e_session_recovery")) &&
|
2016-05-05 07:45:59 -07:00
|
|
|
(!no_session_recovery))
|
2016-04-22 06:32:45 -07:00
|
|
|
{
|
|
|
|
ewd->wl.session_recovery =
|
|
|
|
wl_registry_bind(registry, id,
|
|
|
|
&zwp_e_session_recovery_interface, 1);
|
2017-01-13 08:34:07 -08:00
|
|
|
zwp_e_session_recovery_add_listener(ewd->wl.session_recovery,
|
|
|
|
&_session_listener, ewd);
|
2016-04-22 06:32:45 -07:00
|
|
|
}
|
2016-05-20 11:04:21 -07:00
|
|
|
else if (!strcmp(interface, "zwp_teamwork"))
|
|
|
|
{
|
|
|
|
ewd->wl.teamwork =
|
|
|
|
wl_registry_bind(registry, id,
|
|
|
|
&zwp_teamwork_interface, EFL_TEAMWORK_VERSION);
|
|
|
|
}
|
2015-09-10 07:37:40 -07:00
|
|
|
else if (!strcmp(interface, "wl_output"))
|
|
|
|
_ecore_wl2_output_add(ewd, id);
|
2015-09-10 08:03:23 -07:00
|
|
|
else if (!strcmp(interface, "wl_seat"))
|
2015-11-22 13:13:36 -08:00
|
|
|
_ecore_wl2_input_add(ewd, id, version);
|
2015-08-19 10:48:19 -07:00
|
|
|
|
2015-10-20 06:53:22 -07:00
|
|
|
event:
|
2015-08-18 12:05:05 -07:00
|
|
|
/* allocate space for event structure */
|
|
|
|
ev = calloc(1, sizeof(Ecore_Wl2_Event_Global));
|
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
ev->id = id;
|
2015-09-30 09:43:41 -07:00
|
|
|
ev->display = ewd;
|
2015-08-18 12:05:05 -07:00
|
|
|
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;
|
2015-09-30 09:43:41 -07:00
|
|
|
ev->display = ewd;
|
2015-08-18 12:05:05 -07:00
|
|
|
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 */
|
2015-10-23 09:03:08 -07:00
|
|
|
if (ewd->globals) eina_hash_del_by_key(ewd->globals, &id);
|
2015-08-18 12:05:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_registry_listener _registry_listener =
|
|
|
|
{
|
|
|
|
_cb_global_add,
|
|
|
|
_cb_global_remove
|
|
|
|
};
|
|
|
|
|
2015-08-18 10:50:02 -07:00
|
|
|
static Eina_Bool
|
2016-05-05 07:45:59 -07:00
|
|
|
_cb_create_data(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED)
|
2015-08-18 10:50:02 -07:00
|
|
|
{
|
2016-05-05 07:45:59 -07:00
|
|
|
Ecore_Wl2_Display *ewd = data;
|
2015-08-18 10:50:02 -07:00
|
|
|
struct wl_event_loop *loop;
|
|
|
|
|
|
|
|
loop = wl_display_get_event_loop(ewd->wl.display);
|
2015-08-20 06:41:39 -07:00
|
|
|
wl_event_loop_dispatch(loop, 0);
|
2015-10-13 11:12:59 -07:00
|
|
|
|
|
|
|
/* wl_display_flush_clients(ewd->wl.display); */
|
2015-08-18 10:50:02 -07:00
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2015-10-13 11:12:59 -07:00
|
|
|
static void
|
|
|
|
_cb_create_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
|
|
|
{
|
2016-05-05 07:45:59 -07:00
|
|
|
Ecore_Wl2_Display *ewd = data;
|
2015-10-13 11:12:59 -07:00
|
|
|
|
|
|
|
wl_display_flush_clients(ewd->wl.display);
|
|
|
|
}
|
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_recovery_timer(Ecore_Wl2_Display *ewd)
|
2015-08-18 10:50:02 -07:00
|
|
|
{
|
2016-05-05 07:45:59 -07:00
|
|
|
if (!_ecore_wl2_display_connect(ewd, 1))
|
|
|
|
return EINA_TRUE;
|
2015-08-18 10:50:02 -07:00
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
ewd->recovery_timer = NULL;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2015-08-18 10:50:02 -07:00
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
static void
|
|
|
|
_recovery_timer_add(Ecore_Wl2_Display *ewd)
|
|
|
|
{
|
2017-01-04 15:20:05 -08:00
|
|
|
Eina_Inlist *tmp, *tmp2;
|
2016-05-05 07:45:59 -07:00
|
|
|
Ecore_Wl2_Output *output;
|
|
|
|
Ecore_Wl2_Input *input;
|
|
|
|
Ecore_Wl2_Window *window;
|
2015-10-26 07:44:44 -07:00
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
eina_hash_free_buckets(ewd->globals);
|
|
|
|
ecore_idle_enterer_del(ewd->idle_enterer);
|
|
|
|
ewd->idle_enterer = NULL;
|
2015-10-26 07:44:44 -07:00
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
ecore_main_fd_handler_del(ewd->fd_hdl);
|
|
|
|
ewd->fd_hdl = NULL;
|
2015-10-26 07:44:44 -07:00
|
|
|
|
2017-03-01 11:49:02 -08:00
|
|
|
ewd->shell_done = EINA_FALSE;
|
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
if (ewd->wl.session_recovery)
|
|
|
|
zwp_e_session_recovery_destroy(ewd->wl.session_recovery);
|
|
|
|
if (ewd->wl.www) www_destroy(ewd->wl.www);
|
2017-01-04 11:20:42 -08:00
|
|
|
if (ewd->wl.zxdg_shell) zxdg_shell_v6_destroy(ewd->wl.zxdg_shell);
|
2016-05-05 07:45:59 -07:00
|
|
|
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)
|
2016-12-14 08:43:39 -08:00
|
|
|
{
|
|
|
|
Ecore_Wl2_Subsurface *subsurf;
|
|
|
|
|
2017-01-04 15:20:05 -08:00
|
|
|
EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp2, subsurf)
|
2016-12-14 08:43:39 -08:00
|
|
|
_ecore_wl2_subsurf_unmap(subsurf);
|
|
|
|
_ecore_wl_window_semi_free(window);
|
|
|
|
window->configure_serial = 0;
|
|
|
|
window->configure_ack = NULL;
|
|
|
|
}
|
2016-05-05 07:45:59 -07:00
|
|
|
|
2016-05-18 13:08:06 -07:00
|
|
|
ewd->recovery_timer =
|
|
|
|
ecore_timer_add(0.5, (Ecore_Task_Cb)_recovery_timer, ewd);
|
2016-05-05 07:45:59 -07:00
|
|
|
_ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_DISCONNECT);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_begin_recovery_maybe(Ecore_Wl2_Display *ewd)
|
|
|
|
{
|
|
|
|
if (ewd->wl.session_recovery)// && (errno == EPIPE))
|
|
|
|
_recovery_timer_add(ewd);
|
|
|
|
else
|
2016-05-06 12:43:01 -07:00
|
|
|
{
|
|
|
|
ERR("Wayland Socket Error: %s", strerror(errno));
|
|
|
|
_ecore_wl2_display_signal_exit();
|
|
|
|
}
|
2016-05-05 07:45:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
|
|
|
|
{
|
|
|
|
Ecore_Wl2_Display *ewd = data;
|
|
|
|
int ret = 0;
|
2015-08-18 10:50:02 -07:00
|
|
|
|
2015-09-28 07:40:03 -07:00
|
|
|
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
|
2015-10-22 10:11:02 -07:00
|
|
|
{
|
|
|
|
ret = wl_display_dispatch(ewd->wl.display);
|
2016-05-05 07:45:59 -07:00
|
|
|
if ((ret < 0) && (errno != EAGAIN)) goto err;
|
2015-10-22 10:11:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
|
2015-09-28 07:40:03 -07:00
|
|
|
{
|
|
|
|
ret = wl_display_flush(ewd->wl.display);
|
|
|
|
if (ret == 0)
|
|
|
|
ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
|
2015-08-18 10:50:02 -07:00
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
if ((ret < 0) && (errno != EAGAIN)) goto err;
|
2015-08-18 10:50:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
2016-05-05 07:45:59 -07:00
|
|
|
|
|
|
|
err:
|
|
|
|
ewd->fd_hdl = NULL;
|
|
|
|
_begin_recovery_maybe(ewd);
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
2015-08-18 10:50:02 -07:00
|
|
|
}
|
|
|
|
|
2015-08-18 12:05:05 -07:00
|
|
|
static void
|
|
|
|
_cb_globals_hash_del(void *data)
|
|
|
|
{
|
|
|
|
Ecore_Wl2_Global *global;
|
|
|
|
|
|
|
|
global = data;
|
|
|
|
|
|
|
|
eina_stringshare_del(global->interface);
|
|
|
|
|
|
|
|
free(global);
|
|
|
|
}
|
|
|
|
|
2015-10-06 08:44:09 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_cb_connect_idle(void *data)
|
|
|
|
{
|
2016-05-05 07:45:59 -07:00
|
|
|
Ecore_Wl2_Display *ewd = data;
|
2015-10-06 08:44:09 -07:00
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
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:
|
2016-03-10 11:56:24 -08:00
|
|
|
if ((ret < 0) && (errno != EAGAIN))
|
2015-10-06 08:44:09 -07:00
|
|
|
{
|
2016-05-05 07:45:59 -07:00
|
|
|
ewd->idle_enterer = NULL;
|
|
|
|
_begin_recovery_maybe(ewd);
|
2015-10-26 07:44:44 -07:00
|
|
|
|
2015-10-06 08:44:09 -07:00
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2017-02-28 09:17:02 -08:00
|
|
|
static Ecore_Wl2_Global *
|
|
|
|
_ecore_wl2_global_find(Ecore_Wl2_Display *ewd, const char *interface)
|
|
|
|
{
|
|
|
|
Eina_Iterator *itr;
|
2017-02-28 09:36:05 -08:00
|
|
|
Ecore_Wl2_Global *global = NULL, *g = NULL;
|
2017-02-28 09:17:02 -08:00
|
|
|
|
|
|
|
itr = eina_hash_iterator_data_new(ewd->globals);
|
|
|
|
if (!itr) return NULL;
|
|
|
|
|
2017-02-28 09:36:05 -08:00
|
|
|
EINA_ITERATOR_FOREACH(itr, g)
|
2017-02-28 09:17:02 -08:00
|
|
|
{
|
|
|
|
if (!strcmp(g->interface, interface))
|
|
|
|
{
|
2017-02-28 09:36:05 -08:00
|
|
|
global = g;
|
2017-02-28 09:17:02 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
eina_iterator_free(itr);
|
|
|
|
return global;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_wl2_shell_bind(Ecore_Wl2_Display *ewd)
|
|
|
|
{
|
|
|
|
Ecore_Wl2_Global *global = NULL;
|
|
|
|
const char **itr;
|
|
|
|
const char *shells[] =
|
|
|
|
{
|
|
|
|
"zxdg_shell_v6",
|
|
|
|
"xdg_shell",
|
|
|
|
"wl_shell",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
if (ewd->shell_done) return;
|
|
|
|
|
|
|
|
for (itr = shells; *itr != NULL; itr++)
|
|
|
|
{
|
|
|
|
global = _ecore_wl2_global_find(ewd, *itr);
|
|
|
|
if (!global) continue;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!global) return;
|
|
|
|
|
2017-03-08 12:13:01 -08:00
|
|
|
if (!strcmp(global->interface, "wl_shell"))
|
2017-02-28 09:17:02 -08:00
|
|
|
{
|
|
|
|
ewd->wl.wl_shell =
|
|
|
|
wl_registry_bind(ewd->wl.registry, global->id,
|
|
|
|
&wl_shell_interface, 1);
|
|
|
|
ewd->shell_done = EINA_TRUE;
|
|
|
|
}
|
|
|
|
else if ((!strcmp(global->interface, "xdg_shell")) &&
|
|
|
|
(!getenv("EFL_WAYLAND_DONT_USE_XDG_SHELL")))
|
|
|
|
{
|
|
|
|
Ecore_Wl2_Window *window;
|
|
|
|
|
|
|
|
ewd->wl.xdg_shell =
|
|
|
|
wl_registry_bind(ewd->wl.registry, global->id,
|
|
|
|
&xdg_shell_interface, 1);
|
|
|
|
xdg_shell_use_unstable_version(ewd->wl.xdg_shell,
|
|
|
|
XDG_V5_UNSTABLE_VERSION);
|
|
|
|
xdg_shell_add_listener(ewd->wl.xdg_shell, &_xdg_shell_listener, NULL);
|
|
|
|
ewd->shell_done = EINA_TRUE;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(ewd->windows, window)
|
|
|
|
if ((window->type != ECORE_WL2_WINDOW_TYPE_DND) &&
|
|
|
|
(window->type != ECORE_WL2_WINDOW_TYPE_NONE))
|
|
|
|
_ecore_wl2_window_shell_surface_init(window);
|
|
|
|
else
|
|
|
|
window->pending.configure = EINA_FALSE;
|
|
|
|
}
|
|
|
|
else if (!strcmp(global->interface, "zxdg_shell_v6"))
|
|
|
|
{
|
|
|
|
ewd->wl.zxdg_shell =
|
|
|
|
wl_registry_bind(ewd->wl.registry, global->id,
|
|
|
|
&zxdg_shell_v6_interface, 1);
|
|
|
|
zxdg_shell_v6_add_listener(ewd->wl.zxdg_shell,
|
|
|
|
&_zxdg_shell_listener, NULL);
|
|
|
|
ewd->shell_done = EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-09 08:19:02 -07:00
|
|
|
static void
|
|
|
|
_cb_sync_done(void *data, struct wl_callback *cb, uint32_t serial EINA_UNUSED)
|
|
|
|
{
|
2015-12-11 08:24:32 -08:00
|
|
|
Ecore_Wl2_Event_Sync_Done *ev;
|
2015-09-09 08:19:02 -07:00
|
|
|
Ecore_Wl2_Display *ewd;
|
|
|
|
|
|
|
|
ewd = data;
|
|
|
|
ewd->sync_done = EINA_TRUE;
|
|
|
|
|
2017-02-28 09:17:02 -08:00
|
|
|
_ecore_wl2_shell_bind(ewd);
|
|
|
|
|
2015-09-09 08:19:02 -07:00
|
|
|
wl_callback_destroy(cb);
|
2015-12-11 08:24:32 -08:00
|
|
|
|
|
|
|
ev = calloc(1, sizeof(Ecore_Wl2_Event_Sync_Done));
|
|
|
|
if (!ev) return;
|
|
|
|
|
|
|
|
ev->display = ewd;
|
|
|
|
ecore_event_add(ECORE_WL2_EVENT_SYNC_DONE, ev, NULL, NULL);
|
2015-09-09 08:19:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_callback_listener _sync_listener =
|
|
|
|
{
|
|
|
|
_cb_sync_done
|
|
|
|
};
|
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync)
|
|
|
|
{
|
|
|
|
struct wl_callback *cb;
|
2016-05-18 13:08:06 -07:00
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
/* try to connect to wayland display with this name */
|
|
|
|
ewd->wl.display = wl_display_connect(ewd->name);
|
2016-07-26 07:55:31 -07:00
|
|
|
if (!ewd->wl.display) return EINA_FALSE;
|
2016-05-05 07:45:59 -07:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-08-20 07:51:57 -07:00
|
|
|
static void
|
|
|
|
_ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
|
|
|
|
{
|
2015-09-10 07:37:40 -07:00
|
|
|
Ecore_Wl2_Output *output;
|
2015-10-01 08:58:50 -07:00
|
|
|
Ecore_Wl2_Input *input;
|
2015-09-10 07:37:40 -07:00
|
|
|
Eina_Inlist *tmp;
|
|
|
|
|
2015-10-09 07:23:30 -07:00
|
|
|
if (ewd->xkb_context) xkb_context_unref(ewd->xkb_context);
|
|
|
|
|
2015-10-01 08:58:50 -07:00
|
|
|
/* free each input */
|
|
|
|
EINA_INLIST_FOREACH_SAFE(ewd->inputs, tmp, input)
|
|
|
|
_ecore_wl2_input_del(input);
|
|
|
|
|
2015-09-10 07:37:40 -07:00
|
|
|
/* free each output */
|
|
|
|
EINA_INLIST_FOREACH_SAFE(ewd->outputs, tmp, output)
|
|
|
|
_ecore_wl2_output_del(output);
|
|
|
|
|
2015-10-09 07:23:30 -07:00
|
|
|
if (ewd->idle_enterer) ecore_idle_enterer_del(ewd->idle_enterer);
|
2015-10-08 12:24:56 -07:00
|
|
|
|
2015-08-20 07:51:57 -07:00
|
|
|
if (ewd->fd_hdl) ecore_main_fd_handler_del(ewd->fd_hdl);
|
|
|
|
|
|
|
|
eina_hash_free(ewd->globals);
|
2015-10-01 09:03:41 -07:00
|
|
|
|
2016-04-22 06:32:45 -07:00
|
|
|
if (ewd->wl.session_recovery)
|
|
|
|
zwp_e_session_recovery_destroy(ewd->wl.session_recovery);
|
2016-03-24 10:19:42 -07:00
|
|
|
if (ewd->wl.www) www_destroy(ewd->wl.www);
|
2017-01-04 11:20:42 -08:00
|
|
|
if (ewd->wl.zxdg_shell) zxdg_shell_v6_destroy(ewd->wl.zxdg_shell);
|
2015-10-01 09:03:41 -07:00
|
|
|
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);
|
|
|
|
|
2015-10-06 11:45:02 -07:00
|
|
|
if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry);
|
2015-08-20 07:51:57 -07:00
|
|
|
}
|
|
|
|
|
2015-09-10 10:21:02 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-08-18 10:50:02 -07:00
|
|
|
EAPI Ecore_Wl2_Display *
|
2015-08-18 12:55:24 -07:00
|
|
|
ecore_wl2_display_create(const char *name)
|
2015-08-18 08:56:07 -07:00
|
|
|
{
|
2015-08-18 10:50:02 -07:00
|
|
|
Ecore_Wl2_Display *ewd;
|
|
|
|
struct wl_event_loop *loop;
|
2015-10-23 09:03:08 -07:00
|
|
|
|
|
|
|
if (!_server_displays)
|
|
|
|
_server_displays = eina_hash_string_superfast_new(NULL);
|
|
|
|
|
2016-01-05 10:10:40 -08:00
|
|
|
if (name)
|
2015-10-23 09:03:08 -07:00
|
|
|
{
|
|
|
|
/* 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;
|
|
|
|
}
|
2015-08-18 10:50:02 -07:00
|
|
|
|
|
|
|
/* allocate space for display structure */
|
|
|
|
ewd = calloc(1, sizeof(Ecore_Wl2_Display));
|
|
|
|
if (!ewd) return NULL;
|
|
|
|
|
2015-10-23 09:03:08 -07:00
|
|
|
ewd->refs++;
|
|
|
|
ewd->pid = getpid();
|
|
|
|
|
2015-08-18 10:50:02 -07:00
|
|
|
/* try to create new wayland display */
|
|
|
|
ewd->wl.display = wl_display_create();
|
|
|
|
if (!ewd->wl.display)
|
|
|
|
{
|
2016-01-14 10:05:55 -08:00
|
|
|
ERR("Could not create wayland display");
|
2015-08-18 10:50:02 -07:00
|
|
|
goto create_err;
|
|
|
|
}
|
|
|
|
|
2015-08-18 12:55:24 -07:00
|
|
|
if (!name)
|
2015-08-18 10:50:02 -07:00
|
|
|
{
|
2015-10-08 12:24:56 -07:00
|
|
|
const char *n;
|
|
|
|
|
|
|
|
n = wl_display_add_socket_auto(ewd->wl.display);
|
|
|
|
if (!n)
|
2015-08-18 12:55:24 -07:00
|
|
|
{
|
2016-01-14 10:05:55 -08:00
|
|
|
ERR("Failed to add display socket");
|
2015-08-18 12:55:24 -07:00
|
|
|
goto socket_err;
|
|
|
|
}
|
2015-10-08 12:24:56 -07:00
|
|
|
|
|
|
|
ewd->name = strdup(n);
|
2015-08-18 12:55:24 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (wl_display_add_socket(ewd->wl.display, name))
|
|
|
|
{
|
2016-01-14 10:05:55 -08:00
|
|
|
ERR("Failed to add display socket");
|
2015-08-18 12:55:24 -07:00
|
|
|
goto socket_err;
|
|
|
|
}
|
2015-10-08 12:24:56 -07:00
|
|
|
|
|
|
|
ewd->name = strdup(name);
|
2015-08-18 10:50:02 -07:00
|
|
|
}
|
|
|
|
|
2015-10-08 11:13:05 -07:00
|
|
|
setenv("WAYLAND_DISPLAY", ewd->name, 1);
|
2015-11-18 06:21:23 -08:00
|
|
|
DBG("WAYLAND_DISPLAY: %s", ewd->name);
|
2015-10-08 11:13:05 -07:00
|
|
|
|
2015-08-18 10:50:02 -07:00
|
|
|
loop = wl_display_get_event_loop(ewd->wl.display);
|
|
|
|
|
|
|
|
ewd->fd_hdl =
|
|
|
|
ecore_main_fd_handler_add(wl_event_loop_get_fd(loop),
|
2016-03-10 10:31:23 -08:00
|
|
|
ECORE_FD_READ | ECORE_FD_ERROR,
|
2015-08-18 10:50:02 -07:00
|
|
|
_cb_create_data, ewd, NULL, NULL);
|
|
|
|
|
2015-10-13 11:12:59 -07:00
|
|
|
ecore_main_fd_handler_prepare_callback_set(ewd->fd_hdl,
|
|
|
|
_cb_create_prepare, ewd);
|
2015-10-23 09:03:08 -07:00
|
|
|
|
|
|
|
/* add this new server display to hash */
|
|
|
|
eina_hash_add(_server_displays, ewd->name, ewd);
|
|
|
|
|
2015-08-18 10:50:02 -07:00
|
|
|
return ewd;
|
|
|
|
|
|
|
|
socket_err:
|
|
|
|
wl_display_destroy(ewd->wl.display);
|
|
|
|
|
|
|
|
create_err:
|
|
|
|
free(ewd);
|
|
|
|
return NULL;
|
2015-10-23 09:03:08 -07:00
|
|
|
|
|
|
|
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;
|
2015-08-18 08:56:07 -07:00
|
|
|
}
|
|
|
|
|
2015-08-18 10:50:02 -07:00
|
|
|
EAPI Ecore_Wl2_Display *
|
2015-08-18 08:56:07 -07:00
|
|
|
ecore_wl2_display_connect(const char *name)
|
|
|
|
{
|
2015-08-18 10:50:02 -07:00
|
|
|
Ecore_Wl2_Display *ewd;
|
2015-10-08 12:24:56 -07:00
|
|
|
const char *n;
|
2015-12-10 08:18:24 -08:00
|
|
|
Eina_Bool hash_create = !_client_displays;
|
2015-10-08 12:24:56 -07:00
|
|
|
|
|
|
|
if (!_client_displays)
|
|
|
|
_client_displays = eina_hash_string_superfast_new(NULL);
|
|
|
|
|
|
|
|
if (!name)
|
|
|
|
{
|
|
|
|
/* client wants to connect to default display */
|
|
|
|
n = getenv("WAYLAND_DISPLAY");
|
2016-05-16 03:53:27 -07:00
|
|
|
if (!n) n = "wayland-0";
|
2016-05-16 03:14:40 -07:00
|
|
|
|
2016-05-16 03:53:27 -07:00
|
|
|
/* we have a default wayland display */
|
2015-10-08 12:24:56 -07:00
|
|
|
|
2016-05-16 03:53:27 -07:00
|
|
|
/* check hash of cached client displays for this name */
|
|
|
|
ewd = eina_hash_find(_client_displays, n);
|
|
|
|
if (ewd) goto found;
|
2015-10-08 12:24:56 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* client wants to connect to specific display */
|
|
|
|
|
|
|
|
/* check hash of cached client displays for this name */
|
|
|
|
ewd = eina_hash_find(_client_displays, name);
|
2015-10-09 07:23:30 -07:00
|
|
|
if (ewd) goto found;
|
2015-10-08 12:24:56 -07:00
|
|
|
}
|
2015-08-18 10:50:02 -07:00
|
|
|
|
|
|
|
/* allocate space for display structure */
|
|
|
|
ewd = calloc(1, sizeof(Ecore_Wl2_Display));
|
|
|
|
if (!ewd) return NULL;
|
2015-08-18 08:56:07 -07:00
|
|
|
|
2015-10-09 07:23:30 -07:00
|
|
|
ewd->refs++;
|
|
|
|
|
2015-10-08 12:24:56 -07:00
|
|
|
if (name)
|
|
|
|
ewd->name = strdup(name);
|
|
|
|
else if (n)
|
|
|
|
ewd->name = strdup(n);
|
|
|
|
|
2015-08-18 12:05:05 -07:00
|
|
|
ewd->globals = eina_hash_int32_new(_cb_globals_hash_del);
|
|
|
|
|
2016-05-05 07:45:59 -07:00
|
|
|
/* 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;
|
2015-08-18 12:05:05 -07:00
|
|
|
|
2015-08-20 07:35:24 -07:00
|
|
|
ewd->xkb_context = xkb_context_new(0);
|
|
|
|
if (!ewd->xkb_context) goto context_err;
|
|
|
|
|
2016-05-03 11:52:03 -07:00
|
|
|
/* add this new client display to hash */
|
|
|
|
eina_hash_add(_client_displays, ewd->name, ewd);
|
|
|
|
|
2015-08-18 10:50:02 -07:00
|
|
|
return ewd;
|
2015-08-18 12:05:05 -07:00
|
|
|
|
2015-08-20 07:35:24 -07:00
|
|
|
context_err:
|
|
|
|
ecore_main_fd_handler_del(ewd->fd_hdl);
|
2015-10-06 11:45:02 -07:00
|
|
|
wl_registry_destroy(ewd->wl.registry);
|
2015-08-20 07:35:24 -07:00
|
|
|
wl_display_disconnect(ewd->wl.display);
|
|
|
|
|
|
|
|
connect_err:
|
2015-08-18 12:05:05 -07:00
|
|
|
eina_hash_free(ewd->globals);
|
2015-10-08 12:24:56 -07:00
|
|
|
free(ewd->name);
|
2015-08-18 12:05:05 -07:00
|
|
|
free(ewd);
|
2015-10-09 07:23:30 -07:00
|
|
|
|
2015-12-10 08:18:24 -08:00
|
|
|
if (hash_create)
|
|
|
|
{
|
|
|
|
eina_hash_free(_client_displays);
|
|
|
|
_client_displays = NULL;
|
|
|
|
}
|
2015-10-21 12:39:16 -07:00
|
|
|
return NULL;
|
|
|
|
|
2015-10-09 07:23:30 -07:00
|
|
|
found:
|
|
|
|
ewd->refs++;
|
|
|
|
return ewd;
|
2015-08-18 08:56:07 -07:00
|
|
|
}
|
2015-08-19 10:41:01 -07:00
|
|
|
|
2015-08-20 07:15:07 -07:00
|
|
|
EAPI void
|
|
|
|
ecore_wl2_display_disconnect(Ecore_Wl2_Display *display)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(display);
|
2016-04-22 06:36:54 -07:00
|
|
|
|
2017-03-01 05:32:18 -08:00
|
|
|
--display->refs;
|
2016-08-10 19:34:00 -07:00
|
|
|
if (display->refs == 0)
|
2015-10-09 07:23:30 -07:00
|
|
|
{
|
2017-02-10 14:23:36 -08:00
|
|
|
wl_display_roundtrip(display->wl.display);
|
2017-03-01 09:08:09 -08:00
|
|
|
|
|
|
|
_ecore_wl2_display_cleanup(display);
|
|
|
|
|
2015-10-09 07:23:30 -07:00
|
|
|
wl_display_disconnect(display->wl.display);
|
2015-12-07 09:18:28 -08:00
|
|
|
|
|
|
|
/* remove this client display from hash */
|
|
|
|
eina_hash_del_by_key(_client_displays, display->name);
|
|
|
|
|
|
|
|
free(display->name);
|
2015-10-09 07:23:30 -07:00
|
|
|
free(display);
|
|
|
|
}
|
2015-08-20 07:15:07 -07:00
|
|
|
}
|
2015-08-20 07:22:03 -07:00
|
|
|
|
|
|
|
EAPI void
|
|
|
|
ecore_wl2_display_destroy(Ecore_Wl2_Display *display)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(display);
|
2016-04-22 06:36:54 -07:00
|
|
|
|
2017-03-01 05:32:18 -08:00
|
|
|
--display->refs;
|
2016-08-10 19:34:00 -07:00
|
|
|
if (display->refs == 0)
|
2015-10-23 09:03:08 -07:00
|
|
|
{
|
2017-03-01 05:32:18 -08:00
|
|
|
/* this ensures that things like wl_registry are destroyed
|
|
|
|
* before we destroy the actual wl_display */
|
|
|
|
_ecore_wl2_display_cleanup(display);
|
|
|
|
|
2015-10-23 09:03:08 -07:00
|
|
|
wl_display_destroy(display->wl.display);
|
2015-12-07 09:18:28 -08:00
|
|
|
|
|
|
|
/* remove this client display from hash */
|
|
|
|
eina_hash_del_by_key(_server_displays, display->name);
|
2016-05-05 07:45:59 -07:00
|
|
|
ecore_timer_del(display->recovery_timer);
|
2015-12-07 09:18:28 -08:00
|
|
|
|
|
|
|
free(display->name);
|
2015-10-23 09:03:08 -07:00
|
|
|
free(display);
|
|
|
|
}
|
2015-08-20 07:22:03 -07:00
|
|
|
}
|
2015-08-20 07:41:33 -07:00
|
|
|
|
|
|
|
EAPI void
|
|
|
|
ecore_wl2_display_terminate(Ecore_Wl2_Display *display)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(display);
|
|
|
|
wl_display_terminate(display->wl.display);
|
|
|
|
}
|
2015-08-20 07:57:07 -07:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2015-08-20 09:18:52 -07:00
|
|
|
|
2016-04-11 14:09:12 -07:00
|
|
|
EAPI void *
|
|
|
|
ecore_wl2_display_dmabuf_get(Ecore_Wl2_Display *display)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
|
|
|
|
return display->wl.dmabuf;
|
|
|
|
}
|
|
|
|
|
2015-08-20 09:18:52 -07:00
|
|
|
EAPI Eina_Iterator *
|
|
|
|
ecore_wl2_display_globals_get(Ecore_Wl2_Display *display)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
|
2017-01-04 11:20:42 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(display->globals, NULL);
|
|
|
|
|
|
|
|
return eina_hash_iterator_data_new(display->globals);
|
2015-08-20 09:18:52 -07:00
|
|
|
}
|
2015-09-25 11:31:30 -07:00
|
|
|
|
2015-09-28 08:58:51 -07:00
|
|
|
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;
|
|
|
|
}
|
2015-10-01 07:00:07 -07:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2015-10-01 07:02:20 -07:00
|
|
|
|
|
|
|
EAPI struct wl_registry *
|
|
|
|
ecore_wl2_display_registry_get(Ecore_Wl2_Display *display)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
|
|
|
|
|
2015-10-06 11:45:02 -07:00
|
|
|
return display->wl.registry;
|
2015-10-01 07:02:20 -07:00
|
|
|
}
|
2015-12-28 06:09:04 -08:00
|
|
|
|
|
|
|
EAPI int
|
|
|
|
ecore_wl2_display_compositor_version_get(Ecore_Wl2_Display *display)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(display, 0);
|
|
|
|
|
|
|
|
return display->wl.compositor_version;
|
|
|
|
}
|