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