Add wm_rotation infrastructure support
[platform/upstream/ecore.git] / src / lib / ecore_evas / ecore_evas_wayland_shm.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #ifdef STDC_HEADERS
6 # include <stdlib.h>
7 # include <stddef.h>
8 #else
9 # ifdef HAVE_STDLIB_H
10 #  include <stdlib.h>
11 # endif
12 #endif
13 #ifdef HAVE_ALLOCA_H
14 # include <alloca.h>
15 #elif !defined alloca
16 # ifdef __GNUC__
17 #  define alloca __builtin_alloca
18 # elif defined _AIX
19 #  define alloca __alloca
20 # elif defined _MSC_VER
21 #  include <malloc.h>
22 #  define alloca _alloca
23 # elif !defined HAVE_ALLOCA
24 #  ifdef  __cplusplus
25 extern "C"
26 #  endif
27 void *alloca (size_t);
28 # endif
29 #endif
30
31 //#define LOGFNS 1
32
33 #ifdef LOGFNS
34 # include <stdio.h>
35 # define LOGFN(fl, ln, fn) \
36    printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
37 #else
38 # define LOGFN(fl, ln, fn)
39 #endif
40
41 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
42 # include <stdlib.h>
43 # include <string.h>
44 # include <unistd.h>
45 # include <sys/types.h>
46 # include <sys/mman.h>
47 #endif
48
49 #include <Eina.h>
50 #include <Evas.h>
51 #include <Ecore.h>
52
53 #include "ecore_evas_private.h"
54 #include "Ecore_Evas.h"
55
56 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
57 # include <Evas_Engine_Wayland_Shm.h>
58 # include <Ecore_Wayland.h>
59
60 /* local structures */
61 typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data;
62 struct _EE_Wl_Smart_Data 
63 {
64    Evas_Object *frame;
65    Evas_Object *text;
66    Evas_Coord x, y, w, h;
67 };
68
69 struct _Ecore_Evas_Engine_Wl_Data
70 {
71    Ecore_Wl_Window *win;
72    Evas_Object *frame;
73 };
74
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);
111
112 static void _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t tm EINA_UNUSED);
113
114 static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool);
115
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);
121
122 /* SMART stuff for frame */
123 static Evas_Smart *_ecore_evas_wl_smart = NULL;
124
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);
131
132 static Evas_Object *_ecore_evas_wl_frame_add(Evas *evas);
133
134 /* local variables */
135 static int _ecore_evas_wl_init_count = 0;
136 static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[5];
137
138 static const struct wl_callback_listener frame_listener =
139 {
140    _ecore_evas_wl_frame_complete,
141 };
142
143 static Ecore_Evas_Engine_Func _ecore_wl_engine_func = 
144 {
145    _ecore_evas_wl_free,
146    _ecore_evas_wl_callback_resize_set,
147    _ecore_evas_wl_callback_move_set,
148    NULL, 
149    NULL,
150    _ecore_evas_wl_callback_delete_request_set,
151    NULL,
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,
156    NULL, // sticky_set
157    NULL, // unsticky_set
158    NULL, // pre_render_set
159    NULL, // post_render_set
160    _ecore_evas_wl_move,
161    NULL, // managed_move
162    _ecore_evas_wl_resize,
163    _ecore_evas_wl_move_resize,
164    NULL, // rotation_set
165    NULL, // shaped_set
166    _ecore_evas_wl_show,
167    _ecore_evas_wl_hide,
168    _ecore_evas_wl_raise,
169    NULL, // lower
170    NULL, // activate
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,
179    NULL, // focus 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
193    NULL, // aspect set
194    NULL, // urgent set
195    NULL, // modal 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
203 };
204
205 /* external variables */
206
207 /* external functions */
208 EAPI Ecore_Evas *
209 ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame)
210 {
211    Ecore_Wl_Window *p = NULL;
212    Evas_Engine_Info_Wayland_Shm *einfo;
213    Ecore_Evas *ee;
214    int method = 0, count = 0;
215
216    LOGFN(__FILE__, __LINE__, __FUNCTION__);
217
218    if (!(method = evas_render_method_lookup("wayland_shm")))
219      {
220         ERR("Render method lookup failed for Wayland_Shm");
221         return NULL;
222      }
223
224    count = ecore_wl_init(disp_name);
225    if (!count)
226      {
227         ERR("Failed to initialize Ecore_Wayland");
228         return NULL;
229      }
230    else if (count == 1)
231      ecore_wl_display_iterate();
232
233    if (!(ee = calloc(1, sizeof(Ecore_Evas))))
234      {
235         ERR("Failed to allocate Ecore_Evas");
236         ecore_wl_shutdown();
237         return NULL;
238      }
239
240    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
241
242    _ecore_evas_wl_init();
243
244    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
245
246    ee->driver = "wayland_shm";
247    if (disp_name) ee->name = strdup(disp_name);
248
249    if (w < 1) w = 1;
250    if (h < 1) h = 1;
251
252    ee->x = x;
253    ee->y = y;
254    ee->w = w;
255    ee->h = h;
256    ee->req.x = ee->x;
257    ee->req.y = ee->y;
258    ee->req.w = ee->w;
259    ee->req.h = ee->h;
260    ee->rotation = 0;
261    ee->prop.max.w = 32767;
262    ee->prop.max.h = 32767;
263    ee->prop.layer = 4;
264    ee->prop.request_pos = 0;
265    ee->prop.sticky = 0;
266    ee->prop.draw_frame = frame;
267    ee->alpha = EINA_FALSE;
268
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);
274
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);
278
279    if (parent) p = ecore_wl_window_find(parent);
280
281    /* FIXME: Get if parent is alpha, and set */
282
283    ee->engine.wl.parent = p;
284    ee->engine.wl.win = 
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;
287
288    if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
289      {
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))
295           {
296              ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
297              ecore_evas_free(ee);
298              _ecore_evas_wl_shutdown();
299              ecore_wl_shutdown();
300              return NULL;
301           }
302      }
303    else 
304      {
305         ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
306         ecore_evas_free(ee);
307         _ecore_evas_wl_shutdown();
308         ecore_wl_shutdown();
309         return NULL;
310      }
311
312    ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free);
313
314    if (ee->prop.draw_frame) 
315      {
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);
319      }
320
321    _ecore_evas_register(ee);
322    ecore_evas_input_event_register(ee);
323
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);
329
330 //   evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
331
332    return ee;
333 }
334
335 /* local functions */
336 static int 
337 _ecore_evas_wl_init(void)
338 {
339    LOGFN(__FILE__, __LINE__, __FUNCTION__);
340
341    if (++_ecore_evas_wl_init_count != 1)
342      return _ecore_evas_wl_init_count;
343
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);
359
360    ecore_event_evas_init();
361
362    return _ecore_evas_wl_init_count;
363 }
364
365 static int 
366 _ecore_evas_wl_shutdown(void)
367 {
368    unsigned int i = 0;
369
370    LOGFN(__FILE__, __LINE__, __FUNCTION__);
371
372    if (--_ecore_evas_wl_init_count != 0)
373      return _ecore_evas_wl_init_count;
374
375    for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++)
376      {
377         if (_ecore_evas_wl_event_hdls[i])
378           ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]);
379      }
380
381    ecore_event_evas_shutdown();
382
383    return _ecore_evas_wl_init_count;
384 }
385
386 static void 
387 _ecore_evas_wl_pre_free(Ecore_Evas *ee)
388 {
389    LOGFN(__FILE__, __LINE__, __FUNCTION__);
390
391    if (!ee) return;
392    if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame);
393 }
394
395 static void 
396 _ecore_evas_wl_free(Ecore_Evas *ee)
397 {
398    LOGFN(__FILE__, __LINE__, __FUNCTION__);
399
400    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
401    ee->engine.wl.buffer = NULL;
402
403    if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win);
404    ee->engine.wl.win = NULL;
405
406    ecore_event_window_unregister(ee->prop.window);
407    ecore_evas_input_event_unregister(ee);
408
409    _ecore_evas_wl_shutdown();
410    ecore_wl_shutdown();
411 }
412
413 static void 
414 _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
415 {
416    LOGFN(__FILE__, __LINE__, __FUNCTION__);
417
418    if (!ee) return;
419    ee->func.fn_resize = func;
420 }
421
422 static void 
423 _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
424 {
425    LOGFN(__FILE__, __LINE__, __FUNCTION__);
426
427    if (!ee) return;
428    ee->func.fn_move = func;
429 }
430
431 static void 
432 _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
433 {
434    LOGFN(__FILE__, __LINE__, __FUNCTION__);
435
436    if (!ee) return;
437    ee->func.fn_delete_request = func;
438 }
439
440 static void 
441 _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
442 {
443    LOGFN(__FILE__, __LINE__, __FUNCTION__);
444
445    if (!ee) return;
446    ee->func.fn_focus_in = func;
447 }
448
449 static void 
450 _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
451 {
452    LOGFN(__FILE__, __LINE__, __FUNCTION__);
453
454    if (!ee) return;
455    ee->func.fn_focus_out = func;
456 }
457
458 static void 
459 _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
460 {
461    LOGFN(__FILE__, __LINE__, __FUNCTION__);
462
463    if (!ee) return;
464    ee->func.fn_mouse_in = func;
465 }
466
467 static void 
468 _ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
469 {
470    LOGFN(__FILE__, __LINE__, __FUNCTION__);
471
472    if (!ee) return;
473    ee->func.fn_mouse_out = func;
474 }
475
476 static void 
477 _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y)
478 {
479    LOGFN(__FILE__, __LINE__, __FUNCTION__);
480
481    if (!ee) return;
482
483    ee->req.x = x;
484    ee->req.y = y;
485
486    if ((ee->x != x) || (ee->y != y))
487      {
488         ee->x = x;
489         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);
493      }
494 }
495
496 static void 
497 _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
498 {
499    Evas_Engine_Info_Wayland_Shm *einfo;
500
501    LOGFN(__FILE__, __LINE__, __FUNCTION__);
502
503    if (!ee) return;
504    if (w < 1) w = 1;
505    if (h < 1) h = 1;
506
507    ee->req.w = w;
508    ee->req.h = h;
509
510    if (!ee->prop.fullscreen)
511      {
512         int fw = 0, fh = 0;
513
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;
518
519         evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
520         w += fw;
521         h += fh;
522      }
523
524    if ((ee->w != w) || (ee->h != h))
525      {
526         ee->w = w;
527         ee->h = h;
528
529         if ((ee->rotation == 90) || (ee->rotation == 270))
530           {
531              evas_output_size_set(ee->evas, h, w);
532              evas_output_viewport_set(ee->evas, 0, 0, h, w);
533           }
534         else
535           {
536              evas_output_size_set(ee->evas, w, h);
537              evas_output_viewport_set(ee->evas, 0, 0, w, h);
538           }
539
540         if (ee->prop.avoid_damage)
541           {
542              int pdam = 0;
543
544              pdam = ecore_evas_avoid_damage_get(ee);
545              ecore_evas_avoid_damage_set(ee, 0);
546              ecore_evas_avoid_damage_set(ee, pdam);
547           }
548
549         if (ee->engine.wl.frame)
550           evas_object_resize(ee->engine.wl.frame, w, h);
551
552         if (ee->engine.wl.buffer)
553           {
554              if(!ee->engine.wl.buffer_valid)
555                {
556                   wl_buffer_destroy(ee->engine.wl.buffer);
557                }
558              else
559                {
560                   ee->engine.wl.buffer_valid = EINA_FALSE;
561                }
562              ee->engine.wl.buffer = NULL;
563           }
564
565         _ecore_evas_wl_ensure_pool_size(ee, w, h);
566
567         if (ee->engine.wl.pool)
568           _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
569
570         einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
571         if (!einfo)
572           {
573             ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
574             return;
575           }
576
577         einfo->info.dest = ee->engine.wl.pool_data;
578         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
579
580         if (ee->engine.wl.win)
581           {
582 //             if (!ee->prop.fullscreen)
583                ecore_wl_window_update_size(ee->engine.wl.win, w, h);
584           }
585
586         if (ee->func.fn_resize) ee->func.fn_resize(ee);
587      }
588 }
589
590 static void 
591 _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
592 {
593    LOGFN(__FILE__, __LINE__, __FUNCTION__);
594
595    if (!ee) return;
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);
600 }
601
602 static void
603 _ecore_evas_wl_ensure_pool_size(Ecore_Evas *ee, int w, int h)
604 {
605    int stride = 0;
606    size_t len = 0;
607
608    stride = w * sizeof(int);
609    len = stride * h;
610
611    if ((ee->engine.wl.pool) && (len < ee->engine.wl.pool_size))
612      return;
613    else
614      {
615         struct wl_shm_pool *pool = NULL;
616         void *data;
617         int size;
618
619         if (ee->engine.wl.pool)
620           wl_shm_pool_destroy(ee->engine.wl.pool);
621
622         /*
623          * Make the pool 1.5 times the current requirement to allow growth
624          * without requiring a new pool allocation
625          */
626         size = 1.5 * len;
627         pool = _ecore_evas_wl_shm_pool_create(size, &data);
628
629         ee->engine.wl.pool = pool;
630         ee->engine.wl.pool_size = size;
631         ee->engine.wl.pool_data = data;
632      }
633 }
634
635 static void
636 _ecore_evas_wl_show(Ecore_Evas *ee)
637 {
638    Evas_Engine_Info_Wayland_Shm *einfo;
639
640    LOGFN(__FILE__, __LINE__, __FUNCTION__);
641
642    if ((!ee) || (ee->visible)) return;
643
644    _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
645
646    if (ee->engine.wl.pool)
647      _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
648
649    einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
650    if (!einfo)
651      {
652         ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
653         return;
654      }
655
656    einfo->info.dest = ee->engine.wl.pool_data;
657    evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
658
659    /* ecore_wl_flush(); */
660
661    if (ee->engine.wl.win)
662      {
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);
668
669         if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
670           wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, 
671                                      ee->prop.clas);
672         if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
673           wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, 
674                                      ee->prop.title);
675      }
676
677    if (ee->engine.wl.frame)
678      {
679         evas_object_show(ee->engine.wl.frame);
680         evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
681      }
682
683    ee->visible = 1;
684    if (ee->func.fn_show) ee->func.fn_show(ee);
685 }
686
687 static void 
688 _ecore_evas_wl_hide(Ecore_Evas *ee)
689 {
690    Evas_Engine_Info_Wayland_Shm *einfo;
691
692    LOGFN(__FILE__, __LINE__, __FUNCTION__);
693
694    if ((!ee) || (!ee->visible)) return;
695
696    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
697    ee->engine.wl.buffer = NULL;
698
699    munmap(ee->engine.wl.pool_data, ee->engine.wl.pool_size);
700
701    einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
702    if ((einfo) && (einfo->info.dest))
703      {
704         einfo->info.dest = NULL;
705         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
706      }
707
708    ecore_wl_window_hide(ee->engine.wl.win);
709
710    ee->visible = 0;
711    ee->should_be_visible = 0;
712
713    if (ee->func.fn_hide) ee->func.fn_hide(ee);
714 }
715
716 static void 
717 _ecore_evas_wl_raise(Ecore_Evas *ee)
718 {
719    LOGFN(__FILE__, __LINE__, __FUNCTION__);
720
721    if ((!ee) || (!ee->visible)) return;
722    ecore_wl_window_raise(ee->engine.wl.win);
723 }
724
725 static void 
726 _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title)
727 {
728    LOGFN(__FILE__, __LINE__, __FUNCTION__);
729
730    if (!ee) return;
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)) 
735      {
736         EE_Wl_Smart_Data *sd;
737
738         if ((sd = evas_object_smart_data_get(ee->engine.wl.frame)))
739           evas_object_text_text_set(sd->text, ee->prop.title);
740      }
741
742    if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
743      wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, 
744                                 ee->prop.title);
745 }
746
747 static void 
748 _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c) 
749 {
750    LOGFN(__FILE__, __LINE__, __FUNCTION__);
751
752    if (!ee) return;
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);
759
760    if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
761      wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, 
762                                 ee->prop.clas);
763 }
764
765 static void 
766 _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h) 
767 {
768    LOGFN(__FILE__, __LINE__, __FUNCTION__);
769
770    if (!ee) return;
771    if (w < 0) w = 0;
772    if (h < 0) h = 0;
773    if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
774    ee->prop.min.w = w;
775    ee->prop.min.h = h;
776 }
777
778 static void 
779 _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h) 
780 {
781    LOGFN(__FILE__, __LINE__, __FUNCTION__);
782
783    if (!ee) return;
784    if (w < 0) w = 0;
785    if (h < 0) h = 0;
786    if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
787    ee->prop.max.w = w;
788    ee->prop.max.h = h;
789 }
790
791 static void 
792 _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h) 
793 {
794    LOGFN(__FILE__, __LINE__, __FUNCTION__);
795
796    if (!ee) return;
797    if (w < 0) w = 0;
798    if (h < 0) h = 0;
799    if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
800    ee->prop.base.w = w;
801    ee->prop.base.h = h;
802 }
803
804 static void 
805 _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h) 
806 {
807    LOGFN(__FILE__, __LINE__, __FUNCTION__);
808
809    if (!ee) return;
810    if (w < 0) w = 0;
811    if (h < 0) h = 0;
812    if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
813    ee->prop.step.w = w;
814    ee->prop.step.h = h;
815 }
816
817 static void 
818 _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer)
819 {
820    LOGFN(__FILE__, __LINE__, __FUNCTION__);
821
822    if (!ee) return;
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;
827 }
828
829 static void 
830 _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify)
831 {
832    LOGFN(__FILE__, __LINE__, __FUNCTION__);
833
834    if (!ee) return;
835    if (ee->prop.iconified == iconify) return;
836    ee->prop.iconified = iconify;
837    /* FIXME: Implement this in Wayland someshow */
838 }
839
840 static void 
841 _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max)
842 {
843    LOGFN(__FILE__, __LINE__, __FUNCTION__);
844
845    if (!ee) return;
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);
851 }
852
853 static void 
854 _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full)
855 {
856    LOGFN(__FILE__, __LINE__, __FUNCTION__);
857
858    if (!ee) return;
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);
864 }
865
866 static void 
867 _ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore)
868 {
869    LOGFN(__FILE__, __LINE__, __FUNCTION__);
870
871    if (!ee) return;
872    ee->ignore_events = ignore;
873    /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */
874 }
875
876 static void 
877 _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha)
878 {
879    Evas_Engine_Info_Wayland_Shm *einfo;
880    Ecore_Wl_Window *win;
881
882    LOGFN(__FILE__, __LINE__, __FUNCTION__);
883
884    if (!ee) return;
885    if ((ee->alpha == alpha)) return;
886    ee->alpha = alpha;
887
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 
890     * freeze is over */
891    if ((win = ee->engine.wl.win))
892      win->alpha = alpha;
893
894    /* if (ee->engine.wl.win) */
895    /*   ecore_wl_window_transparent_set(ee->engine.wl.win, alpha); */
896
897    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
898    ee->engine.wl.buffer = NULL;
899
900    _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
901
902    if (ee->engine.wl.pool)
903      _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
904
905    if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
906      {
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);
912      }
913
914    if (ee->engine.wl.win)
915      {
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);
920      }
921 }
922
923 static void 
924 _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent)
925 {
926    Evas_Engine_Info_Wayland_Shm *einfo;
927
928    LOGFN(__FILE__, __LINE__, __FUNCTION__);
929
930    if (!ee) return;
931    if ((ee->transparent == transparent)) return;
932    ee->transparent = transparent;
933
934    if (ee->engine.wl.win)
935      ecore_wl_window_transparent_set(ee->engine.wl.win, transparent);
936
937    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
938    ee->engine.wl.buffer = NULL;
939
940    _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
941
942    if (ee->engine.wl.pool)
943      _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
944
945    if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
946      {
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);
952      }
953
954    if (ee->engine.wl.win)
955      {
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);
960      }
961 }
962
963 static void
964 _ecore_evas_wl_frame_complete(void *data, struct wl_callback *callback, uint32_t tm EINA_UNUSED)
965 {
966    Ecore_Evas *ee = data;
967    Ecore_Wl_Window *win = NULL;
968
969    if (!ee) return;
970    if (!(win = ee->engine.wl.win)) return;
971
972    win->frame_callback = NULL;
973    win->frame_pending = EINA_FALSE;
974    wl_callback_destroy(callback);
975
976    if (win->surface)
977      {
978         win->frame_callback = wl_surface_frame(win->surface);
979         wl_callback_add_listener(win->frame_callback, &frame_listener, ee);
980      }
981 }
982
983 static int 
984 _ecore_evas_wl_render(Ecore_Evas *ee)
985 {
986    int rend = 0;
987    Ecore_Wl_Window *win = NULL;
988
989    if (!(win = ee->engine.wl.win)) return 0;
990
991    if (!ee) return 0;
992    if (!ee->visible)
993      evas_norender(ee->evas);
994    else
995      {
996         Eina_List *ll = NULL;
997         Ecore_Evas *ee2 = NULL;
998
999         if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
1000
1001         EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
1002           {
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);
1007           }
1008
1009         if (!win->frame_pending)
1010           {
1011              Eina_List *updates;
1012
1013              if (!win->frame_callback)
1014                {
1015                   win->frame_callback = wl_surface_frame(win->surface);
1016                   wl_callback_add_listener(win->frame_callback,
1017                                            &frame_listener, ee);
1018                }
1019
1020              if ((updates = evas_render_updates(ee->evas)))
1021                {
1022                   Eina_List *l = NULL;
1023                   Eina_Rectangle *r;
1024
1025                   LOGFN(__FILE__, __LINE__, __FUNCTION__);
1026
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);
1034                   ecore_wl_flush();
1035
1036                   evas_render_updates_free(updates);
1037                   _ecore_evas_idle_timeout_update(ee);
1038                   rend = 1;
1039
1040                   if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
1041
1042                   win->frame_pending = EINA_TRUE;
1043
1044                }
1045           }
1046      }
1047    return rend;
1048 }
1049
1050 static void 
1051 _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
1052 {
1053    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1054
1055    if (x) *x = 0;
1056    if (y) *y = 0;
1057    ecore_wl_screen_size_get(w, h);
1058 }
1059
1060 static void 
1061 _ecore_evas_wl_screen_dpi_get(const Ecore_Evas *ee __UNUSED__, int *xdpi, int *ydpi)
1062 {
1063    int dpi = 0;
1064
1065    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1066
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;
1073 }
1074
1075 static struct wl_shm_pool *
1076 _ecore_evas_wl_shm_pool_create(int size, void **data)
1077 {
1078    struct wl_shm *shm;
1079    struct wl_shm_pool *pool;
1080    char tmp[PATH_MAX];
1081    int fd;
1082
1083    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1084
1085    if (!(shm = ecore_wl_shm_get())) return NULL;
1086
1087    strcpy(tmp, "/tmp/ecore-evas-wayland_shm-XXXXXX");
1088    if ((fd = mkstemp(tmp)) < 0) 
1089      {
1090         ERR("Could not create temporary file.");
1091         return NULL;
1092      }
1093
1094    if (ftruncate(fd, size) < 0) 
1095      {
1096         ERR("Could not truncate temporary file.");
1097         close(fd);
1098         return NULL;
1099      }
1100
1101    *data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
1102    unlink(tmp);
1103
1104    if (*data == MAP_FAILED) 
1105      {
1106         ERR("mmap of temporary file failed.");
1107         close(fd);
1108         return NULL;
1109      }
1110
1111    pool = wl_shm_create_pool(shm, fd, size);
1112
1113    close(fd);
1114
1115    return pool;
1116 }
1117
1118 static void
1119 _ecore_evas_wl_buffer_release(void *data, struct wl_buffer *buffer)
1120 {
1121    Ecore_Evas *ee = data;
1122
1123    if (ee->engine.wl.buffer == buffer)
1124      ee->engine.wl.buffer_valid = EINA_FALSE;
1125    else
1126      wl_buffer_destroy(buffer);
1127 }
1128
1129 static const struct wl_buffer_listener _buffer_listener_release =
1130 {
1131    _ecore_evas_wl_buffer_release
1132 };
1133
1134 static void 
1135 _ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool)
1136 {
1137    unsigned int format;
1138    int stride = 0;
1139
1140    if ((ee->alpha) || (ee->transparent))
1141      format = WL_SHM_FORMAT_ARGB8888;
1142    else
1143      format = WL_SHM_FORMAT_XRGB8888;
1144
1145    stride = (ee->w * sizeof(int));
1146
1147    ee->engine.wl.buffer =
1148      wl_shm_pool_create_buffer(pool, 0, ee->w, ee->h, stride, format);
1149
1150    wl_buffer_add_listener(ee->engine.wl.buffer,
1151                           &_buffer_listener_release, ee);
1152 }
1153
1154 void 
1155 _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location)
1156 {
1157    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1158
1159    if (!ee) return;
1160    if (ee->engine.wl.win) 
1161      {
1162         ee->engine.wl.win->resizing = EINA_TRUE;
1163         ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location);
1164      }
1165 }
1166
1167 void 
1168 _ecore_evas_wayland_shm_move(Ecore_Evas *ee, int x, int y)
1169 {
1170    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1171
1172    if (!ee) return;
1173    if (ee->engine.wl.win) 
1174      {
1175         ee->engine.wl.win->moving = EINA_TRUE;
1176         ecore_wl_window_move(ee->engine.wl.win, x, y);
1177      }
1178 }
1179
1180 static Eina_Bool 
1181 _ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
1182 {
1183    Ecore_Evas *ee;
1184    Ecore_Wl_Event_Mouse_In *ev;
1185
1186    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1187
1188    ev = event;
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;
1192
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);
1197    ee->in = EINA_TRUE;
1198
1199    return ECORE_CALLBACK_PASS_ON;
1200 }
1201
1202 static Eina_Bool 
1203 _ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1204 {
1205    Ecore_Evas *ee;
1206    Ecore_Wl_Event_Mouse_Out *ev;
1207
1208    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1209
1210    ev = event;
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;
1214    if (ee->in)
1215      {
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;
1222      }
1223    return ECORE_CALLBACK_PASS_ON;
1224 }
1225
1226 static Eina_Bool 
1227 _ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
1228 {
1229    Ecore_Evas *ee;
1230    Ecore_Wl_Event_Focus_In *ev;
1231
1232    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1233
1234    ev = event;
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;
1242 }
1243
1244 static Eina_Bool 
1245 _ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1246 {
1247    Ecore_Evas *ee;
1248    Ecore_Wl_Event_Focus_In *ev;
1249
1250    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1251
1252    ev = event;
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;
1260 }
1261
1262 static Eina_Bool 
1263 _ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event)
1264 {
1265    Ecore_Evas *ee;
1266    Ecore_Wl_Event_Window_Configure *ev;
1267    int nw = 0, nh = 0;
1268
1269    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1270
1271    ev = event;
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;
1275
1276    if (ee->prop.fullscreen)
1277      {
1278         _ecore_evas_wl_move(ee, ev->x, ev->y);
1279         _ecore_evas_wl_resize(ee, ev->w, ev->h);
1280
1281         return ECORE_CALLBACK_PASS_ON;
1282      }
1283
1284    if ((ee->x != ev->x) || (ee->y != ev->y))
1285      {
1286         ee->req.x = ee->x;
1287         ee->req.y = ee->y;
1288         if (ee->func.fn_move) ee->func.fn_move(ee);
1289      }
1290
1291    nw = ev->w;
1292    nh = ev->h;
1293
1294    if ((ee->prop.maximized) || (!ee->prop.fullscreen))
1295      {
1296         int fw = 0, fh = 0;
1297
1298         evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
1299         nw = ev->w - fw;
1300         nh = ev->h - fh;
1301      }
1302
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;
1307
1308    if ((ee->w != nw) || (ee->h != nh))
1309      {
1310         ee->req.w = nw;
1311         ee->req.h = nh;
1312         if (ee->func.fn_resize) ee->func.fn_resize(ee);
1313      }
1314
1315    return ECORE_CALLBACK_PASS_ON;
1316 }
1317
1318 static void 
1319 _ecore_evas_wl_smart_init(void) 
1320 {
1321    if (_ecore_evas_wl_smart) return;
1322      {
1323         static const Evas_Smart_Class sc = 
1324           {
1325              "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION, 
1326              _ecore_evas_wl_smart_add, 
1327              _ecore_evas_wl_smart_del, 
1328              NULL, 
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
1333           };
1334         _ecore_evas_wl_smart = evas_smart_class_new(&sc);
1335      }
1336 }
1337
1338 static void 
1339 _ecore_evas_wl_smart_add(Evas_Object *obj) 
1340 {
1341    EE_Wl_Smart_Data *sd;
1342    Evas *evas;
1343
1344    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1345
1346    if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return;
1347
1348    evas = evas_object_evas_get(obj);
1349
1350    sd->x = 0;
1351    sd->y = 0;
1352    sd->w = 1;
1353    sd->h = 1;
1354
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);
1358
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);
1365
1366    evas_object_smart_data_set(obj, sd);
1367 }
1368
1369 static void 
1370 _ecore_evas_wl_smart_del(Evas_Object *obj) 
1371 {
1372    EE_Wl_Smart_Data *sd;
1373
1374    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1375
1376    if (!(sd = evas_object_smart_data_get(obj))) return;
1377    evas_object_del(sd->text);
1378    evas_object_del(sd->frame);
1379    free(sd);
1380 }
1381
1382 static void 
1383 _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) 
1384 {
1385    EE_Wl_Smart_Data *sd;
1386
1387    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1388
1389    if (!(sd = evas_object_smart_data_get(obj))) return;
1390    if ((sd->w == w) && (sd->h == h)) return;
1391    sd->w = w;
1392    sd->h = h;
1393    evas_object_resize(sd->frame, w, h);
1394 }
1395
1396 static void 
1397 _ecore_evas_wl_smart_show(Evas_Object *obj) 
1398 {
1399    EE_Wl_Smart_Data *sd;
1400
1401    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1402
1403    if (!(sd = evas_object_smart_data_get(obj))) return;
1404    evas_object_show(sd->frame);
1405    evas_object_show(sd->text);
1406 }
1407
1408 static void 
1409 _ecore_evas_wl_smart_hide(Evas_Object *obj) 
1410 {
1411    EE_Wl_Smart_Data *sd;
1412
1413    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1414
1415    if (!(sd = evas_object_smart_data_get(obj))) return;
1416    evas_object_hide(sd->text);
1417    evas_object_hide(sd->frame);
1418 }
1419
1420 static Evas_Object *
1421 _ecore_evas_wl_frame_add(Evas *evas) 
1422 {
1423    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1424
1425    _ecore_evas_wl_smart_init();
1426    return evas_object_smart_add(evas, _ecore_evas_wl_smart);
1427 }
1428
1429 #else
1430 EAPI Ecore_Evas *
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__)
1432 {
1433    return NULL;
1434 }
1435 #endif