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,
201 NULL, // wm_rot_preferred_rotation_set
202 NULL // wm_rot_available_rotations_set
205 /* external variables */
207 /* external functions */
209 ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame)
211 Ecore_Wl_Window *p = NULL;
212 Evas_Engine_Info_Wayland_Shm *einfo;
214 int method = 0, count = 0;
216 LOGFN(__FILE__, __LINE__, __FUNCTION__);
218 if (!(method = evas_render_method_lookup("wayland_shm")))
220 ERR("Render method lookup failed for Wayland_Shm");
224 count = ecore_wl_init(disp_name);
227 ERR("Failed to initialize Ecore_Wayland");
231 ecore_wl_display_iterate();
233 if (!(ee = calloc(1, sizeof(Ecore_Evas))))
235 ERR("Failed to allocate Ecore_Evas");
240 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
242 _ecore_evas_wl_init();
244 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
246 ee->driver = "wayland_shm";
247 if (disp_name) ee->name = strdup(disp_name);
261 ee->prop.max.w = 32767;
262 ee->prop.max.h = 32767;
264 ee->prop.request_pos = 0;
266 ee->prop.draw_frame = frame;
267 ee->alpha = EINA_FALSE;
269 ee->evas = evas_new();
270 evas_data_attach_set(ee->evas, ee);
271 evas_output_method_set(ee->evas, method);
272 evas_output_size_set(ee->evas, ee->w, ee->h);
273 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
275 /* FIXME: This needs to be set based on theme & scale */
276 if (ee->prop.draw_frame)
277 evas_output_framespace_set(ee->evas, 4, 18, 8, 22);
279 if (parent) p = ecore_wl_window_find(parent);
281 /* FIXME: Get if parent is alpha, and set */
283 ee->engine.wl.parent = p;
285 ecore_wl_window_new(p, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
286 ee->prop.window = ee->engine.wl.win->id;
288 if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
290 einfo->info.rotation = ee->rotation;
291 einfo->info.destination_alpha = ee->alpha;
292 einfo->info.rotation = ee->rotation;
293 einfo->info.debug = EINA_FALSE;
294 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
296 ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
298 _ecore_evas_wl_shutdown();
305 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
307 _ecore_evas_wl_shutdown();
312 ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free);
314 if (ee->prop.draw_frame)
316 ee->engine.wl.frame = _ecore_evas_wl_frame_add(ee->evas);
317 evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE);
318 evas_object_move(ee->engine.wl.frame, 0, 0);
321 _ecore_evas_register(ee);
322 ecore_evas_input_event_register(ee);
324 ecore_event_window_register(ee->prop.window, ee, ee->evas,
325 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
326 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
327 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
328 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
330 // evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
335 /* local functions */
337 _ecore_evas_wl_init(void)
339 LOGFN(__FILE__, __LINE__, __FUNCTION__);
341 if (++_ecore_evas_wl_init_count != 1)
342 return _ecore_evas_wl_init_count;
344 _ecore_evas_wl_event_hdls[0] =
345 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN,
346 _ecore_evas_wl_cb_mouse_in, NULL);
347 _ecore_evas_wl_event_hdls[1] =
348 ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT,
349 _ecore_evas_wl_cb_mouse_out, NULL);
350 _ecore_evas_wl_event_hdls[2] =
351 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN,
352 _ecore_evas_wl_cb_focus_in, NULL);
353 _ecore_evas_wl_event_hdls[3] =
354 ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT,
355 _ecore_evas_wl_cb_focus_out, NULL);
356 _ecore_evas_wl_event_hdls[4] =
357 ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE,
358 _ecore_evas_wl_cb_window_configure, NULL);
360 ecore_event_evas_init();
362 return _ecore_evas_wl_init_count;
366 _ecore_evas_wl_shutdown(void)
370 LOGFN(__FILE__, __LINE__, __FUNCTION__);
372 if (--_ecore_evas_wl_init_count != 0)
373 return _ecore_evas_wl_init_count;
375 for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++)
377 if (_ecore_evas_wl_event_hdls[i])
378 ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]);
381 ecore_event_evas_shutdown();
383 return _ecore_evas_wl_init_count;
387 _ecore_evas_wl_pre_free(Ecore_Evas *ee)
389 LOGFN(__FILE__, __LINE__, __FUNCTION__);
392 if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame);
396 _ecore_evas_wl_free(Ecore_Evas *ee)
398 LOGFN(__FILE__, __LINE__, __FUNCTION__);
400 if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
401 ee->engine.wl.buffer = NULL;
403 if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win);
404 ee->engine.wl.win = NULL;
406 ecore_event_window_unregister(ee->prop.window);
407 ecore_evas_input_event_unregister(ee);
409 _ecore_evas_wl_shutdown();
414 _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
416 LOGFN(__FILE__, __LINE__, __FUNCTION__);
419 ee->func.fn_resize = func;
423 _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
425 LOGFN(__FILE__, __LINE__, __FUNCTION__);
428 ee->func.fn_move = func;
432 _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
434 LOGFN(__FILE__, __LINE__, __FUNCTION__);
437 ee->func.fn_delete_request = func;
441 _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
443 LOGFN(__FILE__, __LINE__, __FUNCTION__);
446 ee->func.fn_focus_in = func;
450 _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
452 LOGFN(__FILE__, __LINE__, __FUNCTION__);
455 ee->func.fn_focus_out = func;
459 _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
461 LOGFN(__FILE__, __LINE__, __FUNCTION__);
464 ee->func.fn_mouse_in = func;
468 _ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
470 LOGFN(__FILE__, __LINE__, __FUNCTION__);
473 ee->func.fn_mouse_out = func;
477 _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y)
479 LOGFN(__FILE__, __LINE__, __FUNCTION__);
486 if ((ee->x != x) || (ee->y != y))
490 if (ee->engine.wl.win)
491 ecore_wl_window_update_location(ee->engine.wl.win, x, y);
492 if (ee->func.fn_move) ee->func.fn_move(ee);
497 _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
499 Evas_Engine_Info_Wayland_Shm *einfo;
501 LOGFN(__FILE__, __LINE__, __FUNCTION__);
510 if (!ee->prop.fullscreen)
514 if (ee->prop.min.w > w) w = ee->prop.min.w;
515 else if (w > ee->prop.max.w) w = ee->prop.max.w;
516 if (ee->prop.min.h > h) h = ee->prop.min.h;
517 else if (h > ee->prop.max.h) h = ee->prop.max.h;
519 evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
524 if ((ee->w != w) || (ee->h != h))
529 if ((ee->rotation == 90) || (ee->rotation == 270))
531 evas_output_size_set(ee->evas, h, w);
532 evas_output_viewport_set(ee->evas, 0, 0, h, w);
536 evas_output_size_set(ee->evas, w, h);
537 evas_output_viewport_set(ee->evas, 0, 0, w, h);
540 if (ee->prop.avoid_damage)
544 pdam = ecore_evas_avoid_damage_get(ee);
545 ecore_evas_avoid_damage_set(ee, 0);
546 ecore_evas_avoid_damage_set(ee, pdam);
549 if (ee->engine.wl.frame)
550 evas_object_resize(ee->engine.wl.frame, w, h);
552 if (ee->engine.wl.buffer)
554 if(!ee->engine.wl.buffer_valid)
556 wl_buffer_destroy(ee->engine.wl.buffer);
560 ee->engine.wl.buffer_valid = EINA_FALSE;
562 ee->engine.wl.buffer = NULL;
565 _ecore_evas_wl_ensure_pool_size(ee, w, h);
567 if (ee->engine.wl.pool)
568 _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
570 einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
573 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
577 einfo->info.dest = ee->engine.wl.pool_data;
578 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
580 if (ee->engine.wl.win)
582 // if (!ee->prop.fullscreen)
583 ecore_wl_window_update_size(ee->engine.wl.win, w, h);
586 if (ee->func.fn_resize) ee->func.fn_resize(ee);
591 _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
593 LOGFN(__FILE__, __LINE__, __FUNCTION__);
596 if ((ee->x != x) || (ee->y != y))
597 _ecore_evas_wl_move(ee, x, y);
598 if ((ee->w != w) || (ee->h != h))
599 _ecore_evas_wl_resize(ee, w, h);
603 _ecore_evas_wl_ensure_pool_size(Ecore_Evas *ee, int w, int h)
608 stride = w * sizeof(int);
611 if ((ee->engine.wl.pool) && (len < ee->engine.wl.pool_size))
615 struct wl_shm_pool *pool = NULL;
619 if (ee->engine.wl.pool)
620 wl_shm_pool_destroy(ee->engine.wl.pool);
623 * Make the pool 1.5 times the current requirement to allow growth
624 * without requiring a new pool allocation
627 pool = _ecore_evas_wl_shm_pool_create(size, &data);
629 ee->engine.wl.pool = pool;
630 ee->engine.wl.pool_size = size;
631 ee->engine.wl.pool_data = data;
636 _ecore_evas_wl_show(Ecore_Evas *ee)
638 Evas_Engine_Info_Wayland_Shm *einfo;
640 LOGFN(__FILE__, __LINE__, __FUNCTION__);
642 if ((!ee) || (ee->visible)) return;
644 _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
646 if (ee->engine.wl.pool)
647 _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
649 einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
652 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
656 einfo->info.dest = ee->engine.wl.pool_data;
657 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
659 /* ecore_wl_flush(); */
661 if (ee->engine.wl.win)
663 ecore_wl_window_show(ee->engine.wl.win);
664 ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h);
665 ee->engine.wl.buffer_valid = EINA_TRUE;
666 ecore_wl_window_buffer_attach(ee->engine.wl.win,
667 ee->engine.wl.buffer, 0, 0);
669 if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
670 wl_shell_surface_set_class(ee->engine.wl.win->shell_surface,
672 if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
673 wl_shell_surface_set_title(ee->engine.wl.win->shell_surface,
677 if (ee->engine.wl.frame)
679 evas_object_show(ee->engine.wl.frame);
680 evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
684 if (ee->func.fn_show) ee->func.fn_show(ee);
688 _ecore_evas_wl_hide(Ecore_Evas *ee)
690 Evas_Engine_Info_Wayland_Shm *einfo;
692 LOGFN(__FILE__, __LINE__, __FUNCTION__);
694 if ((!ee) || (!ee->visible)) return;
696 if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
697 ee->engine.wl.buffer = NULL;
699 munmap(ee->engine.wl.pool_data, ee->engine.wl.pool_size);
701 einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
702 if ((einfo) && (einfo->info.dest))
704 einfo->info.dest = NULL;
705 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
708 ecore_wl_window_hide(ee->engine.wl.win);
711 ee->should_be_visible = 0;
713 if (ee->func.fn_hide) ee->func.fn_hide(ee);
717 _ecore_evas_wl_raise(Ecore_Evas *ee)
719 LOGFN(__FILE__, __LINE__, __FUNCTION__);
721 if ((!ee) || (!ee->visible)) return;
722 ecore_wl_window_raise(ee->engine.wl.win);
726 _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title)
728 LOGFN(__FILE__, __LINE__, __FUNCTION__);
731 if (ee->prop.title) free(ee->prop.title);
732 ee->prop.title = NULL;
733 if (title) ee->prop.title = strdup(title);
734 if ((ee->prop.draw_frame) && (ee->engine.wl.frame))
736 EE_Wl_Smart_Data *sd;
738 if ((sd = evas_object_smart_data_get(ee->engine.wl.frame)))
739 evas_object_text_text_set(sd->text, ee->prop.title);
742 if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
743 wl_shell_surface_set_title(ee->engine.wl.win->shell_surface,
748 _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
750 LOGFN(__FILE__, __LINE__, __FUNCTION__);
753 if (ee->prop.name) free(ee->prop.name);
754 if (ee->prop.clas) free(ee->prop.clas);
755 ee->prop.name = NULL;
756 ee->prop.clas = NULL;
757 if (n) ee->prop.name = strdup(n);
758 if (c) ee->prop.clas = strdup(c);
760 if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
761 wl_shell_surface_set_class(ee->engine.wl.win->shell_surface,
766 _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h)
768 LOGFN(__FILE__, __LINE__, __FUNCTION__);
773 if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
779 _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h)
781 LOGFN(__FILE__, __LINE__, __FUNCTION__);
786 if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
792 _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h)
794 LOGFN(__FILE__, __LINE__, __FUNCTION__);
799 if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
805 _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h)
807 LOGFN(__FILE__, __LINE__, __FUNCTION__);
812 if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
818 _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer)
820 LOGFN(__FILE__, __LINE__, __FUNCTION__);
823 if (ee->prop.layer == layer) return;
824 if (layer < 1) layer = 1;
825 else if (layer > 255) layer = 255;
826 ee->prop.layer = layer;
830 _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify)
832 LOGFN(__FILE__, __LINE__, __FUNCTION__);
835 if (ee->prop.iconified == iconify) return;
836 ee->prop.iconified = iconify;
837 /* FIXME: Implement this in Wayland someshow */
841 _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max)
843 LOGFN(__FILE__, __LINE__, __FUNCTION__);
846 if (ee->prop.maximized == max) return;
847 ee->prop.maximized = max;
848 ecore_wl_window_maximized_set(ee->engine.wl.win, max);
849 if (ee->func.fn_state_change)
850 ee->func.fn_state_change(ee);
854 _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full)
856 LOGFN(__FILE__, __LINE__, __FUNCTION__);
859 if (ee->prop.fullscreen == full) return;
860 ee->prop.fullscreen = full;
861 ecore_wl_window_fullscreen_set(ee->engine.wl.win, full);
862 if (ee->func.fn_state_change)
863 ee->func.fn_state_change(ee);
867 _ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore)
869 LOGFN(__FILE__, __LINE__, __FUNCTION__);
872 ee->ignore_events = ignore;
873 /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */
877 _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha)
879 Evas_Engine_Info_Wayland_Shm *einfo;
880 Ecore_Wl_Window *win;
882 LOGFN(__FILE__, __LINE__, __FUNCTION__);
885 if ((ee->alpha == alpha)) return;
888 /* FIXME: NB: We should really add a ecore_wl_window_alpha_set function
889 * but we are in API freeze, so just hack it in for now and fix when
891 if ((win = ee->engine.wl.win))
894 /* if (ee->engine.wl.win) */
895 /* ecore_wl_window_transparent_set(ee->engine.wl.win, alpha); */
897 if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
898 ee->engine.wl.buffer = NULL;
900 _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
902 if (ee->engine.wl.pool)
903 _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
905 if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
907 einfo->info.destination_alpha = alpha;
908 einfo->info.dest = ee->engine.wl.pool_data;
909 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
910 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
911 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
914 if (ee->engine.wl.win)
916 ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h);
917 ee->engine.wl.buffer_valid = EINA_TRUE;
918 ecore_wl_window_buffer_attach(ee->engine.wl.win,
919 ee->engine.wl.buffer, 0, 0);
924 _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent)
926 Evas_Engine_Info_Wayland_Shm *einfo;
928 LOGFN(__FILE__, __LINE__, __FUNCTION__);
931 if ((ee->transparent == transparent)) return;
932 ee->transparent = transparent;
934 if (ee->engine.wl.win)
935 ecore_wl_window_transparent_set(ee->engine.wl.win, transparent);
937 if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
938 ee->engine.wl.buffer = NULL;
940 _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
942 if (ee->engine.wl.pool)
943 _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
945 if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
947 einfo->info.destination_alpha = transparent;
948 einfo->info.dest = ee->engine.wl.pool_data;
949 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
950 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
951 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
954 if (ee->engine.wl.win)
956 ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h);
957 ee->engine.wl.buffer_valid = EINA_TRUE;
958 ecore_wl_window_buffer_attach(ee->engine.wl.win,
959 ee->engine.wl.buffer, 0, 0);
964 _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t tm EINA_UNUSED)
966 Ecore_Evas *ee = data;
967 Ecore_Wl_Window *win = NULL;
970 if (!(win = ee->engine.wl.win)) return;
972 win->frame_callback = NULL;
973 win->frame_pending = EINA_FALSE;
974 wl_callback_destroy(callback);
978 win->frame_callback = wl_surface_frame(win->surface);
979 wl_callback_add_listener(win->frame_callback, &frame_listener, ee);
984 _ecore_evas_wl_render(Ecore_Evas *ee)
987 Ecore_Wl_Window *win = NULL;
989 if (!(win = ee->engine.wl.win)) return 0;
993 evas_norender(ee->evas);
996 Eina_List *ll = NULL;
997 Ecore_Evas *ee2 = NULL;
999 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
1001 EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
1003 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
1004 if (ee2->engine.func->fn_render)
1005 rend |= ee2->engine.func->fn_render(ee2);
1006 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
1009 if (!win->frame_pending)
1013 if (!win->frame_callback)
1015 win->frame_callback = wl_surface_frame(win->surface);
1016 wl_callback_add_listener(win->frame_callback,
1017 &frame_listener, ee);
1020 if ((updates = evas_render_updates(ee->evas)))
1022 Eina_List *l = NULL;
1025 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1027 ee->engine.wl.buffer_valid = EINA_TRUE;
1028 ecore_wl_window_buffer_attach(ee->engine.wl.win,
1029 ee->engine.wl.buffer, 0, 0);
1030 EINA_LIST_FOREACH(updates, l, r)
1031 ecore_wl_window_damage(ee->engine.wl.win,
1032 r->x, r->y, r->w, r->h);
1033 ecore_wl_window_commit(ee->engine.wl.win);
1036 evas_render_updates_free(updates);
1037 _ecore_evas_idle_timeout_update(ee);
1040 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
1042 win->frame_pending = EINA_TRUE;
1051 _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
1053 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1057 ecore_wl_screen_size_get(w, h);
1061 _ecore_evas_wl_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi)
1065 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1067 if (xdpi) *xdpi = 0;
1068 if (ydpi) *ydpi = 0;
1069 /* FIXME: Ideally this needs to get the DPI from a specific screen */
1070 dpi = ecore_wl_dpi_get();
1071 if (xdpi) *xdpi = dpi;
1072 if (ydpi) *ydpi = dpi;
1075 static struct wl_shm_pool *
1076 _ecore_evas_wl_shm_pool_create(int size, void **data)
1079 struct wl_shm_pool *pool;
1083 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1085 if (!(shm = ecore_wl_shm_get())) return NULL;
1087 strcpy(tmp, "/tmp/ecore-evas-wayland_shm-XXXXXX");
1088 if ((fd = mkstemp(tmp)) < 0)
1090 ERR("Could not create temporary file.");
1094 if (ftruncate(fd, size) < 0)
1096 ERR("Could not truncate temporary file.");
1101 *data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
1104 if (*data == MAP_FAILED)
1106 ERR("mmap of temporary file failed.");
1111 pool = wl_shm_create_pool(shm, fd, size);
1119 _ecore_evas_wl_buffer_release(void *data, struct wl_buffer *buffer)
1121 Ecore_Evas *ee = data;
1123 if (ee->engine.wl.buffer == buffer)
1124 ee->engine.wl.buffer_valid = EINA_FALSE;
1126 wl_buffer_destroy(buffer);
1129 static const struct wl_buffer_listener _buffer_listener_release =
1131 _ecore_evas_wl_buffer_release
1135 _ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool)
1137 unsigned int format;
1140 if ((ee->alpha) || (ee->transparent))
1141 format = WL_SHM_FORMAT_ARGB8888;
1143 format = WL_SHM_FORMAT_XRGB8888;
1145 stride = (ee->w * sizeof(int));
1147 ee->engine.wl.buffer =
1148 wl_shm_pool_create_buffer(pool, 0, ee->w, ee->h, stride, format);
1150 wl_buffer_add_listener(ee->engine.wl.buffer,
1151 &_buffer_listener_release, ee);
1155 _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location)
1157 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1160 if (ee->engine.wl.win)
1162 ee->engine.wl.win->resizing = EINA_TRUE;
1163 ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location);
1168 _ecore_evas_wayland_shm_move(Ecore_Evas *ee, int x, int y)
1170 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1173 if (ee->engine.wl.win)
1175 ee->engine.wl.win->moving = EINA_TRUE;
1176 ecore_wl_window_move(ee->engine.wl.win, x, y);
1181 _ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
1184 Ecore_Wl_Event_Mouse_In *ev;
1186 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1189 ee = ecore_event_window_match(ev->window);
1190 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1191 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1193 if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
1194 ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
1195 evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
1196 _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp);
1199 return ECORE_CALLBACK_PASS_ON;
1203 _ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1206 Ecore_Wl_Event_Mouse_Out *ev;
1208 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1211 ee = ecore_event_window_match(ev->window);
1212 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1213 if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1216 ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
1217 // _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp);
1218 evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
1219 if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
1220 if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
1221 ee->in = EINA_FALSE;
1223 return ECORE_CALLBACK_PASS_ON;
1227 _ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
1230 Ecore_Wl_Event_Focus_In *ev;
1232 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1235 ee = ecore_event_window_match(ev->win);
1236 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1237 if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1238 ee->prop.focused = 1;
1239 evas_focus_in(ee->evas);
1240 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
1241 return ECORE_CALLBACK_PASS_ON;
1245 _ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1248 Ecore_Wl_Event_Focus_In *ev;
1250 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1253 ee = ecore_event_window_match(ev->win);
1254 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1255 if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1256 evas_focus_out(ee->evas);
1257 ee->prop.focused = 0;
1258 if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
1259 return ECORE_CALLBACK_PASS_ON;
1263 _ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event)
1266 Ecore_Wl_Event_Window_Configure *ev;
1269 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1272 ee = ecore_event_window_match(ev->win);
1273 if (!ee) return ECORE_CALLBACK_PASS_ON;
1274 if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1276 if (ee->prop.fullscreen)
1278 _ecore_evas_wl_move(ee, ev->x, ev->y);
1279 _ecore_evas_wl_resize(ee, ev->w, ev->h);
1281 return ECORE_CALLBACK_PASS_ON;
1284 if ((ee->x != ev->x) || (ee->y != ev->y))
1288 if (ee->func.fn_move) ee->func.fn_move(ee);
1294 if ((ee->prop.maximized) || (!ee->prop.fullscreen))
1298 evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
1303 if (ee->prop.min.w > nw) nw = ee->prop.min.w;
1304 else if (nw > ee->prop.max.w) nw = ee->prop.max.w;
1305 if (ee->prop.min.h > nh) nh = ee->prop.min.h;
1306 else if (nh > ee->prop.max.h) nh = ee->prop.max.h;
1308 if ((ee->w != nw) || (ee->h != nh))
1312 if (ee->func.fn_resize) ee->func.fn_resize(ee);
1315 return ECORE_CALLBACK_PASS_ON;
1319 _ecore_evas_wl_smart_init(void)
1321 if (_ecore_evas_wl_smart) return;
1323 static const Evas_Smart_Class sc =
1325 "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION,
1326 _ecore_evas_wl_smart_add,
1327 _ecore_evas_wl_smart_del,
1329 _ecore_evas_wl_smart_resize,
1330 _ecore_evas_wl_smart_show,
1331 _ecore_evas_wl_smart_hide,
1332 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
1334 _ecore_evas_wl_smart = evas_smart_class_new(&sc);
1339 _ecore_evas_wl_smart_add(Evas_Object *obj)
1341 EE_Wl_Smart_Data *sd;
1344 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1346 if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return;
1348 evas = evas_object_evas_get(obj);
1355 sd->frame = evas_object_rectangle_add(evas);
1356 evas_object_color_set(sd->frame, 249, 249, 249, 255);
1357 evas_object_smart_member_add(sd->frame, obj);
1359 sd->text = evas_object_text_add(evas);
1360 evas_object_color_set(sd->text, 0, 0, 0, 255);
1361 evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN);
1362 evas_object_text_font_set(sd->text, "Sans", 10);
1363 evas_object_text_text_set(sd->text, "Smart Test");
1364 evas_object_smart_member_add(sd->text, obj);
1366 evas_object_smart_data_set(obj, sd);
1370 _ecore_evas_wl_smart_del(Evas_Object *obj)
1372 EE_Wl_Smart_Data *sd;
1374 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1376 if (!(sd = evas_object_smart_data_get(obj))) return;
1377 evas_object_del(sd->text);
1378 evas_object_del(sd->frame);
1383 _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
1385 EE_Wl_Smart_Data *sd;
1387 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1389 if (!(sd = evas_object_smart_data_get(obj))) return;
1390 if ((sd->w == w) && (sd->h == h)) return;
1393 evas_object_resize(sd->frame, w, h);
1397 _ecore_evas_wl_smart_show(Evas_Object *obj)
1399 EE_Wl_Smart_Data *sd;
1401 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1403 if (!(sd = evas_object_smart_data_get(obj))) return;
1404 evas_object_show(sd->frame);
1405 evas_object_show(sd->text);
1409 _ecore_evas_wl_smart_hide(Evas_Object *obj)
1411 EE_Wl_Smart_Data *sd;
1413 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1415 if (!(sd = evas_object_smart_data_get(obj))) return;
1416 evas_object_hide(sd->text);
1417 evas_object_hide(sd->frame);
1420 static Evas_Object *
1421 _ecore_evas_wl_frame_add(Evas *evas)
1423 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1425 _ecore_evas_wl_smart_init();
1426 return evas_object_smart_add(evas, _ecore_evas_wl_smart);
1431 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__)