aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c')
-rw-r--r--libraries/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c1131
1 files changed, 1131 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c b/libraries/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c
new file mode 100644
index 0000000..72e8555
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_evas/ecore_evas_wayland_egl.c
@@ -0,0 +1,1131 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#define LOGFNS 1
6
7#ifdef LOGFNS
8# include <stdio.h>
9# define LOGFN(fl, ln, fn) \
10 printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
11#else
12# define LOGFN(fl, ln, fn)
13#endif
14
15#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
16# include <stdlib.h>
17# include <string.h>
18# include <unistd.h>
19# include <sys/types.h>
20# include <sys/mman.h>
21#endif
22
23#include <Eina.h>
24#include <Evas.h>
25#include <Ecore.h>
26
27#include "ecore_evas_private.h"
28#include "Ecore_Evas.h"
29
30#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
31# include <wayland-egl.h>
32# include <Evas_Engine_Wayland_Egl.h>
33# include <Ecore_Wayland.h>
34
35/* local structures */
36typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data;
37struct _EE_Wl_Smart_Data
38{
39 Evas_Object *frame, *text;
40 Evas_Coord x, y, w, h;
41};
42
43/* local function prototypes */
44static int _ecore_evas_wl_init(void);
45static int _ecore_evas_wl_shutdown(void);
46static void _ecore_evas_wl_pre_free(Ecore_Evas *ee);
47static void _ecore_evas_wl_free(Ecore_Evas *ee);
48static void _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
49static void _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
50static void _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
51static void _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
52static void _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
53static void _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
54static void _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y);
55static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h);
56static void _ecore_evas_wl_show(Ecore_Evas *ee);
57static void _ecore_evas_wl_hide(Ecore_Evas *ee);
58static void _ecore_evas_wl_raise(Ecore_Evas *ee);
59static void _ecore_evas_wl_lower(Ecore_Evas *ee);
60static void _ecore_evas_wl_activate(Ecore_Evas *ee);
61static void _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *t);
62static void _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c);
63static void _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h);
64static void _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h);
65static void _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h);
66static void _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h);
67static void _ecore_evas_wl_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y);
68static void _ecore_evas_wl_object_cursor_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__);
69static void _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer);
70static void _ecore_evas_wl_focus_set(Ecore_Evas *ee, int focus __UNUSED__);
71static void _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify);
72static void _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max);
73static void _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full __UNUSED__);
74static int _ecore_evas_wl_render(Ecore_Evas *ee);
75static void _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h);
76
77static Eina_Bool _ecore_evas_wl_event_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event);
78static Eina_Bool _ecore_evas_wl_event_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event);
79static Eina_Bool _ecore_evas_wl_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event);
80static Eina_Bool _ecore_evas_wl_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event);
81static Eina_Bool _ecore_evas_wl_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event);
82static Eina_Bool _ecore_evas_wl_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event);
83static Eina_Bool _ecore_evas_wl_event_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
84static Eina_Bool _ecore_evas_wl_event_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
85
86static void _ecore_evas_wl_handle_configure(void *data, struct wl_shell_surface *shell_surface __UNUSED__, uint32_t timestamp __UNUSED__, uint32_t edges __UNUSED__, int32_t width, int32_t height);
87static void _ecore_evas_wl_handle_popup_done(void *data __UNUSED__, struct wl_shell_surface *shell_surface __UNUSED__);
88
89/* SMART stuff for frame */
90static Evas_Smart *_ecore_evas_wl_smart = NULL;
91
92static void _ecore_evas_wl_smart_init(void);
93static void _ecore_evas_wl_smart_add(Evas_Object *obj);
94static void _ecore_evas_wl_smart_del(Evas_Object *obj);
95static void _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
96static void _ecore_evas_wl_smart_show(Evas_Object *obj);
97static void _ecore_evas_wl_smart_hide(Evas_Object *obj);
98
99static Evas_Object *_ecore_evas_wl_frame_add(Evas *evas);
100
101/* local variables */
102static int _ecore_evas_wl_init_count = 0;
103static Ecore_Event_Handler *_ecore_evas_wl_event_handlers[8];
104static uint32_t _ecore_evas_wl_btn_timestamp;
105static const struct wl_shell_surface_listener _ecore_evas_wl_shell_surface_listener =
106{
107 _ecore_evas_wl_handle_configure,
108 _ecore_evas_wl_handle_popup_done
109};
110
111static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
112{
113 _ecore_evas_wl_free,
114 _ecore_evas_wl_callback_resize_set,
115 _ecore_evas_wl_callback_move_set,
116 NULL, // callback show set
117 NULL, // callback hide set
118 _ecore_evas_wl_callback_delete_request_set,
119 NULL, // callback destroy set
120 _ecore_evas_wl_callback_focus_in_set,
121 _ecore_evas_wl_callback_focus_out_set,
122 _ecore_evas_wl_callback_mouse_in_set,
123 NULL, // callback mouse out set
124 NULL, // callback sticky set
125 NULL, // callback unsticky set
126 NULL, // callback pre render set
127 NULL, // callback post render set
128 _ecore_evas_wl_move,
129 NULL, // func managed move
130 _ecore_evas_wl_resize,
131 NULL, // _ecore_evas_wl_move_resize,
132 NULL, // func rotation set
133 NULL, // func shaped set
134 _ecore_evas_wl_show,
135 _ecore_evas_wl_hide,
136 _ecore_evas_wl_raise,
137 _ecore_evas_wl_lower,
138 _ecore_evas_wl_activate,
139 _ecore_evas_wl_title_set,
140 _ecore_evas_wl_name_class_set,
141 _ecore_evas_wl_size_min_set,
142 _ecore_evas_wl_size_max_set,
143 _ecore_evas_wl_size_base_set,
144 _ecore_evas_wl_size_step_set,
145 _ecore_evas_wl_object_cursor_set,
146 _ecore_evas_wl_layer_set,
147 _ecore_evas_wl_focus_set,
148 _ecore_evas_wl_iconified_set,
149 NULL, // func borderless set
150 NULL, // func override set
151 _ecore_evas_wl_maximized_set,
152 _ecore_evas_wl_fullscreen_set,
153 NULL, // _ecore_evas_wl_avoid_damage_set,
154 NULL, // func withdrawn set
155 NULL, // func sticky set
156 NULL, // func ignore events set
157 NULL, // func alpha set
158 NULL, // func transparent set
159 _ecore_evas_wl_render,
160 _ecore_evas_wl_screen_geometry_get
161};
162
163#endif
164
165#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
166EAPI Ecore_Evas *
167ecore_evas_wayland_egl_new(const char *disp_name, int x, int y, int w, int h, int frame)
168{
169 Evas_Engine_Info_Wayland_Egl *einfo;
170 Ecore_Evas *ee;
171 int method = 0;
172 static int _win_id = 1;
173
174 LOGFN(__FILE__, __LINE__, __FUNCTION__);
175
176 if (!(method = evas_render_method_lookup("wayland_egl")))
177 {
178 printf("Render method lookup failed for Wayland Egl");
179 return NULL;
180 }
181
182 if (!ecore_wl_init(disp_name))
183 {
184 printf("Failed to initialize Ecore Wayland");
185 return NULL;
186 }
187
188 if (!(ee = calloc(1, sizeof(Ecore_Evas))))
189 {
190 printf("Failed to allocate Ecore_Evas.");
191 ecore_wl_shutdown();
192 return NULL;
193 }
194
195 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
196
197 _ecore_evas_wl_init();
198
199 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
200
201 ee->driver = "wayland_egl";
202 if (disp_name) ee->name = strdup(disp_name);
203
204 if (w < 1) w = 1;
205 if (h < 1) h = 1;
206
207 ee->req.x = ee->x = x;
208 ee->req.y = ee->y = y;
209 ee->req.w = ee->w = w;
210 ee->req.h = ee->h = h;
211 ee->rotation = 0;
212 ee->prop.max.w = ee->prop.max.h = 32767;
213 ee->prop.layer = 4;
214 ee->prop.request_pos = 0;
215 ee->prop.sticky = 0;
216 ee->prop.draw_frame = frame;
217 ee->prop.window = _win_id++;
218
219 ee->evas = evas_new();
220 evas_data_attach_set(ee->evas, ee);
221 evas_output_method_set(ee->evas, method);
222 evas_output_size_set(ee->evas, ee->w, ee->h);
223 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
224
225 if (ee->prop.draw_frame)
226 evas_output_framespace_set(ee->evas, 4, 18, 8, 22);
227
228 if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas)))
229 {
230 einfo->info.display = ecore_wl_display_get();
231 einfo->info.rotation = ee->rotation;
232 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
233 {
234 printf("Failed to set Evas Engine Info for '%s'.", ee->driver);
235 ecore_evas_free(ee);
236 return NULL;
237 }
238 }
239 else
240 {
241 printf("Failed to get Evas Engine Info for '%s'.", ee->driver);
242 ecore_evas_free(ee);
243 return NULL;
244 }
245
246 /* NB: we need to be notified before 'free' so we can munmap the evas
247 * engine destination */
248 ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free);
249
250 if (ee->prop.draw_frame)
251 {
252 ee->engine.wl.frame = _ecore_evas_wl_frame_add(ee->evas);
253 evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE);
254 evas_object_move(ee->engine.wl.frame, 0, 0);
255 }
256
257 ecore_evas_input_event_register(ee);
258 _ecore_evas_register(ee);
259
260 ecore_event_window_register(ee->prop.window, ee, ee->evas,
261 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
262 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
263 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
264 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
265
266 evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
267
268 return ee;
269}
270
271/* local functions */
272static int
273_ecore_evas_wl_init(void)
274{
275 LOGFN(__FILE__, __LINE__, __FUNCTION__);
276
277 if (++_ecore_evas_wl_init_count != 1)
278 return _ecore_evas_wl_init_count;
279
280 _ecore_evas_wl_event_handlers[0] =
281 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
282 _ecore_evas_wl_event_mouse_down, NULL);
283 _ecore_evas_wl_event_handlers[1] =
284 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
285 _ecore_evas_wl_event_mouse_up, NULL);
286 _ecore_evas_wl_event_handlers[2] =
287 ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
288 _ecore_evas_wl_event_mouse_move, NULL);
289 _ecore_evas_wl_event_handlers[3] =
290 ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL,
291 _ecore_evas_wl_event_mouse_wheel, NULL);
292 _ecore_evas_wl_event_handlers[4] =
293 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
294 _ecore_evas_wl_event_mouse_in, NULL);
295 _ecore_evas_wl_event_handlers[5] =
296 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
297 _ecore_evas_wl_event_mouse_out, NULL);
298 _ecore_evas_wl_event_handlers[6] =
299 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
300 _ecore_evas_wl_event_focus_in, NULL);
301 _ecore_evas_wl_event_handlers[7] =
302 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
303 _ecore_evas_wl_event_focus_out, NULL);
304
305 ecore_event_evas_init();
306
307 return _ecore_evas_wl_init_count;
308}
309
310static int
311_ecore_evas_wl_shutdown(void)
312{
313 unsigned int i = 0;
314
315 LOGFN(__FILE__, __LINE__, __FUNCTION__);
316
317 if (--_ecore_evas_wl_init_count != 0)
318 return _ecore_evas_wl_init_count;
319
320 for (i = 0; i < sizeof(_ecore_evas_wl_event_handlers) / sizeof(Ecore_Event_Handler *); i++)
321 {
322 if (_ecore_evas_wl_event_handlers[i])
323 ecore_event_handler_del(_ecore_evas_wl_event_handlers[i]);
324 }
325
326 ecore_event_evas_shutdown();
327
328 return _ecore_evas_wl_init_count;
329}
330
331static void
332_ecore_evas_wl_pre_free(Ecore_Evas *ee)
333{
334 LOGFN(__FILE__, __LINE__, __FUNCTION__);
335
336 if (!ee) return;
337 if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame);
338}
339
340static void
341_ecore_evas_wl_free(Ecore_Evas *ee)
342{
343 LOGFN(__FILE__, __LINE__, __FUNCTION__);
344
345 if (ee)
346 {
347 /* destroy shell surface */
348 if (ee->engine.wl.shell_surface)
349 wl_shell_surface_destroy(ee->engine.wl.shell_surface);
350 ee->engine.wl.shell_surface = NULL;
351
352 /* destroy surface */
353 if (ee->engine.wl.surface) wl_surface_destroy(ee->engine.wl.surface);
354 ee->engine.wl.surface = NULL;
355
356 ecore_event_window_unregister(ee->prop.window);
357 ecore_evas_input_event_unregister(ee);
358 }
359 _ecore_evas_wl_shutdown();
360 ecore_wl_shutdown();
361}
362
363static void
364_ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
365{
366 LOGFN(__FILE__, __LINE__, __FUNCTION__);
367
368 if (!ee) return;
369 ee->func.fn_resize = func;
370}
371
372static void
373_ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
374{
375 LOGFN(__FILE__, __LINE__, __FUNCTION__);
376
377 if (!ee) return;
378 ee->func.fn_move = func;
379}
380
381static void
382_ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
383{
384 LOGFN(__FILE__, __LINE__, __FUNCTION__);
385
386 if (!ee) return;
387 ee->func.fn_delete_request = func;
388}
389
390static void
391_ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
392{
393 LOGFN(__FILE__, __LINE__, __FUNCTION__);
394
395 if (!ee) return;
396 ee->func.fn_focus_in = func;
397}
398
399static void
400_ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
401{
402 LOGFN(__FILE__, __LINE__, __FUNCTION__);
403
404 if (!ee) return;
405 ee->func.fn_focus_out = func;
406}
407
408static void
409_ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
410{
411 LOGFN(__FILE__, __LINE__, __FUNCTION__);
412
413 if (!ee) return;
414 ee->func.fn_mouse_in = func;
415}
416
417static void
418_ecore_evas_wl_move(Ecore_Evas *ee, int x, int y)
419{
420 LOGFN(__FILE__, __LINE__, __FUNCTION__);
421
422 if (!ee) return;
423// if ((ee->x == x) && (ee->y == y)) return;
424 ee->req.x = x;
425 ee->req.y = y;
426
427 ee->x = x;
428 ee->y = y;
429 if (ee->engine.wl.shell_surface)
430 {
431 wl_shell_surface_move(ee->engine.wl.shell_surface,
432 ecore_wl_input_device_get(),
433 _ecore_evas_wl_btn_timestamp);
434 }
435 if (ee->func.fn_move) ee->func.fn_move(ee);
436}
437
438static void
439_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
440{
441 LOGFN(__FILE__, __LINE__, __FUNCTION__);
442
443 if (!ee) return;
444 if (w < 1) w = 1;
445 if (h < 1) h = 1;
446 if ((ee->w == w) && (ee->h == h)) return;
447
448 ee->req.w = w;
449 ee->req.h = h;
450
451 /* if (ee->visible) */
452 /* { */
453 /* damage old surface, if it exists */
454
455 /* NB: This removes any lingering screen artifacts in the compositor.
456 * This may be a 'HACK' if the issue is actually in the wayland
457 * compositor, but for now lets implement this so we don't have screen
458 * artifacts laying around during a resize */
459 /* if (ee->engine.wl.surface) */
460 /* wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h); */
461 /* } */
462
463 ee->w = w;
464 ee->h = h;
465
466// ecore_wl_flush();
467
468 evas_output_size_set(ee->evas, ee->w, ee->h);
469 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
470 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
471 if (ee->engine.wl.frame)
472 evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
473
474 /* if ((ee->visible) && (ee->engine.wl.surface)) */
475 /* wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h); */
476
477 if (ee->func.fn_resize) ee->func.fn_resize(ee);
478}
479
480static void
481_ecore_evas_wl_show(Ecore_Evas *ee)
482{
483 Evas_Engine_Info_Wayland_Egl *einfo;
484
485 LOGFN(__FILE__, __LINE__, __FUNCTION__);
486
487 if (!ee) return;
488 if (ee->visible) return;
489
490 einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
491
492 /* create new surface */
493 ee->engine.wl.surface =
494 wl_compositor_create_surface(ecore_wl_compositor_get());
495 wl_surface_set_user_data(ee->engine.wl.surface, (void *)ee->prop.window);
496
497 /* create new shell surface */
498 ee->engine.wl.shell_surface =
499 wl_shell_get_shell_surface(ecore_wl_shell_get(), ee->engine.wl.surface);
500
501 /* set the engine surface here. This should trigger an egl window create */
502 einfo->info.surface = ee->engine.wl.surface;
503 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
504
505 /* add listener for configure events (happen on shell surface resize) */
506 wl_shell_surface_add_listener(ee->engine.wl.shell_surface,
507 &_ecore_evas_wl_shell_surface_listener, ee);
508
509 /* Raise this surface to the top */
510 wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
511
512 if (ee->engine.wl.frame)
513 {
514 evas_object_show(ee->engine.wl.frame);
515 evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
516 }
517
518 ecore_wl_flush();
519
520 ee->visible = 1;
521 if (ee->func.fn_show) ee->func.fn_show(ee);
522}
523
524static void
525_ecore_evas_wl_hide(Ecore_Evas *ee)
526{
527 Evas_Engine_Info_Wayland_Egl *einfo;
528
529 LOGFN(__FILE__, __LINE__, __FUNCTION__);
530
531 if (!ee) return;
532 if (!ee->visible) return;
533
534 /* get engine info */
535 einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
536 einfo->info.surface = NULL;
537 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
538
539 /* destroy shell surface */
540 if (ee->engine.wl.shell_surface)
541 wl_shell_surface_destroy(ee->engine.wl.shell_surface);
542 ee->engine.wl.shell_surface = NULL;
543
544 /* destroy surface */
545 if (ee->engine.wl.surface) wl_surface_destroy(ee->engine.wl.surface);
546 ee->engine.wl.surface = NULL;
547
548 ee->visible = 0;
549 ee->should_be_visible = 0;
550 if (ee->func.fn_hide) ee->func.fn_hide(ee);
551}
552
553static void
554_ecore_evas_wl_raise(Ecore_Evas *ee)
555{
556 LOGFN(__FILE__, __LINE__, __FUNCTION__);
557
558 if ((!ee) || (!ee->visible)) return;
559 if (!ee->engine.wl.shell_surface) return;
560 wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
561}
562
563static void
564_ecore_evas_wl_lower(Ecore_Evas *ee)
565{
566 LOGFN(__FILE__, __LINE__, __FUNCTION__);
567
568 if ((!ee) || (!ee->visible)) return;
569 /* FIXME: Need a way to tell Wayland to lower */
570}
571
572static void
573_ecore_evas_wl_activate(Ecore_Evas *ee)
574{
575 LOGFN(__FILE__, __LINE__, __FUNCTION__);
576
577 if ((!ee) || (!ee->visible)) return;
578 if (!ee->engine.wl.shell_surface) return;
579 wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
580}
581
582static void
583_ecore_evas_wl_title_set(Ecore_Evas *ee, const char *t)
584{
585 LOGFN(__FILE__, __LINE__, __FUNCTION__);
586
587 if (!ee) return;
588 if (ee->prop.title) free(ee->prop.title);
589 ee->prop.title = NULL;
590 if (t) ee->prop.title = strdup(t);
591
592 if ((ee->prop.draw_frame) && (ee->engine.wl.frame))
593 {
594 EE_Wl_Smart_Data *sd;
595
596 if (!(sd = evas_object_smart_data_get(ee->engine.wl.frame))) return;
597 evas_object_text_text_set(sd->text, ee->prop.title);
598 }
599}
600
601static void
602_ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
603{
604 LOGFN(__FILE__, __LINE__, __FUNCTION__);
605
606 if (!ee) return;
607 if (ee->prop.name) free(ee->prop.name);
608 if (ee->prop.clas) free(ee->prop.clas);
609 ee->prop.name = NULL;
610 ee->prop.clas = NULL;
611 if (n) ee->prop.name = strdup(n);
612 if (c) ee->prop.clas = strdup(c);
613 /* FIXME: Forward these changes to Wayland somehow */
614}
615
616static void
617_ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h)
618{
619 LOGFN(__FILE__, __LINE__, __FUNCTION__);
620
621 if (!ee) return;
622 if (w < 0) w = 0;
623 if (h < 0) h = 0;
624 if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
625 ee->prop.min.w = w;
626 ee->prop.min.h = h;
627}
628
629static void
630_ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h)
631{
632 LOGFN(__FILE__, __LINE__, __FUNCTION__);
633
634 if (!ee) return;
635 if (w < 0) w = 0;
636 if (h < 0) h = 0;
637 if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
638 ee->prop.max.w = w;
639 ee->prop.max.h = h;
640}
641
642static void
643_ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h)
644{
645 LOGFN(__FILE__, __LINE__, __FUNCTION__);
646
647 if (!ee) return;
648 if (w < 0) w = 0;
649 if (h < 0) h = 0;
650 if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
651 ee->prop.base.w = w;
652 ee->prop.base.h = h;
653}
654
655static void
656_ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h)
657{
658 LOGFN(__FILE__, __LINE__, __FUNCTION__);
659
660 if (!ee) return;
661 if (w < 0) w = 0;
662 if (h < 0) h = 0;
663 if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
664 ee->prop.step.w = w;
665 ee->prop.step.h = h;
666}
667
668static void
669_ecore_evas_wl_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
670{
671 int x = 0, y = 0;
672
673 LOGFN(__FILE__, __LINE__, __FUNCTION__);
674
675 if (!ee) return;
676 if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
677 ee->prop.cursor.object = NULL;
678
679 if (!obj)
680 {
681 ee->prop.cursor.layer = 0;
682 ee->prop.cursor.hot.x = 0;
683 ee->prop.cursor.hot.y = 0;
684 return;
685 }
686
687 ee->prop.cursor.object = obj;
688 ee->prop.cursor.layer = layer;
689 ee->prop.cursor.hot.x = hot_x;
690 ee->prop.cursor.hot.y = hot_y;
691
692 evas_pointer_output_xy_get(ee->evas, &x, &y);
693 evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
694 evas_object_move(ee->prop.cursor.object,
695 x - ee->prop.cursor.hot.x, y - ee->prop.cursor.hot.y);
696 evas_object_pass_events_set(ee->prop.cursor.object, 1);
697 if (evas_pointer_inside_get(ee->evas))
698 evas_object_show(ee->prop.cursor.object);
699
700 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
701 _ecore_evas_wl_object_cursor_del, ee);
702}
703
704static void
705_ecore_evas_wl_object_cursor_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
706{
707 Ecore_Evas *ee;
708
709 if (!(ee = data)) return;
710 ee->prop.cursor.object = NULL;
711}
712
713static void
714_ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer)
715{
716 LOGFN(__FILE__, __LINE__, __FUNCTION__);
717
718 if (!ee) return;
719 if (ee->prop.layer == layer) return;
720 if (layer < 1) layer = 1;
721 else if (layer > 255) layer = 255;
722 ee->prop.layer = layer;
723}
724
725static void
726_ecore_evas_wl_focus_set(Ecore_Evas *ee, int focus __UNUSED__)
727{
728 LOGFN(__FILE__, __LINE__, __FUNCTION__);
729
730 if ((!ee) || (!ee->visible)) return;
731 if (!ee->engine.wl.shell_surface) return;
732 wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
733}
734
735static void
736_ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify)
737{
738 LOGFN(__FILE__, __LINE__, __FUNCTION__);
739
740 if (!ee) return;
741 if (ee->prop.iconified == iconify) return;
742 ee->prop.iconified = iconify;
743 /* FIXME: Implement this in Wayland someshow */
744}
745
746static void
747_ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max)
748{
749 LOGFN(__FILE__, __LINE__, __FUNCTION__);
750
751 if (!ee) return;
752 if (ee->prop.maximized == max) return;
753 ee->prop.maximized = max;
754 /* FIXME: Implement this in Wayland someshow */
755}
756
757static void
758_ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full __UNUSED__)
759{
760 LOGFN(__FILE__, __LINE__, __FUNCTION__);
761
762 if ((!ee) || (!ee->visible)) return;
763 if (!ee->engine.wl.shell_surface) return;
764 wl_shell_surface_set_fullscreen(ee->engine.wl.shell_surface);
765}
766
767static int
768_ecore_evas_wl_render(Ecore_Evas *ee)
769{
770 int rend = 0;
771
772 if (!ee) return 0;
773 if (!ee->visible)
774 evas_norender(ee->evas);
775 else
776 {
777 Eina_List *ll = NULL, *updates = NULL;
778 Ecore_Evas *ee2 = NULL;
779
780 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
781
782 EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
783 {
784 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
785 if (ee2->engine.func->fn_render)
786 rend |= ee2->engine.func->fn_render(ee2);
787 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
788 }
789
790 if ((updates = evas_render_updates(ee->evas)))
791 {
792 /* if (ee->engine.wl.surface) */
793 /* { */
794 /* Eina_List *l = NULL; */
795 /* Eina_Rectangle *r; */
796
797 /* EINA_LIST_FOREACH(updates, l, r) */
798 /* wl_surface_damage(ee->engine.wl.surface, */
799 /* r->x, r->y, r->w, r->h); */
800 /* } */
801
802 evas_render_updates_free(updates);
803 _ecore_evas_idle_timeout_update(ee);
804 rend = 1;
805
806 ecore_wl_flush();
807 }
808
809 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
810 }
811
812 return rend;
813}
814
815static void
816_ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
817{
818 LOGFN(__FILE__, __LINE__, __FUNCTION__);
819
820 if (x) *x = 0;
821 if (y) *y = 0;
822 ecore_wl_screen_size_get(w, h);
823}
824
825static Eina_Bool
826_ecore_evas_wl_event_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event)
827{
828 Ecore_Evas *ee;
829 Ecore_Event_Mouse_Button *ev;
830
831 LOGFN(__FILE__, __LINE__, __FUNCTION__);
832
833 ev = event;
834 _ecore_evas_wl_btn_timestamp = ev->timestamp;
835 ee = ecore_event_window_match(ev->window);
836 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
837 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
838 evas_event_feed_mouse_down(ee->evas, ev->buttons, ev->modifiers,
839 ev->timestamp, NULL);
840 return ECORE_CALLBACK_PASS_ON;
841}
842
843static Eina_Bool
844_ecore_evas_wl_event_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event)
845{
846 Ecore_Evas *ee;
847 Ecore_Event_Mouse_Button *ev;
848
849 LOGFN(__FILE__, __LINE__, __FUNCTION__);
850
851 ev = event;
852 ee = ecore_event_window_match(ev->window);
853 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
854 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
855 evas_event_feed_mouse_up(ee->evas, ev->buttons, ev->modifiers,
856 ev->timestamp, NULL);
857 return ECORE_CALLBACK_PASS_ON;
858}
859
860static Eina_Bool
861_ecore_evas_wl_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
862{
863 Ecore_Evas *ee;
864 Ecore_Event_Mouse_Move *ev;
865
866 ev = event;
867 ee = ecore_event_window_match(ev->window);
868 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
869 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
870 ee->mouse.x = ev->x;
871 ee->mouse.y = ev->y;
872 evas_event_feed_mouse_move(ee->evas, ev->x, ev->y, ev->timestamp, NULL);
873 _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp);
874 return ECORE_CALLBACK_PASS_ON;
875}
876
877static Eina_Bool
878_ecore_evas_wl_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
879{
880 Ecore_Evas *ee;
881 Ecore_Event_Mouse_Wheel *ev;
882
883 LOGFN(__FILE__, __LINE__, __FUNCTION__);
884
885 ev = event;
886 ee = ecore_event_window_match(ev->window);
887 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
888 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
889 evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z,
890 ev->timestamp, NULL);
891 return ECORE_CALLBACK_PASS_ON;
892}
893
894static Eina_Bool
895_ecore_evas_wl_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
896{
897 Ecore_Evas *ee;
898 Ecore_Wl_Event_Mouse_In *ev;
899
900 LOGFN(__FILE__, __LINE__, __FUNCTION__);
901
902 ev = event;
903 ee = ecore_event_window_match(ev->window);
904 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
905 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
906 if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
907 ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
908 evas_event_feed_mouse_in(ee->evas, ev->time, NULL);
909 _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->time);
910 return ECORE_CALLBACK_PASS_ON;
911}
912
913static Eina_Bool
914_ecore_evas_wl_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
915{
916 Ecore_Evas *ee;
917 Ecore_Wl_Event_Mouse_Out *ev;
918
919 LOGFN(__FILE__, __LINE__, __FUNCTION__);
920
921 ev = event;
922 ee = ecore_event_window_match(ev->window);
923 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
924 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
925 ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
926 _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->time);
927 evas_event_feed_mouse_out(ee->evas, ev->time, NULL);
928 if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
929 if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
930 return ECORE_CALLBACK_PASS_ON;
931}
932
933static Eina_Bool
934_ecore_evas_wl_event_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
935{
936 Ecore_Evas *ee;
937 Ecore_Wl_Event_Focus_In *ev;
938
939 LOGFN(__FILE__, __LINE__, __FUNCTION__);
940
941 ev = event;
942 ee = ecore_event_window_match(ev->window);
943 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
944 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
945 ee->prop.focused = 1;
946 evas_focus_in(ee->evas);
947 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
948 return ECORE_CALLBACK_PASS_ON;
949}
950
951static Eina_Bool
952_ecore_evas_wl_event_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
953{
954 Ecore_Evas *ee;
955 Ecore_Wl_Event_Focus_Out *ev;
956
957 LOGFN(__FILE__, __LINE__, __FUNCTION__);
958
959 ev = event;
960 ee = ecore_event_window_match(ev->window);
961 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
962 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
963 evas_focus_out(ee->evas);
964 ee->prop.focused = 0;
965 if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
966 return ECORE_CALLBACK_PASS_ON;
967}
968
969static void
970_ecore_evas_wl_handle_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t timestamp __UNUSED__, uint32_t edges __UNUSED__, int32_t width, int32_t height)
971{
972 Ecore_Evas *ee;
973
974 /* NB: Trap to prevent compositor from crashing */
975 if ((width <= 0) || (height <= 0)) return;
976
977 if (!(ee = data)) return;
978
979 printf("EGL Handle Configure Message\n");
980 if ((shell_surface) && (ee->engine.wl.shell_surface))
981 {
982 if (ee->engine.wl.shell_surface != shell_surface) return;
983 ecore_evas_resize(ee, width, height);
984 }
985}
986
987static void
988_ecore_evas_wl_handle_popup_done(void *data __UNUSED__, struct wl_shell_surface *shell_surface __UNUSED__)
989{
990
991}
992
993static void
994_ecore_evas_wl_smart_init(void)
995{
996 if (_ecore_evas_wl_smart) return;
997 {
998 static const Evas_Smart_Class sc =
999 {
1000 "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION,
1001 _ecore_evas_wl_smart_add,
1002 _ecore_evas_wl_smart_del,
1003 NULL,
1004 _ecore_evas_wl_smart_resize,
1005 _ecore_evas_wl_smart_show,
1006 _ecore_evas_wl_smart_hide,
1007 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
1008 };
1009 _ecore_evas_wl_smart = evas_smart_class_new(&sc);
1010 }
1011}
1012
1013static void
1014_ecore_evas_wl_smart_add(Evas_Object *obj)
1015{
1016 EE_Wl_Smart_Data *sd;
1017 Evas *evas;
1018
1019 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1020
1021 if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return;
1022
1023 evas = evas_object_evas_get(obj);
1024
1025 sd->x = 0;
1026 sd->y = 0;
1027 sd->w = 1;
1028 sd->h = 1;
1029
1030 sd->frame = evas_object_rectangle_add(evas);
1031 evas_object_is_frame_object_set(sd->frame, EINA_TRUE);
1032 evas_object_color_set(sd->frame, 249, 249, 249, 255);
1033 evas_object_smart_member_add(sd->frame, obj);
1034
1035 sd->text = evas_object_text_add(evas);
1036 evas_object_color_set(sd->text, 0, 0, 0, 255);
1037 evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN);
1038 evas_object_text_font_set(sd->text, "Sans", 10);
1039 evas_object_text_text_set(sd->text, "Smart Test");
1040
1041 evas_object_smart_data_set(obj, sd);
1042}
1043
1044static void
1045_ecore_evas_wl_smart_del(Evas_Object *obj)
1046{
1047 EE_Wl_Smart_Data *sd;
1048
1049 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1050
1051 if (!(sd = evas_object_smart_data_get(obj))) return;
1052 evas_object_del(sd->text);
1053 evas_object_del(sd->frame);
1054 free(sd);
1055}
1056
1057static void
1058_ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
1059{
1060 EE_Wl_Smart_Data *sd;
1061
1062 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1063
1064 if (!(sd = evas_object_smart_data_get(obj))) return;
1065 if ((sd->w == w) && (sd->h == h)) return;
1066 sd->w = w;
1067 sd->h = h;
1068 evas_object_resize(sd->frame, w, h);
1069}
1070
1071static void
1072_ecore_evas_wl_smart_show(Evas_Object *obj)
1073{
1074 EE_Wl_Smart_Data *sd;
1075
1076 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1077
1078 if (!(sd = evas_object_smart_data_get(obj))) return;
1079 evas_object_show(sd->frame);
1080 evas_object_show(sd->text);
1081}
1082
1083static void
1084_ecore_evas_wl_smart_hide(Evas_Object *obj)
1085{
1086 EE_Wl_Smart_Data *sd;
1087
1088 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1089
1090 if (!(sd = evas_object_smart_data_get(obj))) return;
1091 evas_object_hide(sd->text);
1092 evas_object_hide(sd->frame);
1093}
1094
1095static Evas_Object *
1096_ecore_evas_wl_frame_add(Evas *evas)
1097{
1098 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1099
1100 _ecore_evas_wl_smart_init();
1101 return evas_object_smart_add(evas, _ecore_evas_wl_smart);
1102}
1103
1104void
1105_ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location)
1106{
1107 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1108
1109 if ((!ee) || (!ee->engine.wl.shell_surface)) return;
1110 wl_shell_surface_resize(ee->engine.wl.shell_surface,
1111 ecore_wl_input_device_get(),
1112 _ecore_evas_wl_btn_timestamp, location);
1113}
1114
1115void
1116_ecore_evas_wayland_egl_drag_start(Ecore_Evas *ee, Ecore_Evas *drag_ee, void *source)
1117{
1118 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1119
1120 if ((!ee) || (!ee->engine.wl.surface)) return;
1121 if ((!source) || (!drag_ee)) return;
1122 ecore_wl_drag_start(source, ee->engine.wl.surface, drag_ee->engine.wl.buffer);
1123}
1124
1125#else
1126EAPI Ecore_Evas *
1127ecore_evas_wayland_egl_new(const char *disp_name __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, int frame __UNUSED__)
1128{
1129 return NULL;
1130}
1131#endif