aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_wayland/ecore_wl.c')
-rw-r--r--libraries/ecore/src/lib/ecore_wayland/ecore_wl.c551
1 files changed, 0 insertions, 551 deletions
diff --git a/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c b/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
deleted file mode 100644
index 5f1b20d..0000000
--- a/libraries/ecore/src/lib/ecore_wayland/ecore_wl.c
+++ /dev/null
@@ -1,551 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <fcntl.h>
6
7/* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ...
8 * What about other OSs ?? */
9#ifdef __linux__
10# include <linux/input.h>
11#else
12# define BTN_LEFT 0x110
13# define BTN_RIGHT 0x111
14# define BTN_MIDDLE 0x112
15# define BTN_SIDE 0x113
16# define BTN_EXTRA 0x114
17# define BTN_FORWARD 0x115
18# define BTN_BACK 0x116
19#endif
20
21#include "Ecore.h"
22#include "ecore_private.h"
23#include "Ecore_Input.h"
24#include "ecore_wl_private.h"
25#include "Ecore_Wayland.h"
26
27/* local function prototypes */
28static Eina_Bool _ecore_wl_shutdown(Eina_Bool close);
29static int _ecore_wl_cb_event_mask_update(unsigned int mask, void *data);
30static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__);
31static void _ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char *interface, unsigned int version __UNUSED__, void *data);
32static Eina_Bool _ecore_wl_egl_init(Ecore_Wl_Display *ewd);
33static Eina_Bool _ecore_wl_egl_shutdown(Ecore_Wl_Display *ewd);
34static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd);
35static Eina_Bool _ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd);
36
37/* local variables */
38static int _ecore_wl_init_count = 0;
39
40/* external variables */
41int _ecore_wl_log_dom = -1;
42Ecore_Wl_Display *_ecore_wl_disp = NULL;
43
44EAPI int ECORE_WL_EVENT_MOUSE_IN = 0;
45EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0;
46EAPI int ECORE_WL_EVENT_FOCUS_IN = 0;
47EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0;
48EAPI int ECORE_WL_EVENT_WINDOW_CONFIGURE = 0;
49EAPI int ECORE_WL_EVENT_DND_ENTER = 0;
50EAPI int ECORE_WL_EVENT_DND_POSITION = 0;
51EAPI int ECORE_WL_EVENT_DND_LEAVE = 0;
52EAPI int ECORE_WL_EVENT_DND_DROP = 0;
53EAPI int ECORE_WL_EVENT_INTERFACES_BOUND = 0;
54
55/**
56 * @defgroup Ecore_Wl_Init_Group Wayland Library Init and Shutdown Functions
57 *
58 * Functions that start and shutdown the Ecore Wayland Library.
59 */
60
61/**
62 * Initialize the Wayland display connection to the given display.
63 *
64 * @param name Display target name. if @c NULL, the default display is
65 * assumed.
66 * @return The number of times the library has been initialized without being
67 * shut down. 0 is returned if an error occurs.
68 *
69 * @ingroup Ecore_Wl_Init_Group
70 */
71EAPI int
72ecore_wl_init(const char *name)
73{
74 LOGFN(__FILE__, __LINE__, __FUNCTION__);
75
76 if (++_ecore_wl_init_count != 1) return _ecore_wl_init_count;
77
78 if (!eina_init()) return --_ecore_wl_init_count;
79
80 _ecore_wl_log_dom =
81 eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR);
82 if (_ecore_wl_log_dom < 0)
83 {
84 EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland");
85 eina_shutdown();
86 return --_ecore_wl_init_count;
87 }
88
89 if (!ecore_init())
90 {
91 ERR("Could not initialize ecore");
92 eina_log_domain_unregister(_ecore_wl_log_dom);
93 _ecore_wl_log_dom = -1;
94 eina_shutdown();
95 return --_ecore_wl_init_count;
96 }
97
98 if (!ecore_event_init())
99 {
100 ERR("Could not initialize ecore_event");
101 eina_log_domain_unregister(_ecore_wl_log_dom);
102 _ecore_wl_log_dom = -1;
103 ecore_shutdown();
104 eina_shutdown();
105 return --_ecore_wl_init_count;
106 }
107
108 if (!ECORE_WL_EVENT_MOUSE_IN)
109 {
110 ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new();
111 ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new();
112 ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new();
113 ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new();
114 ECORE_WL_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
115 ECORE_WL_EVENT_DND_ENTER = ecore_event_type_new();
116 ECORE_WL_EVENT_DND_POSITION = ecore_event_type_new();
117 ECORE_WL_EVENT_DND_LEAVE = ecore_event_type_new();
118 ECORE_WL_EVENT_DND_DROP = ecore_event_type_new();
119 ECORE_WL_EVENT_INTERFACES_BOUND = ecore_event_type_new();
120 }
121
122 if (!(_ecore_wl_disp = malloc(sizeof(Ecore_Wl_Display))))
123 {
124 ERR("Could not allocate memory for Ecore_Wl_Display structure");
125 eina_log_domain_unregister(_ecore_wl_log_dom);
126 _ecore_wl_log_dom = -1;
127 ecore_event_shutdown();
128 ecore_shutdown();
129 eina_shutdown();
130 return --_ecore_wl_init_count;
131 }
132
133 memset(_ecore_wl_disp, 0, sizeof(Ecore_Wl_Display));
134
135 if (!(_ecore_wl_disp->wl.display = wl_display_connect(name)))
136 {
137 ERR("Could not connect to Wayland display");
138 eina_log_domain_unregister(_ecore_wl_log_dom);
139 _ecore_wl_log_dom = -1;
140 ecore_event_shutdown();
141 ecore_shutdown();
142 eina_shutdown();
143 return --_ecore_wl_init_count;
144 }
145
146 _ecore_wl_disp->fd =
147 wl_display_get_fd(_ecore_wl_disp->wl.display,
148 _ecore_wl_cb_event_mask_update, _ecore_wl_disp);
149
150 _ecore_wl_disp->fd_hdl =
151 ecore_main_fd_handler_add(_ecore_wl_disp->fd, ECORE_FD_READ,
152 _ecore_wl_cb_handle_data, _ecore_wl_disp,
153 NULL, NULL);
154
155 wl_list_init(&_ecore_wl_disp->inputs);
156 wl_list_init(&_ecore_wl_disp->outputs);
157
158 wl_display_add_global_listener(_ecore_wl_disp->wl.display,
159 _ecore_wl_cb_handle_global, _ecore_wl_disp);
160
161 /* FIXME: Process connection events ?? */
162 wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE);
163
164 /* if (!_ecore_wl_egl_init(_ecore_wl_disp)) */
165 /* { */
166 /* ERR("Could not initialize EGL"); */
167 /* free(_ecore_wl_disp); */
168 /* eina_log_domain_unregister(_ecore_wl_log_dom); */
169 /* _ecore_wl_log_dom = -1; */
170 /* ecore_event_shutdown(); */
171 /* ecore_shutdown(); */
172 /* eina_shutdown(); */
173 /* return --_ecore_wl_init_count; */
174 /* } */
175
176 /* _ecore_wl_disp->create_image = */
177 /* (void *)eglGetProcAddress("eglCreateImageKHR"); */
178 /* _ecore_wl_disp->destroy_image = */
179 /* (void *)eglGetProcAddress("eglDestroyImageKHR"); */
180
181 /* TODO: create pointer surfaces */
182
183 if (!_ecore_wl_xkb_init(_ecore_wl_disp))
184 {
185 ERR("Could not initialize XKB");
186 _ecore_wl_egl_shutdown(_ecore_wl_disp);
187 free(_ecore_wl_disp);
188 eina_log_domain_unregister(_ecore_wl_log_dom);
189 _ecore_wl_log_dom = -1;
190 ecore_event_shutdown();
191 ecore_shutdown();
192 eina_shutdown();
193 return --_ecore_wl_init_count;
194 }
195
196 _ecore_wl_window_init();
197
198 return _ecore_wl_init_count;
199}
200
201/**
202 * Shuts down the Ecore Wayland Library
203 *
204 * In shutting down the library, the Wayland display connection is terminated
205 * and any event handlers for it are removed.
206 *
207 * @return The number of times the library has been initialized without
208 * being shut down.
209 *
210 * @ingroup Ecore_Wl_Init_Group
211 */
212EAPI int
213ecore_wl_shutdown(void)
214{
215 LOGFN(__FILE__, __LINE__, __FUNCTION__);
216
217 return _ecore_wl_shutdown(EINA_TRUE);
218}
219
220/**
221 * @defgroup Ecore_Wl_Flush_Group Wayland Synchronization Functions
222 *
223 * Functions that ensure that all commands which have been issued by the
224 * Ecore Wayland library have been sent to the server.
225 */
226
227/**
228 * Sends all Wayland commands to the Wayland Display.
229 *
230 * @ingroup Ecore_Wl_Flush_Group
231 * @since 1.2
232 */
233EAPI void
234ecore_wl_flush(void)
235{
236 LOGFN(__FILE__, __LINE__, __FUNCTION__);
237
238 while (_ecore_wl_disp->mask & WL_DISPLAY_WRITABLE)
239 wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_WRITABLE);
240// wl_display_flush(_ecore_wl_disp->wl.display); // old flush code
241}
242
243/**
244 * Flushes the command buffer and waits until all requests have been
245 * processed by the server.
246 *
247 * @ingroup Ecore_Wl_Flush_Group
248 * @since 1.2
249 */
250EAPI void
251ecore_wl_sync(void)
252{
253 LOGFN(__FILE__, __LINE__, __FUNCTION__);
254
255 wl_display_roundtrip(_ecore_wl_disp->wl.display);
256 // old sync code
257// wl_display_iterate(_ecore_wl_disp->wl.display, WL_DISPLAY_READABLE);
258}
259
260/**
261 * @defgroup Ecore_Wl_Display_Group Wayland Display Functions
262 *
263 * Functions that set and retrieve various information about the Wayland Display.
264 */
265
266/**
267 * Retrieves the Wayland Shm Interface used for the current Wayland connection.
268 *
269 * @return The current wayland shm interface
270 *
271 * @ingroup Ecore_Wl_Display_Group
272 * @since 1.2
273 */
274EAPI struct wl_shm *
275ecore_wl_shm_get(void)
276{
277 return _ecore_wl_disp->wl.shm;
278}
279
280/**
281 * Retrieves the Wayland Display Interface used for the current Wayland connection.
282 *
283 * @return The current wayland display interface
284 *
285 * @ingroup Ecore_Wl_Display_Group
286 * @since 1.2
287 */
288EAPI struct wl_display *
289ecore_wl_display_get(void)
290{
291 return _ecore_wl_disp->wl.display;
292}
293
294/**
295 * Retrieves the size of the current screen.
296 *
297 * @param w where to return the width. May be NULL. Returns 0 on error.
298 * @param h where to return the height. May be NULL. Returns 0 on error.
299 *
300 * @ingroup Ecore_Wl_Display_Group
301 * @since 1.2
302 */
303EAPI void
304ecore_wl_screen_size_get(int *w, int *h)
305{
306 LOGFN(__FILE__, __LINE__, __FUNCTION__);
307
308 if (w) *w = _ecore_wl_disp->output->allocation.w;
309 if (h) *h = _ecore_wl_disp->output->allocation.h;
310}
311
312/* @since 1.2 */
313EAPI void
314ecore_wl_pointer_xy_get(int *x, int *y)
315{
316 LOGFN(__FILE__, __LINE__, __FUNCTION__);
317
318 _ecore_wl_input_pointer_xy_get(x, y);
319}
320
321/* local functions */
322static Eina_Bool
323_ecore_wl_shutdown(Eina_Bool close)
324{
325 LOGFN(__FILE__, __LINE__, __FUNCTION__);
326
327 if (--_ecore_wl_init_count != 0) return _ecore_wl_init_count;
328 if (!_ecore_wl_disp) return _ecore_wl_init_count;
329
330 _ecore_wl_window_shutdown();
331
332 if (_ecore_wl_disp->fd_hdl)
333 ecore_main_fd_handler_del(_ecore_wl_disp->fd_hdl);
334
335 if (close)
336 {
337 Ecore_Wl_Output *out, *tout;
338 Ecore_Wl_Input *in, *tin;
339
340 wl_list_for_each_safe(out, tout, &_ecore_wl_disp->outputs, link)
341 _ecore_wl_output_del(out);
342
343 wl_list_for_each_safe(in, tin, &_ecore_wl_disp->inputs, link)
344 _ecore_wl_input_del(in);
345
346 _ecore_wl_xkb_shutdown(_ecore_wl_disp);
347 /* _ecore_wl_egl_shutdown(_ecore_wl_disp); */
348
349 if (_ecore_wl_disp->wl.shell)
350 wl_shell_destroy(_ecore_wl_disp->wl.shell);
351 if (_ecore_wl_disp->wl.shm) wl_shm_destroy(_ecore_wl_disp->wl.shm);
352 if (_ecore_wl_disp->wl.data_device_manager)
353 wl_data_device_manager_destroy(_ecore_wl_disp->wl.data_device_manager);
354 if (_ecore_wl_disp->wl.compositor)
355 wl_compositor_destroy(_ecore_wl_disp->wl.compositor);
356 if (_ecore_wl_disp->wl.display)
357 {
358 wl_display_flush(_ecore_wl_disp->wl.display);
359 wl_display_disconnect(_ecore_wl_disp->wl.display);
360 }
361 free(_ecore_wl_disp);
362 }
363
364 ecore_event_shutdown();
365 ecore_shutdown();
366
367 eina_log_domain_unregister(_ecore_wl_log_dom);
368 _ecore_wl_log_dom = -1;
369 eina_shutdown();
370
371 return _ecore_wl_init_count;
372}
373
374static int
375_ecore_wl_cb_event_mask_update(unsigned int mask, void *data)
376{
377 Ecore_Wl_Display *ewd;
378
379 LOGFN(__FILE__, __LINE__, __FUNCTION__);
380
381 ewd = data;
382 ewd->mask = mask;
383 return 0;
384}
385
386static Eina_Bool
387_ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl __UNUSED__)
388{
389 Ecore_Wl_Display *ewd;
390
391 LOGFN(__FILE__, __LINE__, __FUNCTION__);
392
393 if (!(ewd = data)) return ECORE_CALLBACK_RENEW;
394 wl_display_iterate(ewd->wl.display, ewd->mask);
395 return ECORE_CALLBACK_RENEW;
396}
397
398static void
399_ecore_wl_cb_handle_global(struct wl_display *disp, unsigned int id, const char *interface, unsigned int version __UNUSED__, void *data)
400{
401 Ecore_Wl_Display *ewd;
402
403 LOGFN(__FILE__, __LINE__, __FUNCTION__);
404
405 if ((!strcmp(interface, "wl_display")) ||
406 (!strcmp(interface, "wl_drm")) ||
407 (!strcmp(interface, "desktop_shell")))
408 return;
409
410 ewd = data;
411
412 if (!strcmp(interface, "wl_compositor"))
413 ewd->wl.compositor = wl_display_bind(disp, id, &wl_compositor_interface);
414 else if (!strcmp(interface, "wl_output"))
415 _ecore_wl_output_add(ewd, id);
416 else if (!strcmp(interface, "wl_input_device"))
417 _ecore_wl_input_add(ewd, id);
418 else if (!strcmp(interface, "wl_shell"))
419 ewd->wl.shell = wl_display_bind(disp, id, &wl_shell_interface);
420 else if (!strcmp(interface, "wl_shm"))
421 ewd->wl.shm = wl_display_bind(disp, id, &wl_shm_interface);
422 else if (!strcmp(interface, "wl_data_device_manager"))
423 {
424 ewd->wl.data_device_manager =
425 wl_display_bind(disp, id, &wl_data_device_manager_interface);
426 }
427
428 if ((ewd->wl.compositor) && (ewd->wl.shm) && (ewd->wl.shell))
429 {
430 Ecore_Wl_Event_Interfaces_Bound *ev;
431
432 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Interfaces_Bound))))
433 return;
434
435 ev->compositor = (ewd->wl.compositor != NULL);
436 ev->shm = (ewd->wl.shm != NULL);
437 ev->shell = (ewd->wl.shell != NULL);
438
439 ecore_event_add(ECORE_WL_EVENT_INTERFACES_BOUND, ev, NULL, NULL);
440 }
441}
442
443static Eina_Bool
444_ecore_wl_egl_init(Ecore_Wl_Display *ewd)
445{
446 EGLint major, minor, n;
447 static const EGLint context_attribs[] =
448 {
449 EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
450 };
451 static const EGLint argb_attribs[] =
452 {
453 EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
454 EGL_ALPHA_SIZE, 1, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0,
455 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE,
456 EGL_WINDOW_BIT, EGL_NONE
457 };
458
459 LOGFN(__FILE__, __LINE__, __FUNCTION__);
460
461 ewd->egl.display = eglGetDisplay(ewd->wl.display);
462 if (!eglInitialize(ewd->egl.display, &major, &minor))
463 {
464 ERR("Failed to initialize EGL display");
465 return EINA_FALSE;
466 }
467
468 if (!eglBindAPI(EGL_OPENGL_ES_API))
469 {
470 ERR("Failed to bind EGL Api");
471 return EINA_FALSE;
472 }
473
474 if ((!eglChooseConfig(ewd->egl.display, argb_attribs, &ewd->egl.argb_config,
475 1, &n)) || (n == 0))
476 {
477 ERR("Failed to choose ARGB config");
478 return EINA_FALSE;
479 }
480
481 ewd->egl.argb_context =
482 eglCreateContext(ewd->egl.display, ewd->egl.argb_config,
483 EGL_NO_CONTEXT, context_attribs);
484 if (!ewd->egl.argb_context)
485 {
486 ERR("Failed to create ARGB context");
487 return EINA_FALSE;
488 }
489
490 if (!eglMakeCurrent(ewd->egl.display, EGL_NO_SURFACE,
491 EGL_NO_SURFACE, ewd->egl.argb_context))
492 {
493 ERR("Failed to make ARGB context current");
494 return EINA_FALSE;
495 }
496
497 return EINA_TRUE;
498}
499
500static Eina_Bool
501_ecore_wl_egl_shutdown(Ecore_Wl_Display *ewd)
502{
503 LOGFN(__FILE__, __LINE__, __FUNCTION__);
504
505 eglMakeCurrent(ewd->egl.display,
506 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
507
508 eglDestroyContext(ewd->egl.display, ewd->egl.argb_context);
509
510 /* NB: This is hanging when we run elm apps as wayland clients
511 * inside the weston compositor */
512
513 /* printf("Egl Terminate\n"); */
514 /* eglTerminate(ewd->egl.display); */
515 /* printf("Egl Terminate Done\n"); */
516
517 eglReleaseThread();
518
519 return EINA_TRUE;
520}
521
522static Eina_Bool
523_ecore_wl_xkb_init(Ecore_Wl_Display *ewd)
524{
525 struct xkb_rule_names names;
526
527 LOGFN(__FILE__, __LINE__, __FUNCTION__);
528
529 names.rules = "evdev";
530 names.model = "evdev";
531 names.layout = "us";
532 names.variant = "";
533 names.options = "";
534
535 if (!(ewd->xkb = xkb_compile_keymap_from_rules(&names)))
536 {
537 ERR("Failed to compile keymap");
538 return EINA_FALSE;
539 }
540
541 return EINA_TRUE;
542}
543
544static Eina_Bool
545_ecore_wl_xkb_shutdown(Ecore_Wl_Display *ewd)
546{
547 LOGFN(__FILE__, __LINE__, __FUNCTION__);
548
549 if (ewd->xkb) xkb_free_keymap(ewd->xkb);
550 return EINA_TRUE;
551}