6 #include "ecore_wl_private.h"
8 /* local function prototypes */
9 static Eina_Bool _ecore_wl_shutdown(Eina_Bool close);
10 static int _ecore_wl_cb_event_mask_update(unsigned int mask, void *data);
11 static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__);
12 static void _ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char *interface, unsigned int version __UNUSED__, void *data);
13 static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd);
14 static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd);
17 static int _ecore_wl_init_count = 0;
19 /* external variables */
20 int _ecore_wl_log_dom = -1;
21 Ecore_Wl_Display *_ecore_wl_disp = NULL;
23 EAPI int ECORE_WL_EVENT_MOUSE_IN = 0;
24 EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0;
25 EAPI int ECORE_WL_EVENT_FOCUS_IN = 0;
26 EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0;
27 EAPI int ECORE_WL_EVENT_WINDOW_CONFIGURE = 0;
28 EAPI int ECORE_WL_EVENT_DND_ENTER = 0;
29 EAPI int ECORE_WL_EVENT_DND_POSITION = 0;
30 EAPI int ECORE_WL_EVENT_DND_LEAVE = 0;
31 EAPI int ECORE_WL_EVENT_DND_DROP = 0;
32 EAPI int ECORE_WL_EVENT_DATA_SOURCE_TARGET = 0;
33 EAPI int ECORE_WL_EVENT_DATA_SOURCE_SEND = 0;
34 EAPI int ECORE_WL_EVENT_SELECTION_DATA_READY = 0;
35 EAPI int ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = 0;
36 EAPI int ECORE_WL_EVENT_INTERFACES_BOUND = 0;
39 * @defgroup Ecore_Wl_Init_Group Wayland Library Init and Shutdown Functions
41 * Functions that start and shutdown the Ecore Wayland Library.
45 * Initialize the Wayland display connection to the given display.
47 * @param name Display target name. if @c NULL, the default display is
49 * @return The number of times the library has been initialized without being
50 * shut down. 0 is returned if an error occurs.
52 * @ingroup Ecore_Wl_Init_Group
55 ecore_wl_init(const char *name)
57 LOGFN(__FILE__, __LINE__, __FUNCTION__);
59 if (++_ecore_wl_init_count != 1) return _ecore_wl_init_count;
61 if (!eina_init()) return --_ecore_wl_init_count;
64 eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR);
65 if (_ecore_wl_log_dom < 0)
67 EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland");
69 return --_ecore_wl_init_count;
74 ERR("Could not initialize ecore");
75 eina_log_domain_unregister(_ecore_wl_log_dom);
76 _ecore_wl_log_dom = -1;
78 return --_ecore_wl_init_count;
81 if (!ecore_event_init())
83 ERR("Could not initialize ecore_event");
84 eina_log_domain_unregister(_ecore_wl_log_dom);
85 _ecore_wl_log_dom = -1;
88 return --_ecore_wl_init_count;
91 if (!ECORE_WL_EVENT_MOUSE_IN)
93 ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new();
94 ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new();
95 ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new();
96 ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new();
97 ECORE_WL_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
98 ECORE_WL_EVENT_DND_ENTER = ecore_event_type_new();
99 ECORE_WL_EVENT_DND_POSITION = ecore_event_type_new();
100 ECORE_WL_EVENT_DND_LEAVE = ecore_event_type_new();
101 ECORE_WL_EVENT_DND_DROP = ecore_event_type_new();
102 ECORE_WL_EVENT_DATA_SOURCE_TARGET = ecore_event_type_new();
103 ECORE_WL_EVENT_DATA_SOURCE_SEND = ecore_event_type_new();
104 ECORE_WL_EVENT_SELECTION_DATA_READY = ecore_event_type_new();
105 ECORE_WL_EVENT_DATA_SOURCE_CANCELLED = ecore_event_type_new();
106 ECORE_WL_EVENT_INTERFACES_BOUND = ecore_event_type_new();
109 if (!(_ecore_wl_disp = malloc(sizeof(Ecore_Wl_Display))))
111 ERR("Could not allocate memory for Ecore_Wl_Display structure");
112 eina_log_domain_unregister(_ecore_wl_log_dom);
113 _ecore_wl_log_dom = -1;
114 ecore_event_shutdown();
117 return --_ecore_wl_init_count;
120 memset(_ecore_wl_disp, 0, sizeof(Ecore_Wl_Display));
122 if (!(_ecore_wl_disp->wl.display = wl_display_connect(name)))
124 ERR("Could not connect to Wayland display");
125 eina_log_domain_unregister(_ecore_wl_log_dom);
126 _ecore_wl_log_dom = -1;
127 ecore_event_shutdown();
130 return --_ecore_wl_init_count;
134 wl_display_get_fd(_ecore_wl_disp->wl.display,
135 _ecore_wl_cb_event_mask_update, _ecore_wl_disp);
137 _ecore_wl_disp->fd_hdl =
138 ecore_main_fd_handler_add(_ecore_wl_disp->fd, ECORE_FD_READ,
139 _ecore_wl_cb_handle_data, _ecore_wl_disp,
142 wl_list_init(&_ecore_wl_disp->inputs);
143 wl_list_init(&_ecore_wl_disp->outputs);
145 wl_display_add_global_listener(_ecore_wl_disp->wl.display,
146 _ecore_wl_cb_handle_global, _ecore_wl_disp);
150 /* FIXME: Process connection events ?? */
151 /* wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE); */
153 /* TODO: create pointer surfaces */
155 if (!_ecore_wl_xkb_init(_ecore_wl_disp))
157 ERR("Could not initialize XKB");
158 free(_ecore_wl_disp);
159 eina_log_domain_unregister(_ecore_wl_log_dom);
160 _ecore_wl_log_dom = -1;
161 ecore_event_shutdown();
164 return --_ecore_wl_init_count;
167 _ecore_wl_window_init();
169 return _ecore_wl_init_count;
173 * Shuts down the Ecore Wayland Library
175 * In shutting down the library, the Wayland display connection is terminated
176 * and any event handlers for it are removed.
178 * @return The number of times the library has been initialized without
181 * @ingroup Ecore_Wl_Init_Group
184 ecore_wl_shutdown(void)
186 LOGFN(__FILE__, __LINE__, __FUNCTION__);
188 return _ecore_wl_shutdown(EINA_TRUE);
192 * @defgroup Ecore_Wl_Flush_Group Wayland Synchronization Functions
194 * Functions that ensure that all commands which have been issued by the
195 * Ecore Wayland library have been sent to the server.
199 * Sends all Wayland commands to the Wayland Display.
201 * @ingroup Ecore_Wl_Flush_Group
207 // LOGFN(__FILE__, __LINE__, __FUNCTION__);
209 while (_ecore_wl_disp->mask & WL_DISPLAY_WRITABLE)
210 wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_WRITABLE);
214 * Flushes the command buffer and waits until all requests have been
215 * processed by the server.
217 * @ingroup Ecore_Wl_Flush_Group
223 // LOGFN(__FILE__, __LINE__, __FUNCTION__);
225 wl_display_sync(_ecore_wl_disp->wl.display);
229 * @defgroup Ecore_Wl_Display_Group Wayland Display Functions
231 * Functions that set and retrieve various information about the Wayland Display.
235 * Retrieves the Wayland Shm Interface used for the current Wayland connection.
237 * @return The current wayland shm interface
239 * @ingroup Ecore_Wl_Display_Group
243 ecore_wl_shm_get(void)
245 return _ecore_wl_disp->wl.shm;
249 * Retrieves the Wayland Display Interface used for the current Wayland connection.
251 * @return The current wayland display interface
253 * @ingroup Ecore_Wl_Display_Group
256 EAPI struct wl_display *
257 ecore_wl_display_get(void)
259 return _ecore_wl_disp->wl.display;
263 * Retrieves the size of the current screen.
265 * @param w where to return the width. May be NULL. Returns 0 on error.
266 * @param h where to return the height. May be NULL. Returns 0 on error.
268 * @ingroup Ecore_Wl_Display_Group
272 ecore_wl_screen_size_get(int *w, int *h)
274 LOGFN(__FILE__, __LINE__, __FUNCTION__);
279 if (!_ecore_wl_disp->output) return;
281 if (w) *w = _ecore_wl_disp->output->allocation.w;
282 if (h) *h = _ecore_wl_disp->output->allocation.h;
287 ecore_wl_pointer_xy_get(int *x, int *y)
289 LOGFN(__FILE__, __LINE__, __FUNCTION__);
291 _ecore_wl_input_pointer_xy_get(x, y);
295 * Return the screen DPI
297 * This is a simplistic call to get DPI. It does not account for differing
298 * DPI in the x and y axes nor does it account for multihead or xinerama and
299 * xrandr where different parts of the screen may have different DPI etc.
301 * @return the general screen DPI (dots/pixels per inch).
306 ecore_wl_dpi_get(void)
310 LOGFN(__FILE__, __LINE__, __FUNCTION__);
312 if (!_ecore_wl_disp->output) return 75;
314 mw = _ecore_wl_disp->output->mw;
315 if (mw <= 0) return 75;
317 w = _ecore_wl_disp->output->allocation.w;
318 /* FIXME: NB: Hrrrmmm, need to verify this. xorg code is using a different
319 * formula to calc this */
320 return (((w * 254) / mw) + 5) / 10;
324 ecore_wl_display_iterate(void)
326 wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE);
330 * Retrieves the requested cursor from the cursor theme
332 * @param cursor_name The desired cursor name to be looked up in the theme
333 * @return the cursor or NULL if the cursor cannot be found
337 EAPI struct wl_cursor *
338 ecore_wl_cursor_get(const char *cursor_name)
340 if ((!_ecore_wl_disp) || (!_ecore_wl_disp->cursor_theme))
343 return wl_cursor_theme_get_cursor(_ecore_wl_disp->cursor_theme,
347 /* local functions */
349 _ecore_wl_shutdown(Eina_Bool close)
351 LOGFN(__FILE__, __LINE__, __FUNCTION__);
353 if (--_ecore_wl_init_count != 0) return _ecore_wl_init_count;
354 if (!_ecore_wl_disp) return _ecore_wl_init_count;
356 _ecore_wl_window_shutdown();
358 if (_ecore_wl_disp->fd_hdl)
359 ecore_main_fd_handler_del(_ecore_wl_disp->fd_hdl);
363 Ecore_Wl_Output *out, *tout;
364 Ecore_Wl_Input *in, *tin;
366 wl_list_for_each_safe(out, tout, &_ecore_wl_disp->outputs, link)
367 _ecore_wl_output_del(out);
369 wl_list_for_each_safe(in, tin, &_ecore_wl_disp->inputs, link)
370 _ecore_wl_input_del(in);
372 _ecore_wl_xkb_shutdown(_ecore_wl_disp);
374 if (_ecore_wl_disp->wl.shell)
375 wl_shell_destroy(_ecore_wl_disp->wl.shell);
376 if (_ecore_wl_disp->wl.shm) wl_shm_destroy(_ecore_wl_disp->wl.shm);
377 if (_ecore_wl_disp->wl.data_device_manager)
378 wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager);
379 if (_ecore_wl_disp->wl.compositor)
380 wl_compositor_destroy(_ecore_wl_disp->wl.compositor);
381 if (_ecore_wl_disp->wl.display)
383 wl_display_flush(_ecore_wl_disp->wl.display);
384 wl_display_disconnect(_ecore_wl_disp->wl.display);
386 free(_ecore_wl_disp);
389 ecore_event_shutdown();
392 eina_log_domain_unregister(_ecore_wl_log_dom);
393 _ecore_wl_log_dom = -1;
396 return _ecore_wl_init_count;
400 _ecore_wl_cb_event_mask_update(unsigned int mask, void *data)
402 Ecore_Wl_Display *ewd;
404 // LOGFN(__FILE__, __LINE__, __FUNCTION__);
412 _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__)
414 Ecore_Wl_Display *ewd;
416 /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
418 if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
419 wl_display_iterate(ewd->wl.display, ewd->mask);
420 return ECORE_CALLBACK_RENEW;
424 _ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char *interface, unsigned int version __UNUSED__, void *data)
426 Ecore_Wl_Display *ewd;
428 // LOGFN(__FILE__, __LINE__, __FUNCTION__);
432 /* TODO: Add listener for wl_display so we can catch fatal errors !! */
434 if (!strcmp(interface, "wl_compositor"))
435 ewd->wl.compositor = wl_display_bind(disp, id, &wl_compositor_interface);
436 else if (!strcmp(interface, "wl_output"))
437 _ecore_wl_output_add(ewd, id);
438 else if (!strcmp(interface, "wl_seat"))
439 _ecore_wl_input_add(ewd, id);
440 else if (!strcmp(interface, "wl_shell"))
441 ewd->wl.shell = wl_display_bind(disp, id, &wl_shell_interface);
442 /* else if (!strcmp(interface, "desktop_shell")) */
443 /* ewd->wl.desktop_shell = wl_display_bind(disp, id, &wl_shell_interface); */
444 else if (!strcmp(interface, "wl_shm"))
446 ewd->wl.shm = wl_display_bind(disp, id, &wl_shm_interface);
448 /* FIXME: We should not hard-code a cursor size here, and we should
449 * also import the theme name from a config or env variable */
450 ewd->cursor_theme = wl_cursor_theme_load(NULL, 32, ewd->wl.shm);
452 else if (!strcmp(interface, "wl_data_device_manager"))
454 ewd->wl.data_device_manager =
455 wl_display_bind(disp, id, &wl_data_device_manager_interface);
458 if ((ewd->wl.compositor) && (ewd->wl.shm) && (ewd->wl.shell))
460 Ecore_Wl_Event_Interfaces_Bound *ev;
462 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Interfaces_Bound))))
465 ev->compositor = (ewd->wl.compositor != NULL);
466 ev->shm = (ewd->wl.shm != NULL);
467 ev->shell = (ewd->wl.shell != NULL);
469 ecore_event_add(ECORE_WL_EVENT_INTERFACES_BOUND, ev, NULL, NULL);
474 _ecore_wl_xkb_init(Ecore_Wl_Display *ewd)
476 LOGFN(__FILE__, __LINE__, __FUNCTION__);
478 if (!(ewd->xkb.context = xkb_context_new(0)))
485 _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd)
487 LOGFN(__FILE__, __LINE__, __FUNCTION__);
489 xkb_context_unref(ewd->xkb.context);
494 struct wl_data_source *
495 _ecore_wl_create_data_source(Ecore_Wl_Display *ewd)
497 return wl_data_device_manager_create_data_source(ewd->wl.data_device_manager);