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