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