17 # define alloca __builtin_alloca
19 # define alloca __alloca
20 # elif defined _MSC_VER
22 # define alloca _alloca
23 # elif !defined HAVE_ALLOCA
27 void *alloca (size_t);
32 #include "ecore_wl_private.h"
34 /* local function prototypes */
35 static Eina_Bool _ecore_wl_shutdown(Eina_Bool close);
36 static Eina_Bool _ecore_wl_cb_idle_enterer(void *data);
37 static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl);
38 static void _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version __UNUSED__);
39 static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd);
40 static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd);
43 static int _ecore_wl_init_count = 0;
44 static const struct wl_registry_listener _ecore_wl_registry_listener =
46 _ecore_wl_cb_handle_global,
47 NULL // handle_global_remove
50 /* external variables */
51 int _ecore_wl_log_dom = -1;
52 Ecore_Wl_Display *_ecore_wl_disp = NULL;
54 EAPI int ECORE_WL_EVENT_MOUSE_IN = 0;
55 EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0;
56 EAPI int ECORE_WL_EVENT_FOCUS_IN = 0;
57 EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0;
58 EAPI int ECORE_WL_EVENT_WINDOW_CONFIGURE = 0;
59 EAPI int ECORE_WL_EVENT_DND_ENTER = 0;
60 EAPI int ECORE_WL_EVENT_DND_POSITION = 0;
61 EAPI int ECORE_WL_EVENT_DND_LEAVE = 0;
62 EAPI int ECORE_WL_EVENT_DND_DROP = 0;
63 EAPI int ECORE_WL_EVENT_DATA_SOURCE_TARGET = 0;
64 EAPI int ECORE_WL_EVENT_DATA_SOURCE_SEND = 0;
65 EAPI int ECORE_WL_EVENT_SELECTION_DATA_READY = 0;
66 EAPI int ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = 0;
67 EAPI int ECORE_WL_EVENT_INTERFACES_BOUND = 0;
70 * @defgroup Ecore_Wl_Init_Group Wayland Library Init and Shutdown Functions
72 * Functions that start and shutdown the Ecore Wayland Library.
76 * Initialize the Wayland display connection to the given display.
78 * @param name Display target name. if @c NULL, the default display is
80 * @return The number of times the library has been initialized without being
81 * shut down. 0 is returned if an error occurs.
83 * @ingroup Ecore_Wl_Init_Group
86 ecore_wl_init(const char *name)
88 LOGFN(__FILE__, __LINE__, __FUNCTION__);
90 if (++_ecore_wl_init_count != 1) return _ecore_wl_init_count;
92 if (!eina_init()) return --_ecore_wl_init_count;
95 eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR);
96 if (_ecore_wl_log_dom < 0)
98 EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland");
100 return --_ecore_wl_init_count;
105 ERR("Could not initialize ecore");
106 eina_log_domain_unregister(_ecore_wl_log_dom);
107 _ecore_wl_log_dom = -1;
109 return --_ecore_wl_init_count;
112 if (!ecore_event_init())
114 ERR("Could not initialize ecore_event");
115 eina_log_domain_unregister(_ecore_wl_log_dom);
116 _ecore_wl_log_dom = -1;
119 return --_ecore_wl_init_count;
122 if (!ECORE_WL_EVENT_MOUSE_IN)
124 ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new();
125 ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new();
126 ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new();
127 ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new();
128 ECORE_WL_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
129 ECORE_WL_EVENT_DND_ENTER = ecore_event_type_new();
130 ECORE_WL_EVENT_DND_POSITION = ecore_event_type_new();
131 ECORE_WL_EVENT_DND_LEAVE = ecore_event_type_new();
132 ECORE_WL_EVENT_DND_DROP = ecore_event_type_new();
133 ECORE_WL_EVENT_DATA_SOURCE_TARGET = ecore_event_type_new();
134 ECORE_WL_EVENT_DATA_SOURCE_SEND = ecore_event_type_new();
135 ECORE_WL_EVENT_SELECTION_DATA_READY = ecore_event_type_new();
136 ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = ecore_event_type_new();
137 ECORE_WL_EVENT_INTERFACES_BOUND = ecore_event_type_new();
140 if (!(_ecore_wl_disp = malloc(sizeof(Ecore_Wl_Display))))
142 ERR("Could not allocate memory for Ecore_Wl_Display structure");
143 eina_log_domain_unregister(_ecore_wl_log_dom);
144 _ecore_wl_log_dom = -1;
145 ecore_event_shutdown();
148 return --_ecore_wl_init_count;
151 memset(_ecore_wl_disp, 0, sizeof(Ecore_Wl_Display));
153 if (!(_ecore_wl_disp->wl.display = wl_display_connect(name)))
155 ERR("Could not connect to Wayland display");
156 eina_log_domain_unregister(_ecore_wl_log_dom);
157 _ecore_wl_log_dom = -1;
158 ecore_event_shutdown();
161 return --_ecore_wl_init_count;
164 _ecore_wl_disp->fd = wl_display_get_fd(_ecore_wl_disp->wl.display);
166 _ecore_wl_disp->fd_hdl =
167 ecore_main_fd_handler_add(_ecore_wl_disp->fd,
169 _ecore_wl_cb_handle_data, _ecore_wl_disp,
172 _ecore_wl_disp->idle_enterer =
173 ecore_idle_enterer_add(_ecore_wl_cb_idle_enterer, _ecore_wl_disp);
175 wl_list_init(&_ecore_wl_disp->inputs);
176 wl_list_init(&_ecore_wl_disp->outputs);
178 _ecore_wl_disp->wl.registry =
179 wl_display_get_registry(_ecore_wl_disp->wl.display);
180 wl_registry_add_listener(_ecore_wl_disp->wl.registry,
181 &_ecore_wl_registry_listener, _ecore_wl_disp);
183 wl_display_dispatch(_ecore_wl_disp->wl.display);
185 if (!_ecore_wl_xkb_init(_ecore_wl_disp))
187 ERR("Could not initialize XKB");
188 free(_ecore_wl_disp);
189 eina_log_domain_unregister(_ecore_wl_log_dom);
190 _ecore_wl_log_dom = -1;
191 ecore_event_shutdown();
194 return --_ecore_wl_init_count;
197 _ecore_wl_window_init();
199 return _ecore_wl_init_count;
203 * Shuts down the Ecore Wayland Library
205 * In shutting down the library, the Wayland display connection is terminated
206 * and any event handlers for it are removed.
208 * @return The number of times the library has been initialized without
211 * @ingroup Ecore_Wl_Init_Group
214 ecore_wl_shutdown(void)
216 LOGFN(__FILE__, __LINE__, __FUNCTION__);
218 return _ecore_wl_shutdown(EINA_TRUE);
222 * @defgroup Ecore_Wl_Flush_Group Wayland Synchronization Functions
224 * Functions that ensure that all commands which have been issued by the
225 * Ecore Wayland library have been sent to the server.
229 * Sends all Wayland commands to the Wayland Display.
231 * @ingroup Ecore_Wl_Flush_Group
237 // LOGFN(__FILE__, __LINE__, __FUNCTION__);
239 wl_display_flush(_ecore_wl_disp->wl.display);
243 * Flushes the command buffer and waits until all requests have been
244 * processed by the server.
246 * @ingroup Ecore_Wl_Flush_Group
252 // LOGFN(__FILE__, __LINE__, __FUNCTION__);
254 wl_display_sync(_ecore_wl_disp->wl.display);
258 * @defgroup Ecore_Wl_Display_Group Wayland Display Functions
260 * Functions that set and retrieve various information about the Wayland Display.
264 * Retrieves the Wayland Shm Interface used for the current Wayland connection.
266 * @return The current wayland shm interface
268 * @ingroup Ecore_Wl_Display_Group
272 ecore_wl_shm_get(void)
274 return _ecore_wl_disp->wl.shm;
278 * Retrieves the Wayland Display Interface used for the current Wayland connection.
280 * @return The current wayland display interface
282 * @ingroup Ecore_Wl_Display_Group
285 EAPI struct wl_display *
286 ecore_wl_display_get(void)
288 return _ecore_wl_disp->wl.display;
292 * Retrieves the size of the current screen.
294 * @param w where to return the width. May be NULL. Returns 0 on error.
295 * @param h where to return the height. May be NULL. Returns 0 on error.
297 * @ingroup Ecore_Wl_Display_Group
301 ecore_wl_screen_size_get(int *w, int *h)
303 LOGFN(__FILE__, __LINE__, __FUNCTION__);
308 if (!_ecore_wl_disp->output) return;
310 if (w) *w = _ecore_wl_disp->output->allocation.w;
311 if (h) *h = _ecore_wl_disp->output->allocation.h;
316 ecore_wl_pointer_xy_get(int *x, int *y)
318 LOGFN(__FILE__, __LINE__, __FUNCTION__);
320 _ecore_wl_input_pointer_xy_get(x, y);
324 * Return the screen DPI
326 * This is a simplistic call to get DPI. It does not account for differing
327 * DPI in the x and y axes nor does it account for multihead or xinerama and
328 * xrandr where different parts of the screen may have different DPI etc.
330 * @return the general screen DPI (dots/pixels per inch).
335 ecore_wl_dpi_get(void)
339 LOGFN(__FILE__, __LINE__, __FUNCTION__);
341 if (!_ecore_wl_disp->output) return 75;
343 mw = _ecore_wl_disp->output->mw;
344 if (mw <= 0) return 75;
346 w = _ecore_wl_disp->output->allocation.w;
347 /* FIXME: NB: Hrrrmmm, need to verify this. xorg code is using a different
348 * formula to calc this */
349 return (((w * 254) / mw) + 5) / 10;
353 ecore_wl_display_iterate(void)
355 wl_display_dispatch(_ecore_wl_disp->wl.display);
359 * Retrieves the requested cursor from the cursor theme
361 * @param cursor_name The desired cursor name to be looked up in the theme
362 * @return the cursor or NULL if the cursor cannot be found
366 EAPI struct wl_cursor *
367 ecore_wl_cursor_get(const char *cursor_name)
369 if ((!_ecore_wl_disp) || (!_ecore_wl_disp->cursor_theme))
372 return wl_cursor_theme_get_cursor(_ecore_wl_disp->cursor_theme,
376 /* local functions */
378 _ecore_wl_shutdown(Eina_Bool close)
380 LOGFN(__FILE__, __LINE__, __FUNCTION__);
382 if (--_ecore_wl_init_count != 0) return _ecore_wl_init_count;
383 if (!_ecore_wl_disp) return _ecore_wl_init_count;
385 _ecore_wl_window_shutdown();
387 if (_ecore_wl_disp->fd_hdl)
388 ecore_main_fd_handler_del(_ecore_wl_disp->fd_hdl);
389 if (_ecore_wl_disp->idle_enterer)
390 ecore_idle_enterer_del(_ecore_wl_disp->idle_enterer);
394 Ecore_Wl_Output *out, *tout;
395 Ecore_Wl_Input *in, *tin;
397 wl_list_for_each_safe(out, tout, &_ecore_wl_disp->outputs, link)
398 _ecore_wl_output_del(out);
400 wl_list_for_each_safe(in, tin, &_ecore_wl_disp->inputs, link)
401 _ecore_wl_input_del(in);
403 _ecore_wl_xkb_shutdown(_ecore_wl_disp);
405 if (_ecore_wl_disp->wl.shell)
406 wl_shell_destroy(_ecore_wl_disp->wl.shell);
407 if (_ecore_wl_disp->wl.shm) wl_shm_destroy(_ecore_wl_disp->wl.shm);
408 if (_ecore_wl_disp->wl.data_device_manager)
409 wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager);
410 if (_ecore_wl_disp->wl.compositor)
411 wl_compositor_destroy(_ecore_wl_disp->wl.compositor);
412 if (_ecore_wl_disp->wl.display)
414 wl_registry_destroy(_ecore_wl_disp->wl.registry);
415 wl_display_flush(_ecore_wl_disp->wl.display);
416 wl_display_disconnect(_ecore_wl_disp->wl.display);
418 free(_ecore_wl_disp);
421 ecore_event_shutdown();
424 eina_log_domain_unregister(_ecore_wl_log_dom);
425 _ecore_wl_log_dom = -1;
428 return _ecore_wl_init_count;
432 _ecore_wl_cb_idle_enterer(void *data)
434 Ecore_Wl_Display *ewd;
437 if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
439 ret = wl_display_flush(ewd->wl.display);
440 if ((ret < 0) && (errno == EAGAIN))
442 ecore_main_fd_handler_active_set(ewd->fd_hdl,
443 (ECORE_FD_READ | ECORE_FD_WRITE));
447 /* FIXME: need do error processing? */
450 return ECORE_CALLBACK_RENEW;
454 _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl)
456 Ecore_Wl_Display *ewd;
459 /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
461 if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
463 /* FIXME: This should also catch ECORE_FD_ERROR and exit */
465 /* wl_display_dispatch_pending(ewd->wl.display); */
467 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
468 wl_display_dispatch(ewd->wl.display);
469 else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
471 ret = wl_display_flush(ewd->wl.display);
473 ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
474 else if ((ret == -1) && (errno != EAGAIN))
476 /* FIXME: need do error processing? */
480 return ECORE_CALLBACK_RENEW;
484 _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version __UNUSED__)
486 Ecore_Wl_Display *ewd;
488 LOGFN(__FILE__, __LINE__, __FUNCTION__);
492 if (!strcmp(interface, "wl_compositor"))
495 wl_registry_bind(registry, id, &wl_compositor_interface, 1);
497 else if (!strcmp(interface, "wl_output"))
498 _ecore_wl_output_add(ewd, id);
499 else if (!strcmp(interface, "wl_seat"))
500 _ecore_wl_input_add(ewd, id);
501 else if (!strcmp(interface, "wl_shell"))
504 wl_registry_bind(registry, id, &wl_shell_interface, 1);
506 else if (!strcmp(interface, "wl_shm"))
508 ewd->wl.shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
510 /* FIXME: We should not hard-code a cursor size here, and we should
511 * also import the theme name from a config or env variable */
512 ewd->cursor_theme = wl_cursor_theme_load(NULL, 32, ewd->wl.shm);
514 else if (!strcmp(interface, "wl_data_device_manager"))
516 ewd->wl.data_device_manager =
517 wl_registry_bind(registry, id, &wl_data_device_manager_interface, 1);
520 if ((ewd->wl.compositor) && (ewd->wl.shm) && (ewd->wl.shell))
522 Ecore_Wl_Event_Interfaces_Bound *ev;
524 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Interfaces_Bound))))
527 ev->compositor = (ewd->wl.compositor != NULL);
528 ev->shm = (ewd->wl.shm != NULL);
529 ev->shell = (ewd->wl.shell != NULL);
531 ecore_event_add(ECORE_WL_EVENT_INTERFACES_BOUND, ev, NULL, NULL);
536 _ecore_wl_xkb_init(Ecore_Wl_Display *ewd)
538 LOGFN(__FILE__, __LINE__, __FUNCTION__);
540 if (!(ewd->xkb.context = xkb_context_new(0)))
547 _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd)
549 LOGFN(__FILE__, __LINE__, __FUNCTION__);
551 xkb_context_unref(ewd->xkb.context);
556 struct wl_data_source *
557 _ecore_wl_create_data_source(Ecore_Wl_Display *ewd)
559 return wl_data_device_manager_create_data_source(ewd->wl.data_device_manager);