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