#include <fcntl.h>
#include "ecore_wl_private.h"
+#include <subsurface-client-protocol.h>
/* local function prototypes */
static Eina_Bool _ecore_wl_shutdown(Eina_Bool close);
+static Eina_Bool _ecore_wl_cb_idle_enterer(void *data);
static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl);
static void _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version __UNUSED__);
static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd);
static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd);
+static void _ecore_wl_sync_wait(Ecore_Wl_Display *ewd);
+static void _ecore_wl_sync_callback(void *data, struct wl_callback *callback, uint32_t serial);
/* local variables */
static int _ecore_wl_init_count = 0;
NULL // handle_global_remove
};
+static const struct wl_callback_listener _ecore_wl_sync_listener =
+{
+ _ecore_wl_sync_callback
+};
+
/* external variables */
int _ecore_wl_log_dom = -1;
Ecore_Wl_Display *_ecore_wl_disp = NULL;
_ecore_wl_disp->fd = wl_display_get_fd(_ecore_wl_disp->wl.display);
- _ecore_wl_disp->fd_hdl =
- ecore_main_fd_handler_add(_ecore_wl_disp->fd,
- ECORE_FD_READ | ECORE_FD_WRITE,
- _ecore_wl_cb_handle_data, _ecore_wl_disp,
+ _ecore_wl_disp->fd_hdl =
+ ecore_main_fd_handler_add(_ecore_wl_disp->fd,
+ ECORE_FD_READ,
+ _ecore_wl_cb_handle_data, _ecore_wl_disp,
NULL, NULL);
+ _ecore_wl_disp->idle_enterer =
+ ecore_idle_enterer_add(_ecore_wl_cb_idle_enterer, _ecore_wl_disp);
+
wl_list_init(&_ecore_wl_disp->inputs);
wl_list_init(&_ecore_wl_disp->outputs);
+ wl_list_init(&_ecore_wl_disp->globals);
_ecore_wl_disp->wl.registry =
wl_display_get_registry(_ecore_wl_disp->wl.display);
{
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
- wl_display_sync(_ecore_wl_disp->wl.display);
+ _ecore_wl_sync_wait(_ecore_wl_disp);
+ while (_ecore_wl_disp->sync_ref_count > 0)
+ wl_display_dispatch(_ecore_wl_disp->wl.display);
}
/**
return _ecore_wl_disp->wl.display;
}
+EAPI struct wl_list *
+ecore_wl_globals_get(void)
+{
+ return &(_ecore_wl_disp->globals);
+}
+
+EAPI struct wl_registry *
+ecore_wl_registry_get(void)
+{
+ return _ecore_wl_disp->wl.registry;
+}
+
/**
* Retrieves the size of the current screen.
*
if (w) *w = 0;
if (h) *h = 0;
+ if (!_ecore_wl_disp->output)
+ ecore_wl_sync();
+
if (!_ecore_wl_disp->output) return;
- if (w) *w = _ecore_wl_disp->output->allocation.w;
- if (h) *h = _ecore_wl_disp->output->allocation.h;
+ switch (_ecore_wl_disp->output->transform)
+ {
+ case WL_OUTPUT_TRANSFORM_90:
+ case WL_OUTPUT_TRANSFORM_270:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ /* Swap width and height */
+ if (w) *w = _ecore_wl_disp->output->allocation.h;
+ if (h) *h = _ecore_wl_disp->output->allocation.w;
+ break;
+ default:
+ if (w) *w = _ecore_wl_disp->output->allocation.w;
+ if (h) *h = _ecore_wl_disp->output->allocation.h;
+ }
}
/* @since 1.2 */
if (_ecore_wl_disp->fd_hdl)
ecore_main_fd_handler_del(_ecore_wl_disp->fd_hdl);
+ if (_ecore_wl_disp->idle_enterer)
+ ecore_idle_enterer_del(_ecore_wl_disp->idle_enterer);
if (close)
{
Ecore_Wl_Output *out, *tout;
Ecore_Wl_Input *in, *tin;
+ Ecore_Wl_Global *global, *tglobal;
wl_list_for_each_safe(out, tout, &_ecore_wl_disp->outputs, link)
_ecore_wl_output_del(out);
wl_list_for_each_safe(in, tin, &_ecore_wl_disp->inputs, link)
_ecore_wl_input_del(in);
+ wl_list_for_each_safe(global, tglobal, &_ecore_wl_disp->globals, link)
+ {
+ wl_list_remove(&global->link);
+ free(global->interface);
+ free(global);
+ }
+
_ecore_wl_xkb_shutdown(_ecore_wl_disp);
if (_ecore_wl_disp->wl.shell)
wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager);
if (_ecore_wl_disp->wl.compositor)
wl_compositor_destroy(_ecore_wl_disp->wl.compositor);
+ if (_ecore_wl_disp->wl.subcompositor)
+ wl_compositor_destroy(_ecore_wl_disp->wl.subcompositor);
if (_ecore_wl_disp->wl.display)
{
wl_registry_destroy(_ecore_wl_disp->wl.registry);
return _ecore_wl_init_count;
}
-static Eina_Bool
+static Eina_Bool
+_ecore_wl_cb_idle_enterer(void *data)
+{
+ Ecore_Wl_Display *ewd;
+ int ret;
+
+ if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
+
+ 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));
+ }
+ else if (ret < 0)
+ {
+ /* FIXME: need do error processing? */
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
_ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl)
{
Ecore_Wl_Display *ewd;
+ int ret;
/* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
wl_display_dispatch(ewd->wl.display);
else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
- wl_display_flush(ewd->wl.display);
+ {
+ ret = wl_display_flush(ewd->wl.display);
+ if (ret == 0)
+ ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
+ else if ((ret == -1) && (errno != EAGAIN))
+ {
+ /* FIXME: need do error processing? */
+ }
+ }
return ECORE_CALLBACK_RENEW;
}
_ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version __UNUSED__)
{
Ecore_Wl_Display *ewd;
+ Ecore_Wl_Global *global;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
ewd = data;
+ global = malloc(sizeof(*global));
+
+ memset(global, 0, sizeof(Ecore_Wl_Global));
+
+ global->id = id;
+ global->interface = strdup(interface);
+ global->version = version;
+ wl_list_insert(ewd->globals.prev, &global->link);
+
if (!strcmp(interface, "wl_compositor"))
{
ewd->wl.compositor =
wl_registry_bind(registry, id, &wl_compositor_interface, 1);
}
+ else if (!strcmp(interface, "wl_subcompositor"))
+ {
+ ewd->wl.subcompositor =
+ wl_registry_bind(registry, id, &wl_subcompositor_interface, 1);
+ }
else if (!strcmp(interface, "wl_output"))
_ecore_wl_output_add(ewd, id);
else if (!strcmp(interface, "wl_seat"))
{
return wl_data_device_manager_create_data_source(ewd->wl.data_device_manager);
}
+
+static void
+_ecore_wl_sync_callback(void *data, struct wl_callback *callback, uint32_t serial EINA_UNUSED)
+{
+ Ecore_Wl_Display *ewd = data;
+
+ ewd->sync_ref_count--;
+ wl_callback_destroy(callback);
+}
+
+static void
+_ecore_wl_sync_wait(Ecore_Wl_Display *ewd)
+{
+ struct wl_callback *callback;
+
+ ewd->sync_ref_count++;
+ callback = wl_display_sync(ewd->wl.display);
+ wl_callback_add_listener(callback, &_ecore_wl_sync_listener, ewd);
+}