ibusimmodule: NULL check using EINA_SAFETY_ON_RETURN
[framework/uifw/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_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
55 static void _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y);
56 static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h);
57 static void _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h);
58 static void _ecore_evas_wl_show(Ecore_Evas *ee);
59 static void _ecore_evas_wl_hide(Ecore_Evas *ee);
60 static void _ecore_evas_wl_raise(Ecore_Evas *ee);
61 static void _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title);
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_layer_set(Ecore_Evas *ee, int layer);
68 static void _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify);
69 static void _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max);
70 static void _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full);
71 static void _ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore);
72 static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha);
73 static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent);
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_ensure_pool_size(Ecore_Evas *ee, int w, int h);
77 static struct wl_shm_pool *_ecore_evas_wl_shm_pool_create(int size, void **data);
78
79 static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool);
80
81 static Eina_Bool _ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event);
82 static Eina_Bool _ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event);
83 static Eina_Bool _ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
84 static Eina_Bool _ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
85 static Eina_Bool _ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event);
86
87 /* SMART stuff for frame */
88 static Evas_Smart *_ecore_evas_wl_smart = NULL;
89
90 static void _ecore_evas_wl_smart_init(void);
91 static void _ecore_evas_wl_smart_add(Evas_Object *obj);
92 static void _ecore_evas_wl_smart_del(Evas_Object *obj);
93 static void _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
94 static void _ecore_evas_wl_smart_show(Evas_Object *obj);
95 static void _ecore_evas_wl_smart_hide(Evas_Object *obj);
96
97 static Evas_Object *_ecore_evas_wl_frame_add(Evas *evas);
98
99 /* local variables */
100 static int _ecore_evas_wl_init_count = 0;
101 static Ecore_Event_Handler *_ecore_evas_wl_event_hdls[5];
102
103 static Ecore_Evas_Engine_Func _ecore_wl_engine_func = 
104 {
105    _ecore_evas_wl_free,
106    _ecore_evas_wl_callback_resize_set,
107    _ecore_evas_wl_callback_move_set,
108    NULL, 
109    NULL,
110    _ecore_evas_wl_callback_delete_request_set,
111    NULL,
112    _ecore_evas_wl_callback_focus_in_set,
113    _ecore_evas_wl_callback_focus_out_set,
114    _ecore_evas_wl_callback_mouse_in_set,
115    _ecore_evas_wl_callback_mouse_out_set,
116    NULL, // sticky_set
117    NULL, // unsticky_set
118    NULL, // pre_render_set
119    NULL, // post_render_set
120    _ecore_evas_wl_move,
121    NULL, // managed_move
122    _ecore_evas_wl_resize,
123    _ecore_evas_wl_move_resize,
124    NULL, // rotation_set
125    NULL, // shaped_set
126    _ecore_evas_wl_show,
127    _ecore_evas_wl_hide,
128    _ecore_evas_wl_raise,
129    NULL, // lower
130    NULL, // activate
131    _ecore_evas_wl_title_set,
132    _ecore_evas_wl_name_class_set,
133    _ecore_evas_wl_size_min_set,
134    _ecore_evas_wl_size_max_set,
135    _ecore_evas_wl_size_base_set,
136    _ecore_evas_wl_size_step_set,
137    NULL, // object_cursor_set
138    _ecore_evas_wl_layer_set,
139    NULL, // focus set
140    _ecore_evas_wl_iconified_set,
141    NULL, // borderless set
142    NULL, // override set
143    _ecore_evas_wl_maximized_set,
144    _ecore_evas_wl_fullscreen_set,
145    NULL, // func avoid_damage set
146    NULL, // func withdrawn set
147    NULL, // func sticky set
148    _ecore_evas_wl_ignore_events_set,
149    _ecore_evas_wl_alpha_set,
150    _ecore_evas_wl_transparent_set,
151    NULL, // window group set
152    NULL, // aspect set
153    NULL, // urgent set
154    NULL, // modal set
155    NULL, // demand attention set
156    NULL, // focus skip set
157    _ecore_evas_wl_render, 
158    _ecore_evas_wl_screen_geometry_get
159 };
160
161 /* external variables */
162
163 /* external functions */
164 EAPI Ecore_Evas *
165 ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame)
166 {
167    Ecore_Wl_Window *p = NULL;
168    Evas_Engine_Info_Wayland_Shm *einfo;
169    Ecore_Evas *ee;
170    int method = 0, count = 0;
171
172    LOGFN(__FILE__, __LINE__, __FUNCTION__);
173
174    if (!(method = evas_render_method_lookup("wayland_shm")))
175      {
176         ERR("Render method lookup failed for Wayland_Shm");
177         return NULL;
178      }
179
180    count = ecore_wl_init(disp_name);
181    if (!count)
182      {
183         ERR("Failed to initialize Ecore_Wayland");
184         return NULL;
185      }
186    else if (count == 1)
187      ecore_wl_display_iterate();
188
189    if (!(ee = calloc(1, sizeof(Ecore_Evas))))
190      {
191         ERR("Failed to allocate Ecore_Evas");
192         ecore_wl_shutdown();
193         return NULL;
194      }
195
196    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
197
198    _ecore_evas_wl_init();
199
200    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
201
202    ee->driver = "wayland_shm";
203    if (disp_name) ee->name = strdup(disp_name);
204
205    if (w < 1) w = 1;
206    if (h < 1) h = 1;
207
208    ee->x = x;
209    ee->y = y;
210    ee->w = w;
211    ee->h = h;
212    ee->req.x = ee->x;
213    ee->req.y = ee->y;
214    ee->req.w = ee->w;
215    ee->req.h = ee->h;
216    ee->rotation = 0;
217    ee->prop.max.w = 32767;
218    ee->prop.max.h = 32767;
219    ee->prop.layer = 4;
220    ee->prop.request_pos = 0;
221    ee->prop.sticky = 0;
222    ee->prop.draw_frame = frame;
223    ee->alpha = EINA_FALSE;
224
225    ee->evas = evas_new();
226    evas_data_attach_set(ee->evas, ee);
227    evas_output_method_set(ee->evas, method);
228    evas_output_size_set(ee->evas, ee->w, ee->h);
229    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
230
231    /* FIXME: This needs to be set based on theme & scale */
232    if (ee->prop.draw_frame)
233      evas_output_framespace_set(ee->evas, 4, 18, 8, 22);
234
235    if (parent) p = ecore_wl_window_find(parent);
236
237    /* FIXME: Get if parent is alpha, and set */
238
239    ee->engine.wl.parent = p;
240    ee->engine.wl.win = 
241      ecore_wl_window_new(p, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_SHM);
242    ee->prop.window = ee->engine.wl.win->id;
243
244    if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
245      {
246         einfo->info.rotation = ee->rotation;
247         einfo->info.destination_alpha = ee->alpha;
248         einfo->info.rotation = ee->rotation;
249         einfo->info.debug = EINA_FALSE;
250         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
251           {
252              ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
253              ecore_evas_free(ee);
254              _ecore_evas_wl_shutdown();
255              ecore_wl_shutdown();
256              return NULL;
257           }
258      }
259    else 
260      {
261         ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
262         ecore_evas_free(ee);
263         _ecore_evas_wl_shutdown();
264         ecore_wl_shutdown();
265         return NULL;
266      }
267
268    ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free);
269
270    if (ee->prop.draw_frame) 
271      {
272         ee->engine.wl.frame = _ecore_evas_wl_frame_add(ee->evas);
273         evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE);
274         evas_object_move(ee->engine.wl.frame, 0, 0);
275      }
276
277    _ecore_evas_register(ee);
278    ecore_evas_input_event_register(ee);
279
280    ecore_event_window_register(ee->prop.window, ee, ee->evas, 
281                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, 
282                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, 
283                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, 
284                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
285
286 //   evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
287
288    return ee;
289 }
290
291 /* local functions */
292 static int 
293 _ecore_evas_wl_init(void)
294 {
295    LOGFN(__FILE__, __LINE__, __FUNCTION__);
296
297    if (++_ecore_evas_wl_init_count != 1)
298      return _ecore_evas_wl_init_count;
299
300    _ecore_evas_wl_event_hdls[0] = 
301      ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, 
302                              _ecore_evas_wl_cb_mouse_in, NULL);
303    _ecore_evas_wl_event_hdls[1] = 
304      ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, 
305                              _ecore_evas_wl_cb_mouse_out, NULL);
306    _ecore_evas_wl_event_hdls[2] = 
307      ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, 
308                              _ecore_evas_wl_cb_focus_in, NULL);
309    _ecore_evas_wl_event_hdls[3] = 
310      ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, 
311                              _ecore_evas_wl_cb_focus_out, NULL);
312    _ecore_evas_wl_event_hdls[4] = 
313      ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, 
314                              _ecore_evas_wl_cb_window_configure, NULL);
315
316    ecore_event_evas_init();
317
318    return _ecore_evas_wl_init_count;
319 }
320
321 static int 
322 _ecore_evas_wl_shutdown(void)
323 {
324    unsigned int i = 0;
325
326    LOGFN(__FILE__, __LINE__, __FUNCTION__);
327
328    if (--_ecore_evas_wl_init_count != 0)
329      return _ecore_evas_wl_init_count;
330
331    for (i = 0; i < sizeof(_ecore_evas_wl_event_hdls) / sizeof(Ecore_Event_Handler *); i++)
332      {
333         if (_ecore_evas_wl_event_hdls[i])
334           ecore_event_handler_del(_ecore_evas_wl_event_hdls[i]);
335      }
336
337    ecore_event_evas_shutdown();
338
339    return _ecore_evas_wl_init_count;
340 }
341
342 static void 
343 _ecore_evas_wl_pre_free(Ecore_Evas *ee)
344 {
345    LOGFN(__FILE__, __LINE__, __FUNCTION__);
346
347    if (!ee) return;
348    if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame);
349 }
350
351 static void 
352 _ecore_evas_wl_free(Ecore_Evas *ee)
353 {
354    LOGFN(__FILE__, __LINE__, __FUNCTION__);
355
356    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
357    ee->engine.wl.buffer = NULL;
358
359    if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win);
360    ee->engine.wl.win = NULL;
361
362    ecore_event_window_unregister(ee->prop.window);
363    ecore_evas_input_event_unregister(ee);
364
365    _ecore_evas_wl_shutdown();
366    ecore_wl_shutdown();
367 }
368
369 static void 
370 _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
371 {
372    LOGFN(__FILE__, __LINE__, __FUNCTION__);
373
374    if (!ee) return;
375    ee->func.fn_resize = func;
376 }
377
378 static void 
379 _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
380 {
381    LOGFN(__FILE__, __LINE__, __FUNCTION__);
382
383    if (!ee) return;
384    ee->func.fn_move = func;
385 }
386
387 static void 
388 _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
389 {
390    LOGFN(__FILE__, __LINE__, __FUNCTION__);
391
392    if (!ee) return;
393    ee->func.fn_delete_request = func;
394 }
395
396 static void 
397 _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
398 {
399    LOGFN(__FILE__, __LINE__, __FUNCTION__);
400
401    if (!ee) return;
402    ee->func.fn_focus_in = func;
403 }
404
405 static void 
406 _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
407 {
408    LOGFN(__FILE__, __LINE__, __FUNCTION__);
409
410    if (!ee) return;
411    ee->func.fn_focus_out = func;
412 }
413
414 static void 
415 _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
416 {
417    LOGFN(__FILE__, __LINE__, __FUNCTION__);
418
419    if (!ee) return;
420    ee->func.fn_mouse_in = func;
421 }
422
423 static void 
424 _ecore_evas_wl_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
425 {
426    LOGFN(__FILE__, __LINE__, __FUNCTION__);
427
428    if (!ee) return;
429    ee->func.fn_mouse_out = func;
430 }
431
432 static void 
433 _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y)
434 {
435    LOGFN(__FILE__, __LINE__, __FUNCTION__);
436
437    if (!ee) return;
438
439    ee->req.x = x;
440    ee->req.y = y;
441    if ((ee->x != x) || (ee->y != y))
442      {
443         ee->x = x;
444         ee->y = y;
445         if (ee->engine.wl.win)
446           ecore_wl_window_update_location(ee->engine.wl.win, x, y);
447         if (ee->func.fn_move) ee->func.fn_move(ee);
448      }
449 }
450
451 static void 
452 _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
453 {
454    Evas_Engine_Info_Wayland_Shm *einfo;
455
456    LOGFN(__FILE__, __LINE__, __FUNCTION__);
457
458    if (!ee) return;
459    if (w < 1) w = 1;
460    if (h < 1) h = 1;
461
462    if (ee->prop.min.w > w) w = ee->prop.min.w;
463    else if (w > ee->prop.max.w) w = ee->prop.max.w;
464    if (ee->prop.min.h > h) h = ee->prop.min.h;
465    else if (h > ee->prop.max.h) h = ee->prop.max.h;
466
467    ee->req.w = w;
468    ee->req.h = h;
469
470    if ((ee->w != w) || (ee->h != h))
471      {
472         ee->w = w;
473         ee->h = h;
474
475         if ((ee->rotation == 90) || (ee->rotation == 270))
476           {
477              evas_output_size_set(ee->evas, h, w);
478              evas_output_viewport_set(ee->evas, 0, 0, h, w);
479           }
480         else
481           {
482              evas_output_size_set(ee->evas, w, h);
483              evas_output_viewport_set(ee->evas, 0, 0, w, h);
484           }
485
486         if (ee->prop.avoid_damage)
487           {
488              int pdam = 0;
489
490              pdam = ecore_evas_avoid_damage_get(ee);
491              ecore_evas_avoid_damage_set(ee, 0);
492              ecore_evas_avoid_damage_set(ee, pdam);
493           }
494
495         if (ee->engine.wl.frame)
496           evas_object_resize(ee->engine.wl.frame, w, h);
497
498         if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
499         ee->engine.wl.buffer = NULL;
500
501         _ecore_evas_wl_ensure_pool_size(ee, w, h);
502
503         if (ee->engine.wl.pool)
504           _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
505
506         einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
507         if (!einfo)
508           {
509             ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
510             return;
511           }
512
513         einfo->info.dest = ee->engine.wl.pool_data;
514         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
515
516         if (ee->engine.wl.win)
517           {
518              ecore_wl_window_buffer_attach(ee->engine.wl.win, 
519                                            ee->engine.wl.buffer, 0, 0);
520              ecore_wl_window_update_size(ee->engine.wl.win, w, h);
521           }
522
523         if (ee->func.fn_resize) ee->func.fn_resize(ee);
524      }
525 }
526
527 static void 
528 _ecore_evas_wl_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
529 {
530    LOGFN(__FILE__, __LINE__, __FUNCTION__);
531
532    if (!ee) return;
533    if ((ee->x != x) || (ee->y != y))
534      _ecore_evas_wl_move(ee, x, y);
535    if ((ee->w != w) || (ee->h != h))
536      _ecore_evas_wl_resize(ee, w, h);
537 }
538
539 static void
540 _ecore_evas_wl_ensure_pool_size(Ecore_Evas *ee, int w, int h)
541 {
542    int stride = 0;
543    size_t len = 0;
544
545    stride = w * sizeof(int);
546    len = stride * h;
547
548    if ((ee->engine.wl.pool) && (len < ee->engine.wl.pool_size))
549      return;
550    else
551      {
552         struct wl_shm_pool *pool = NULL;
553         void *data;
554         int size;
555
556         if (ee->engine.wl.pool)
557           wl_shm_pool_destroy(ee->engine.wl.pool);
558
559         /*
560          * Make the pool 1.5 times the current requirement to allow growth
561          * without requiring a new pool allocation
562          */
563         size = 1.5 * len;
564         pool = _ecore_evas_wl_shm_pool_create(size, &data);
565
566         ee->engine.wl.pool = pool;
567         ee->engine.wl.pool_size = size;
568         ee->engine.wl.pool_data = data;
569      }
570 }
571
572 static void
573 _ecore_evas_wl_show(Ecore_Evas *ee)
574 {
575    Evas_Engine_Info_Wayland_Shm *einfo;
576
577    LOGFN(__FILE__, __LINE__, __FUNCTION__);
578
579    if ((!ee) || (ee->visible)) return;
580
581    _ecore_evas_wl_ensure_pool_size(ee, ee->w, ee->h);
582
583    if (ee->engine.wl.pool)
584      _ecore_evas_wl_buffer_new(ee, ee->engine.wl.pool);
585
586    einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
587    if (!einfo)
588      {
589         ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
590         return;
591      }
592
593    einfo->info.dest = ee->engine.wl.pool_data;
594    evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
595
596    /* ecore_wl_flush(); */
597
598    if (ee->engine.wl.win)
599      {
600         ecore_wl_window_show(ee->engine.wl.win);
601         ecore_wl_window_buffer_attach(ee->engine.wl.win, 
602                                       ee->engine.wl.buffer, 0, 0);
603         ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h);
604
605         if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
606           wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, 
607                                      ee->prop.clas);
608         if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
609           wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, 
610                                      ee->prop.title);
611      }
612
613    if (ee->engine.wl.frame)
614      {
615         evas_object_show(ee->engine.wl.frame);
616         evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
617      }
618
619    ee->visible = 1;
620    if (ee->func.fn_show) ee->func.fn_show(ee);
621 }
622
623 static void 
624 _ecore_evas_wl_hide(Ecore_Evas *ee)
625 {
626    Evas_Engine_Info_Wayland_Shm *einfo;
627
628    LOGFN(__FILE__, __LINE__, __FUNCTION__);
629
630    if ((!ee) || (!ee->visible)) return;
631
632    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
633    ee->engine.wl.buffer = NULL;
634
635    munmap(ee->engine.wl.pool_data, ee->engine.wl.pool_size);
636
637    einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
638    if ((einfo) && (einfo->info.dest))
639      {
640         einfo->info.dest = NULL;
641         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
642      }
643
644    ecore_wl_window_hide(ee->engine.wl.win);
645
646    ee->visible = 0;
647    ee->should_be_visible = 0;
648
649    if (ee->func.fn_hide) ee->func.fn_hide(ee);
650 }
651
652 static void 
653 _ecore_evas_wl_raise(Ecore_Evas *ee)
654 {
655    LOGFN(__FILE__, __LINE__, __FUNCTION__);
656
657    if ((!ee) || (!ee->visible)) return;
658    ecore_wl_window_raise(ee->engine.wl.win);
659 }
660
661 static void 
662 _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *title)
663 {
664    LOGFN(__FILE__, __LINE__, __FUNCTION__);
665
666    if (!ee) return;
667    if (ee->prop.title) free(ee->prop.title);
668    ee->prop.title = NULL;
669    if (title) ee->prop.title = strdup(title);
670    if ((ee->prop.draw_frame) && (ee->engine.wl.frame)) 
671      {
672         EE_Wl_Smart_Data *sd;
673
674         if (!(sd = evas_object_smart_data_get(ee->engine.wl.frame))) return;
675         evas_object_text_text_set(sd->text, ee->prop.title);
676      }
677
678    if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
679      wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, 
680                                 ee->prop.title);
681 }
682
683 static void 
684 _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c) 
685 {
686    LOGFN(__FILE__, __LINE__, __FUNCTION__);
687
688    if (!ee) return;
689    if (ee->prop.name) free(ee->prop.name);
690    if (ee->prop.clas) free(ee->prop.clas);
691    ee->prop.name = NULL;
692    ee->prop.clas = NULL;
693    if (n) ee->prop.name = strdup(n);
694    if (c) ee->prop.clas = strdup(c);
695
696    if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
697      wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, 
698                                 ee->prop.clas);
699 }
700
701 static void 
702 _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h) 
703 {
704    LOGFN(__FILE__, __LINE__, __FUNCTION__);
705
706    if (!ee) return;
707    if (w < 0) w = 0;
708    if (h < 0) h = 0;
709    if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
710    ee->prop.min.w = w;
711    ee->prop.min.h = h;
712 }
713
714 static void 
715 _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h) 
716 {
717    LOGFN(__FILE__, __LINE__, __FUNCTION__);
718
719    if (!ee) return;
720    if (w < 0) w = 0;
721    if (h < 0) h = 0;
722    if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
723    ee->prop.max.w = w;
724    ee->prop.max.h = h;
725 }
726
727 static void 
728 _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h) 
729 {
730    LOGFN(__FILE__, __LINE__, __FUNCTION__);
731
732    if (!ee) return;
733    if (w < 0) w = 0;
734    if (h < 0) h = 0;
735    if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
736    ee->prop.base.w = w;
737    ee->prop.base.h = h;
738 }
739
740 static void 
741 _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h) 
742 {
743    LOGFN(__FILE__, __LINE__, __FUNCTION__);
744
745    if (!ee) return;
746    if (w < 0) w = 0;
747    if (h < 0) h = 0;
748    if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
749    ee->prop.step.w = w;
750    ee->prop.step.h = h;
751 }
752
753 static void 
754 _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer)
755 {
756    LOGFN(__FILE__, __LINE__, __FUNCTION__);
757
758    if (!ee) return;
759    if (ee->prop.layer == layer) return;
760    if (layer < 1) layer = 1;
761    else if (layer > 255) layer = 255;
762    ee->prop.layer = layer;
763 }
764
765 static void 
766 _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify)
767 {
768    LOGFN(__FILE__, __LINE__, __FUNCTION__);
769
770    if (!ee) return;
771    if (ee->prop.iconified == iconify) return;
772    ee->prop.iconified = iconify;
773    /* FIXME: Implement this in Wayland someshow */
774 }
775
776 static void 
777 _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max)
778 {
779    LOGFN(__FILE__, __LINE__, __FUNCTION__);
780
781    if (!ee) return;
782    if (ee->prop.maximized == max) return;
783    ee->prop.maximized = max;
784    ecore_wl_window_maximized_set(ee->engine.wl.win, max);
785 }
786
787 static void 
788 _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full)
789 {
790    LOGFN(__FILE__, __LINE__, __FUNCTION__);
791
792    if ((!ee) || (!ee->visible)) return;
793    if (ee->prop.fullscreen == full) return;
794    ee->prop.fullscreen = full;
795    ecore_wl_window_fullscreen_set(ee->engine.wl.win, full);
796 }
797
798 static void 
799 _ecore_evas_wl_ignore_events_set(Ecore_Evas *ee, int ignore)
800 {
801    LOGFN(__FILE__, __LINE__, __FUNCTION__);
802
803    if (!ee) return;
804    ee->ignore_events = ignore;
805    /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */
806 }
807
808 static void 
809 _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha)
810 {
811    Evas_Engine_Info_Wayland_Shm *einfo;
812
813    LOGFN(__FILE__, __LINE__, __FUNCTION__);
814
815    if (!ee) return;
816    if ((ee->alpha == alpha)) return;
817    ee->alpha = alpha;
818    if (ee->engine.wl.win)
819      ecore_wl_window_transparent_set(ee->engine.wl.win, alpha);
820    if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
821      {
822         einfo->info.destination_alpha = alpha;
823         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
824           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
825         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
826      }
827 }
828
829 static void 
830 _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent)
831 {
832    Evas_Engine_Info_Wayland_Shm *einfo;
833
834    LOGFN(__FILE__, __LINE__, __FUNCTION__);
835
836    if (!ee) return;
837    if ((ee->transparent == transparent)) return;
838    ee->transparent = transparent;
839    if (ee->engine.wl.win)
840      ecore_wl_window_transparent_set(ee->engine.wl.win, transparent);
841    if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas)))
842      {
843         einfo->info.destination_alpha = transparent;
844         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
845           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
846         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
847      }
848 }
849
850 static int 
851 _ecore_evas_wl_render(Ecore_Evas *ee)
852 {
853    int rend = 0;
854
855    if (!ee) return 0;
856    if (!ee->visible)
857      evas_norender(ee->evas);
858    else
859      {
860         Eina_List *ll = NULL, *updates = NULL;
861         Ecore_Evas *ee2 = NULL;
862
863         if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
864
865         EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) 
866           {
867              if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
868              if (ee2->engine.func->fn_render)
869                rend |= ee2->engine.func->fn_render(ee2);
870              if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
871           }
872
873         if ((updates = evas_render_updates(ee->evas))) 
874           {
875              Eina_List *l = NULL;
876              Eina_Rectangle *r;
877
878              LOGFN(__FILE__, __LINE__, __FUNCTION__);
879
880              EINA_LIST_FOREACH(updates, l, r) 
881                ecore_wl_window_damage(ee->engine.wl.win, 
882                                       r->x, r->y, r->w, r->h);
883
884              ecore_wl_flush();
885
886              evas_render_updates_free(updates);
887              _ecore_evas_idle_timeout_update(ee);
888              rend = 1;
889           }
890
891         if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
892      }
893    return rend;
894 }
895
896 static void 
897 _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
898 {
899    LOGFN(__FILE__, __LINE__, __FUNCTION__);
900
901    if (x) *x = 0;
902    if (y) *y = 0;
903    ecore_wl_screen_size_get(w, h);
904 }
905
906 static struct wl_shm_pool *
907 _ecore_evas_wl_shm_pool_create(int size, void **data)
908 {
909    struct wl_shm *shm;
910    struct wl_shm_pool *pool;
911    char tmp[PATH_MAX];
912    int fd;
913
914    LOGFN(__FILE__, __LINE__, __FUNCTION__);
915
916    if (!(shm = ecore_wl_shm_get())) return NULL;
917
918    strcpy(tmp, "/tmp/ecore-evas-wayland_shm-XXXXXX");
919    if ((fd = mkstemp(tmp)) < 0) 
920      {
921         ERR("Could not create temporary file.");
922         return NULL;
923      }
924
925    if (ftruncate(fd, size) < 0) 
926      {
927         ERR("Could not truncate temporary file.");
928         close(fd);
929         return NULL;
930      }
931
932    *data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
933    unlink(tmp);
934
935    if (*data == MAP_FAILED) 
936      {
937         ERR("mmap of temporary file failed.");
938         close(fd);
939         return NULL;
940      }
941
942    pool = wl_shm_create_pool(shm, fd, size);
943
944    close(fd);
945
946    return pool;
947 }
948
949 static void 
950 _ecore_evas_wl_buffer_new(Ecore_Evas *ee, struct wl_shm_pool *pool)
951 {
952    unsigned int format;
953    int stride = 0;
954
955    if ((ee->alpha) || (ee->transparent))
956      format = WL_SHM_FORMAT_ARGB8888;
957    else
958      format = WL_SHM_FORMAT_XRGB8888;
959
960    stride = (ee->w * sizeof(int));
961
962    ee->engine.wl.buffer = 
963      wl_shm_pool_create_buffer(pool, 0, ee->w, ee->h, stride, format);
964 }
965
966 void 
967 _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location)
968 {
969    LOGFN(__FILE__, __LINE__, __FUNCTION__);
970
971    if (!ee) return;
972    if (ee->engine.wl.win) 
973      {
974         ee->engine.wl.win->resizing = EINA_TRUE;
975         ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location);
976      }
977 }
978
979 void 
980 _ecore_evas_wayland_shm_move(Ecore_Evas *ee, int x, int y)
981 {
982    LOGFN(__FILE__, __LINE__, __FUNCTION__);
983
984    if (!ee) return;
985    if (ee->engine.wl.win) 
986      {
987         ee->engine.wl.win->moving = EINA_TRUE;
988         ecore_wl_window_move(ee->engine.wl.win, x, y);
989      }
990 }
991
992 static Eina_Bool 
993 _ecore_evas_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
994 {
995    Ecore_Evas *ee;
996    Ecore_Wl_Event_Mouse_In *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    if (!ee->in)
1005      {
1006         if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
1007         ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
1008         evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
1009 //        _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp);
1010         ee->in = EINA_TRUE;
1011      }
1012    return ECORE_CALLBACK_PASS_ON;
1013 }
1014
1015 static Eina_Bool 
1016 _ecore_evas_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1017 {
1018    Ecore_Evas *ee;
1019    Ecore_Wl_Event_Mouse_Out *ev;
1020
1021    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1022
1023    ev = event;
1024    ee = ecore_event_window_match(ev->window);
1025    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1026    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1027    if (ee->in)
1028      {
1029         ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
1030 //        _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp);
1031         evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
1032         if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
1033         if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
1034         ee->in = EINA_FALSE;
1035      }
1036    return ECORE_CALLBACK_PASS_ON;
1037 }
1038
1039 static Eina_Bool 
1040 _ecore_evas_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
1041 {
1042    Ecore_Evas *ee;
1043    Ecore_Wl_Event_Focus_In *ev;
1044
1045    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1046
1047    ev = event;
1048    ee = ecore_event_window_match(ev->win);
1049    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1050    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1051    ee->prop.focused = 1;
1052    evas_focus_in(ee->evas);
1053    if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
1054    return ECORE_CALLBACK_PASS_ON;
1055 }
1056
1057 static Eina_Bool 
1058 _ecore_evas_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
1059 {
1060    Ecore_Evas *ee;
1061    Ecore_Wl_Event_Focus_In *ev;
1062
1063    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1064
1065    ev = event;
1066    ee = ecore_event_window_match(ev->win);
1067    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1068    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1069    evas_focus_out(ee->evas);
1070    ee->prop.focused = 0;
1071    if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
1072    return ECORE_CALLBACK_PASS_ON;
1073 }
1074
1075 static Eina_Bool 
1076 _ecore_evas_wl_cb_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event)
1077 {
1078    Ecore_Evas *ee;
1079    Ecore_Wl_Event_Window_Configure *ev;
1080
1081    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1082
1083    ev = event;
1084    ee = ecore_event_window_match(ev->win);
1085    if (!ee) return ECORE_CALLBACK_PASS_ON;
1086    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1087
1088    if ((ee->x != ev->x) || (ee->y != ev->y))
1089      {
1090         /* ee->x = ev->x; */
1091         /* ee->y = ev->y; */
1092         ee->req.x = ee->x;
1093         ee->req.y = ee->y;
1094         if (ee->func.fn_move) ee->func.fn_move(ee);
1095      }
1096    if ((ee->req.w != ev->w) || (ee->req.h != ev->h))
1097      {
1098         /* ee->w = ev->w; */
1099         /* ee->h = ev->h; */
1100         ee->req.w = ev->w;
1101         ee->req.h = ev->h;
1102         if (ee->func.fn_resize) ee->func.fn_resize(ee);
1103      }
1104
1105    return ECORE_CALLBACK_PASS_ON;
1106 }
1107
1108 static void 
1109 _ecore_evas_wl_smart_init(void) 
1110 {
1111    if (_ecore_evas_wl_smart) return;
1112      {
1113         static const Evas_Smart_Class sc = 
1114           {
1115              "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION, 
1116              _ecore_evas_wl_smart_add, 
1117              _ecore_evas_wl_smart_del, 
1118              NULL, 
1119              _ecore_evas_wl_smart_resize, 
1120              _ecore_evas_wl_smart_show, 
1121              _ecore_evas_wl_smart_hide, 
1122              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
1123           };
1124         _ecore_evas_wl_smart = evas_smart_class_new(&sc);
1125      }
1126 }
1127
1128 static void 
1129 _ecore_evas_wl_smart_add(Evas_Object *obj) 
1130 {
1131    EE_Wl_Smart_Data *sd;
1132    Evas *evas;
1133
1134    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1135
1136    if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return;
1137
1138    evas = evas_object_evas_get(obj);
1139
1140    sd->x = 0;
1141    sd->y = 0;
1142    sd->w = 1;
1143    sd->h = 1;
1144
1145    sd->frame = evas_object_rectangle_add(evas);
1146    evas_object_is_frame_object_set(sd->frame, EINA_TRUE);
1147    evas_object_color_set(sd->frame, 249, 249, 249, 255);
1148    evas_object_smart_member_add(sd->frame, obj);
1149
1150    sd->text = evas_object_text_add(evas);
1151    evas_object_color_set(sd->text, 0, 0, 0, 255);
1152    evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN);
1153    evas_object_text_font_set(sd->text, "Sans", 10);
1154    evas_object_text_text_set(sd->text, "Smart Test");
1155
1156    evas_object_smart_data_set(obj, sd);
1157 }
1158
1159 static void 
1160 _ecore_evas_wl_smart_del(Evas_Object *obj) 
1161 {
1162    EE_Wl_Smart_Data *sd;
1163
1164    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1165
1166    if (!(sd = evas_object_smart_data_get(obj))) return;
1167    evas_object_del(sd->text);
1168    evas_object_del(sd->frame);
1169    free(sd);
1170 }
1171
1172 static void 
1173 _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) 
1174 {
1175    EE_Wl_Smart_Data *sd;
1176
1177    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1178
1179    if (!(sd = evas_object_smart_data_get(obj))) return;
1180    if ((sd->w == w) && (sd->h == h)) return;
1181    sd->w = w;
1182    sd->h = h;
1183    evas_object_resize(sd->frame, w, h);
1184 }
1185
1186 static void 
1187 _ecore_evas_wl_smart_show(Evas_Object *obj) 
1188 {
1189    EE_Wl_Smart_Data *sd;
1190
1191    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1192
1193    if (!(sd = evas_object_smart_data_get(obj))) return;
1194    evas_object_show(sd->frame);
1195    evas_object_show(sd->text);
1196 }
1197
1198 static void 
1199 _ecore_evas_wl_smart_hide(Evas_Object *obj) 
1200 {
1201    EE_Wl_Smart_Data *sd;
1202
1203    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1204
1205    if (!(sd = evas_object_smart_data_get(obj))) return;
1206    evas_object_hide(sd->text);
1207    evas_object_hide(sd->frame);
1208 }
1209
1210 static Evas_Object *
1211 _ecore_evas_wl_frame_add(Evas *evas) 
1212 {
1213    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1214
1215    _ecore_evas_wl_smart_init();
1216    return evas_object_smart_add(evas, _ecore_evas_wl_smart);
1217 }
1218
1219 #else
1220 EAPI Ecore_Evas *
1221 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__)
1222 {
1223    return NULL;
1224 }
1225 #endif