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);
35 # define LOGFN(fl, ln, fn) \
36 printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
38 # define LOGFN(fl, ln, fn)
41 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
45 # include <sys/types.h>
46 # include <sys/mman.h>
53 #include "ecore_evas_private.h"
54 #include "Ecore_Evas.h"
56 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
57 # include <Evas_Engine_Wayland_Shm.h>
58 # include <Ecore_Wayland.h>
60 /* local structures */
61 typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data;
62 struct _EE_Wl_Smart_Data
66 Evas_Coord x, y, w, h;
69 struct _Ecore_Evas_Engine_Wl_Data
75 /* local function prototypes */
76 static int _ecore_evas_wl_init(void);
77 static int _ecore_evas_wl_shutdown(void);
78 static void _ecore_evas_wl_pre_free(Ecore_Evas *ee);
79 static void _ecore_evas_wl_free(Ecore_Evas *ee);
80 static void _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
81 static void _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
82 static void _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
83 static void _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
84 static void _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
85 static void _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
86 static void _ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
87 static void _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y);
88 static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h);
89 static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h);
90 static void _ecore_evas_wl_show(Ecore_Evas *ee);
91 static void _ecore_evas_wl_hide(Ecore_Evas *ee);
92 static void _ecore_evas_wl_raise(Ecore_Evas *ee);
93 static void _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title);
94 static void _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c);
95 static void _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h);
96 static void _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h);
97 static void _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h);
98 static void _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h);
99 static void _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer);
100 static void _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify);
101 static void _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max);
102 static void _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full);
103 static void _ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore);
104 static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha);
105 static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent);
106 static int _ecore_evas_wl_render(Ecore_Evas *ee);
107 static void _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h);
108 static void _ecore_evas_wl_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi);
109 static void _ecore_evas_wl_ensure_pool_size(Ecore_Evas *ee, int w, int h);
110 static struct wl_shm_pool *_ecore_evas_wl_shm_pool_create(int size, void **data);
112 static void _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t tm EINA_UNUSED);
114 static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool);
116 static Eina_Bool _ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event);
117 static Eina_Bool _ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event);
118 static Eina_Bool _ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
119 static Eina_Bool _ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
120 static Eina_Bool _ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event);
122 /* SMART stuff for frame */
123 static Evas_Smart *_ecore_evas_wl_smart = NULL;
125 static void _ecore_evas_wl_smart_init(void);
126 static void _ecore_evas_wl_smart_add(Evas_Object *obj);
127 static void _ecore_evas_wl_smart_del(Evas_Object *obj);
128 static void _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
129 static void _ecore_evas_wl_smart_show(Evas_Object *obj);
130 static void _ecore_evas_wl_smart_hide(Evas_Object *obj);
132 static Evas_Object *_ecore_evas_wl_frame_add(Evas *evas);
134 /* local variables */
135 static int _ecore_evas_wl_init_count = 0;
136 static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[5];
138 static const struct wl_callback_listener frame_listener =
140 _ecore_evas_wl_frame_complete,
143 static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
146 _ecore_evas_wl_callback_resize_set,
147 _ecore_evas_wl_callback_move_set,
150 _ecore_evas_wl_callback_delete_request_set,
152 _ecore_evas_wl_callback_focus_in_set,
153 _ecore_evas_wl_callback_focus_out_set,
154 _ecore_evas_wl_callback_mouse_in_set,
155 _ecore_evas_wl_callback_mouse_out_set,
157 NULL, // unsticky_set
158 NULL, // pre_render_set
159 NULL, // post_render_set
161 NULL, // managed_move
162 _ecore_evas_wl_resize,
163 _ecore_evas_wl_move_resize,
164 NULL, // rotation_set
168 _ecore_evas_wl_raise,
171 _ecore_evas_wl_title_set,
172 _ecore_evas_wl_name_class_set,
173 _ecore_evas_wl_size_min_set,
174 _ecore_evas_wl_size_max_set,
175 _ecore_evas_wl_size_base_set,
176 _ecore_evas_wl_size_step_set,
177 NULL, // object_cursor_set
178 _ecore_evas_wl_layer_set,
180 _ecore_evas_wl_iconified_set,
181 NULL, // borderless set
182 NULL, // override set
183 _ecore_evas_wl_maximized_set,
184 _ecore_evas_wl_fullscreen_set,
185 NULL, // func avoid_damage set
186 NULL, // func withdrawn set
187 NULL, // func sticky set
188 _ecore_evas_wl_ignore_events_set,
189 _ecore_evas_wl_alpha_set,
190 _ecore_evas_wl_transparent_set,
191 NULL, // func profiles set
192 NULL, // window group set
196 NULL, // demand attention set
197 NULL, // focus skip set
198 _ecore_evas_wl_render,
199 _ecore_evas_wl_screen_geometry_get,
200 _ecore_evas_wl_screen_dpi_get
203 /* external variables */
205 /* external functions */
207 ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame)
209 Ecore_Wl_Window *p = NULL;
210 Evas_Engine_Info_Wayland_Shm *einfo;
212 int method = 0, count = 0;
214 LOGFN(__FILE__, __LINE__, __FUNCTION__);
216 if (!(method = evas_render_method_lookup("wayland_shm")))
218 ERR("Render method lookup failed for Wayland_Shm");
222 count = ecore_wl_init(disp_name);
225 ERR("Failed to initialize Ecore_Wayland");
229 ecore_wl_display_iterate();
231 if (!(ee = calloc(1, sizeof(Ecore_Evas))))
233 ERR("Failed to allocate Ecore_Evas");
238 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
240 _ecore_evas_wl_init();
242 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
244 ee->driver = "wayland_shm";
245 if (disp_name) ee->name = strdup(disp_name);
259 ee->prop.max.w = 32767;
260 ee->prop.max.h = 32767;
262 ee->prop.request_pos = 0;
264 ee->prop.draw_frame = frame;
265 ee->alpha = EINA_FALSE;
267 ee->evas = evas_new();
268 evas_data_attach_set(ee->evas, ee);
269 evas_output_method_set(ee->evas, method);
270 evas_output_size_set(ee->evas, ee->w, ee->h);
271 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
273 /* FIXME: This needs to be set based on theme & scale */
274 if (ee->prop.draw_frame)
275 evas_output_framespace_set(ee->evas, 4, 18, 8, 22);
277 if (parent) p = ecore_wl_window_find(parent);
279 /* FIXME: Get if parent is alpha, and set */
281 ee->engine.wl.parent = p;
283 ecore_wl_window_new(p, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
284 ee->prop.window = ee->engine.wl.win->id;
286 if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
288 einfo->info.rotation = ee->rotation;
289 einfo->info.destination_alpha = ee->alpha;
290 einfo->info.rotation = ee->rotation;
291 einfo->info.debug = EINA_FALSE;
292 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
294 ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
296 _ecore_evas_wl_shutdown();
303 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
305 _ecore_evas_wl_shutdown();
310 ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free);
312 if (ee->prop.draw_frame)
314 ee->engine.wl.frame = _ecore_evas_wl_frame_add(ee->evas);
315 evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE);
316 evas_object_move(ee->engine.wl.frame, 0, 0);
319 _ecore_evas_register(ee);
320 ecore_evas_input_event_register(ee);
322 ecore_event_window_register(ee->prop.window, ee, ee->evas,
323 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
324 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
325 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
326 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
328 // evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
333 /* local functions */
335 _ecore_evas_wl_init(void)
337 LOGFN(__FILE__, __LINE__, __FUNCTION__);
339 if (++_ecore_evas_wl_init_count != 1)
340 return _ecore_evas_wl_init_count;
342 _ecore_evas_wl_event_hdls[0] =
343 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
344 _ecore_evas_wl_cb_mouse_in, NULL);
345 _ecore_evas_wl_event_hdls[1] =
346 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
347 _ecore_evas_wl_cb_mouse_out, NULL);
348 _ecore_evas_wl_event_hdls[2] =
349 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
350 _ecore_evas_wl_cb_focus_in, NULL);
351 _ecore_evas_wl_event_hdls[3] =
352 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
353 _ecore_evas_wl_cb_focus_out, NULL);
354 _ecore_evas_wl_event_hdls[4] =
355 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
356 _ecore_evas_wl_cb_window_configure, NULL);
358 ecore_event_evas_init();
360 return _ecore_evas_wl_init_count;
364 _ecore_evas_wl_shutdown(void)
368 LOGFN(__FILE__, __LINE__, __FUNCTION__);
370 if (--_ecore_evas_wl_init_count != 0)
371 return _ecore_evas_wl_init_count;
373 for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++)
375 if (_ecore_evas_wl_event_hdls[i])
376 ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]);
379 ecore_event_evas_shutdown();
381 return _ecore_evas_wl_init_count;
385 _ecore_evas_wl_pre_free(Ecore_Evas *ee)
387 LOGFN(__FILE__, __LINE__, __FUNCTION__);
390 if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame);
394 _ecore_evas_wl_free(Ecore_Evas *ee)
396 LOGFN(__FILE__, __LINE__, __FUNCTION__);
398 if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
399 ee->engine.wl.buffer = NULL;
401 if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win);
402 ee->engine.wl.win = NULL;
404 ecore_event_window_unregister(ee->prop.window);
405 ecore_evas_input_event_unregister(ee);
407 _ecore_evas_wl_shutdown();
412 _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
414 LOGFN(__FILE__, __LINE__, __FUNCTION__);
417 ee->func.fn_resize = func;
421 _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
423 LOGFN(__FILE__, __LINE__, __FUNCTION__);
426 ee->func.fn_move = func;
430 _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
432 LOGFN(__FILE__, __LINE__, __FUNCTION__);
435 ee->func.fn_delete_request = func;
439 _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
441 LOGFN(__FILE__, __LINE__, __FUNCTION__);
444 ee->func.fn_focus_in = func;
448 _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
450 LOGFN(__FILE__, __LINE__, __FUNCTION__);
453 ee->func.fn_focus_out = func;
457 _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
459 LOGFN(__FILE__, __LINE__, __FUNCTION__);
462 ee->func.fn_mouse_in = func;
466 _ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
468 LOGFN(__FILE__, __LINE__, __FUNCTION__);
471 ee->func.fn_mouse_out = func;
475 _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y)
477 LOGFN(__FILE__, __LINE__, __FUNCTION__);
484 if ((ee->x != x) || (ee->y != y))
488 if (ee->engine.wl.win)
489 ecore_wl_window_update_location(ee->engine.wl.win, x, y);
490 if (ee->func.fn_move) ee->func.fn_move(ee);
495 _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
497 Evas_Engine_Info_Wayland_Shm *einfo;
499 LOGFN(__FILE__, __LINE__, __FUNCTION__);
508 if (!ee->prop.fullscreen)
512 if (ee->prop.min.w > w) w = ee->prop.min.w;
513 else if (w > ee->prop.max.w) w = ee->prop.max.w;
514 if (ee->prop.min.h > h) h = ee->prop.min.h;
515 else if (h > ee->prop.max.h) h = ee->prop.max.h;
517 evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
522 if ((ee->w != w) || (ee->h != h))
527 if ((ee->rotation == 90) || (ee->rotation == 270))
529 evas_output_size_set(ee->evas, h, w);
530 evas_output_viewport_set(ee->evas, 0, 0, h, w);
534 evas_output_size_set(ee->evas, w, h);
535 evas_output_viewport_set(ee->evas, 0, 0, w, h);
538 if (ee->prop.avoid_damage)
542 pdam = ecore_evas_avoid_damage_get(ee);
543 ecore_evas_avoid_damage_set(ee, 0);
544 ecore_evas_avoid_damage_set(ee, pdam);
547 if (ee->engine.wl.frame)
548 evas_object_resize(ee->engine.wl.frame, w, h);
550 if (ee->engine.wl.buffer)
552 if(!ee->engine.wl.buffer_valid)
554 wl_buffer_destroy(ee->engine.wl.buffer);
558 ee->engine.wl.buffer_valid = EINA_FALSE;
560 ee->engine.wl.buffer = NULL;
563 _ecore_evas_wl_ensure_pool_size(ee, w, h);
565 if (ee->engine.wl.pool)
566 _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
568 einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
571 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
575 einfo->info.dest = ee->engine.wl.pool_data;
576 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
578 if (ee->engine.wl.win)
580 // if (!ee->prop.fullscreen)
581 ecore_wl_window_update_size(ee->engine.wl.win, w, h);
584 if (ee->func.fn_resize) ee->func.fn_resize(ee);
589 _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
591 LOGFN(__FILE__, __LINE__, __FUNCTION__);
594 if ((ee->x != x) || (ee->y != y))
595 _ecore_evas_wl_move(ee, x, y);
596 if ((ee->w != w) || (ee->h != h))
597 _ecore_evas_wl_resize(ee, w, h);
601 _ecore_evas_wl_ensure_pool_size(Ecore_Evas *ee, int w, int h)
606 stride = w * sizeof(int);
609 if ((ee->engine.wl.pool) && (len < ee->engine.wl.pool_size))
613 struct wl_shm_pool *pool = NULL;
617 if (ee->engine.wl.pool)
618 wl_shm_pool_destroy(ee->engine.wl.pool);
621 * Make the pool 1.5 times the current requirement to allow growth
622 * without requiring a new pool allocation
625 pool = _ecore_evas_wl_shm_pool_create(size, &data);
627 ee->engine.wl.pool = pool;
628 ee->engine.wl.pool_size = size;
629 ee->engine.wl.pool_data = data;
634 _ecore_evas_wl_show(Ecore_Evas *ee)
636 Evas_Engine_Info_Wayland_Shm *einfo;
638 LOGFN(__FILE__, __LINE__, __FUNCTION__);
640 if ((!ee) || (ee->visible)) return;
642 _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
644 if (ee->engine.wl.pool)
645 _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
647 einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
650 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
654 einfo->info.dest = ee->engine.wl.pool_data;
655 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
657 /* ecore_wl_flush(); */
659 if (ee->engine.wl.win)
661 ecore_wl_window_show(ee->engine.wl.win);
662 ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h);
663 ee->engine.wl.buffer_valid = EINA_TRUE;
664 ecore_wl_window_buffer_attach(ee->engine.wl.win,
665 ee->engine.wl.buffer, 0, 0);
667 if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
668 wl_shell_surface_set_class(ee->engine.wl.win->shell_surface,
670 if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
671 wl_shell_surface_set_title(ee->engine.wl.win->shell_surface,
675 if (ee->engine.wl.frame)
677 evas_object_show(ee->engine.wl.frame);
678 evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
682 if (ee->func.fn_show) ee->func.fn_show(ee);
686 _ecore_evas_wl_hide(Ecore_Evas *ee)
688 Evas_Engine_Info_Wayland_Shm *einfo;
690 LOGFN(__FILE__, __LINE__, __FUNCTION__);
692 if ((!ee) || (!ee->visible)) return;
694 if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
695 ee->engine.wl.buffer = NULL;
697 munmap(ee->engine.wl.pool_data, ee->engine.wl.pool_size);
699 einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
700 if ((einfo) && (einfo->info.dest))
702 einfo->info.dest = NULL;
703 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
706 ecore_wl_window_hide(ee->engine.wl.win);
709 ee->should_be_visible = 0;
711 if (ee->func.fn_hide) ee->func.fn_hide(ee);
715 _ecore_evas_wl_raise(Ecore_Evas *ee)
717 LOGFN(__FILE__, __LINE__, __FUNCTION__);
719 if ((!ee) || (!ee->visible)) return;
720 ecore_wl_window_raise(ee->engine.wl.win);
724 _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title)
726 LOGFN(__FILE__, __LINE__, __FUNCTION__);
729 if (ee->prop.title) free(ee->prop.title);
730 ee->prop.title = NULL;
731 if (title) ee->prop.title = strdup(title);
732 if ((ee->prop.draw_frame) && (ee->engine.wl.frame))
734 EE_Wl_Smart_Data *sd;
736 if ((sd = evas_object_smart_data_get(ee->engine.wl.frame)))
737 evas_object_text_text_set(sd->text, ee->prop.title);
740 if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
741 wl_shell_surface_set_title(ee->engine.wl.win->shell_surface,
746 _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
748 LOGFN(__FILE__, __LINE__, __FUNCTION__);
751 if (ee->prop.name) free(ee->prop.name);
752 if (ee->prop.clas) free(ee->prop.clas);
753 ee->prop.name = NULL;
754 ee->prop.clas = NULL;
755 if (n) ee->prop.name = strdup(n);
756 if (c) ee->prop.clas = strdup(c);
758 if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
759 wl_shell_surface_set_class(ee->engine.wl.win->shell_surface,
764 _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h)
766 LOGFN(__FILE__, __LINE__, __FUNCTION__);
771 if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
777 _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h)
779 LOGFN(__FILE__, __LINE__, __FUNCTION__);
784 if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
790 _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h)
792 LOGFN(__FILE__, __LINE__, __FUNCTION__);
797 if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
803 _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h)
805 LOGFN(__FILE__, __LINE__, __FUNCTION__);
810 if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
816 _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer)
818 LOGFN(__FILE__, __LINE__, __FUNCTION__);
821 if (ee->prop.layer == layer) return;
822 if (layer < 1) layer = 1;
823 else if (layer > 255) layer = 255;
824 ee->prop.layer = layer;
828 _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify)
830 LOGFN(__FILE__, __LINE__, __FUNCTION__);
833 if (ee->prop.iconified == iconify) return;
834 ee->prop.iconified = iconify;
835 /* FIXME: Implement this in Wayland someshow */
839 _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max)
841 LOGFN(__FILE__, __LINE__, __FUNCTION__);
844 if (ee->prop.maximized == max) return;
845 ee->prop.maximized = max;
846 ecore_wl_window_maximized_set(ee->engine.wl.win, max);
847 if (ee->func.fn_state_change)
848 ee->func.fn_state_change(ee);
852 _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full)
854 LOGFN(__FILE__, __LINE__, __FUNCTION__);
857 if (ee->prop.fullscreen == full) return;
858 ee->prop.fullscreen = full;
859 ecore_wl_window_fullscreen_set(ee->engine.wl.win, full);
860 if (ee->func.fn_state_change)
861 ee->func.fn_state_change(ee);
865 _ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore)
867 LOGFN(__FILE__, __LINE__, __FUNCTION__);
870 ee->ignore_events = ignore;
871 /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */
875 _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha)
877 Evas_Engine_Info_Wayland_Shm *einfo;
878 Ecore_Wl_Window *win;
880 LOGFN(__FILE__, __LINE__, __FUNCTION__);
883 if ((ee->alpha == alpha)) return;
886 /* FIXME: NB: We should really add a ecore_wl_window_alpha_set function
887 * but we are in API freeze, so just hack it in for now and fix when
889 if ((win = ee->engine.wl.win))
892 /* if (ee->engine.wl.win) */
893 /* ecore_wl_window_transparent_set(ee->engine.wl.win, alpha); */
895 if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
896 ee->engine.wl.buffer = NULL;
898 _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
900 if (ee->engine.wl.pool)
901 _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
903 if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
905 einfo->info.destination_alpha = alpha;
906 einfo->info.dest = ee->engine.wl.pool_data;
907 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
908 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
909 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
912 if (ee->engine.wl.win)
914 ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h);
915 ee->engine.wl.buffer_valid = EINA_TRUE;
916 ecore_wl_window_buffer_attach(ee->engine.wl.win,
917 ee->engine.wl.buffer, 0, 0);
922 _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent)
924 Evas_Engine_Info_Wayland_Shm *einfo;
926 LOGFN(__FILE__, __LINE__, __FUNCTION__);
929 if ((ee->transparent == transparent)) return;
930 ee->transparent = transparent;
932 if (ee->engine.wl.win)
933 ecore_wl_window_transparent_set(ee->engine.wl.win, transparent);
935 if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
936 ee->engine.wl.buffer = NULL;
938 _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
940 if (ee->engine.wl.pool)
941 _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
943 if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
945 einfo->info.destination_alpha = transparent;
946 einfo->info.dest = ee->engine.wl.pool_data;
947 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
948 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
949 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
952 if (ee->engine.wl.win)
954 ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h);
955 ee->engine.wl.buffer_valid = EINA_TRUE;
956 ecore_wl_window_buffer_attach(ee->engine.wl.win,
957 ee->engine.wl.buffer, 0, 0);
962 _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t tm EINA_UNUSED)
964 Ecore_Evas *ee = data;
965 Ecore_Wl_Window *win = NULL;
968 if (!(win = ee->engine.wl.win)) return;
970 win->frame_callback = NULL;
971 win->frame_pending = EINA_FALSE;
972 wl_callback_destroy(callback);
976 win->frame_callback = wl_surface_frame(win->surface);
977 wl_callback_add_listener(win->frame_callback, &frame_listener, ee);
982 _ecore_evas_wl_render(Ecore_Evas *ee)
985 Ecore_Wl_Window *win = NULL;
987 if (!(win = ee->engine.wl.win)) return 0;
991 evas_norender(ee->evas);
994 Eina_List *ll = NULL;
995 Ecore_Evas *ee2 = NULL;
997 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
999 EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
1001 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
1002 if (ee2->engine.func->fn_render)
1003 rend |= ee2->engine.func->fn_render(ee2);
1004 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
1007 if (!win->frame_pending)
1011 if (!win->frame_callback)
1013 win->frame_callback = wl_surface_frame(win->surface);
1014 wl_callback_add_listener(win->frame_callback,
1015 &frame_listener, ee);
1018 if ((updates = evas_render_updates(ee->evas)))
1020 Eina_List *l = NULL;
1023 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1025 ee->engine.wl.buffer_valid = EINA_TRUE;
1026 ecore_wl_window_buffer_attach(ee->engine.wl.win,
1027 ee->engine.wl.buffer, 0, 0);
1028 EINA_LIST_FOREACH(updates, l, r)
1029 ecore_wl_window_damage(ee->engine.wl.win,
1030 r->x, r->y, r->w, r->h);
1031 ecore_wl_window_commit(ee->engine.wl.win);
1034 evas_render_updates_free(updates);
1035 _ecore_evas_idle_timeout_update(ee);
1038 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
1040 win->frame_pending = EINA_TRUE;
1049 _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
1051 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1055 ecore_wl_screen_size_get(w, h);
1059 _ecore_evas_wl_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi)
1063 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1065 if (xdpi) *xdpi = 0;
1066 if (ydpi) *ydpi = 0;
1067 /* FIXME: Ideally this needs to get the DPI from a specific screen */
1068 dpi = ecore_wl_dpi_get();
1069 if (xdpi) *xdpi = dpi;
1070 if (ydpi) *ydpi = dpi;
1073 static struct wl_shm_pool *
1074 _ecore_evas_wl_shm_pool_create(int size, void **data)
1077 struct wl_shm_pool *pool;
1081 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1083 if (!(shm = ecore_wl_shm_get())) return NULL;
1085 strcpy(tmp, "/tmp/ecore-evas-wayland_shm-XXXXXX");
1086 if ((fd = mkstemp(tmp)) < 0)
1088 ERR("Could not create temporary file.");
1092 if (ftruncate(fd, size) < 0)
1094 ERR("Could not truncate temporary file.");
1099 *data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
1102 if (*data == MAP_FAILED)
1104 ERR("mmap of temporary file failed.");
1109 pool = wl_shm_create_pool(shm, fd, size);
1117 _ecore_evas_wl_buffer_release(void *data, struct wl_buffer *buffer)
1119 Ecore_Evas *ee = data;
1121 if (ee->engine.wl.buffer == buffer)
1122 ee->engine.wl.buffer_valid = EINA_FALSE;
1124 wl_buffer_destroy(buffer);
1127 static const struct wl_buffer_listener _buffer_listener_release =
1129 _ecore_evas_wl_buffer_release
1133 _ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool)
1135 unsigned int format;
1138 if ((ee->alpha) || (ee->transparent))
1139 format = WL_SHM_FORMAT_ARGB8888;
1141 format = WL_SHM_FORMAT_XRGB8888;
1143 stride = (ee->w * sizeof(int));
1145 ee->engine.wl.buffer =
1146 wl_shm_pool_create_buffer(pool, 0, ee->w, ee->h, stride, format);
1148 wl_buffer_add_listener(ee->engine.wl.buffer,
1149 &_buffer_listener_release, ee);
1153 _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location)
1155 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1158 if (ee->engine.wl.win)
1160 ee->engine.wl.win->resizing = EINA_TRUE;
1161 ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location);
1166 _ecore_evas_wayland_shm_move(Ecore_Evas *ee, int x, int y)
1168 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1171 if (ee->engine.wl.win)
1173 ee->engine.wl.win->moving = EINA_TRUE;
1174 ecore_wl_window_move(ee->engine.wl.win, x, y);
1179 _ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
1182 Ecore_Wl_Event_Mouse_In *ev;
1184 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1187 ee = ecore_event_window_match(ev->window);
1188 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1189 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1191 if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
1192 ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
1193 evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
1194 _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp);
1197 return ECORE_CALLBACK_PASS_ON;
1201 _ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1204 Ecore_Wl_Event_Mouse_Out *ev;
1206 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1209 ee = ecore_event_window_match(ev->window);
1210 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1211 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1214 ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
1215 // _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp);
1216 evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
1217 if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
1218 if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
1219 ee->in = EINA_FALSE;
1221 return ECORE_CALLBACK_PASS_ON;
1225 _ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
1228 Ecore_Wl_Event_Focus_In *ev;
1230 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1233 ee = ecore_event_window_match(ev->win);
1234 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1235 if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1236 ee->prop.focused = 1;
1237 evas_focus_in(ee->evas);
1238 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
1239 return ECORE_CALLBACK_PASS_ON;
1243 _ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1246 Ecore_Wl_Event_Focus_In *ev;
1248 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1251 ee = ecore_event_window_match(ev->win);
1252 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1253 if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1254 evas_focus_out(ee->evas);
1255 ee->prop.focused = 0;
1256 if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
1257 return ECORE_CALLBACK_PASS_ON;
1261 _ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event)
1264 Ecore_Wl_Event_Window_Configure *ev;
1267 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1270 ee = ecore_event_window_match(ev->win);
1271 if (!ee) return ECORE_CALLBACK_PASS_ON;
1272 if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1274 if (ee->prop.fullscreen)
1276 _ecore_evas_wl_move(ee, ev->x, ev->y);
1277 _ecore_evas_wl_resize(ee, ev->w, ev->h);
1279 return ECORE_CALLBACK_PASS_ON;
1282 if ((ee->x != ev->x) || (ee->y != ev->y))
1286 if (ee->func.fn_move) ee->func.fn_move(ee);
1292 if ((ee->prop.maximized) || (!ee->prop.fullscreen))
1296 evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
1301 if (ee->prop.min.w > nw) nw = ee->prop.min.w;
1302 else if (nw > ee->prop.max.w) nw = ee->prop.max.w;
1303 if (ee->prop.min.h > nh) nh = ee->prop.min.h;
1304 else if (nh > ee->prop.max.h) nh = ee->prop.max.h;
1306 if ((ee->w != nw) || (ee->h != nh))
1310 if (ee->func.fn_resize) ee->func.fn_resize(ee);
1313 return ECORE_CALLBACK_PASS_ON;
1317 _ecore_evas_wl_smart_init(void)
1319 if (_ecore_evas_wl_smart) return;
1321 static const Evas_Smart_Class sc =
1323 "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION,
1324 _ecore_evas_wl_smart_add,
1325 _ecore_evas_wl_smart_del,
1327 _ecore_evas_wl_smart_resize,
1328 _ecore_evas_wl_smart_show,
1329 _ecore_evas_wl_smart_hide,
1330 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
1332 _ecore_evas_wl_smart = evas_smart_class_new(&sc);
1337 _ecore_evas_wl_smart_add(Evas_Object *obj)
1339 EE_Wl_Smart_Data *sd;
1342 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1344 if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return;
1346 evas = evas_object_evas_get(obj);
1353 sd->frame = evas_object_rectangle_add(evas);
1354 evas_object_color_set(sd->frame, 249, 249, 249, 255);
1355 evas_object_smart_member_add(sd->frame, obj);
1357 sd->text = evas_object_text_add(evas);
1358 evas_object_color_set(sd->text, 0, 0, 0, 255);
1359 evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN);
1360 evas_object_text_font_set(sd->text, "Sans", 10);
1361 evas_object_text_text_set(sd->text, "Smart Test");
1362 evas_object_smart_member_add(sd->text, obj);
1364 evas_object_smart_data_set(obj, sd);
1368 _ecore_evas_wl_smart_del(Evas_Object *obj)
1370 EE_Wl_Smart_Data *sd;
1372 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1374 if (!(sd = evas_object_smart_data_get(obj))) return;
1375 evas_object_del(sd->text);
1376 evas_object_del(sd->frame);
1381 _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
1383 EE_Wl_Smart_Data *sd;
1385 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1387 if (!(sd = evas_object_smart_data_get(obj))) return;
1388 if ((sd->w == w) && (sd->h == h)) return;
1391 evas_object_resize(sd->frame, w, h);
1395 _ecore_evas_wl_smart_show(Evas_Object *obj)
1397 EE_Wl_Smart_Data *sd;
1399 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1401 if (!(sd = evas_object_smart_data_get(obj))) return;
1402 evas_object_show(sd->frame);
1403 evas_object_show(sd->text);
1407 _ecore_evas_wl_smart_hide(Evas_Object *obj)
1409 EE_Wl_Smart_Data *sd;
1411 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1413 if (!(sd = evas_object_smart_data_get(obj))) return;
1414 evas_object_hide(sd->text);
1415 evas_object_hide(sd->frame);
1418 static Evas_Object *
1419 _ecore_evas_wl_frame_add(Evas *evas)
1421 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1423 _ecore_evas_wl_smart_init();
1424 return evas_object_smart_add(evas, _ecore_evas_wl_smart);
1429 ecore_evas_wayland_shm_new(const char *disp_name __UNUSED__, unsigned int parent __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, Eina_Bool frame __UNUSED__)