e17794db9ce282a221e564efe6503351a40393f8
[platform/upstream/efl.git] / src / modules / ecore_evas / engines / wayland / ecore_evas_wayland_common.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #include "ecore_evas_wayland_private.h"
6 #include <Evas_Engine_Wayland.h>
7 #include "ecore_wl2_internal.h"
8 #include <wayland-tbm-client.h>
9
10 EAPI extern Eina_List *_evas_canvas_image_data_unset(Evas *eo_e);
11 EAPI extern void _evas_canvas_image_data_regenerate(Eina_List *list);
12
13 #define _smart_frame_type "ecore_evas_wl_frame"
14
15 static const char *interface_wl_name = "wayland";
16 static const int interface_wl_version = 1;
17 // TIZEN_ONLY(20171120) : evas sw tbm_buf backend
18 static struct wayland_tbm_client *tbm_client;
19
20 Eina_List *ee_list;
21
22 /* local structure for evas devices with IDs */
23 typedef struct _EE_Wl_Device EE_Wl_Device;
24 struct _EE_Wl_Device
25 {
26    Evas_Device *seat;
27    Evas_Device *pointer;
28    Evas_Device *keyboard;
29    Evas_Device *touch;
30    unsigned int id;
31 };
32
33 /* local variables */
34 static int _ecore_evas_wl_init_count = 0;
35 static Eina_Array *_ecore_evas_wl_event_hdls;
36
37 // TIZEN_ONLY(20160617) : uniconify force render
38 static void _ecore_evas_wl_common_damage_add(Ecore_Evas *ee);
39 //
40
41 static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location);
42 static void _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize);
43 static void _ecore_evas_wl_selection_init(Ecore_Evas *ee);
44 static void _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, Eina_Bool on);
45
46 //TIZEN_ONLY(20171115): support output transform
47 static void _rotation_do(Ecore_Evas *ee, int rotation, int output_rotation, int resize);
48
49 static int
50 _ecore_evas_wl_common_engine_rotation_get(Ecore_Evas *ee)
51 {
52    Evas_Engine_Info_Wayland *einfo;
53    einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
54    if (!einfo) return 0;
55    return einfo->info.rotation;
56 }
57
58 void
59 _ecore_evas_wl_common_engine_info_rotation_set(Ecore_Evas *ee, Evas_Engine_Info *info)
60 {
61    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
62
63    if (!strncmp(ee->driver, "wayland_shm", 11))
64      {
65 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
66         Evas_Engine_Info_Wayland *einfo = (Evas_Engine_Info_Wayland *)info;
67         einfo->info.rotation = (ee->rotation + wdata->output_rotation) % 360;
68         ecore_wl2_window_buffer_transform_set(wdata->win, wdata->output_rotation / 90);
69         WRN("evas engine rotate: %d", einfo->info.rotation);
70 #endif
71      }
72    else if (!strncmp(ee->driver, "wayland_egl", 11))
73      {
74 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
75         Evas_Engine_Info_Wayland *einfo = (Evas_Engine_Info_Wayland *)info;
76         einfo->info.rotation = (ee->rotation + wdata->output_rotation) % 360;
77         /* the buffer transform information will be set in side of gl when rendering finish */
78         einfo->window_rotation = ee->rotation;
79         WRN("evas engine rotate: %d", einfo->info.rotation);
80 #endif
81      }
82 }
83
84 static Eina_Bool
85 _ecore_evas_wl_common_rotate_update(Ecore_Evas *ee)
86 {
87    Ecore_Evas_Engine_Wl_Data *wdata;
88    int rotation;
89
90    wdata = ee->engine.data;
91
92    if (ecore_wl2_window_ignore_output_transform_get(wdata->win))
93      rotation = 0;
94    else
95      {
96         Ecore_Wl2_Output *output = ecore_wl2_window_output_find(wdata->win);
97         rotation = ecore_wl2_output_transform_get(output) * 90;
98      }
99
100    WRN("ignore_output_transform(%d) rotation(%d)", ecore_wl2_window_ignore_output_transform_get(wdata->win), rotation);
101
102    if (_ecore_evas_wl_common_engine_rotation_get(ee) == ((rotation + ee->rotation) % 360))
103      return EINA_FALSE;
104
105    if (ee->in_async_render)
106      {
107         ee->delayed.output_rotation = rotation;
108         ee->delayed.rotation = ee->rotation;
109         ee->delayed.rotation_resize = 0;
110         ee->delayed.rotation_changed = EINA_TRUE;
111         return EINA_FALSE;
112      }
113
114    _rotation_do(ee, ee->rotation, rotation, 0);
115
116    return EINA_TRUE;
117 }
118 //
119
120 //TIZEN_ONLY(20191129): Not using this function in tizen
121 /* local functions */
122 #if 0
123 static void
124 _anim_cb_tick(Ecore_Wl2_Window *win EINA_UNUSED, uint32_t timestamp, void *data)
125 {
126    Ecore_Evas *ee = data;
127    Ecore_Evas_Engine_Wl_Data *edata;
128    double t;//, rt;
129    /* static double pt = 0.0, prt = 0.0; */
130
131    edata = ee->engine.data;
132
133    if (!edata->ticking) return;
134    t = ((double)timestamp / 1000.0);
135    ecore_loop_time_set(t);
136    /* rt = ecore_time_get(); */
137    /* printf("ECORE_EVAS: wl client anim tick %p | %p - %1.5f @ %1.5f delt=%1.5f | %1.5f\n", ee, edata, t, ecore_time_get(), t - pt, rt - prt); */
138    ecore_evas_animator_tick(ee, NULL, t);
139    /* pt = t; */
140    /* prt = rt; */
141 }
142
143 static void
144 _ecore_evas_wl_common_animator_register(Ecore_Evas *ee)
145 {
146    Ecore_Evas_Engine_Wl_Data *edata;
147
148    edata = (Ecore_Evas_Engine_Wl_Data *)ee->engine.data;
149
150    EINA_SAFETY_ON_TRUE_RETURN(edata->ticking);
151    EINA_SAFETY_ON_TRUE_RETURN(edata->frame != NULL);
152
153    edata->frame =
154      ecore_wl2_window_frame_callback_add(edata->win, _anim_cb_tick, ee);
155    if (!ecore_wl2_window_pending_get(edata->win) && !ee->in_async_render &&
156        !ee->animator_ticked && !ee->animator_ran && !ee->draw_block)
157      ecore_wl2_window_false_commit(edata->win);
158    edata->ticking = EINA_TRUE;
159 }
160
161 static void
162 _ecore_evas_wl_common_animator_unregister(Ecore_Evas *ee)
163 {
164    Ecore_Evas_Engine_Wl_Data *edata;
165
166    edata = ee->engine.data;
167    edata->ticking = EINA_FALSE;
168    if (edata->frame)
169      ecore_wl2_window_frame_callback_del(edata->frame);
170    edata->frame = NULL;
171 }
172 #endif
173
174 static void
175 _ecore_evas_wl_common_evas_changed(Ecore_Evas *ee, Eina_Bool changed)
176 {
177    Ecore_Evas_Engine_Wl_Data *edata;
178
179    if (changed) return;
180
181    edata = (Ecore_Evas_Engine_Wl_Data *)ee->engine.data;
182    if (edata->ticking && !ecore_wl2_window_pending_get(edata->win))
183      ecore_wl2_window_false_commit(edata->win);
184 }
185
186 static void
187 _ecore_evas_wl_common_state_update(Ecore_Evas *ee)
188 {
189    if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
190 }
191
192 static void
193 _ecore_evas_wl_common_wm_rotation_protocol_set(Ecore_Evas *ee)
194 {
195    Ecore_Evas_Engine_Wl_Data *wdata;
196
197    wdata = ee->engine.data;
198
199    ee->prop.wm_rot.supported =
200      ecore_wl2_window_wm_rotation_supported_get(wdata->win);
201 }
202
203 static Eina_Bool
204 _ecore_evas_wl_common_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
205 {
206    Ecore_Evas *ee;
207    Ecore_Event_Mouse_IO *ev;
208
209    LOGFN;
210
211    ev = event;
212    ee = ecore_event_window_match(ev->window);
213    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
214    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
215    if (_ecore_evas_mouse_in_check(ee, ev->dev)) return ECORE_CALLBACK_PASS_ON;
216
217    _ecore_evas_mouse_inout_set(ee, ev->dev, EINA_TRUE, EINA_FALSE);
218    ecore_event_evas_seat_modifier_lock_update(ee->evas, ev->modifiers, ev->dev);
219    evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
220    _ecore_evas_mouse_device_move_process(ee, ev->dev, ev->x, ev->y, ev->timestamp);
221    return ECORE_CALLBACK_PASS_ON;
222 }
223
224 static Eina_Bool
225 _ecore_evas_wl_common_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
226 {
227    Ecore_Evas *ee;
228    Ecore_Event_Mouse_IO *ev;
229
230    LOGFN;
231
232    ev = event;
233    ee = ecore_event_window_match(ev->window);
234    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
235    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
236    if (!_ecore_evas_mouse_in_check(ee, ev->dev)) return ECORE_CALLBACK_PASS_ON;
237
238    ecore_event_evas_seat_modifier_lock_update(ee->evas,
239                                               ev->modifiers, ev->dev);
240    _ecore_evas_mouse_device_move_process(ee, ev->dev, ev->x, ev->y, ev->timestamp);
241    evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
242    _ecore_evas_mouse_inout_set(ee, ev->dev, EINA_FALSE, EINA_FALSE);
243    return ECORE_CALLBACK_PASS_ON;
244 }
245
246 static Eina_Bool
247 _ecore_evas_wl_common_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
248 {
249    Ecore_Evas *ee;
250    Ecore_Wl2_Event_Focus_In *ev;
251
252    LOGFN;
253
254    ev = event;
255    ee = ecore_event_window_match(ev->window);
256    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
257    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
258    _ecore_evas_focus_device_set(ee, ev->dev, EINA_TRUE);
259    return ECORE_CALLBACK_PASS_ON;
260 }
261
262 static Eina_Bool
263 _ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
264 {
265    Ecore_Evas *ee;
266    Ecore_Wl2_Event_Focus_Out *ev;
267
268    LOGFN;
269
270    ev = event;
271    ee = ecore_event_window_match(ev->window);
272    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
273    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
274    _ecore_evas_focus_device_set(ee, ev->dev, EINA_FALSE);
275    return ECORE_CALLBACK_PASS_ON;
276 }
277
278 static void
279 _ee_display_unset(Ecore_Evas *ee)
280 {
281    Evas_Engine_Info_Wayland *einfo;
282    Ecore_Evas_Engine_Wl_Data *wdata;
283
284    einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
285    if (!einfo) return;
286
287    wdata = ee->engine.data;
288    if (!strcmp(ee->driver, "wayland_egl"))
289      wdata->regen_objs = _evas_canvas_image_data_unset(ecore_evas_get(ee));
290
291    if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
292      WRN("Failed to set Evas Engine Info for '%s'", ee->driver);
293 }
294
295 static Eina_Bool
296 _ecore_evas_wl_common_cb_disconnect(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
297 {
298    Ecore_Wl2_Event_Disconnect *ev = event;
299    Eina_List *l;
300    Ecore_Evas *ee;
301
302    EINA_LIST_FOREACH(ee_list, l, ee)
303      {
304         Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
305
306         if (wdata->display != ev->display) continue;
307         wdata->sync_done = EINA_FALSE;
308         wdata->defer_show = EINA_TRUE;
309         ee->visible = EINA_FALSE;
310         wdata->reset_pending = 1;
311         ee->draw_block = EINA_TRUE;
312         _ee_display_unset(ee);
313      }
314    return ECORE_CALLBACK_RENEW;
315 }
316
317 //TIZEN_ONLY(20191129): Not using this function in tizen
318 /*
319 static Eina_Bool
320 ee_needs_alpha(Ecore_Evas *ee)
321 {
322    return ee->shadow.l || ee->shadow.r || ee->shadow.t || ee->shadow.b ||
323           ee->alpha;
324 }
325 */
326
327 // TIZEN_ONLY(20160630)
328 void
329 _ecore_evas_wl_common_move(Ecore_Evas *ee, int x, int y)
330 {
331    Ecore_Evas_Engine_Wl_Data *wdata;
332    LOGFN;
333
334    if (!ee) return;
335
336    wdata = ee->engine.data;
337    ee->req.x = x;
338    ee->req.y = y;
339
340    if ((ee->x != x) || (ee->y != y))
341      {
342         ee->x = x;
343         ee->y = y;
344         if (ee->func.fn_move) ee->func.fn_move(ee);
345      }
346    if (wdata)
347      ecore_wl2_window_position_set(wdata->win, ee->req.x, ee->req.y);
348 }
349 //
350
351 static void
352 _ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h)
353 {
354    Ecore_Evas_Engine_Wl_Data *wdata;
355    int ow, oh, ew, eh;
356    int diff = 0;
357
358    LOGFN;
359
360    if (!ee) return;
361
362    wdata = ee->engine.data;
363    if (!wdata) return;
364
365    ee->req.w = w;
366    ee->req.h = h;
367
368    /* TODO: wayland client can resize the ecore_evas directly.
369     * In the future, we will remove ee->req value in wayland backend */
370    ew = ee->w;
371    eh = ee->h;
372    ee->w = w;
373    ee->h = h;
374
375    if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel && wdata->win->pending.min)
376      {
377         wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, ee->prop.min.w, ee->prop.min.h);
378         wdata->win->pending.min = 0;
379      }
380    if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel && wdata->win->pending.max)
381      {
382         wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, ee->prop.max.w, ee->prop.max.h);
383         wdata->win->pending.max = 0;
384      }
385
386    if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel && wdata->win->pending.min)
387      {
388         wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, ee->prop.min.w, ee->prop.min.h);
389         wdata->win->pending.min = 0;
390      }
391    if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel && wdata->win->pending.max)
392      {
393         wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, ee->prop.max.w, ee->prop.max.h);
394         wdata->win->pending.max = 0;
395      }
396
397    if (!ee->prop.fullscreen)
398      {
399         int fw = 0, fh = 0;
400         int maxw = 0, maxh = 0;
401         int minw = 0, minh = 0;
402
403         evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
404
405         if (ECORE_EVAS_PORTRAIT(ee))
406           {
407              if (ee->prop.min.w > 0)
408                minw = (ee->prop.min.w - fw);
409              if (ee->prop.min.h > 0)
410                minh = (ee->prop.min.h - fh);
411              if (ee->prop.max.w > 0)
412                maxw = (ee->prop.max.w + fw);
413              if (ee->prop.max.h > 0)
414                maxh = (ee->prop.max.h + fh);
415           }
416         else
417           {
418              if (ee->prop.min.w > 0)
419                minw = (ee->prop.min.w - fh);
420              if (ee->prop.min.h > 0)
421                minh = (ee->prop.min.h - fw);
422              if (ee->prop.max.w > 0)
423                maxw = (ee->prop.max.w + fh);
424              if (ee->prop.max.h > 0)
425                maxh = (ee->prop.max.h + fw);
426           }
427
428         if ((maxw > 0) && (w > maxw))
429           w = maxw;
430         else if (w < minw)
431           w = minw;
432
433         if ((maxh > 0) && (h > maxh))
434           h = maxh;
435         else if (h < minh)
436           h = minh;
437
438         if (!ee->prop.maximized)
439           {
440              /* calc new size using base size & step size */
441              if (ee->prop.step.w > 1)
442                {
443                   int bw = ee->prop.base.w ?: minw;
444                   w = (bw + (((w - bw) / ee->prop.step.w) * ee->prop.step.w));
445                }
446
447              if (ee->prop.step.h > 1)
448                {
449                   int bh = ee->prop.base.h ?: minh;
450                   h = (bh + (((h - bh) / ee->prop.step.h) * ee->prop.step.h));
451                }
452
453              if (!wdata->win->display->wl.efl_hints && EINA_DBL_NONZERO(ee->prop.aspect))
454                {
455                   /* copied from e_client.c */
456                   Evas_Aspect_Control aspect;
457                   int aw, ah;
458                   double val, a;
459
460                   if (h > 0)
461                     {
462                        a = (double)w / (double)h;
463                        if (fabs(a - ee->prop.aspect) > 0.001)
464                          {
465                             int step_w = ee->prop.step.w ?: 1;
466                             int step_h = ee->prop.step.h ?: 1;
467
468                             if (wdata->resizing ||
469                                 ecore_wl2_window_resizing_get(wdata->win))
470                               ew = wdata->cw, eh = wdata->ch;
471                             if (abs(w - ew) > abs(h - eh))
472                               aspect = EVAS_ASPECT_CONTROL_HORIZONTAL;
473                             else
474                               aspect = EVAS_ASPECT_CONTROL_VERTICAL;
475                             switch (aspect)
476                               {
477                                case EVAS_ASPECT_CONTROL_HORIZONTAL:
478                                  val = ((h - (w / ee->prop.aspect)) *
479                                         step_h) / step_h;
480                                  if (val > 0) ah = ceil(val);
481                                  else ah = floor(val);
482                                  if ((h - ah > minh) || (minh < 1))
483                                    {
484                                       h -= ah;
485                                       break;
486                                    }
487                                  EINA_FALLTHROUGH;
488                                  /* no break */
489                                default:
490                                  val = (((h * ee->prop.aspect) - w) *
491                                         step_w) / step_w;
492                                  if (val > 0) aw = ceil(val);
493                                  else aw = floor(val);
494                                  if ((w + aw < maxw) || (maxw < 1))
495                                    w += aw;
496                                  break;
497                               }
498                          }
499                     }
500                }
501           }
502
503         ee->w = w;
504         ee->h = h;
505         ee->req.w = w;
506         ee->req.h = h;
507
508         if (ECORE_EVAS_PORTRAIT(ee))
509           {
510              w += fw;
511              h += fh;
512           }
513         else
514           {
515              w += fh;
516              h += fw;
517           }
518      }
519
520    //TIZEN_ONLY(20171115): support output transform
521    _ecore_evas_wl_common_rotate_update(ee);
522    //
523
524    if (ECORE_EVAS_PORTRAIT(ee))
525       evas_output_size_get(ee->evas, &ow, &oh);
526    else
527       evas_output_size_get(ee->evas, &oh, &ow);
528
529    if (ECORE_EVAS_PORTRAIT(ee) && ((ow != w) || (oh != h)))
530      diff = 1;
531    if (!ECORE_EVAS_PORTRAIT(ee) && ((ow != h) || (oh != w)))
532      diff = 1;
533
534    if (diff)
535      {
536         if (ECORE_EVAS_PORTRAIT(ee))
537           {
538              evas_output_size_set(ee->evas, w, h);
539              evas_output_viewport_set(ee->evas, 0, 0, w, h);
540           }
541         else
542           {
543              evas_output_size_set(ee->evas, h, w);
544              evas_output_viewport_set(ee->evas, 0, 0, h, w);
545           }
546
547         if (ee->prop.avoid_damage)
548           {
549              int pdam = 0;
550
551              pdam = ecore_evas_avoid_damage_get(ee);
552              ecore_evas_avoid_damage_set(ee, 0);
553              ecore_evas_avoid_damage_set(ee, pdam);
554           }
555
556         if (ee->func.fn_resize) ee->func.fn_resize(ee);
557      }
558    ecore_wl2_window_geometry_set(wdata->win, ee->x, ee->y, w, h);
559 }
560
561 static void
562 _ecore_evas_wl_common_wm_rot_manual_rotation_done_job(void *data)
563 {
564    Ecore_Evas *ee = (Ecore_Evas *)data;
565    Ecore_Evas_Engine_Wl_Data *wdata;
566
567    wdata = ee->engine.data;
568
569    wdata->wm_rot.manual_mode_job = NULL;
570    ee->prop.wm_rot.manual_mode.wait_for_done = EINA_FALSE;
571
572    ecore_wl2_window_rotation_change_done_send
573      (wdata->win, ee->rotation, ee->w, ee->h);
574
575    wdata->wm_rot.done = EINA_FALSE;
576 }
577
578 static void
579 _ecore_evas_wl_common_wm_rot_manual_rotation_done(Ecore_Evas *ee)
580 {
581    if ((ee->prop.wm_rot.supported) &&
582        (ee->prop.wm_rot.app_set) &&
583        (ee->prop.wm_rot.manual_mode.set))
584      {
585         if (ee->prop.wm_rot.manual_mode.wait_for_done)
586           {
587              Ecore_Evas_Engine_Wl_Data *wdata;
588
589              wdata = ee->engine.data;
590
591              if (ee->prop.wm_rot.manual_mode.timer)
592                ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
593              ee->prop.wm_rot.manual_mode.timer = NULL;
594
595              if (wdata->wm_rot.manual_mode_job)
596                ecore_job_del(wdata->wm_rot.manual_mode_job);
597
598              wdata->wm_rot.manual_mode_job = ecore_job_add
599                (_ecore_evas_wl_common_wm_rot_manual_rotation_done_job, ee);
600           }
601      }
602 }
603
604 static Eina_Bool
605 _ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout(void *data)
606 {
607    Ecore_Evas *ee = data;
608
609    ee->prop.wm_rot.manual_mode.timer = NULL;
610    _ecore_evas_wl_common_wm_rot_manual_rotation_done(ee);
611    return ECORE_CALLBACK_CANCEL;
612 }
613
614 void _ecore_evas_framespace_get(Ecore_Evas *ee, int *fw, int *fh)
615 {
616    int ww, wh, sw, sh, framew, frameh, cw, ch;
617
618    ecore_evas_geometry_get(ee, NULL, NULL, &ww, &wh);
619
620    sw = ee->shadow.l + ee->shadow.r;
621    sh = ee->shadow.t + ee->shadow.b;
622    evas_output_framespace_get(ee->evas, NULL, NULL, &framew, &frameh);
623
624    cw = ww - (framew - sw);
625    ch = wh - (frameh - sh);
626
627    if (fw) *fw = ww - cw;
628    if (fh) *fh = wh - ch;
629 }
630
631 static void
632 _ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout_update(Ecore_Evas *ee)
633 {
634    if (ee->prop.wm_rot.manual_mode.timer)
635      ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
636
637    ee->prop.wm_rot.manual_mode.timer = ecore_timer_add
638      (4.0f, _ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout, ee);
639 }
640
641 static Eina_Bool
642 _ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
643 {
644    Ecore_Evas *ee;
645    Ecore_Evas_Engine_Wl_Data *wdata;
646    Ecore_Wl2_Event_Window_Configure *ev;
647    int nw = 0, nh = 0, fw, fh, pfw, pfh;
648    Eina_Bool active, prev_max, prev_full, state_change = EINA_FALSE;
649
650    // TIZEN_ONLY(20160630)
651    int nx = 0, ny = 0;
652    //
653
654    LOGFN;
655
656    ev = event;
657    ee = ecore_event_window_match(ev->win);
658    if (!ee) return ECORE_CALLBACK_PASS_ON;
659    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
660
661    wdata = ee->engine.data;
662    if (!wdata) return ECORE_CALLBACK_PASS_ON;
663    if (wdata->win->pending.geom) return ECORE_CALLBACK_PASS_ON;
664
665    if (!ecore_wl2_window_resizing_get(wdata->win) && !wdata->resizing)
666      wdata->cw = wdata->ch = 0;
667
668    prev_max = ee->prop.maximized;
669    prev_full = ee->prop.fullscreen;
670 //TIZEN_ONLY(20180220): maximized set using the client's value
671 /*
672    ee->prop.maximized =
673      (ev->states & ECORE_WL2_WINDOW_STATE_MAXIMIZED) == ECORE_WL2_WINDOW_STATE_MAXIMIZED;
674 */
675    ee->prop.maximized =  ecore_wl2_window_maximized_get(wdata->win);
676 //
677 //TIZEN_ONLY(20180220): fullscreen set using the client's value
678 /*
679    ee->prop.fullscreen =
680      (ev->states & ECORE_WL2_WINDOW_STATE_FULLSCREEN) == ECORE_WL2_WINDOW_STATE_FULLSCREEN;
681 */
682    ee->prop.fullscreen =  ecore_wl2_window_fullscreen_get(wdata->win);
683 //
684    active = wdata->activated;
685    wdata->activated = ecore_wl2_window_activated_get(wdata->win);
686
687    /* If the compositor set these, we need to update internal state
688     * so things like CSD continue to function */
689    wdata->win->set_config.maximized = ee->prop.maximized;
690    wdata->win->set_config.fullscreen = ee->prop.fullscreen;
691
692    nw = ev->w;
693    nh = ev->h;
694 // TIZEN_ONLY(20180424) : handle window position
695    nx = ev->x;
696    ny = ev->y;
697 //
698 // TIZEN_ONLY(20200212) : get window position by window_geometry
699    ecore_wl2_window_geometry_get(wdata->win, &nx, &ny, NULL, NULL);
700 //
701
702    _ecore_evas_framespace_get(ee, &fw, &fh);
703
704    pfw = fw;
705    pfh = fh;
706
707    if ((prev_max != ee->prop.maximized) ||
708        (prev_full != ee->prop.fullscreen) ||
709        (active != wdata->activated))
710      {
711         state_change = EINA_TRUE;
712         _ecore_evas_wl_common_state_update(ee);
713         _ecore_evas_framespace_get(ee, &fw, &fh);
714      }
715    if ((!nw) && (!nh))
716      {
717 // TIZEN_ONLY(20180424) : handle window position
718         if ((ee->x != nx) || (ee->y != ny))
719           _ecore_evas_wl_common_move(ee, nx, ny);
720 //
721         if ((wdata->win->set_config.serial != wdata->win->req_config.serial) &&
722             wdata->win->req_config.serial && wdata->win->surface &&
723             ((!state_change) || ((pfw == fw) && (pfh == fh))))
724           {
725              ecore_wl2_window_commit(wdata->win, EINA_TRUE);
726           }
727         return ECORE_CALLBACK_RENEW;
728      }
729
730    if (!ee->prop.borderless)
731      {
732         if (ECORE_EVAS_PORTRAIT(ee))
733           {
734              nw -= fw;
735              nh -= fh;
736           }
737         else
738           {
739              nw -= fh;
740              nh -= fw;
741           }
742      }
743
744    if (ee->prop.fullscreen || (ee->req.w != nw) || (ee->req.h != nh))
745      {
746 // TIZEN_ONLY(20160630)
747         if (ee->prop.fullscreen)
748           _ecore_evas_wl_common_move(ee, nx, ny);
749 //
750
751         if (ecore_wl2_window_resizing_get(wdata->win) || wdata->resizing)
752           {
753              if ((wdata->cw != nw) || (wdata->ch != nh))
754                _ecore_evas_wl_common_resize(ee, nw, nh);
755              wdata->cw = nw, wdata->ch = nh;
756           }
757         else
758           _ecore_evas_wl_common_resize(ee, nw, nh);
759      }
760    wdata->resizing = ecore_wl2_window_resizing_get(wdata->win);
761
762 // TIZEN_ONLY(20160630)
763    if ((ee->x != nx) || (ee->y != ny))
764      _ecore_evas_wl_common_move(ee, nx, ny);
765 //
766
767    if (ee->prop.wm_rot.supported)
768      {
769         if (wdata->wm_rot.prepare)
770           {
771              if ((ee->prop.wm_rot.w == nw) &&
772                  (ee->prop.wm_rot.h == nh))
773                {
774                   ee->prop.wm_rot.win_resize = EINA_FALSE;
775                   wdata->wm_rot.configure_coming = EINA_FALSE;
776                }
777           }
778         else if (wdata->wm_rot.request)
779           {
780              if ((wdata->wm_rot.configure_coming) &&
781                  (ee->prop.wm_rot.w == nw) &&
782                  (ee->prop.wm_rot.h == nh))
783                {
784                   wdata->wm_rot.configure_coming = EINA_FALSE;
785
786                   if (ee->prop.wm_rot.manual_mode.set)
787                     {
788                        ee->prop.wm_rot.manual_mode.wait_for_done = EINA_TRUE;
789                        _ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout_update(ee);
790                     }
791
792                   _ecore_evas_wl_common_rotation_set(ee,
793                                                      ee->prop.wm_rot.angle,
794                                                      EINA_TRUE);
795                }
796           }
797      }
798
799    //TIZEN_ONLY(20171115): support output transform
800    _ecore_evas_wl_common_rotate_update(ee);
801    //
802
803    return ECORE_CALLBACK_PASS_ON;
804 }
805
806 static Eina_Bool
807 _ecore_evas_wl_common_cb_window_configure_complete(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
808 {
809    Ecore_Evas *ee;
810    Ecore_Wl2_Event_Window_Configure_Complete *ev;
811    Evas_Engine_Info_Wayland *einfo;
812    Ecore_Evas_Engine_Wl_Data *wdata;
813
814    LOGFN;
815
816    ev = event;
817    ee = ecore_event_window_match(ev->win);
818    if (!ee) return ECORE_CALLBACK_PASS_ON;
819
820    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
821
822    einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
823    if (!einfo) return ECORE_CALLBACK_PASS_ON;
824
825    einfo->info.hidden = EINA_FALSE;
826    if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
827      ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
828
829    wdata = ee->engine.data;
830    ee->draw_block = EINA_FALSE;
831    if (wdata->frame) ecore_evas_manual_render(ee);
832
833    return ECORE_CALLBACK_PASS_ON;
834 }
835
836  static Eina_Bool
837 _ecore_evas_wl_common_cb_aux_message(void *data  EINA_UNUSED, int type EINA_UNUSED, void *event)
838 {
839    Ecore_Evas *ee;
840    Ecore_Wl2_Event_Aux_Message *ev;
841
842    ev = event;
843    ee = ecore_event_window_match(ev->win);
844    if (!ee) return ECORE_CALLBACK_PASS_ON;
845    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
846    if (eina_streq(ev->key, "stack_del"))
847      {
848         if (ee->func.fn_delete_request)
849           ee->func.fn_delete_request(ee);
850      }
851    return ECORE_CALLBACK_RENEW;
852 }
853
854  static Eina_Bool
855 _ecore_evas_wl_common_cb_aux_hint_supported(void *data  EINA_UNUSED, int type EINA_UNUSED, void *event)
856 {
857    Ecore_Evas *ee;
858    Ecore_Wl2_Event_Aux_Hint_Supported *ev;
859    Eina_Stringshare *hint;
860    Ecore_Evas_Engine_Wl_Data *wdata;
861
862    ev = event;
863    ee = ecore_event_window_match(ev->win);
864    if (!ee) return ECORE_CALLBACK_PASS_ON;
865    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
866    wdata = ee->engine.data;
867    EINA_LIST_FREE(ee->prop.aux_hint.supported_list, hint) eina_stringshare_del(hint);
868    ee->prop.aux_hint.supported_list = ecore_wl2_window_aux_hints_supported_get(wdata->win);
869    return ECORE_CALLBACK_RENEW;
870 }
871
872  static Eina_Bool
873 _ecore_evas_wl_common_cb_aux_hint_allowed(void *data  EINA_UNUSED, int type EINA_UNUSED, void *event)
874 {
875    Ecore_Evas *ee;
876    Ecore_Wl2_Event_Aux_Hint_Allowed *ev;
877    Eina_List *l;
878    Ecore_Evas_Aux_Hint *aux;
879
880    ev = event;
881    ee = ecore_event_window_match(ev->win);
882    if (!ee) return ECORE_CALLBACK_PASS_ON;
883    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
884
885    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, l, aux)
886      {
887         if (aux->id == ev->id)
888           {
889              aux->allowed = 1;
890              if (!aux->notified)
891                {
892                   _ecore_evas_wl_common_state_update(ee);
893                   aux->notified = 1;
894                }
895              break;
896           }
897      }
898    return ECORE_CALLBACK_PASS_ON;
899 }
900
901 // TIZEN_ONLY(20170212): pend rotation until app set rotation
902 static Eina_Bool
903 _ecore_evas_wl_common_cb_window_pending_rotate(Ecore_Evas *ee, Ecore_Wl2_Event_Window_Rotation *ev)
904 {
905    Ecore_Evas_Engine_Wl_Data *wdata;
906    DBG("PendingRotation: ecore_evas_wl pending rotation callback from WM");
907    DBG("PendingRotation: ecore_evas_wl angle app(%d) wm(%d)", ee->prop.wm_rot.pending_mode.app_angle, ee->prop.wm_rot.pending_mode.wm_angle);
908
909    wdata = ee->engine.data;
910    if (!wdata) return ECORE_CALLBACK_PASS_ON;
911
912    if ((!ee->prop.wm_rot.supported) || (!ee->prop.wm_rot.app_set))
913      return ECORE_CALLBACK_PASS_ON;
914
915 //TODO: deal with the rotation difference between client and server
916 //If app not set proper rotation, client cannot deal with the rotation properly.
917 //Need to discuss this issue with server.
918
919
920    DBG("PendingRotation: ecore_evas_wl pend rotation");
921    //THIS IS HOTFIX: we need to negotiate rotation done protocol with display server.
922    ecore_wl2_window_rotation_change_done_send(wdata->win, ee->rotation, ee->w, ee->h);
923
924    //Server has responsibility to show frame even though app not call render when app turns on manual rotation render feature.
925    //until server add the code, client create fake damage.
926    _ecore_evas_wl_common_damage_add(ee);
927
928    ee->prop.wm_rot.pending_mode.wm_angle = ev->angle;
929    return ECORE_CALLBACK_PASS_ON;
930 }
931 //
932
933 static Eina_Bool
934 _ecore_evas_wl_common_cb_window_rotate(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
935 {
936    Ecore_Evas *ee;
937    Ecore_Wl2_Event_Window_Rotation *ev;
938    Ecore_Evas_Engine_Wl_Data *wdata;
939    int fw, fh, nw ,nh;
940
941    LOGFN;
942
943    ev = event;
944    ee = ecore_event_window_match(ev->win);
945    if (!ee) return ECORE_CALLBACK_PASS_ON;
946    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
947
948 // TIZEN_ONLY(20170212): pend rotation until app set rotation
949    if (ee->prop.wm_rot.pending_mode.app_set)
950      return _ecore_evas_wl_common_cb_window_pending_rotate(ee, ev);
951    DBG("PendingRotation: ecore_evas_wl rotation callback from WM");
952 //
953
954    // TIZEN_ONLY
955    /*
956    _ecore_evas_wl_common_rotation_set(ee, ev->rotation, ev->resize);
957    */
958    wdata = ee->engine.data;
959    if (!wdata) return ECORE_CALLBACK_PASS_ON;
960
961    if ((!ee->prop.wm_rot.supported) || (!ee->prop.wm_rot.app_set))
962      return ECORE_CALLBACK_PASS_ON;
963
964    wdata->wm_rot.request = 1;
965    wdata->wm_rot.done = 0;
966
967    nw = ev->w;
968    nh = ev->h;
969
970    _ecore_evas_framespace_get(ee, &fw, &fh);
971
972    if (!ee->prop.borderless)
973      {
974         if (ECORE_EVAS_PORTRAIT(ee))
975           {
976              nw -= fw;
977              nh -= fh;
978           }
979         else
980           {
981              nw -= fh;
982              nh -= fw;
983           }
984      }
985
986    /* TIZEN_ONLY: if the width or height are zero, it means the client should
987       decide its own window dimension. */
988    if (nw > 0 && nh > 0)
989      {
990         if ((ee->w != nw) || (ee->h != nh))
991           {
992              _ecore_evas_wl_common_resize(ee, nw, nh);
993           }
994      }
995
996    if (ee->prop.wm_rot.manual_mode.set)
997      {
998         ee->prop.wm_rot.manual_mode.wait_for_done = EINA_TRUE;
999         _ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout_update(ee);
1000      }
1001
1002    _ecore_evas_wl_common_rotation_set(ee, ev->angle, 1);
1003
1004    wdata->wm_rot.done = 1;
1005    //
1006
1007    return ECORE_CALLBACK_PASS_ON;
1008 }
1009
1010 static void
1011 _mouse_move_dispatch(Ecore_Evas *ee)
1012 {
1013    Ecore_Evas_Cursor *cursor;
1014    Eina_Iterator *itr = eina_hash_iterator_data_new(ee->prop.cursors);
1015
1016    EINA_SAFETY_ON_NULL_RETURN(itr);
1017
1018    EINA_ITERATOR_FOREACH(itr, cursor)
1019      _ecore_evas_mouse_move_process(ee, cursor->pos_x, cursor->pos_y,
1020                                     ecore_loop_time_get());
1021    eina_iterator_free(itr);
1022 }
1023
1024 //TIZEN_ONLY(20171115): support output transform
1025 /* ee->rotation shouldn't include the output rotation value. Therefore, we
1026  * SHOULD handle the window rotation and output transform seperately.
1027  * rotation: window rotation
1028  * output_rotation: screen rotation
1029 static void
1030 _rotation_do(Ecore_Evas *ee, int rotation, int resize)
1031  */
1032 static void
1033 _rotation_do(Ecore_Evas *ee, int rotation, int output_rotation, int resize)
1034 //
1035 {
1036    //TIZEN_ONLY(20191129): einfo using for specific case below.
1037    //Evas_Engine_Info_Wayland *einfo;
1038    //
1039    Ecore_Evas_Engine_Wl_Data *wdata;
1040    int rot_dif;
1041
1042    //TIZEN_ONLY(20191129): einfo using for specific case below.
1043    /*
1044    einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
1045    if (einfo)
1046      {
1047         einfo->info.rotation = rotation;
1048         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1049           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1050      }
1051    */
1052
1053    wdata = ee->engine.data;
1054
1055    /* calculate difference in rotation */
1056    rot_dif = ee->rotation - rotation;
1057    if (rot_dif < 0) rot_dif = -rot_dif;
1058
1059    /* set ecore_wayland window rotation */
1060    ecore_wl2_window_rotation_set(wdata->win, rotation);
1061
1062    /* check if rotation is just a flip */
1063    //TIZEN_ONLY(20171115): support output transform
1064    /*
1065    if (rot_dif != 180)
1066     */
1067    if (rot_dif % 180)
1068    //
1069      {
1070         int minw, minh, maxw, maxh;
1071         int basew, baseh, stepw, steph;
1072
1073         /* check if we are rotating with resize */
1074         if (!resize)
1075           {
1076              int fw, fh;
1077              int ww, hh;
1078
1079              /* grab framespace width & height */
1080              evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
1081
1082              /* check for fullscreen */
1083              //TIZEN_ONLY(20171115): support output transform
1084              /*
1085              if (ee->prop.fullscreen)
1086               */
1087              if (ee->prop.fullscreen && !ee->prop.maximized)
1088              //
1089                {
1090                   /* resize the canvas based on rotation */
1091                   if ((rotation == 0) || (rotation == 180))
1092                     {
1093                        /* resize the canvas */
1094                        evas_output_size_set(ee->evas, ee->req.w, ee->req.h);
1095                        evas_output_viewport_set(ee->evas, 0, 0,
1096                                                 ee->req.w, ee->req.h);
1097                     }
1098                   else
1099                     {
1100                        /* resize the canvas */
1101                        evas_output_size_set(ee->evas, ee->req.h, ee->req.w);
1102                        evas_output_viewport_set(ee->evas, 0, 0,
1103                                                 ee->req.h, ee->req.w);
1104                     }
1105                }
1106
1107              /* add canvas damage */
1108              if (ECORE_EVAS_PORTRAIT(ee))
1109                evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
1110              else
1111                evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h, ee->req.w);
1112              ww = ee->h;
1113              hh = ee->w;
1114              ee->w = ww;
1115              ee->h = hh;
1116              ee->req.w = ww;
1117              ee->req.h = hh;
1118           }
1119         else
1120           {
1121              /* resize the canvas based on rotation */
1122              if ((rotation == 0) || (rotation == 180))
1123                {
1124                   evas_output_size_set(ee->evas, ee->w, ee->h);
1125                   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1126                }
1127              else
1128                {
1129                   evas_output_size_set(ee->evas, ee->h, ee->w);
1130                   evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
1131                }
1132
1133              /* call the ecore_evas' resize function */
1134              if (ee->func.fn_resize) ee->func.fn_resize(ee);
1135
1136              /* add canvas damage */
1137              if (ECORE_EVAS_PORTRAIT(ee))
1138                evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1139              else
1140                evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1141           }
1142
1143         /* get min, max, base, & step sizes */
1144         ecore_evas_size_min_get(ee, &minw, &minh);
1145         ecore_evas_size_max_get(ee, &maxw, &maxh);
1146         ecore_evas_size_base_get(ee, &basew, &baseh);
1147         ecore_evas_size_step_get(ee, &stepw, &steph);
1148
1149         /* record the current rotation of the ecore_evas */
1150         ee->rotation = rotation;
1151         //TIZEN_ONLY(20171115): support output transform
1152         wdata->output_rotation = output_rotation;
1153         //
1154
1155         /* reset min, max, base, & step sizes */
1156         ecore_evas_size_min_set(ee, minh, minw);
1157         ecore_evas_size_max_set(ee, maxh, maxw);
1158         ecore_evas_size_base_set(ee, baseh, basew);
1159         ecore_evas_size_step_set(ee, steph, stepw);
1160
1161         /* send a mouse_move process
1162          *
1163          * NB: Is This Really Needed ?
1164          * Yes, it's required to update the mouse position, relatively to
1165          * widgets. After a rotation change, e.g., the mouse might not be over
1166          * a button anymore. */
1167         _mouse_move_dispatch(ee);
1168      }
1169    else
1170      {
1171         /* record the current rotation of the ecore_evas */
1172         ee->rotation = rotation;
1173         //TIZEN_ONLY(20171115): support output transform
1174         wdata->output_rotation = output_rotation;
1175         //
1176
1177         /* send a mouse_move process
1178          *
1179          * NB: Is This Really Needed ? Yes, it's required to update the mouse
1180          * position, relatively to widgets. */
1181         _mouse_move_dispatch(ee);
1182
1183         /* call the ecore_evas' resize function */
1184         if (ee->func.fn_resize) ee->func.fn_resize(ee);
1185
1186         /* add canvas damage */
1187         if (ECORE_EVAS_PORTRAIT(ee))
1188           evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1189         else
1190           evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1191      }
1192
1193    //TIZEN_ONLY(20171115): support output transform
1194    if (!strcmp(ee->driver, "wayland_shm"))
1195      {
1196 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
1197         Evas_Engine_Info_Wayland *einfo;
1198         einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
1199         if (!einfo) return;
1200
1201         _ecore_evas_wl_common_engine_info_rotation_set(ee, (Evas_Engine_Info *)einfo);
1202
1203         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1204           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1205 #endif
1206      }
1207    else if (!strcmp(ee->driver, "wayland_egl"))
1208      {
1209 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
1210         Evas_Engine_Info_Wayland *einfo;
1211         einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
1212         if (!einfo) return;
1213
1214         _ecore_evas_wl_common_engine_info_rotation_set(ee, (Evas_Engine_Info *)einfo);
1215
1216         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1217           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1218 #endif
1219      }
1220
1221    _ecore_evas_wl_common_state_update(ee);
1222    //
1223 }
1224
1225 static Eina_Bool
1226 _ecore_evas_wl_common_cb_www_drag(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
1227 {
1228    Ecore_Wl2_Event_Window_WWW_Drag *ev = event;
1229    Ecore_Evas_Engine_Wl_Data *wdata;
1230    Ecore_Evas *ee;
1231
1232    ee = ecore_event_window_match(ev->window);
1233    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1234    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1235
1236    wdata = ee->engine.data;
1237    wdata->dragging = !!ev->dragging;
1238    if (!ev->dragging)
1239      evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1240    return ECORE_CALLBACK_RENEW;
1241 }
1242
1243 static Eina_Bool
1244 _ecore_evas_wl_common_cb_www(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
1245 {
1246    Ecore_Wl2_Event_Window_WWW *ev = event;
1247    Ecore_Evas_Engine_Wl_Data *wdata;
1248    Ecore_Evas *ee;
1249
1250    ee = ecore_event_window_match(ev->window);
1251    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
1252    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1253
1254    wdata = ee->engine.data;
1255    wdata->x_rel += ev->x_rel;
1256    wdata->y_rel += ev->y_rel;
1257    wdata->timestamp = ev->timestamp;
1258    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1259    return ECORE_CALLBACK_RENEW;
1260 }
1261
1262 static void
1263 _ecore_evas_wl_common_cb_device_event_free(void *user_data, void *func_data)
1264 {
1265    efl_unref(user_data);
1266    free(func_data);
1267 }
1268
1269 static void
1270 _ecore_evas_wl_common_device_event_add(int event_type, Ecore_Wl2_Device_Type device_type, unsigned int id, Evas_Device *dev, Ecore_Evas *ee)
1271 {
1272    Ecore_Wl2_Event_Device *ev;
1273
1274    ev = calloc(1, sizeof(Ecore_Wl2_Event_Device));
1275    EINA_SAFETY_ON_NULL_RETURN(ev);
1276
1277    ev->dev = efl_ref(dev);
1278    ev->type = device_type;
1279    ev->seat_id = id;
1280    ev->window_id = ee->prop.window;
1281
1282    ecore_event_add(event_type, ev,
1283                    _ecore_evas_wl_common_cb_device_event_free, dev);
1284 }
1285
1286 static EE_Wl_Device *
1287 _ecore_evas_wl_common_seat_add(Ecore_Evas *ee, unsigned int id, const char *name)
1288 {
1289    Ecore_Evas_Engine_Wl_Data *wdata;
1290    EE_Wl_Device *device;
1291    Evas_Device *dev;
1292    char buf[32];
1293
1294    device = calloc(1, sizeof(EE_Wl_Device));
1295    EINA_SAFETY_ON_NULL_RETURN_VAL(device, NULL);
1296
1297    if (!name)
1298      {
1299         snprintf(buf, sizeof(buf), "seat-%u", id);
1300         name = buf;
1301      }
1302    dev =
1303      evas_device_add_full(ee->evas, name, "Wayland seat", NULL, NULL,
1304                           EVAS_DEVICE_CLASS_SEAT, EVAS_DEVICE_SUBCLASS_NONE);
1305    EINA_SAFETY_ON_NULL_GOTO(dev, err_dev);
1306    evas_device_seat_id_set(dev, id);
1307    device->seat = dev;
1308    device->id = id;
1309
1310    wdata = ee->engine.data;
1311    wdata->devices_list = eina_list_append(wdata->devices_list, device);
1312
1313    _ecore_evas_wl_common_device_event_add(ECORE_WL2_EVENT_DEVICE_ADDED,
1314                                           ECORE_WL2_DEVICE_TYPE_SEAT,
1315                                           id, dev, ee);
1316    return device;
1317  err_dev:
1318    free(device);
1319    return NULL;
1320 }
1321
1322 static Eina_Bool
1323 _ecore_evas_wl_common_cb_global_added(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
1324 {
1325    Ecore_Wl2_Event_Global *ev = event;
1326    Ecore_Evas *ee;
1327    Eina_List *l, *ll;
1328    EE_Wl_Device *device;
1329
1330    if ((!ev->interface) || (strcmp(ev->interface, "wl_seat")))
1331        return ECORE_CALLBACK_PASS_ON;
1332
1333    EINA_LIST_FOREACH(ee_list, l, ee)
1334      {
1335         Eina_Bool already_present = EINA_FALSE;
1336         Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
1337
1338         if (ev->display != wdata->display) continue;
1339         EINA_LIST_FOREACH(wdata->devices_list, ll, device)
1340           {
1341              if (device->id == ev->id)
1342                {
1343                   already_present = EINA_TRUE;
1344                   break;
1345                }
1346           }
1347
1348         if (already_present)
1349           continue;
1350
1351         if (!_ecore_evas_wl_common_seat_add(ee, ev->id, NULL))
1352           break;
1353      }
1354
1355    return ECORE_CALLBACK_PASS_ON;
1356 }
1357
1358 static void
1359 _ecore_evas_wl_common_device_free(EE_Wl_Device *device)
1360 {
1361    if (device->seat)
1362      evas_device_del(device->seat);
1363    if (device->pointer)
1364      evas_device_del(device->pointer);
1365    if (device->keyboard)
1366      evas_device_del(device->keyboard);
1367    if (device->touch)
1368      evas_device_del(device->touch);
1369    free(device);
1370 }
1371
1372 static Eina_Bool
1373 _ecore_evas_wl_common_cb_global_removed(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
1374 {
1375    Ecore_Wl2_Event_Global *ev = event;
1376    Ecore_Evas *ee;
1377    Eina_List *l, *ll;
1378
1379    if ((!ev->interface) || (strcmp(ev->interface, "wl_seat")))
1380        return ECORE_CALLBACK_PASS_ON;
1381
1382    EINA_LIST_FOREACH(ee_list, l, ee)
1383      {
1384         Ecore_Evas_Engine_Wl_Data *wdata;
1385         EE_Wl_Device *device;
1386         Eina_Bool found = EINA_FALSE;
1387
1388         wdata = ee->engine.data;
1389         if (ev->display != wdata->display) continue;
1390
1391         EINA_LIST_FOREACH(wdata->devices_list, ll, device)
1392           {
1393              if (device->id == ev->id)
1394                {
1395                   found = EINA_TRUE;
1396                   break;
1397                }
1398           }
1399
1400         if (found)
1401           {
1402              _ecore_evas_wl_common_device_event_add
1403                (ECORE_WL2_EVENT_DEVICE_REMOVED, ECORE_WL2_DEVICE_TYPE_SEAT,
1404                    ev->id, device->seat, ee);
1405
1406              wdata->devices_list =
1407                eina_list_remove(wdata->devices_list, device);
1408
1409              _ecore_evas_wl_common_device_free(device);
1410           }
1411      }
1412
1413    return ECORE_CALLBACK_PASS_ON;
1414 }
1415
1416 static Eina_Bool
1417 _ecore_evas_wl_common_cb_seat_name_changed(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
1418 {
1419    Ecore_Wl2_Event_Seat_Name *ev = event;
1420    Ecore_Evas *ee;
1421    Eina_List *l, *ll;
1422
1423    EINA_LIST_FOREACH(ee_list, l, ee)
1424      {
1425         Ecore_Evas_Engine_Wl_Data *wdata;
1426         EE_Wl_Device *device;
1427
1428         wdata = ee->engine.data;
1429         if (ev->display != wdata->display) continue;
1430
1431         EINA_LIST_FOREACH(wdata->devices_list, ll, device)
1432           {
1433              if (device->id == ev->id)
1434                {
1435                   evas_device_name_set(device->seat, ev->name);
1436                   break;
1437                }
1438           }
1439      }
1440
1441    return ECORE_CALLBACK_PASS_ON;
1442 }
1443
1444 static Eina_Bool
1445 _ecore_evas_wl_common_cb_seat_capabilities_changed(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
1446 {
1447    Ecore_Wl2_Event_Seat_Capabilities *ev = event;
1448    Ecore_Evas *ee;
1449    Eina_List *l, *ll;
1450
1451    EINA_LIST_FOREACH(ee_list, l, ee)
1452      {
1453         Ecore_Evas_Engine_Wl_Data *wdata;
1454         EE_Wl_Device *device;
1455
1456         wdata = ee->engine.data;
1457         if (ev->display != wdata->display) continue;
1458
1459         EINA_LIST_FOREACH(wdata->devices_list, ll, device)
1460           {
1461              if (device->id == ev->id)
1462                {
1463                   if (ev->pointer_enabled && !device->pointer)
1464                     {
1465                        device->pointer =
1466                          evas_device_add_full(ee->evas, "Mouse",
1467                                               "A wayland pointer device",
1468                                               device->seat, NULL,
1469                                               EVAS_DEVICE_CLASS_MOUSE,
1470                                               EVAS_DEVICE_SUBCLASS_NONE);
1471
1472                        _ecore_evas_wl_common_device_event_add
1473                          (ECORE_WL2_EVENT_DEVICE_ADDED,
1474                              ECORE_WL2_DEVICE_TYPE_POINTER,
1475                              ev->id, device->pointer, ee);
1476                     }
1477                   else if (!ev->pointer_enabled && device->pointer)
1478                     {
1479                        _ecore_evas_wl_common_device_event_add
1480                          (ECORE_WL2_EVENT_DEVICE_REMOVED,
1481                              ECORE_WL2_DEVICE_TYPE_POINTER, ev->id,
1482                              device->pointer, ee);
1483
1484                        evas_device_del(device->pointer);
1485                        device->pointer = NULL;
1486                     }
1487
1488                   if (ev->keyboard_enabled && !device->keyboard)
1489                     {
1490                        device->keyboard =
1491                          evas_device_add_full(ee->evas, "Keyboard",
1492                                               "A wayland keyboard device",
1493                                               device->seat, NULL,
1494                                               EVAS_DEVICE_CLASS_KEYBOARD,
1495                                               EVAS_DEVICE_SUBCLASS_NONE);
1496
1497                        _ecore_evas_wl_common_device_event_add
1498                          (ECORE_WL2_EVENT_DEVICE_ADDED,
1499                              ECORE_WL2_DEVICE_TYPE_KEYBOARD,
1500                              ev->id, device->keyboard, ee);
1501                     }
1502                   else if (!ev->keyboard_enabled && device->keyboard)
1503                     {
1504                        _ecore_evas_wl_common_device_event_add
1505                          (ECORE_WL2_EVENT_DEVICE_REMOVED,
1506                              ECORE_WL2_DEVICE_TYPE_KEYBOARD, ev->id,
1507                              device->keyboard, ee);
1508
1509                        evas_device_del(device->keyboard);
1510                        device->keyboard = NULL;
1511                     }
1512
1513                   if (ev->touch_enabled && !device->touch)
1514                     {
1515                        device->touch =
1516                          evas_device_add_full(ee->evas, "Touch",
1517                                               "A wayland touch device",
1518                                               device->seat, NULL,
1519                                               EVAS_DEVICE_CLASS_TOUCH,
1520                                               EVAS_DEVICE_SUBCLASS_NONE);
1521
1522                        _ecore_evas_wl_common_device_event_add
1523                          (ECORE_WL2_EVENT_DEVICE_ADDED,
1524                              ECORE_WL2_DEVICE_TYPE_TOUCH,
1525                              ev->id, device->touch, ee);
1526                     }
1527                   else if (!ev->touch_enabled && device->touch)
1528                     {
1529                        _ecore_evas_wl_common_device_event_add
1530                          (ECORE_WL2_EVENT_DEVICE_REMOVED,
1531                              ECORE_WL2_DEVICE_TYPE_TOUCH,
1532                              ev->id, device->touch, ee);
1533
1534                        evas_device_del(device->touch);
1535                        device->touch = NULL;
1536                     }
1537
1538                   break;
1539                }
1540           }
1541      }
1542
1543    return ECORE_CALLBACK_PASS_ON;
1544 }
1545
1546 // TIZEN_ONLY(20160617) : uniconify force render
1547 static void
1548 _ecore_evas_wl_common_damage_add(Ecore_Evas *ee)
1549 {
1550    if (ee->prop.iconified)
1551      return;
1552
1553    /* add canvas damage
1554     * redrawing canvas is necessary if evas engine destroy the buffer.
1555     */
1556    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1557 }
1558 //
1559
1560 static Eina_Bool
1561 _ecore_evas_wl_common_cb_iconify_state_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1562 {
1563    Ecore_Evas *ee;
1564    Ecore_Wl2_Event_Window_Iconify_State_Change *ev;
1565    // TIZEN_ONLY(20151231) : handling iconic state on tizen
1566    Ecore_Evas_Engine_Wl_Data *wdata;
1567    //
1568
1569    ev = event;
1570    ee = ecore_event_window_match(ev->win);
1571    if (!ee) return ECORE_CALLBACK_PASS_ON;
1572    // TIZEN_ONLY(20151231) : handling iconic state on tizen
1573    /*
1574    if (!ev->force) return ECORE_CALLBACK_PASS_ON;
1575    */
1576    //
1577    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1578
1579    if (ee->prop.iconified == ev->iconified)
1580      return ECORE_CALLBACK_PASS_ON;
1581
1582    ee->prop.iconified = ev->iconified;
1583
1584    // TIZEN_ONLY(20151231) : handling iconic state on tizen
1585    wdata = ee->engine.data;
1586    if (wdata && ev->force)
1587      ecore_wl2_window_iconify_state_update(wdata->win, ev->iconified, EINA_FALSE);
1588    //
1589
1590    // TIZEN_ONLY(20200311) : uniconify update rotate
1591    if (!ee->prop.iconified)
1592       _ecore_evas_wl_common_rotate_update(ee);
1593    //
1594
1595    _ecore_evas_wl_common_state_update(ee);
1596
1597 // TIZEN_ONLY(20160617) : uniconify force render
1598    _ecore_evas_wl_common_damage_add(ee);
1599 //
1600    return ECORE_CALLBACK_PASS_ON;
1601 }
1602
1603 // TIZEN_ONLY(20150703) : support conformant
1604 static Eina_Bool
1605 _ecore_evas_wl_common_cb_conformant_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1606 {
1607    Ecore_Evas *ee;
1608    Ecore_Wl2_Event_Conformant_Change *ev;
1609
1610    ev = event;
1611    ee = ecore_event_window_match(ev->win);
1612    if (!ee) return ECORE_CALLBACK_PASS_ON;
1613    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1614
1615    if ((ev->part_type == ECORE_WL2_INDICATOR_PART) && (ee->indicator_state != ev->state))
1616      ee->indicator_state = ev->state;
1617    else if ((ev->part_type == ECORE_WL2_KEYBOARD_PART) && (ee->keyboard_state != ev->state))
1618      ee->keyboard_state = ev->state;
1619    else if ((ev->part_type == ECORE_WL2_CLIPBOARD_PART) && (ee->clipboard_state != ev->state))
1620      ee->clipboard_state = ev->state;
1621
1622    _ecore_evas_wl_common_state_update(ee);
1623
1624    return ECORE_CALLBACK_PASS_ON;
1625 }
1626 //
1627
1628 static Eina_Bool
1629 _ecore_evas_wl_common_strcmp(const char *dst, const char *src)
1630 {
1631    int dst_len, src_len, str_len;
1632
1633    dst_len = strlen(dst);
1634    src_len = strlen(src);
1635
1636    if (src_len > dst_len) str_len = src_len;
1637    else str_len = dst_len;
1638
1639    if (!strncmp(dst, src, str_len))
1640      return EINA_TRUE;
1641    else
1642      return EINA_FALSE;
1643 }
1644
1645 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1646
1647 static Evas_Device_Class
1648 _ecore_evas_wl_common_ecore_device_class_to_evas(Ecore_Device_Class cls)
1649 {
1650    switch (cls)
1651      {
1652         case ECORE_DEVICE_CLASS_NONE:
1653           return EVAS_DEVICE_CLASS_NONE;
1654         case ECORE_DEVICE_CLASS_SEAT:
1655           return EVAS_DEVICE_CLASS_SEAT;
1656         case ECORE_DEVICE_CLASS_KEYBOARD:
1657           return EVAS_DEVICE_CLASS_KEYBOARD;
1658         case ECORE_DEVICE_CLASS_MOUSE:
1659           return EVAS_DEVICE_CLASS_MOUSE;
1660         case ECORE_DEVICE_CLASS_TOUCH:
1661           return EVAS_DEVICE_CLASS_TOUCH;
1662         case ECORE_DEVICE_CLASS_PEN:
1663           return EVAS_DEVICE_CLASS_PEN;
1664         case ECORE_DEVICE_CLASS_WAND:
1665           return EVAS_DEVICE_CLASS_WAND;
1666         case ECORE_DEVICE_CLASS_GAMEPAD:
1667           return EVAS_DEVICE_CLASS_GAMEPAD;
1668         default:
1669           return EVAS_DEVICE_CLASS_NONE;
1670      }
1671 }
1672
1673 static Eina_Bool
1674 _ecore_evas_wl_common_evas_device_find(Evas *evas, const char *name, const Ecore_Device_Class ecore_cls, const char *identifier)
1675 {
1676    Eina_List *list, *l;
1677    Evas_Device *device;
1678    const char *evas_device_name;
1679    const char *evas_device_description;
1680    Evas_Device_Class evas_cls = EVAS_DEVICE_CLASS_NONE;
1681
1682    EINA_SAFETY_ON_NULL_RETURN_VAL(evas, EINA_FALSE);
1683    EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1684    EINA_SAFETY_ON_NULL_RETURN_VAL(identifier, EINA_FALSE);
1685
1686    evas_cls = _ecore_evas_wl_common_ecore_device_class_to_evas(ecore_cls);
1687
1688    list = (Eina_List *)evas_device_list(evas, NULL);
1689    EINA_LIST_FOREACH(list, l, device)
1690      {
1691         evas_device_name = evas_device_name_get(device);
1692         evas_device_description = evas_device_description_get(device);
1693         if (!evas_device_name || !evas_device_description) continue;
1694
1695         if ((evas_device_class_get(device) == evas_cls) &&
1696             _ecore_evas_wl_common_strcmp(evas_device_name, name) &&
1697             _ecore_evas_wl_common_strcmp(evas_device_description, identifier))
1698           {
1699              return EINA_TRUE;
1700           }
1701      }
1702    return EINA_FALSE;
1703 }
1704
1705 static Evas_Device *
1706 _ecore_evas_wl_common_default_seat_get(Evas *evas)
1707 {
1708    Eina_List *list, *l;
1709    Evas_Device *device;
1710    const char *evas_device_description;
1711
1712    EINA_SAFETY_ON_NULL_RETURN_VAL(evas, EINA_FALSE);
1713
1714    list = (Eina_List *)evas_device_list(evas, NULL);
1715    EINA_LIST_FOREACH(list, l, device)
1716      {
1717         evas_device_description = evas_device_description_get(device);
1718         if (!evas_device_description) continue;
1719
1720         if ((evas_device_class_get(device) == EVAS_DEVICE_CLASS_SEAT) &&
1721             !strncmp(evas_device_description, "Wayland seat", sizeof("Wayland seat")))
1722           {
1723              return device;
1724           }
1725      }
1726    return NULL;
1727 }
1728
1729 static Eina_Bool
1730 _ecore_evas_wl_common_cb_tizen_device_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1731 {
1732    Ecore_Event_Device_Info *ev;
1733    Ecore_Wl2_Window *win = NULL;
1734    Ecore_Wl2_Display *display = NULL;
1735    Ecore_Evas *ee;
1736    Eina_List *l;
1737
1738    ev = event;
1739    if (!ev->name) return ECORE_CALLBACK_PASS_ON;
1740    if (!ev->identifier) return ECORE_CALLBACK_PASS_ON;
1741    if (ev->window) win = ecore_wl2_window_find(ev->window);
1742    if (win) display = ecore_wl2_window_display_get(win);
1743
1744    EINA_LIST_FOREACH(ee_list, l, ee)
1745      {
1746         Ecore_Evas_Engine_Wl_Data *wdata;
1747         Evas_Device *seat;
1748
1749         wdata = ee->engine.data;
1750         if (display != wdata->display) continue;
1751
1752         if (_ecore_evas_wl_common_evas_device_find(ee->evas, ev->name, ev->clas, ev->identifier)) continue;
1753         seat = _ecore_evas_wl_common_default_seat_get(ee->evas);
1754
1755         evas_device_add_full(ee->evas, ev->name,
1756                              ev->identifier,
1757                              seat, NULL,
1758                              ev->clas,
1759                              ev->subclas);
1760      }
1761
1762    return ECORE_CALLBACK_PASS_ON;
1763 }
1764
1765 static Eina_Bool
1766 _ecore_evas_wl_common_cb_tizen_device_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1767 {
1768    Ecore_Event_Device_Info *ev;
1769    Ecore_Wl2_Window *win = NULL;
1770    Ecore_Wl2_Display *display = NULL;
1771    Ecore_Evas *ee;
1772    Eina_List *list, *l, *ll, *ll_next;
1773    const char *evas_device_name;
1774    const char *evas_device_description;
1775    Evas_Device_Class evas_cls = EVAS_DEVICE_CLASS_NONE;
1776
1777    ev = event;
1778    if (!ev->name) return ECORE_CALLBACK_PASS_ON;
1779    if (!ev->identifier) return ECORE_CALLBACK_PASS_ON;
1780    evas_cls = _ecore_evas_wl_common_ecore_device_class_to_evas(ev->clas);
1781
1782    if (ev->window) win = ecore_wl2_window_find(ev->window);
1783    if (win) display = ecore_wl2_window_display_get(win);
1784
1785    EINA_LIST_FOREACH(ee_list, l, ee)
1786      {
1787         Ecore_Evas_Engine_Wl_Data *wdata;
1788         Evas_Device *device;
1789
1790         wdata = ee->engine.data;
1791         if (display != wdata->display) continue;
1792
1793         list = (Eina_List *)evas_device_list(ee->evas, NULL);
1794         EINA_LIST_FOREACH_SAFE(list, ll, ll_next, device)
1795           {
1796              evas_device_name = evas_device_name_get(device);
1797              evas_device_description = evas_device_description_get(device);
1798              if (!evas_device_name || !evas_device_description) continue;
1799
1800              if ((evas_device_class_get(device) == evas_cls) &&
1801                  _ecore_evas_wl_common_strcmp(evas_device_name, ev->name) &&
1802                  _ecore_evas_wl_common_strcmp(evas_device_description, ev->identifier))
1803                {
1804                   evas_device_del(device);
1805                }
1806           }
1807      }
1808
1809    return ECORE_CALLBACK_PASS_ON;
1810 }
1811
1812 //
1813
1814 // TIZEN_ONLY(20160120): support visibility_change event
1815 static Eina_Bool
1816 _ecore_evas_wl_common_cb_window_visibility_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1817 {
1818    Ecore_Evas *ee;
1819    Ecore_Wl2_Event_Window_Visibility_Change *ev;
1820
1821    ev = event;
1822    ee = ecore_event_window_match(ev->win);
1823
1824    if (!ee) return ECORE_CALLBACK_PASS_ON;
1825    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1826
1827    if (ee->prop.obscured == ev->fully_obscured)
1828      return ECORE_CALLBACK_PASS_ON;
1829
1830    ee->prop.obscured = ev->fully_obscured;
1831    _ecore_evas_wl_common_state_update(ee);
1832    return ECORE_CALLBACK_PASS_ON;
1833
1834 }
1835 //
1836
1837 //TIZEN_ONLY(20200707): support tizen_renderer_surface
1838 static Eina_Bool
1839 _ecore_evas_wl_common_cb_window_redraw_request(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
1840 {
1841    Ecore_Evas *ee;
1842    Ecore_Wl2_Event_Window_Redraw_Request *ev;
1843
1844    ev = event;
1845    ee = ecore_event_window_match(ev->win);
1846
1847    if (!ee) return ECORE_CALLBACK_PASS_ON;
1848    if (ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1849
1850    _ecore_evas_wl_common_damage_add(ee);
1851
1852    return ECORE_CALLBACK_PASS_ON;
1853 }
1854 //
1855
1856 static int
1857 _ecore_evas_wl_common_init(void)
1858 {
1859    Ecore_Event_Handler *h;
1860    LOGFN;
1861
1862    if (++_ecore_evas_wl_init_count != 1)
1863      return _ecore_evas_wl_init_count;
1864
1865    _ecore_evas_wl_event_hdls = eina_array_new(1);
1866
1867    h = ecore_event_handler_add(ECORE_EVENT_MOUSE_IN,
1868                              _ecore_evas_wl_common_cb_mouse_in, NULL);
1869    eina_array_push(_ecore_evas_wl_event_hdls, h);
1870
1871    h = ecore_event_handler_add(ECORE_EVENT_MOUSE_OUT,
1872                                _ecore_evas_wl_common_cb_mouse_out, NULL);
1873    eina_array_push(_ecore_evas_wl_event_hdls, h);
1874
1875    h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_IN,
1876                                _ecore_evas_wl_common_cb_focus_in, NULL);
1877    eina_array_push(_ecore_evas_wl_event_hdls, h);
1878
1879    h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_OUT,
1880                                _ecore_evas_wl_common_cb_focus_out, NULL);
1881    eina_array_push(_ecore_evas_wl_event_hdls, h);
1882
1883    h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE,
1884                                _ecore_evas_wl_common_cb_window_configure, NULL);
1885    eina_array_push(_ecore_evas_wl_event_hdls, h);
1886
1887    h = ecore_event_handler_add(_ecore_wl2_event_window_www,
1888                                _ecore_evas_wl_common_cb_www, NULL);
1889    eina_array_push(_ecore_evas_wl_event_hdls, h);
1890
1891    h = ecore_event_handler_add(_ecore_wl2_event_window_www_drag,
1892                                _ecore_evas_wl_common_cb_www_drag, NULL);
1893    eina_array_push(_ecore_evas_wl_event_hdls, h);
1894
1895    h = ecore_event_handler_add(ECORE_WL2_EVENT_DISCONNECT,
1896                                _ecore_evas_wl_common_cb_disconnect, NULL);
1897    eina_array_push(_ecore_evas_wl_event_hdls, h);
1898
1899    h = ecore_event_handler_add(ECORE_WL2_EVENT_GLOBAL_ADDED,
1900                                _ecore_evas_wl_common_cb_global_added, NULL);
1901    eina_array_push(_ecore_evas_wl_event_hdls, h);
1902
1903    h = ecore_event_handler_add(ECORE_WL2_EVENT_GLOBAL_REMOVED,
1904                                _ecore_evas_wl_common_cb_global_removed, NULL);
1905    eina_array_push(_ecore_evas_wl_event_hdls, h);
1906
1907    h = ecore_event_handler_add(ECORE_WL2_EVENT_SEAT_NAME_CHANGED,
1908                                _ecore_evas_wl_common_cb_seat_name_changed, NULL);
1909    eina_array_push(_ecore_evas_wl_event_hdls, h);
1910
1911    h = ecore_event_handler_add(ECORE_WL2_EVENT_SEAT_CAPABILITIES_CHANGED,
1912                                _ecore_evas_wl_common_cb_seat_capabilities_changed,
1913                                NULL);
1914    eina_array_push(_ecore_evas_wl_event_hdls, h);
1915
1916    h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE_COMPLETE,
1917                                _ecore_evas_wl_common_cb_window_configure_complete,
1918                                NULL);
1919    eina_array_push(_ecore_evas_wl_event_hdls, h);
1920
1921    h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_ROTATE,
1922                                _ecore_evas_wl_common_cb_window_rotate, NULL);
1923    eina_array_push(_ecore_evas_wl_event_hdls, h);
1924
1925    h = ecore_event_handler_add(ECORE_WL2_EVENT_AUX_HINT_ALLOWED,
1926                                _ecore_evas_wl_common_cb_aux_hint_allowed, NULL);
1927    eina_array_push(_ecore_evas_wl_event_hdls, h);
1928
1929    h = ecore_event_handler_add(ECORE_WL2_EVENT_AUX_HINT_SUPPORTED,
1930                                _ecore_evas_wl_common_cb_aux_hint_supported, NULL);
1931    eina_array_push(_ecore_evas_wl_event_hdls, h);
1932
1933    h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_ICONIFY_STATE_CHANGE,
1934                                _ecore_evas_wl_common_cb_iconify_state_change, NULL);
1935    eina_array_push(_ecore_evas_wl_event_hdls, h);
1936
1937    h = ecore_event_handler_add(ECORE_WL2_EVENT_AUX_MESSAGE,
1938                                _ecore_evas_wl_common_cb_aux_message, NULL);
1939    eina_array_push(_ecore_evas_wl_event_hdls, h);
1940
1941    // TIZEN_ONLY(20150703) : support conformant
1942    h = ecore_event_handler_add(ECORE_WL2_EVENT_CONFORMANT_CHANGE,
1943                                _ecore_evas_wl_common_cb_conformant_change, NULL);
1944    eina_array_push(_ecore_evas_wl_event_hdls, h);
1945    //
1946    // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1947    h = ecore_event_handler_add(ECORE_EVENT_DEVICE_ADD,
1948                                _ecore_evas_wl_common_cb_tizen_device_add, NULL);
1949    eina_array_push(_ecore_evas_wl_event_hdls, h);
1950    h = ecore_event_handler_add(ECORE_EVENT_DEVICE_DEL,
1951                                _ecore_evas_wl_common_cb_tizen_device_del, NULL);
1952    eina_array_push(_ecore_evas_wl_event_hdls, h);
1953    //
1954    // TIZEN_ONLY(20160120): support visibility_change event
1955    h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE,
1956                                _ecore_evas_wl_common_cb_window_visibility_change, NULL);
1957    eina_array_push(_ecore_evas_wl_event_hdls, h);
1958    //
1959
1960    // TIZEN_ONLY(20200707): support redraw request event
1961    h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_REDRAW_REQUEST,
1962                                _ecore_evas_wl_common_cb_window_redraw_request, NULL);
1963    eina_array_push(_ecore_evas_wl_event_hdls, h);
1964    //
1965
1966    ecore_event_evas_init();
1967
1968    return _ecore_evas_wl_init_count;
1969 }
1970
1971 static int
1972 _ecore_evas_wl_common_shutdown(void)
1973 {
1974    LOGFN;
1975
1976    if (--_ecore_evas_wl_init_count != 0)
1977      return _ecore_evas_wl_init_count;
1978
1979    while (eina_array_count(_ecore_evas_wl_event_hdls))
1980      ecore_event_handler_del(eina_array_pop(_ecore_evas_wl_event_hdls));
1981    eina_array_free(_ecore_evas_wl_event_hdls);
1982    _ecore_evas_wl_event_hdls = NULL;
1983
1984    ecore_event_evas_shutdown();
1985
1986    return _ecore_evas_wl_init_count;
1987 }
1988
1989 static void
1990 _ecore_evas_wl_common_free(Ecore_Evas *ee)
1991 {
1992    Ecore_Evas_Engine_Wl_Data *wdata;
1993    EE_Wl_Device *device;
1994
1995    LOGFN;
1996
1997    if (!ee) return;
1998
1999 #if 0
2000    // TIZEN_ONLY(20171120) : evas sw tbm_buf backend
2001    if (!strcmp(ee->driver, "wayland_shm"))
2002      {
2003        Evas_Engine_Info_Wayland *einfo;
2004        einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
2005        if (einfo && einfo->info.tbm_client)
2006          {
2007            if (_ecore_evas_wl_init_count == 1)
2008              wayland_tbm_client_deinit(einfo->info.tbm_client);
2009          }
2010      }
2011 #endif
2012
2013    wdata = ee->engine.data;
2014    ee_list = eina_list_remove(ee_list, ee);
2015
2016    //TIZEN_ONLY(20171115): support output transform
2017    if (wdata->output_transform_hdl)
2018      ecore_event_handler_del(wdata->output_transform_hdl);
2019    if (wdata->ignore_output_transform_hdl)
2020      ecore_event_handler_del(wdata->ignore_output_transform_hdl);
2021    //
2022
2023    eina_list_free(wdata->regen_objs);
2024    if (wdata->frame) ecore_wl2_window_frame_callback_del(wdata->frame);
2025    wdata->frame = NULL;
2026    ecore_event_handler_del(wdata->sync_handler);
2027    ecore_event_handler_del(wdata->changed_handler);
2028    ecore_event_handler_del(wdata->send_handler);
2029    ecore_event_handler_del(wdata->offer_handler);
2030    ecore_event_handler_del(wdata->dnd_leave_handler);
2031    ecore_event_handler_del(wdata->dnd_enter_handler);
2032    ecore_event_handler_del(wdata->dnd_motion_handler);
2033    ecore_event_handler_del(wdata->dnd_drop_handler);
2034    ecore_event_handler_del(wdata->dnd_end_handler);
2035
2036    if (wdata->win)
2037      {
2038         ecore_wl2_window_close_callback_set(wdata->win, NULL, NULL);
2039         ecore_wl2_window_free(wdata->win);
2040         wdata->win = NULL;
2041      }
2042    ecore_wl2_display_disconnect(wdata->display);
2043
2044    EINA_LIST_FREE(wdata->devices_list, device)
2045       free(device);
2046
2047    free(wdata);
2048
2049    ecore_event_window_unregister(ee->prop.window);
2050
2051    _ecore_evas_wl_common_shutdown();
2052
2053    ecore_wl2_shutdown();
2054 }
2055
2056 static void
2057 _ecore_evas_wl_common_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
2058 {
2059    LOGFN;
2060
2061    if (!ee) return;
2062
2063    //TIZEN_ONLY(20180817) : atomic move + resize of window
2064    unsigned int serial = 0;
2065    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2066    if (!wdata) return;
2067
2068    //TODO: Need ee->func.fn_geometry() ?
2069
2070    if ((ee->x != x) || (ee->y != y))
2071      _ecore_evas_wl_common_move(ee, x, y);
2072
2073    if ((ee->w != w) || (ee->h != h))
2074      _ecore_evas_wl_common_resize(ee, w, h);
2075
2076    if (!strncmp(ee->driver, "wayland_shm", 11))
2077      {
2078 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
2079         Evas_Engine_Info_Wayland *einfo;
2080         einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
2081         if (!einfo) return;
2082         serial = einfo->info.serial;
2083 #endif
2084      }
2085    else if (!strcmp(ee->driver, "wayland_egl"))
2086      {
2087 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
2088         Evas_Engine_Info_Wayland *einfo;
2089         einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
2090         if (!einfo) return;
2091         serial = einfo->info.serial;
2092 #endif
2093      }
2094
2095    ecore_wl2_window_sync_geometry_set(wdata->win, serial, x, y, w, h);
2096    // end of TIZEN_ONLY(20180817)
2097
2098 /*
2099    if ((ee->w != w) || (ee->h != h))
2100      _ecore_evas_wl_common_resize(ee, w, h);
2101 */
2102 }
2103
2104 static void
2105 _ecore_evas_wl_common_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
2106 {
2107    if (!ee) return;
2108    ee->func.fn_resize = func;
2109 }
2110
2111 static void
2112 _ecore_evas_wl_common_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
2113 {
2114    if (!ee) return;
2115    ee->func.fn_move = func;
2116 }
2117
2118 static void
2119 _ecore_evas_wl_common_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
2120 {
2121    if (!ee) return;
2122    ee->func.fn_delete_request = func;
2123 }
2124
2125 static void
2126 _ecore_evas_wl_common_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
2127 {
2128    if (!ee) return;
2129    ee->func.fn_focus_in = func;
2130 }
2131
2132 static void
2133 _ecore_evas_wl_common_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
2134 {
2135    if (!ee) return;
2136    ee->func.fn_focus_out = func;
2137 }
2138
2139 static void
2140 _ecore_evas_wl_common_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
2141 {
2142    if (!ee) return;
2143    ee->func.fn_mouse_in = func;
2144 }
2145
2146 static void
2147 _ecore_evas_wl_common_callback_mouse_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
2148 {
2149    if (!ee) return;
2150    ee->func.fn_mouse_out = func;
2151 }
2152
2153 static void
2154 _ecore_evas_wl_common_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
2155 {
2156    Ecore_Evas_Engine_Wl_Data *wdata;
2157    Ecore_Wl2_Input *input;
2158
2159    LOGFN;
2160
2161    wdata = ee->engine.data;
2162    input = ecore_wl2_display_input_find_by_name(ecore_wl2_window_display_get(wdata->win), "default");
2163    if (input) ecore_wl2_input_pointer_xy_get(input, x, y);
2164 }
2165
2166 // TIZEN_ONLY(20171114): support a pointer warp
2167 static Eina_Bool
2168 _ecore_evas_wl_common_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
2169 {
2170    Ecore_Evas_Engine_Wl_Data *wdata;
2171    Eina_Bool ret;
2172
2173    LOGFN;
2174
2175    if ((!ee) || (!ee->visible)) return EINA_FALSE;
2176    wdata = ee->engine.data;
2177    if(!wdata) return EINA_FALSE;
2178
2179    ret = ecore_wl2_window_pointer_warp(wdata->win, x, y);
2180    return ret;
2181 }
2182 //
2183
2184 static void
2185 _ecore_evas_wl_common_wm_rot_preferred_rotation_set(Ecore_Evas *ee, int rot)
2186 {
2187    if (ee->prop.wm_rot.supported)
2188      {
2189         Ecore_Evas_Engine_Wl_Data *wdata;
2190
2191         wdata = ee->engine.data;
2192         if (!ee->prop.wm_rot.app_set)
2193           {
2194              ecore_wl2_window_rotation_app_set(wdata->win, EINA_TRUE);
2195              ee->prop.wm_rot.app_set = EINA_TRUE;
2196           }
2197
2198         ecore_wl2_window_preferred_rotation_set(wdata->win, rot);
2199         ee->prop.wm_rot.preferred_rot = rot;
2200      }
2201 }
2202
2203 static void
2204 _ecore_evas_wl_common_wm_rot_available_rotations_set(Ecore_Evas *ee, const int *rots, unsigned int count)
2205 {
2206    if (ee->prop.wm_rot.supported)
2207      {
2208         Ecore_Evas_Engine_Wl_Data *wdata;
2209
2210         wdata = ee->engine.data;
2211         if (!ee->prop.wm_rot.app_set)
2212           {
2213              ecore_wl2_window_rotation_app_set(wdata->win, EINA_TRUE);
2214              ee->prop.wm_rot.app_set = EINA_TRUE;
2215           }
2216
2217         if (ee->prop.wm_rot.available_rots)
2218           {
2219              free(ee->prop.wm_rot.available_rots);
2220              ee->prop.wm_rot.available_rots = NULL;
2221           }
2222
2223         ee->prop.wm_rot.count = 0;
2224
2225         if (count > 0)
2226           {
2227              ee->prop.wm_rot.available_rots = calloc(count, sizeof(int));
2228              if (!ee->prop.wm_rot.available_rots) return;
2229
2230              memcpy(ee->prop.wm_rot.available_rots, rots, sizeof(int) * count);
2231           }
2232
2233         ee->prop.wm_rot.count = count;
2234
2235         ecore_wl2_window_available_rotations_set(wdata->win, rots, count);
2236      }
2237 }
2238
2239 static void
2240 _ecore_evas_wl_common_wm_rot_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set)
2241 {
2242    ee->prop.wm_rot.manual_mode.set = set;
2243 }
2244
2245 static void
2246 _ecore_evas_wl_common_pointer_device_xy_get(const Ecore_Evas *ee, const Efl_Input_Device *pointer, Evas_Coord *x, Evas_Coord *y)
2247 {
2248    Ecore_Evas_Engine_Wl_Data *wdata;
2249    Ecore_Wl2_Input *input;
2250    const Eo *seat;
2251
2252    LOGFN;
2253
2254    wdata = ee->engine.data;
2255    seat = evas_device_parent_get(pointer);
2256    EINA_SAFETY_ON_NULL_RETURN(seat);
2257    input = ecore_wl2_display_input_find(ecore_wl2_window_display_get(wdata->win), evas_device_seat_id_get(seat));
2258    EINA_SAFETY_ON_NULL_RETURN(input);
2259    ecore_wl2_input_pointer_xy_get(input, x, y);
2260 }
2261
2262  void
2263 _ecore_evas_wl_common_aux_hints_supported_update(Ecore_Evas *ee)
2264 {
2265    Ecore_Evas_Engine_Wl_Data *wdata;
2266
2267    LOGFN;
2268
2269    if (!ee) return;
2270    wdata = ee->engine.data;
2271    ee->prop.aux_hint.supported_list = ecore_wl2_window_aux_hints_supported_get(wdata->win);
2272 }
2273
2274 static void
2275 _ecore_evas_wl_common_raise(Ecore_Evas *ee)
2276 {
2277    Ecore_Evas_Engine_Wl_Data *wdata;
2278
2279    LOGFN;
2280
2281    if (!ee) return;
2282    wdata = ee->engine.data;
2283    ecore_wl2_window_raise(wdata->win);
2284 }
2285
2286 // TIZEN_ONLY(20150612) : support lower request
2287 void
2288 _ecore_evas_wl_common_lower(Ecore_Evas *ee)
2289 {
2290    Ecore_Evas_Engine_Wl_Data *wdata;
2291
2292    if (!ee) return;
2293    wdata = ee->engine.data;
2294    ecore_wl2_window_lower(wdata->win);
2295 }
2296 //
2297
2298 // TIZEN_ONLY(20150430) : support activate request
2299 void
2300 _ecore_evas_wl_common_activate(Ecore_Evas *ee)
2301 {
2302    Ecore_Evas_Engine_Wl_Data *wdata;
2303
2304    if (!ee) return;
2305    wdata = ee->engine.data;
2306    ecore_evas_show(ee);
2307
2308    if (ee->prop.iconified)
2309      _ecore_evas_wl_common_iconified_set(ee, EINA_FALSE);
2310
2311    ecore_wl2_window_activate(wdata->win);
2312 }
2313 //
2314
2315 // TIZEN_ONLY(20161228) : tizen_rotation v2
2316 void
2317 _ecore_evas_wl_common_wm_rot_cb_angle_changed(Ecore_Wl2_Window *win, int rot, Eina_Bool resize, int w, int h, void *data)
2318 {
2319    Ecore_Evas *ee;
2320    Ecore_Evas_Engine_Wl_Data *wdata;
2321    int minw, minh, maxw, maxh;
2322    int basew, baseh, stepw, steph;
2323
2324    ee = (Ecore_Evas *)data;
2325    EINA_SAFETY_ON_NULL_RETURN(ee);
2326
2327    wdata = ee->engine.data;
2328    EINA_SAFETY_ON_NULL_RETURN(wdata);
2329
2330    EINA_SAFETY_ON_FALSE_RETURN(win == wdata->win);
2331
2332    if ((!ee->prop.wm_rot.supported) || (!ee->prop.wm_rot.app_set))
2333      return;
2334
2335    /* get min, max, base, & step sizes */
2336    ecore_evas_size_min_get(ee, &minw, &minh);
2337    ecore_evas_size_max_get(ee, &maxw, &maxh);
2338    ecore_evas_size_base_get(ee, &basew, &baseh);
2339    ecore_evas_size_step_get(ee, &stepw, &steph);
2340
2341    wdata->wm_rot.request = 1;
2342    wdata->wm_rot.done = 0;
2343
2344    ee->rotation = rot;
2345
2346    /* reset min, max, base, & step sizes */
2347    ecore_evas_size_min_set(ee, minw, minh);
2348    ecore_evas_size_max_set(ee, maxw, maxh);
2349    ecore_evas_size_base_set(ee, basew, baseh);
2350    ecore_evas_size_step_set(ee, stepw, steph);
2351
2352    _ecore_evas_wl_common_resize(ee, w, h);
2353
2354    if (ee->prop.wm_rot.manual_mode.set)
2355      {
2356         ee->prop.wm_rot.manual_mode.wait_for_done = EINA_TRUE;
2357         _ecore_evas_wl_common_wm_rot_manual_rotation_done_timeout_update(ee);
2358      }
2359
2360    if (ee->in_async_render)
2361      {
2362         ee->delayed.output_rotation = wdata->output_rotation;
2363         ee->delayed.rotation = rot;
2364         ee->delayed.rotation_resize = resize;
2365         ee->delayed.rotation_changed = EINA_TRUE;
2366         return;
2367      }
2368
2369    if (ECORE_EVAS_PORTRAIT(ee))
2370      evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2371    else
2372      evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h, ee->req.w);
2373
2374    /* send a mouse_move process
2375     *
2376     * NB: Is This Really Needed ?
2377     * Yes, it's required to update the mouse position, relatively to
2378     * widgets. After a rotation change, e.g., the mouse might not be over
2379     * a button anymore. */
2380    _mouse_move_dispatch(ee);
2381
2382    if (!strcmp(ee->driver, "wayland_shm"))
2383      {
2384 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
2385         Evas_Engine_Info_Wayland *einfo;
2386         einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
2387         if (!einfo) return;
2388
2389         //TIZEN_ONLY(20171115): support output transform
2390         /*
2391         einfo->info.rotation = rot;
2392          */
2393         _ecore_evas_wl_common_engine_info_rotation_set(ee, (Evas_Engine_Info *)einfo);
2394         //
2395
2396         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2397           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2398 #endif
2399      }
2400    else if (!strcmp(ee->driver, "wayland_egl"))
2401      {
2402 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
2403         Evas_Engine_Info_Wayland *einfo;
2404         einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
2405         if (!einfo) return;
2406
2407         //TIZEN_ONLY(20171115): support output transform
2408         /*
2409         einfo->info.rotation = rot;
2410          */
2411         _ecore_evas_wl_common_engine_info_rotation_set(ee, (Evas_Engine_Info *)einfo);
2412         //
2413
2414         /* TIZEN_ONLY(20160728):
2415            wayland spec is not define whether wl_egl_window_create() can use null surface or not.
2416            so current tizen device does not allow to create null surface wayland window.
2417          */
2418         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2419           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2420 #endif
2421      }
2422
2423    _ecore_evas_wl_common_state_update(ee);
2424
2425    wdata->wm_rot.done = 1;
2426 }
2427 //
2428
2429 static void
2430 _ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title)
2431 {
2432    Ecore_Evas_Engine_Wl_Data *wdata;
2433
2434    LOGFN;
2435
2436    if (!ee) return;
2437    if (eina_streq(ee->prop.title, title)) return;
2438    free(ee->prop.title);
2439    ee->prop.title = eina_strdup(title);
2440
2441    if (ee->prop.title)
2442      {
2443         wdata = ee->engine.data;
2444         ecore_wl2_window_title_set(wdata->win, ee->prop.title);
2445      }
2446 }
2447
2448 static void
2449 _ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
2450 {
2451    Ecore_Evas_Engine_Wl_Data *wdata;
2452
2453    LOGFN;
2454
2455    if (!ee) return;
2456    wdata = ee->engine.data;
2457    if (!eina_streq(ee->prop.name, n))
2458      {
2459         if (ee->prop.name) free(ee->prop.name);
2460         ee->prop.name = NULL;
2461         if (n) ee->prop.name = strdup(n);
2462      }
2463    if (!eina_streq(ee->prop.clas, c))
2464      {
2465         if (ee->prop.clas) free(ee->prop.clas);
2466         ee->prop.clas = NULL;
2467         if (c) ee->prop.clas = strdup(c);
2468      }
2469
2470    if (ee->prop.clas)
2471      ecore_wl2_window_class_set(wdata->win, ee->prop.clas);
2472 }
2473
2474 static void
2475 _ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h)
2476 {
2477    Ecore_Evas_Engine_Wl_Data *wdata;
2478    LOGFN;
2479
2480    if (!ee) return;
2481
2482    if (w < 0) w = 0;
2483    if (h < 0) h = 0;
2484    if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
2485    ee->prop.min.w = w;
2486    ee->prop.min.h = h;
2487    wdata = ee->engine.data;
2488    if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel)
2489      {
2490         wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, w, h);
2491         wdata->win->pending.min = 0;
2492      }
2493    if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel)
2494      {
2495         wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, w, h);
2496         wdata->win->pending.min = 0;
2497      }
2498    else
2499      wdata->win->pending.min = 1;
2500    _ecore_evas_wl_common_resize(ee, ee->w, ee->h);
2501 }
2502
2503 static void
2504 _ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h)
2505 {
2506    Ecore_Evas_Engine_Wl_Data *wdata;
2507    LOGFN;
2508
2509    if (!ee) return;
2510    if (w < 0) w = 0;
2511    if (h < 0) h = 0;
2512    if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
2513    ee->prop.max.w = w;
2514    ee->prop.max.h = h;
2515    wdata = ee->engine.data;
2516    if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel)
2517      {
2518         wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, w, h);
2519         wdata->win->pending.max = 0;
2520      }
2521    if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel)
2522      {
2523         wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, w, h);
2524         wdata->win->pending.max = 0;
2525      }
2526    else
2527      wdata->win->pending.max = 1;
2528    _ecore_evas_wl_common_resize(ee, ee->w, ee->h);
2529 }
2530
2531 static void
2532 _ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h)
2533 {
2534    LOGFN;
2535
2536    if (!ee) return;
2537    if (w < 0) w = 0;
2538    if (h < 0) h = 0;
2539    if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
2540    ee->prop.base.w = w;
2541    ee->prop.base.h = h;
2542    _ecore_evas_wl_common_resize(ee, ee->w, ee->h);
2543 }
2544
2545 static void
2546 _ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h)
2547 {
2548    LOGFN;
2549
2550    if (!ee) return;
2551    if (w < 0) w = 0;
2552    if (h < 0) h = 0;
2553    if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
2554    ee->prop.step.w = w;
2555    ee->prop.step.h = h;
2556    _ecore_evas_wl_common_resize(ee, ee->w, ee->h);
2557 }
2558
2559 static void
2560 _ecore_evas_wl_common_aspect_set(Ecore_Evas *ee, double aspect)
2561 {
2562    LOGFN;
2563
2564    if (!ee) return;
2565    if (EINA_FLT_EQ(ee->prop.aspect, aspect)) return;
2566    ee->prop.aspect = aspect;
2567    _ecore_evas_wl_common_resize(ee, ee->w, ee->h);
2568 }
2569
2570 static void
2571 _ecore_evas_wl_common_focus_skip_set(Ecore_Evas *ee, Eina_Bool skip)
2572 {
2573    Ecore_Evas_Engine_Wl_Data *wdata;
2574
2575    wdata = ee->engine.data;
2576    if (!wdata) return;
2577    if (ee->prop.focus_skip == skip) return;
2578    ee->prop.focus_skip = skip;
2579    ecore_wl2_window_focus_skip_set(wdata->win, skip);
2580 }
2581
2582 static void
2583 _ecore_evas_wl_common_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer EINA_UNUSED, int hot_x, int hot_y)
2584 {
2585    Ecore_Evas_Engine_Wl_Data *wdata;
2586    Ecore_Wl2_Input *input;
2587
2588    wdata = ee->engine.data;
2589    if (obj == _ecore_evas_default_cursor_image_get(ee)) return;
2590    input = ecore_wl2_display_input_find_by_name(ecore_wl2_window_display_get(wdata->win), "default");
2591    if (input) ecore_wl2_input_pointer_set(input, NULL, hot_x, hot_y);
2592 }
2593
2594 // TIZEN_ONLY(20160429)
2595 static void
2596 _ecore_evas_wl_layer_update(Ecore_Evas *ee)
2597 {
2598    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2599
2600    if (ee->prop.layer < 3)
2601      {
2602         if ((wdata->state.above) || (!wdata->state.below))
2603           {
2604              wdata->state.above = 0;
2605              wdata->state.below = 1;
2606              ecore_wl2_window_stack_mode_set(wdata->win, ECORE_WL2_WINDOW_STACK_BELOW);
2607           }
2608      }
2609    else if (ee->prop.layer > 5)
2610      {
2611         if ((!wdata->state.above) || (wdata->state.below))
2612           {
2613              wdata->state.above = 1;
2614              wdata->state.below = 0;
2615              ecore_wl2_window_stack_mode_set(wdata->win, ECORE_WL2_WINDOW_STACK_ABOVE);
2616           }
2617      }
2618    else
2619      {
2620         if ((wdata->state.above) || (wdata->state.below))
2621           {
2622              wdata->state.above = 0;
2623              wdata->state.below = 0;
2624              ecore_wl2_window_stack_mode_set(wdata->win, ECORE_WL2_WINDOW_STACK_NONE);
2625           }
2626      }
2627 }
2628 //
2629
2630 static void
2631 _ecore_evas_wl_common_layer_set(Ecore_Evas *ee, int layer)
2632 {
2633    LOGFN;
2634
2635    if (!ee) return;
2636    if (ee->prop.layer == layer) return;
2637    if (layer < 1) layer = 1;
2638    else if (layer > 255) layer = 255;
2639    ee->prop.layer = layer;
2640    // TIZEN_ONLY(20160429)
2641    _ecore_evas_wl_layer_update(ee);
2642    //
2643    _ecore_evas_wl_common_state_update(ee);
2644 }
2645
2646 static void
2647 _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, Eina_Bool on)
2648 {
2649    Ecore_Evas_Engine_Wl_Data *wdata;
2650
2651    LOGFN;
2652
2653    if (!ee) return;
2654    ee->prop.iconified = on;
2655
2656    wdata = ee->engine.data;
2657    ecore_wl2_window_iconified_set(wdata->win, on);
2658
2659    // TIZEN_ONLY(20200311) : uniconify update rotate
2660    if (!ee->prop.iconified)
2661       _ecore_evas_wl_common_rotate_update(ee);
2662    //
2663
2664 // TIZEN_ONLY
2665    _ecore_evas_wl_common_state_update(ee);
2666
2667     /* 20160617 : uniconify force render */
2668    _ecore_evas_wl_common_damage_add(ee);
2669 //
2670 }
2671
2672 static void
2673 _ecore_evas_wl_common_borderless_set(Ecore_Evas *ee, Eina_Bool on)
2674 {
2675    LOGFN;
2676
2677    if (!ee) return;
2678    if (ee->prop.borderless == on) return;
2679    ee->prop.borderless = on;
2680
2681    _ecore_evas_wl_common_state_update(ee);
2682 }
2683
2684 static void
2685 _ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, Eina_Bool on)
2686 {
2687    Ecore_Evas_Engine_Wl_Data *wdata;
2688
2689    LOGFN;
2690
2691    if (!ee) return;
2692    if (ee->prop.maximized == on) return;
2693
2694    wdata = ee->engine.data;
2695    ecore_wl2_window_maximized_set(wdata->win, on);
2696 }
2697
2698 static void
2699 _ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
2700 {
2701    Ecore_Evas_Engine_Wl_Data *wdata;
2702
2703    LOGFN;
2704
2705    if (!ee) return;
2706    if (ee->prop.fullscreen == on) return;
2707
2708    wdata = ee->engine.data;
2709    ecore_wl2_window_fullscreen_set(wdata->win, on);
2710 }
2711
2712 static void
2713 _ecore_evas_wl_common_ignore_events_set(Ecore_Evas *ee, int ignore)
2714 {
2715    LOGFN;
2716
2717    if (!ee) return;
2718    ee->ignore_events = ignore;
2719    /* NB: Hmmm, may need to pass this to ecore_wl_window in the future */
2720 }
2721
2722 static void
2723 _ecore_evas_wl_common_render_flush_pre(void *data, Evas *evas, void *event EINA_UNUSED)
2724 {
2725    Ecore_Evas *ee = data;
2726    Evas_Engine_Info_Wayland *einfo;
2727    Ecore_Evas_Engine_Wl_Data *wdata;
2728    int fx, fy;
2729
2730    einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(evas);
2731    if (!einfo) return;
2732
2733    wdata = ee->engine.data;
2734    if (!wdata) return;
2735
2736    if (wdata->win->pending.configure) return;
2737
2738    //TIZEN_ONLY(20180514): support to rotate window which does not have shell surface
2739    /*
2740    if (!ecore_wl2_window_shell_surface_exists(wdata->win)) return;
2741    */
2742    //
2743
2744    ecore_wl2_window_update_begin(wdata->win);
2745
2746 // TIZEN_ONLY(20160419) : to handle wm_rotation
2747    if ((wdata->wm_rot.done) &&
2748        (!ee->prop.wm_rot.manual_mode.set))
2749      {
2750         DBG("PendingRotation: client sends rotation change done to server");
2751         wdata->wm_rot.request = 0;
2752         wdata->wm_rot.done = 0;
2753         ecore_wl2_window_rotation_change_done_send(wdata->win, ee->rotation, ee->w, ee->h);
2754      }
2755 //
2756
2757    /* Surviving bits of WWW - track interesting state we might want
2758     * to pass to clients to do client side effects
2759     */
2760    ecore_wl2_window_geometry_get(wdata->win,
2761                                  &einfo->window.x,
2762                                  &einfo->window.y,
2763                                  &einfo->window.w,
2764                                  &einfo->window.h);
2765    if (einfo->resizing)
2766      {
2767         einfo->x_rel = 0;
2768         einfo->y_rel = 0;
2769      }
2770    else
2771      {
2772         einfo->x_rel = wdata->x_rel;
2773         einfo->y_rel = wdata->y_rel;
2774      }
2775    einfo->timestamp = wdata->timestamp;
2776    evas_pointer_canvas_xy_get(evas, &einfo->x_cursor, &einfo->y_cursor);
2777    evas_output_framespace_get(evas, &fx, &fy, NULL, NULL);
2778    einfo->x_cursor -= fx;
2779    einfo->y_cursor -= fy;
2780    wdata->x_rel = wdata->y_rel = 0;
2781    einfo->resizing = ecore_wl2_window_resizing_get(wdata->win);
2782    einfo->dragging = wdata->dragging;
2783    einfo->drag_start = EINA_FALSE;
2784    einfo->drag_stop = EINA_FALSE;
2785    if (einfo->drag_ack && !einfo->dragging) einfo->drag_stop = EINA_TRUE;
2786    if (einfo->dragging && !einfo->drag_ack) einfo->drag_start = EINA_TRUE;
2787    einfo->drag_ack = wdata->dragging;
2788 }
2789
2790 static void
2791 _ecore_evas_wayland_alpha_do(Ecore_Evas *ee, int alpha)
2792 {
2793    Evas_Engine_Info_Wayland *einfo;
2794    Ecore_Evas_Engine_Wl_Data *wdata;
2795    int fw, fh;
2796
2797    LOGFN;
2798
2799    if (!ee) return;
2800    if (ee->alpha == alpha) return;
2801
2802    /* alpha used for transparent as well.
2803                 ecore_evas_transparent_get() must be valid. */
2804    ee->transparent = ee->alpha = alpha;
2805
2806    wdata = ee->engine.data;
2807    if (!wdata->sync_done) return;
2808
2809    if (wdata->win) ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
2810
2811    _ecore_evas_wl_common_wm_rotation_protocol_set(ee);
2812
2813    evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
2814
2815    if ((einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas)))
2816      {
2817         einfo->info.destination_alpha = EINA_TRUE;
2818         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2819           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2820         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
2821      }
2822 }
2823
2824 static void
2825 _ecore_evas_wl_common_render_updates(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED)
2826 {
2827    Ecore_Evas *ee = data;
2828
2829    if (ee->delayed.alpha_changed)
2830      {
2831         _ecore_evas_wayland_alpha_do(ee, ee->delayed.alpha);
2832         ee->delayed.alpha_changed = EINA_FALSE;
2833      }
2834    if (ee->delayed.rotation_changed)
2835      {
2836         //TIZEN_ONLY(20171115): support output transform
2837         /*
2838         _rotation_do(ee, ee->delayed.rotation, ee->delayed.rotation_resize);
2839          */
2840         _rotation_do(ee, ee->delayed.rotation, ee->delayed.output_rotation, ee->delayed.rotation_resize);
2841         ee->delayed.rotation_changed = EINA_FALSE;
2842      }
2843 }
2844
2845 static Eina_Bool
2846 _ecore_evas_wl_common_prepare(Ecore_Evas *ee)
2847 {
2848    Ecore_Evas_Engine_Wl_Data *wdata;
2849
2850    if (!(wdata = ee->engine.data)) return EINA_FALSE;
2851    if (!wdata->sync_done) return EINA_FALSE;
2852
2853    if (wdata->win->pending.configure) return EINA_FALSE;
2854
2855    return EINA_TRUE;
2856 }
2857
2858 static void
2859 _ecore_evas_wl_common_withdrawn_set(Ecore_Evas *ee, Eina_Bool on)
2860 {
2861    LOGFN;
2862
2863    if (ee->prop.withdrawn == on) return;
2864
2865    ee->prop.withdrawn = on;
2866
2867    if (on)
2868      ecore_evas_hide(ee);
2869    else
2870      ecore_evas_show(ee);
2871
2872    _ecore_evas_wl_common_state_update(ee);
2873 }
2874
2875 static void
2876 _ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
2877 {
2878    Ecore_Evas_Engine_Wl_Data *wdata;
2879
2880    LOGFN;
2881
2882    if (x) *x = 0;
2883    if (y) *y = 0;
2884
2885    wdata = ee->engine.data;
2886    ecore_wl2_display_screen_size_get(wdata->display, w, h);
2887 }
2888
2889 static void
2890 _ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi)
2891 {
2892    Ecore_Wl2_Window *win;
2893    Ecore_Wl2_Output *output;
2894    int dpi = 0;
2895
2896    LOGFN;
2897
2898    if (!ee) return;
2899    if (xdpi) *xdpi = 0;
2900    if (ydpi) *ydpi = 0;
2901
2902    /* FIXME: Ideally this needs to get the DPI from a specific screen */
2903
2904    win = ecore_evas_wayland2_window_get(ee);
2905    output = ecore_wl2_window_output_find(win);
2906    dpi = ecore_wl2_output_dpi_get(output);
2907
2908    if (xdpi) *xdpi = dpi;
2909    if (ydpi) *ydpi = dpi;
2910 }
2911
2912 static void
2913 _ecore_evas_wayland_resize(Ecore_Evas *ee, int location)
2914 {
2915    Ecore_Evas_Engine_Wl_Data *wdata;
2916
2917    LOGFN;
2918
2919    if (!ee) return;
2920    wdata = ee->engine.data;
2921    if (wdata->win)
2922      ecore_wl2_window_resize(wdata->win, NULL, location);
2923 }
2924
2925 static void
2926 _ecore_evas_wayland_move(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED)
2927 {
2928    Ecore_Evas_Engine_Wl_Data *wdata;
2929
2930    LOGFN;
2931
2932    if (!ee) return;
2933    wdata = ee->engine.data;
2934    if (wdata->win) ecore_wl2_window_move(wdata->win, NULL);
2935 }
2936
2937 static void
2938 _ecore_evas_wayland_type_set(Ecore_Evas *ee, int type)
2939 {
2940    Ecore_Evas_Engine_Wl_Data *wdata;
2941
2942    if (!ee) return;
2943    wdata = ee->engine.data;
2944
2945    ecore_wl2_window_type_set(wdata->win, type);
2946 }
2947
2948 static Ecore_Wl2_Window *
2949 _ecore_evas_wayland_window_get(const Ecore_Evas *ee)
2950 {
2951    Ecore_Evas_Engine_Wl_Data *wdata;
2952
2953    if (!(!strncmp(ee->driver, "wayland", 7)))
2954      return NULL;
2955
2956    wdata = ee->engine.data;
2957    return wdata->win;
2958 }
2959
2960 /* static void */
2961 /* _ecore_evas_wayland_pointer_set(Ecore_Evas *ee EINA_UNUSED, int hot_x EINA_UNUSED, int hot_y EINA_UNUSED) */
2962 /* { */
2963
2964 /* } */
2965
2966 static void
2967 _ecore_evas_wayland_aux_hint_add(Ecore_Evas *ee, int id, const char *hint, const char *val)
2968 {
2969    Ecore_Evas_Engine_Wl_Data *wdata;
2970
2971    if (!ee) return;
2972    wdata = ee->engine.data;
2973    ecore_wl2_window_aux_hint_add(wdata->win, id, hint, val);
2974 }
2975
2976 static void
2977 _ecore_evas_wayland_aux_hint_change(Ecore_Evas *ee, int id, const char *val)
2978 {
2979    Ecore_Evas_Engine_Wl_Data *wdata;
2980
2981    if (!ee) return;
2982    wdata = ee->engine.data;
2983    ecore_wl2_window_aux_hint_change(wdata->win, id, val);
2984 }
2985
2986 static void
2987 _ecore_evas_wayland_aux_hint_del(Ecore_Evas *ee, int id)
2988 {
2989    Ecore_Evas_Engine_Wl_Data *wdata;
2990
2991    if (!ee) return;
2992    wdata = ee->engine.data;
2993    ecore_wl2_window_aux_hint_del(wdata->win, id);
2994 }
2995
2996 // TIZEN_ONLY(20160201) : support to handle input rectangle
2997 static void
2998 _ecore_evas_wayland_input_rect_set(Ecore_Evas *ee, Eina_Rectangle *input_rect)
2999 {
3000    Ecore_Evas_Engine_Wl_Data *wdata;
3001
3002    if (!ee) return;
3003    wdata = ee->engine.data;
3004    ecore_wl2_window_input_rect_set(wdata->win, input_rect);
3005 }
3006
3007 static void
3008 _ecore_evas_wayland_input_rect_add(Ecore_Evas *ee, Eina_Rectangle *input_rect)
3009 {
3010    Ecore_Evas_Engine_Wl_Data *wdata;
3011
3012    if (!ee) return;
3013    wdata = ee->engine.data;
3014    ecore_wl2_window_input_rect_add(wdata->win, input_rect);
3015 }
3016
3017 static void
3018 _ecore_evas_wayland_input_rect_subtract(Ecore_Evas *ee, Eina_Rectangle *input_rect)
3019 {
3020    Ecore_Evas_Engine_Wl_Data *wdata;
3021
3022    if (!ee) return;
3023    wdata = ee->engine.data;
3024    ecore_wl2_window_input_rect_subtract(wdata->win, input_rect);
3025 }
3026 //
3027
3028 static Ecore_Evas_Interface_Wayland *
3029 _ecore_evas_wl_interface_new(void)
3030 {
3031    Ecore_Evas_Interface_Wayland *iface;
3032
3033    iface = calloc(1, sizeof(Ecore_Evas_Interface_Wayland));
3034    if (!iface) return NULL;
3035
3036    iface->base.name = interface_wl_name;
3037    iface->base.version = interface_wl_version;
3038
3039    iface->resize = _ecore_evas_wayland_resize;
3040    iface->move = _ecore_evas_wayland_move;
3041    /* iface->pointer_set = _ecore_evas_wayland_pointer_set; */
3042    iface->type_set = _ecore_evas_wayland_type_set;
3043    iface->window2_get = _ecore_evas_wayland_window_get;
3044    iface->aux_hint_add = _ecore_evas_wayland_aux_hint_add;
3045    iface->aux_hint_change = _ecore_evas_wayland_aux_hint_change;
3046    iface->aux_hint_del = _ecore_evas_wayland_aux_hint_del;
3047    // TIZEN_ONLY(20160201) : support to handle input rectangle
3048    iface->input_rect_set = _ecore_evas_wayland_input_rect_set;
3049    iface->input_rect_add = _ecore_evas_wayland_input_rect_add;
3050    iface->input_rect_subtract = _ecore_evas_wayland_input_rect_subtract;
3051    //
3052
3053    return iface;
3054 }
3055
3056 static void
3057 _ecore_evas_wl_common_show(Ecore_Evas *ee)
3058 {
3059    Evas_Engine_Info_Wayland *einfo;
3060    Ecore_Evas_Engine_Wl_Data *wdata;
3061
3062    LOGFN;
3063
3064    if ((!ee) || (ee->visible)) return;
3065
3066    wdata = ee->engine.data;
3067    if (!wdata->sync_done)
3068      {
3069         wdata->defer_show = EINA_TRUE;
3070         return;
3071      }
3072    ee->visible = 1;
3073
3074    if (wdata->win)
3075      {
3076         int w = ee->w, h = ee->h;
3077         int fw, fh;
3078
3079         if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel && wdata->win->pending.min)
3080           {
3081              wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, ee->prop.min.w, ee->prop.min.h);
3082              wdata->win->pending.min = 0;
3083           }
3084         if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel && wdata->win->pending.max)
3085           {
3086              wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, ee->prop.max.w, ee->prop.max.h);
3087              wdata->win->pending.max = 0;
3088           }
3089         if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel && wdata->win->pending.min)
3090           {
3091              wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, ee->prop.min.w, ee->prop.min.h);
3092              wdata->win->pending.min = 0;
3093           }
3094         if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel && wdata->win->pending.max)
3095           {
3096              wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, ee->prop.max.w, ee->prop.max.h);
3097              wdata->win->pending.max = 0;
3098           }
3099
3100         evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
3101 // TIZEN_ONLY(20180424) : handle window position
3102 /*
3103         ecore_wl2_window_geometry_set(wdata->win, 0, 0, ee->w, ee->h);
3104 */
3105         if (!ee->prop.fullscreen) {
3106           if (ECORE_EVAS_PORTRAIT(ee))
3107             {
3108                w += fw;
3109                h += fh;
3110             }
3111           else
3112             {
3113                w += fh;
3114                h += fw;
3115             }
3116         }
3117
3118         ecore_wl2_window_geometry_set(wdata->win, ee->x, ee->y, w, h);
3119 //
3120         ecore_wl2_window_show(wdata->win);
3121         ecore_wl2_window_alpha_set(wdata->win, ee->alpha);
3122
3123         einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
3124         if (einfo)
3125           {
3126              einfo->info.wl2_win = wdata->win;
3127              einfo->info.hidden = wdata->win->pending.configure; //EINA_FALSE;
3128              einfo->www_avail = !!wdata->win->www_surface;
3129              if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3130                ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
3131              if (ECORE_EVAS_PORTRAIT(ee))
3132                evas_damage_rectangle_add(ee->evas, 0, 0, ee->w + fw, ee->h + fh);
3133              else
3134                evas_damage_rectangle_add(ee->evas, 0, 0, ee->h + fh, ee->w + fw);
3135           }
3136      }
3137
3138    ee->prop.withdrawn = EINA_FALSE;
3139    if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
3140
3141    ee->should_be_visible = 1;
3142    if (ee->func.fn_show) ee->func.fn_show(ee);
3143 }
3144
3145 static void
3146 _ecore_evas_wl_common_hide(Ecore_Evas *ee)
3147 {
3148    Evas_Engine_Info_Wayland *einfo;
3149    Ecore_Evas_Engine_Wl_Data *wdata;
3150
3151    LOGFN;
3152
3153    if ((!ee) || (!ee->visible)) return;
3154    wdata = ee->engine.data;
3155
3156    evas_sync(ee->evas);
3157
3158    einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
3159    if (einfo)
3160      {
3161         einfo->info.hidden = EINA_TRUE;
3162         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3163           {
3164              ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
3165           }
3166      }
3167
3168    if (wdata->win)
3169      ecore_wl2_window_hide(wdata->win);
3170
3171    if (ee->prop.override)
3172      {
3173         ee->prop.withdrawn = EINA_TRUE;
3174         if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
3175      }
3176
3177    if (!ee->visible) return;
3178    ee->visible = 0;
3179    ee->should_be_visible = 0;
3180
3181    if (ee->func.fn_hide) ee->func.fn_hide(ee);
3182 }
3183
3184 static void
3185 _ecore_evas_wl_common_alpha_set(Ecore_Evas *ee, int alpha)
3186 {
3187    if (ee->in_async_render)
3188      {
3189         ee->delayed.alpha = alpha;
3190         ee->delayed.alpha_changed = EINA_TRUE;
3191         return;
3192      }
3193
3194    _ecore_evas_wayland_alpha_do(ee, alpha);
3195 }
3196
3197 // TIZEN_ONLY(20170212): pend rotation until app set rotation
3198 void
3199 _ecore_evas_wl_common_app_rotation_set(Ecore_Evas *ee, int rotation, int resize)
3200 {
3201    Ecore_Evas_Engine_Wl_Data *wdata;
3202
3203    DBG("PendingRotation: ecore_evas_wl app rotation_set rot=%d", rotation);
3204
3205    ecore_evas_data_set(ee, "pending_rotation", NULL);
3206
3207    if (!resize) return;
3208
3209    wdata = ee->engine.data;
3210    if (!wdata) return;
3211
3212    if ((!ee->prop.wm_rot.supported) || (!ee->prop.wm_rot.app_set))
3213      return;
3214
3215    DBG("RotationPending: ecore_evas_wl do rotation %d", rotation);
3216    //wdata->wm_rot.request = 1;
3217    //wdata->wm_rot.done = 0;
3218    ee->prop.wm_rot.pending_mode.app_angle = rotation;
3219
3220    if (!strcmp(ee->driver, "wayland_shm"))
3221      {
3222 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
3223         _ecore_evas_wl_common_rotation_set(ee, rotation, 1);
3224 #endif
3225      }
3226    else if (!strcmp(ee->driver, "wayland_egl"))
3227      {
3228 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
3229         _ecore_evas_wl_common_rotation_set(ee, rotation, 1);
3230 #endif
3231      }
3232
3233    //wdata->wm_rot.done = 1;
3234 }
3235 //
3236
3237 static void
3238 _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize)
3239 {
3240    LOGFN;
3241
3242    if (ee->rotation == rotation) return;
3243
3244 // TIZEN_ONLY(20170212): pend rotation until app set rotation
3245    if (ecore_evas_data_get(ee, "pending_rotation"))
3246      {
3247         return _ecore_evas_wl_common_app_rotation_set(ee, rotation, resize);
3248      }
3249 //
3250    if (ee->in_async_render)
3251      {
3252         //TIZEN_ONLY(20191004): support output transform
3253         Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3254         ee->delayed.output_rotation = wdata->output_rotation;
3255         //
3256         ee->delayed.rotation = rotation;
3257         ee->delayed.rotation_resize = resize;
3258         ee->delayed.rotation_changed = EINA_TRUE;
3259      }
3260    else
3261      //TIZEN_ONLY(20171115): support output transform
3262      /*
3263      _rotation_do(ee, rotation, resize);
3264       */
3265      {
3266         Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3267         _rotation_do(ee, rotation, wdata->output_rotation, resize);
3268      }
3269 }
3270
3271 //TIZEN_ONLY(20171115): support output transform
3272 static Eina_Bool
3273 _ecore_evas_wl_common_cb_output_transform(void *data, int type EINA_UNUSED, void *event)
3274 {
3275    Ecore_Evas *ee = data;
3276    Ecore_Wl2_Event_Output_Transform *ev = event;
3277    Ecore_Evas_Engine_Wl_Data *wdata;
3278    Ecore_Wl2_Output *output;
3279    Eina_Bool changed;
3280
3281    if (!ee) return ECORE_CALLBACK_PASS_ON;
3282    if (!(wdata = ee->engine.data)) return ECORE_CALLBACK_PASS_ON;
3283    if (ecore_wl2_window_iconified_get(wdata->win)) return ECORE_CALLBACK_PASS_ON;
3284
3285    output = ecore_wl2_window_output_find(wdata->win);
3286    if (output != ev->output) return ECORE_CALLBACK_PASS_ON;
3287
3288    changed = _ecore_evas_wl_common_rotate_update(ee);
3289
3290    if (!ee->manual_render && changed)
3291      evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
3292
3293    return ECORE_CALLBACK_PASS_ON;
3294 }
3295
3296 static Eina_Bool
3297 _ecore_evas_wl_common_cb_ignore_output_transform(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
3298 {
3299    Ecore_Evas *ee = data;
3300    Eina_Bool changed;
3301
3302    if (!ee) return ECORE_CALLBACK_PASS_ON;
3303
3304    changed = _ecore_evas_wl_common_rotate_update(ee);
3305
3306    if (!ee->manual_render && changed)
3307      evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
3308
3309    return ECORE_CALLBACK_PASS_ON;
3310 }
3311
3312 static void
3313 _ecore_evas_wl_common_output_transform_register(Ecore_Evas *ee)
3314 {
3315    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3316    Ecore_Wl2_Output *output;
3317
3318    if (wdata->output_transform_hdl) return;
3319
3320    output = ecore_wl2_window_output_find(wdata->win);
3321    wdata->output_rotation = ecore_wl2_output_transform_get(output) * 90;
3322
3323    wdata->output_transform_hdl =
3324      ecore_event_handler_add(ECORE_WL2_EVENT_OUTPUT_TRANSFORM,
3325                              _ecore_evas_wl_common_cb_output_transform, ee);
3326    wdata->ignore_output_transform_hdl =
3327      ecore_event_handler_add(ECORE_WL2_EVENT_IGNORE_OUTPUT_TRANSFORM,
3328                              _ecore_evas_wl_common_cb_ignore_output_transform, ee);
3329 }
3330 //
3331
3332 //TIZEN_ONLY(20171218) : Add to free evas engine rsc before free evas
3333 static void
3334 _ecore_evas_wl_common_evas_engine_rsc_free(Ecore_Evas *ee)
3335 {
3336     if (!ee) return;
3337
3338     // evas sw tbm_buf backend
3339     if (!strcmp(ee->driver, "wayland_shm"))
3340       {
3341         Evas_Engine_Info_Wayland *einfo;
3342         einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
3343         if (einfo && einfo->info.tbm_client)
3344           {
3345             if (_ecore_evas_wl_init_count == 1)
3346               {
3347                  wayland_tbm_client_deinit(einfo->info.tbm_client);
3348                  einfo->info.tbm_client = NULL;
3349               }
3350           }
3351       }
3352 }
3353
3354 static Eina_Bool
3355 _ee_cb_sync_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
3356 {
3357    Ecore_Evas *ee;
3358    Evas_Engine_Info_Wayland *einfo;
3359    Ecore_Evas_Engine_Wl_Data *wdata;
3360
3361    ee = data;
3362    wdata = ee->engine.data;
3363    if (wdata->sync_done) return ECORE_CALLBACK_PASS_ON;
3364    wdata->sync_done = EINA_TRUE;
3365
3366    if ((einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas)))
3367      {
3368         einfo->info.destination_alpha = EINA_TRUE;
3369         einfo->info.rotation = ee->rotation;
3370         einfo->info.wl2_win = wdata->win;
3371
3372         if (wdata->reset_pending)
3373           {
3374              ee->draw_block = EINA_FALSE;
3375           }
3376         if (evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3377           {
3378              if (wdata->reset_pending && !strcmp(ee->driver, "wayland_egl"))
3379                _evas_canvas_image_data_regenerate(wdata->regen_objs);
3380              wdata->regen_objs = NULL;
3381           }
3382         else
3383           ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
3384         wdata->reset_pending = 0;
3385      }
3386    else
3387      {
3388         ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
3389      }
3390
3391    if (wdata->defer_show)
3392      {
3393         wdata->defer_show = EINA_FALSE;
3394         _ecore_evas_wl_common_show(ee);
3395      }
3396
3397    return ECORE_CALLBACK_PASS_ON;
3398 }
3399
3400 static Eina_Bool
3401 _ecore_wl2_devices_setup(Ecore_Evas *ee, Ecore_Wl2_Display *display)
3402 {
3403    Eina_Bool r = EINA_TRUE;
3404    Ecore_Wl2_Input *input;
3405    Eina_Iterator *itr = ecore_wl2_display_inputs_get(display);
3406
3407    EINA_SAFETY_ON_NULL_RETURN_VAL(itr, EINA_FALSE);
3408    EINA_ITERATOR_FOREACH(itr, input)
3409      {
3410         EE_Wl_Device *device;
3411         Ecore_Wl2_Seat_Capabilities cap;
3412         unsigned int id;
3413         Eina_Stringshare *name;
3414
3415         id = ecore_wl2_input_seat_id_get(input);
3416         cap = ecore_wl2_input_seat_capabilities_get(input);
3417         name = ecore_wl2_input_name_get(input);
3418         device = _ecore_evas_wl_common_seat_add(ee, id, name);
3419
3420         if (!device)
3421           {
3422              r = EINA_FALSE;
3423              break;
3424           }
3425
3426         if (cap & ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD)
3427           {
3428              device->keyboard =
3429                evas_device_add_full(ee->evas, "Keyboard",
3430                                     "A wayland keyboard device",
3431                                     device->seat, NULL,
3432                                     EVAS_DEVICE_CLASS_KEYBOARD,
3433                                     EVAS_DEVICE_SUBCLASS_NONE);
3434
3435              _ecore_evas_wl_common_device_event_add
3436                (ECORE_WL2_EVENT_DEVICE_ADDED, ECORE_WL2_DEVICE_TYPE_KEYBOARD,
3437                    id, device->keyboard, ee);
3438           }
3439         if (cap & ECORE_WL2_SEAT_CAPABILITIES_POINTER)
3440           {
3441              device->pointer =
3442                evas_device_add_full(ee->evas, "Mouse",
3443                                     "A wayland pointer device",
3444                                     device->seat, NULL,
3445                                     EVAS_DEVICE_CLASS_MOUSE,
3446                                     EVAS_DEVICE_SUBCLASS_NONE);
3447
3448              _ecore_evas_wl_common_device_event_add
3449                (ECORE_WL2_EVENT_DEVICE_ADDED, ECORE_WL2_DEVICE_TYPE_POINTER,
3450                    id, device->pointer, ee);
3451           }
3452         if (cap & ECORE_WL2_SEAT_CAPABILITIES_TOUCH)
3453           {
3454              device->touch =
3455                evas_device_add_full(ee->evas, "Touch",
3456                                     "A wayland touch device",
3457                                     device->seat, NULL,
3458                                     EVAS_DEVICE_CLASS_TOUCH,
3459                                     EVAS_DEVICE_SUBCLASS_NONE);
3460
3461              _ecore_evas_wl_common_device_event_add
3462                (ECORE_WL2_EVENT_DEVICE_ADDED, ECORE_WL2_DEVICE_TYPE_TOUCH,
3463                    id, device->touch, ee);
3464           }
3465      }
3466    eina_iterator_free(itr);
3467    return r;
3468 }
3469
3470 static void
3471 _reeval_seat(unsigned int *seat, Ecore_Evas *ee)
3472 {
3473    if (*seat == 0)
3474      {
3475         *seat =
3476           evas_device_seat_id_get(evas_default_device_get
3477                                   (ee->evas, EVAS_DEVICE_CLASS_SEAT));
3478      }
3479 }
3480
3481 static inline void
3482 _clear_selection(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection)
3483 {
3484    Ecore_Evas_Engine_Wl_Data *edata = ee->engine.data;
3485    Ecore_Evas_Selection_Callbacks *cbs = &edata->selection_data[selection].callbacks;
3486
3487    EINA_SAFETY_ON_FALSE_RETURN(cbs->cancel);
3488
3489    cbs->cancel(ee, seat, selection);
3490    eina_array_free(cbs->available_types);
3491    memset(cbs, 0, sizeof(Ecore_Evas_Selection_Callbacks));
3492 }
3493
3494 static void
3495 _store_selection_cbs(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel)
3496 {
3497    Ecore_Evas_Wl_Selection_Data *sdata;
3498    Ecore_Evas_Engine_Wl_Data *edata;
3499    Ecore_Evas_Selection_Callbacks *cbs;
3500
3501    edata = ee->engine.data;
3502    sdata = &edata->selection_data[selection];
3503    cbs = &sdata->callbacks;
3504
3505    if (cbs->cancel)
3506      {
3507         _clear_selection(ee, seat, selection);
3508      }
3509
3510    cbs->delivery = delivery;
3511    cbs->cancel = cancel;
3512    cbs->available_types = available_types;
3513 }
3514
3515 static inline Ecore_Wl2_Input*
3516 _fetch_input(Ecore_Evas *ee, unsigned int seat)
3517 {
3518    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3519    return ecore_wl2_display_input_find(ecore_wl2_window_display_get(wdata->win), seat);
3520 }
3521
3522 static Eina_Bool
3523 _ecore_evas_wl_selection_claim(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel)
3524 {
3525    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3526    Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
3527    char *tmp_array[eina_array_count(available_types) + 1];
3528
3529    if (selection == ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER)
3530      {
3531         _store_selection_cbs(ee, seat, selection, available_types, delivery, cancel);
3532         return EINA_TRUE;
3533      }
3534
3535    _reeval_seat(&seat, ee);
3536    _store_selection_cbs(ee, seat, selection, available_types, delivery, cancel);
3537
3538    for (unsigned int i = 0; i < eina_array_count(available_types); ++i)
3539      {
3540         tmp_array[i] = eina_array_data_get(available_types, i);
3541      }
3542    tmp_array[eina_array_count(available_types)] = NULL;
3543
3544    data->sent_serial = ecore_wl2_dnd_selection_set(_fetch_input(ee, seat), (const char**)tmp_array);
3545    return EINA_TRUE;
3546 }
3547
3548
3549 static Eina_Future*
3550 _ecore_evas_wl_selection_request(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_types)
3551 {
3552    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3553    Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
3554    Ecore_Wl2_Input *input;
3555    Ecore_Wl2_Offer *offer = NULL;
3556    Eina_Future *future;
3557
3558    _reeval_seat(&seat, ee);
3559    input = _fetch_input(ee, seat);
3560
3561    if (data->delivery)
3562      {
3563         eina_promise_reject(data->delivery, ecore_evas_request_replaced);
3564         data->delivery = NULL;
3565      }
3566    data->delivery = efl_loop_promise_new(efl_main_loop_get());
3567    future = eina_future_new(data->delivery);
3568
3569    if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
3570      {
3571         offer = data->offer = wdata->external_offer;
3572      }
3573    else if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
3574      {
3575         offer = data->offer = ecore_wl2_dnd_selection_get(input);
3576      }
3577
3578    if (!offer)
3579      {
3580         eina_promise_reject(data->delivery, ecore_evas_no_selection);
3581         data->delivery = NULL;
3582      }
3583    else
3584      {
3585         Eina_Array *available_types = ecore_wl2_offer_mimes_get(offer);
3586         char *selected_type = NULL;
3587
3588         for (unsigned int i = 0; i < eina_array_count(available_types) && !selected_type; ++i)
3589           {
3590              char *available_type = eina_array_data_get(available_types, i);
3591              for (unsigned int j = 0; j < eina_array_count(acceptable_types) && !selected_type; ++j)
3592                {
3593                   char *acceptable_type = eina_array_data_get(acceptable_types, j);
3594                   if (eina_streq(acceptable_type, available_type))
3595                     {
3596                        selected_type = available_type;
3597                        data->later_convert = NULL;
3598                        break;
3599                     }
3600
3601                   const char *convert_available_type;
3602                   Eina_Iterator *convertions = eina_content_converter_possible_conversions(available_type);
3603                   EINA_ITERATOR_FOREACH(convertions, convert_available_type)
3604                     {
3605                        if (eina_streq(convert_available_type, acceptable_type))
3606                          {
3607                             selected_type = available_type;
3608                             data->later_convert = acceptable_type;
3609                          }
3610                     }
3611                   eina_iterator_free(convertions);
3612                }
3613
3614           }
3615         if (selected_type)
3616           {
3617              ecore_wl2_offer_receive(offer, selected_type);
3618              ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
3619           }
3620         else
3621           {
3622              eina_promise_reject(data->delivery, ecore_evas_no_matching_type);
3623              data->delivery = NULL;
3624           }
3625       }
3626
3627    return future;
3628 }
3629
3630 static Eina_Bool
3631 _ecore_evas_wl_selection_has_owner(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection EINA_UNUSED)
3632 {
3633    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3634    Ecore_Wl2_Input *input;
3635
3636    _reeval_seat(&seat, ee);
3637    input = _fetch_input(ee, seat);
3638
3639    if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER )
3640      return !!ecore_wl2_dnd_selection_get(input);
3641    else if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
3642      {
3643         Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
3644         return !!data->offer;
3645      }
3646
3647    return EINA_FALSE; //the selection buffer is not supportet in wayland
3648 }
3649
3650 static Eina_Bool
3651 _wl_selection_changed(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
3652 {
3653    Ecore_Wl2_Event_Seat_Selection *sel = event;
3654    Ecore_Evas *ee = data;
3655    Ecore_Wl2_Input *input;
3656    unsigned int seat = sel->seat;
3657
3658    _reeval_seat(&seat, ee);
3659    input = _fetch_input(ee, seat);
3660    if (!ecore_wl2_dnd_selection_get(input))
3661      return ECORE_CALLBACK_PASS_ON;
3662
3663    if (ee->func.fn_selection_changed)
3664      ee->func.fn_selection_changed(ee, 0, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER);
3665
3666    return ECORE_CALLBACK_PASS_ON;
3667 }
3668
3669 typedef struct {
3670    Eina_Rw_Slice slice;
3671    unsigned int written_bytes;
3672 } Delayed_Writing;
3673
3674 static Eina_Bool
3675 _write_to_fd(void *data, Ecore_Fd_Handler *fd_handler)
3676 {
3677    int fd;
3678    size_t len;
3679    Delayed_Writing *slice = data;
3680
3681    fd = ecore_main_fd_handler_fd_get(fd_handler);
3682    if (fd < 0) goto end;
3683
3684    len = write(fd, (char*)slice->slice.mem + slice->written_bytes,
3685                slice->slice.len - slice->written_bytes);
3686
3687    slice->written_bytes += len;
3688    if (slice->written_bytes != slice->slice.len)
3689      {
3690         return EINA_TRUE;
3691      }
3692    else
3693      {
3694 end:
3695         ecore_main_fd_handler_del(fd_handler);
3696         free(slice->slice.mem);
3697         free(slice);
3698         if (fd > -1) close(fd);
3699         return EINA_FALSE;
3700      }
3701 }
3702
3703 static Eina_Bool
3704 _wl_interaction_send(void *data, int type EINA_UNUSED, void *event)
3705 {
3706    Ecore_Wl2_Event_Data_Source_Send *ev = event;
3707    Ecore_Evas *ee = data;
3708    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3709    Ecore_Evas_Wl_Selection_Data *selection = NULL;
3710    Delayed_Writing *forign_slice = calloc(1, sizeof(Delayed_Writing));
3711    Ecore_Evas_Selection_Buffer buffer = ECORE_EVAS_SELECTION_BUFFER_LAST;
3712
3713    if (ev->serial == wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER].sent_serial)
3714      buffer = ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER;
3715    else if (ev->serial == wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].sent_serial)
3716      {
3717         buffer = ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER;
3718         ee->drag.accepted = EINA_TRUE;
3719      }
3720
3721    if (buffer == ECORE_EVAS_SELECTION_BUFFER_LAST)
3722      {
3723         //silent return, this send request was *not* for this window
3724         goto end;
3725      }
3726
3727    selection = &wdata->selection_data[buffer];
3728    EINA_SAFETY_ON_NULL_GOTO(selection, end);
3729    EINA_SAFETY_ON_NULL_GOTO(selection->callbacks.delivery, end);
3730    EINA_SAFETY_ON_FALSE_GOTO(selection->callbacks.delivery(ee, ev->seat, buffer, ev->type, &forign_slice->slice), end);
3731    ecore_main_fd_handler_add(ev->fd, ECORE_FD_WRITE, _write_to_fd, forign_slice, NULL, NULL);
3732
3733    return ECORE_CALLBACK_PASS_ON;
3734
3735 end:
3736    free(forign_slice);
3737    return ECORE_CALLBACK_PASS_ON;
3738 }
3739
3740 static Eina_Bool
3741 _wl_selection_receive(void *data, int type EINA_UNUSED, void *event)
3742 {
3743    Ecore_Evas *ee = data;
3744    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3745    Ecore_Wl2_Event_Offer_Data_Ready *ready = event;
3746    Ecore_Evas_Selection_Buffer selection = ECORE_EVAS_SELECTION_BUFFER_LAST;
3747
3748    if ((!ready->data) || (ready->len < 1))
3749      {
3750         ERR("no selection data");
3751         return ECORE_CALLBACK_PASS_ON;
3752      }
3753    for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
3754      {
3755         if (wdata->selection_data[i].offer == ready->offer)
3756           {
3757              selection = i;
3758              break;
3759           }
3760      }
3761
3762    if (selection == ECORE_EVAS_SELECTION_BUFFER_LAST)
3763      return ECORE_CALLBACK_PASS_ON;
3764
3765    //Now deliver the content
3766    Eina_Slice slice;
3767
3768    if (eina_str_has_prefix(ready->mimetype,"text"))
3769      {
3770         //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
3771         slice.len = ready->len + 1;
3772         slice.mem = eina_memdup((unsigned char*)ready->data, ready->len, EINA_TRUE);
3773      }
3774    else
3775      {
3776         slice.len = ready->len;
3777         slice.mem = ready->data;
3778      }
3779
3780    Eina_Content *content = eina_content_new(slice, ready->mimetype);
3781
3782    if (wdata->selection_data[selection].later_convert)
3783      {
3784         Eina_Content *tmp = eina_content_convert(content, wdata->selection_data[selection].later_convert);
3785         wdata->selection_data[selection].later_convert = NULL;
3786         eina_content_free(content);
3787         content = tmp;
3788      }
3789
3790    eina_promise_resolve(wdata->selection_data[selection].delivery, eina_value_content_init(content));
3791    wdata->selection_data[selection].delivery = NULL;
3792    eina_content_free(content);
3793
3794    return ECORE_CALLBACK_PASS_ON;
3795 }
3796
3797 static Eina_Bool
3798 _wl_selection_dnd_leave(void *data, int type EINA_UNUSED, void *event)
3799 {
3800    Ecore_Evas *ee = data;
3801    Eina_Position2D cpos;
3802    Eina_Position2D fpos = EINA_POSITION2D(0, 0);
3803    Ecore_Wl2_Event_Dnd_Leave *ev = event;
3804    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3805
3806    if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
3807
3808    //evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
3809    ecore_wl2_input_pointer_xy_get(ecore_wl2_display_input_find(ev->display, ev->seat), &cpos.x, &cpos.y);
3810    ecore_evas_dnd_leave(data, ev->seat, EINA_POSITION2D(cpos.x - fpos.x, cpos.y - fpos.y));
3811    wdata->external_offer = NULL;
3812
3813    return ECORE_CALLBACK_PASS_ON;
3814 }
3815
3816 static Eina_Bool
3817 _wl_selection_dnd_motion(void *data, int type EINA_UNUSED, void *event)
3818 {
3819    Ecore_Evas *ee = data;
3820    Ecore_Wl2_Event_Dnd_Motion *ev = event;
3821    Eina_Position2D fpos = EINA_POSITION2D(0, 0);
3822
3823    if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
3824
3825    evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
3826    ecore_evas_dnd_position_set(data, ev->seat, EINA_POSITION2D(ev->x - fpos.x, ev->y - fpos.y));
3827    return ECORE_CALLBACK_PASS_ON;
3828 }
3829 static Eina_Bool
3830 _wl_selection_dnd_enter(void *data, int type EINA_UNUSED, void *event)
3831 {
3832    Ecore_Evas *ee = data;
3833    Ecore_Wl2_Event_Dnd_Enter *ev = event;
3834    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3835    Eina_Position2D fpos = EINA_POSITION2D(0, 0);
3836
3837    if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
3838
3839    evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
3840    ecore_evas_dnd_enter(data, ev->seat, eina_array_iterator_new(ecore_wl2_offer_mimes_get(ev->offer)), EINA_POSITION2D(ev->x - fpos.x, ev->y - fpos.y));
3841    ecore_wl2_offer_mimes_set(ev->offer, ecore_wl2_offer_mimes_get(ev->offer));
3842    wdata->external_offer = ev->offer;
3843    return ECORE_CALLBACK_PASS_ON;
3844 }
3845
3846 static Eina_Bool
3847 _wl_selection_dnd_drop(void *data, int type EINA_UNUSED, void *event)
3848 {
3849    Ecore_Evas *ee = data;
3850    Ecore_Wl2_Event_Dnd_Drop *ev = event;
3851    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3852    if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
3853    wdata = ee->engine.data;
3854
3855    if (ee->func.fn_dnd_drop)
3856      ee->func.fn_dnd_drop(ee, ev->seat, ecore_evas_dnd_pos_get(ee, ev->seat), "ask");
3857
3858    ecore_wl2_dnd_drag_end(_fetch_input(ee, ev->seat));
3859    wdata->external_offer = NULL;
3860
3861    return ECORE_CALLBACK_PASS_ON;
3862 }
3863 static Eina_Bool
3864 _wl_selection_dnd_end(void *data, int type EINA_UNUSED, void *event)
3865 {
3866    Ecore_Evas *ee = data;
3867    Ecore_Wl2_Event_Dnd_End *ev = event;
3868
3869    if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
3870
3871
3872    if (ee->drag.free)
3873      ee->drag.free(ee, ev->seat, ee->drag.data, ee->drag.accepted);
3874    ee->drag.free = NULL;
3875    //we got dropped, we should call
3876
3877    return ECORE_CALLBACK_PASS_ON;
3878 }
3879
3880 static void
3881 _ecore_evas_wl_selection_init(Ecore_Evas *ee)
3882 {
3883    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3884
3885    wdata->changed_handler =
3886      ecore_event_handler_add(ECORE_WL2_EVENT_SEAT_SELECTION,
3887                              _wl_selection_changed, ee);
3888    wdata->send_handler =
3889      ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND,
3890                              _wl_interaction_send, ee);
3891    wdata->offer_handler =
3892      ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY,
3893                              _wl_selection_receive, ee);
3894    wdata->dnd_leave_handler =
3895      ecore_event_handler_add(ECORE_WL2_EVENT_DND_LEAVE,
3896                              _wl_selection_dnd_leave, ee);
3897    wdata->dnd_motion_handler =
3898      ecore_event_handler_add(ECORE_WL2_EVENT_DND_MOTION,
3899                              _wl_selection_dnd_motion, ee);
3900    wdata->dnd_enter_handler =
3901      ecore_event_handler_add(ECORE_WL2_EVENT_DND_ENTER,
3902                              _wl_selection_dnd_enter, ee);
3903    wdata->dnd_drop_handler =
3904      ecore_event_handler_add(ECORE_WL2_EVENT_DND_DROP,
3905                              _wl_selection_dnd_drop, ee);
3906    wdata->dnd_end_handler =
3907      ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_END,
3908                              _wl_selection_dnd_end, ee);
3909
3910    for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
3911      {
3912         wdata->selection_data[i].callbacks.available_types = NULL;
3913         wdata->selection_data[i].callbacks.delivery = NULL;
3914         wdata->selection_data[i].callbacks.cancel = NULL;
3915      }
3916 }
3917
3918 static Eina_Bool
3919 _ecore_evas_wl_dnd_start(Ecore_Evas *ee, unsigned int seat, Eina_Array *available_types, Ecore_Evas *drag_rep, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel, const char *action EINA_UNUSED)
3920 {
3921    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
3922    const char *tmp_array[eina_array_count(available_types) + 1];
3923
3924    _reeval_seat(&seat, ee);
3925    _store_selection_cbs(ee, seat, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER, available_types, delivery, cancel);
3926
3927    for (unsigned int i = 0; i < eina_array_count(available_types); ++i)
3928      {
3929         tmp_array[i] = eina_array_data_get(available_types, i);
3930      }
3931    tmp_array[eina_array_count(available_types)] = NULL;
3932
3933    ecore_wl2_dnd_drag_types_set(_fetch_input(ee, seat), (const char**)tmp_array);
3934    wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].sent_serial =
3935             ecore_wl2_dnd_drag_start(_fetch_input(ee, seat), _ecore_evas_wayland_window_get(ee), _ecore_evas_wayland_window_get(drag_rep));
3936    return EINA_TRUE;
3937 }
3938
3939 static Eina_Bool
3940 _ecore_evas_wl_dnd_stop(Ecore_Evas *ee, unsigned int seat)
3941 {
3942    _clear_selection(ee, seat, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER);
3943    _reeval_seat(&seat, ee);
3944    ecore_wl2_dnd_drag_end(_fetch_input(ee, seat));
3945    return EINA_TRUE;
3946 }
3947
3948 static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
3949 {
3950    _ecore_evas_wl_common_free,
3951    _ecore_evas_wl_common_callback_resize_set,
3952    _ecore_evas_wl_common_callback_move_set,
3953    NULL,
3954    NULL,
3955    _ecore_evas_wl_common_callback_delete_request_set,
3956    NULL,
3957    _ecore_evas_wl_common_callback_focus_in_set,
3958    _ecore_evas_wl_common_callback_focus_out_set,
3959    _ecore_evas_wl_common_callback_mouse_in_set,
3960    _ecore_evas_wl_common_callback_mouse_out_set,
3961    NULL, // sticky_set
3962    NULL, // unsticky_set
3963    NULL, // pre_render_set
3964    NULL, // post_render_set
3965    _ecore_evas_wl_common_move,
3966    NULL, // managed_move
3967    _ecore_evas_wl_common_resize,
3968    _ecore_evas_wl_common_move_resize,
3969    _ecore_evas_wl_common_rotation_set,
3970    NULL, // shaped_set
3971    _ecore_evas_wl_common_show,
3972    _ecore_evas_wl_common_hide,
3973    _ecore_evas_wl_common_raise,
3974    _ecore_evas_wl_common_lower,
3975    _ecore_evas_wl_common_activate,
3976    _ecore_evas_wl_common_title_set,
3977    _ecore_evas_wl_common_name_class_set,
3978    _ecore_evas_wl_common_size_min_set,
3979    _ecore_evas_wl_common_size_max_set,
3980    _ecore_evas_wl_common_size_base_set,
3981    _ecore_evas_wl_common_size_step_set,
3982    _ecore_evas_wl_common_object_cursor_set,
3983    NULL,
3984    _ecore_evas_wl_common_layer_set,
3985    NULL, // focus set
3986    _ecore_evas_wl_common_iconified_set,
3987    _ecore_evas_wl_common_borderless_set,
3988    NULL, // override set
3989    _ecore_evas_wl_common_maximized_set,
3990    _ecore_evas_wl_common_fullscreen_set,
3991    NULL, // func avoid_damage set
3992    _ecore_evas_wl_common_withdrawn_set,
3993    NULL, // func sticky set
3994    _ecore_evas_wl_common_ignore_events_set,
3995    _ecore_evas_wl_common_alpha_set,
3996    _ecore_evas_wl_common_alpha_set, // transparent set
3997    NULL, // func profiles set
3998    NULL, // func profile set
3999    NULL, // window group set
4000    _ecore_evas_wl_common_aspect_set,
4001    NULL, // urgent set
4002    NULL, // modal set
4003    NULL, // demand attention set
4004    _ecore_evas_wl_common_focus_skip_set,
4005    NULL,
4006    _ecore_evas_wl_common_screen_geometry_get,
4007    _ecore_evas_wl_common_screen_dpi_get,
4008    NULL, // func msg parent send
4009    NULL, // func msg send
4010
4011    _ecore_evas_wl_common_pointer_xy_get,
4012    // TIZEN_ONLY(20171114): support a pointer warp
4013    _ecore_evas_wl_common_pointer_warp,
4014    //
4015
4016    _ecore_evas_wl_common_wm_rot_preferred_rotation_set,
4017    _ecore_evas_wl_common_wm_rot_available_rotations_set,
4018    _ecore_evas_wl_common_wm_rot_manual_rotation_done_set,
4019    _ecore_evas_wl_common_wm_rot_manual_rotation_done,
4020
4021    NULL, // aux_hints_set
4022
4023    //TIZEN_ONLY(180618): Use timer for animator
4024    NULL,
4025    NULL,
4026    #if 0
4027    _ecore_evas_wl_common_animator_register,
4028    _ecore_evas_wl_common_animator_unregister,
4029    #endif
4030    //
4031
4032    _ecore_evas_wl_common_evas_changed,
4033    NULL, //fn_focus_device_set
4034    NULL, //fn_callback_focus_device_in_set
4035    NULL, //fn_callback_focus_device_out_set
4036    NULL, //fn_callback_device_mouse_in_set
4037    NULL, //fn_callback_device_mouse_out_set
4038    _ecore_evas_wl_common_pointer_device_xy_get,
4039    _ecore_evas_wl_common_prepare,
4040    NULL, //fn_last_tick_get
4041    //TIZEN_ONLY(20171218) : Add to free evas engine rsc before free evas
4042    _ecore_evas_wl_common_evas_engine_rsc_free,
4043
4044    _ecore_evas_wl_selection_claim, //fn_selection_claim
4045    _ecore_evas_wl_selection_has_owner, //fn_selection_has_owner
4046    _ecore_evas_wl_selection_request, //fn_selection_request
4047    _ecore_evas_wl_dnd_start, //fn_dnd_start
4048    _ecore_evas_wl_dnd_stop, //fn_dnd_stop
4049 };
4050
4051 static void
4052 _ecore_evas_wl_common_win_close(void *data, Ecore_Wl2_Window *win EINA_UNUSED)
4053 {
4054    Ecore_Evas *ee = data;
4055    Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
4056
4057    if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
4058
4059    wdata->win = NULL;
4060 }
4061
4062 Ecore_Evas *
4063 _ecore_evas_wl_common_new_internal(const char *disp_name, Ecore_Window parent, int x, int y, int w, int h, Eina_Bool frame, const int *opt, const char *engine_name)
4064 {
4065    Ecore_Wl2_Display *ewd;
4066    Ecore_Wl2_Window *p = NULL;
4067    Evas_Engine_Info_Wayland *einfo;
4068    Ecore_Evas_Engine_Wl_Data *wdata;
4069    Ecore_Evas_Interface_Wayland *iface;
4070    Ecore_Evas *ee = NULL;
4071    int method = 0;
4072
4073    LOGFN;
4074
4075    if (!(method = evas_render_method_lookup(engine_name)))
4076      {
4077         WRN("Render method lookup failed for %s", engine_name);
4078         return NULL;
4079      }
4080
4081    if (!ecore_wl2_init())
4082      {
4083         WRN("Failed to initialize Ecore_Wl2");
4084         return NULL;
4085      }
4086
4087    ewd = ecore_wl2_display_connect(disp_name);
4088    if (!ewd)
4089      {
4090         WRN("Failed to connect to Wayland Display %s", disp_name);
4091         goto conn_err;
4092      }
4093
4094    if (!(ee = calloc(1, sizeof(Ecore_Evas))))
4095      {
4096         ERR("Failed to allocate Ecore_Evas");
4097         goto ee_err;
4098      }
4099
4100    if (!(wdata = calloc(1, sizeof(Ecore_Evas_Engine_Wl_Data))))
4101      {
4102         ERR("Failed to allocate Ecore_Evas_Engine_Wl_Data");
4103         goto w_err;
4104      }
4105
4106    if (frame) WRN("draw_frame is now deprecated and will have no effect");
4107
4108    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
4109
4110    _ecore_evas_wl_common_init();
4111
4112    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
4113    ee->engine.data = wdata;
4114
4115    iface = _ecore_evas_wl_interface_new();
4116    ee->engine.ifaces = eina_list_append(ee->engine.ifaces, iface);
4117
4118    ee->driver = engine_name;
4119    if (disp_name) ee->name = strdup(disp_name);
4120    
4121 //TIZEN_ONLY(20171228): set default size of ecore_evas
4122    if (w < 1) w = 1;
4123    if (h < 1) h = 1;
4124 //
4125
4126    ee->w = w;
4127    ee->h = h;
4128    ee->req.x = ee->x;
4129    ee->req.y = ee->y;
4130    ee->req.w = ee->w;
4131    ee->req.h = ee->h;
4132    ee->rotation = 0;
4133    ee->prop.max.w = 32767;
4134    ee->prop.max.h = 32767;
4135    ee->prop.layer = 4;
4136    ee->prop.request_pos = EINA_FALSE;
4137    ee->prop.sticky = EINA_FALSE;
4138    ee->prop.withdrawn = EINA_TRUE;
4139    ee->prop.obscured = EINA_TRUE; // TIZEN_ONLY(20160120): support visibility_change event
4140    ee->alpha = EINA_FALSE;
4141
4142    /* Wayland egl engine can't async render */
4143    if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER") ||
4144        !strcmp(engine_name, "wayland_egl"))
4145      ee->can_async_render = 0;
4146    else
4147      ee->can_async_render = 1;
4148
4149    if (parent)
4150      {
4151         p = ecore_wl2_display_window_find(ewd, parent);
4152         ee->alpha = ecore_wl2_window_alpha_get(p);
4153      }
4154
4155    wdata->sync_done = EINA_FALSE;
4156    wdata->parent = p;
4157    wdata->display = ewd;
4158
4159    wdata->win = ecore_wl2_window_new(ewd, p, x, y, w, h);
4160    ecore_wl2_window_close_callback_set(wdata->win,
4161                                        _ecore_evas_wl_common_win_close, ee);
4162    ee->prop.window = ecore_wl2_window_id_get(wdata->win);
4163    ee->prop.aux_hint.supported_list =
4164      ecore_wl2_window_aux_hints_supported_get(wdata->win);
4165    ecore_evas_aux_hint_add(ee, "wm.policy.win.msg.use", "1");
4166
4167    //TIZEN_ONLY(20171115): support output transform
4168    _ecore_evas_wl_common_output_transform_register(ee);
4169    //
4170
4171    if (!ecore_evas_evas_new(ee, ee->w, ee->h))
4172      {
4173         ERR("Can not create Canvas.");
4174         goto eng_err;
4175      }
4176
4177    evas_output_method_set(ee->evas, method);
4178
4179    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST,
4180                            _ecore_evas_wl_common_render_updates, ee);
4181
4182    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE,
4183                            _ecore_evas_wl_common_render_flush_pre, ee);
4184
4185    if (ewd->sync_done)
4186      {
4187         wdata->sync_done = EINA_TRUE;
4188         if ((einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas)))
4189           {
4190              if (opt)
4191                {
4192                   int op;
4193                   for (op = 0; opt[op]; op++)
4194                     {
4195                        if (opt[op] == ECORE_EVAS_OPT_GL_DEPTH)
4196                          {
4197                             op++;
4198                             einfo->depth_bits = opt[op];
4199                          }
4200                        else if (opt[op] == ECORE_EVAS_OPT_GL_STENCIL)
4201                          {
4202                             op++;
4203                             einfo->stencil_bits = opt[op];
4204                          }
4205                        else if (opt[op] == ECORE_EVAS_OPT_GL_MSAA)
4206                          {
4207                             op++;
4208                             einfo->msaa_bits = opt[op];
4209                          }
4210                     }
4211                }
4212
4213              /* TIZEN_ONLY(20190509):
4214                 This might bring less performance at full region rendering,
4215                 but there are some compatibility issues,
4216                 Non-background ui apps, overlay video apps has been already... */
4217              einfo->info.destination_alpha = EINA_TRUE;
4218              //einfo->info.destination_alpha = ee_needs_alpha(ee);
4219              einfo->info.rotation = ee->rotation;
4220              einfo->info.depth = 32;
4221              einfo->info.wl2_win = wdata->win;
4222              einfo->info.hidden = EINA_TRUE;
4223
4224              // TIZEN_ONLY(20171120) : evas sw tbm_buf backend
4225              if (!strcmp(engine_name, "wayland_shm"))
4226                {
4227                  if (_ecore_evas_wl_init_count == 1)
4228                    tbm_client = wayland_tbm_client_init(ecore_wl2_display_get(ewd));
4229                  einfo->info.tbm_client = tbm_client;
4230                }
4231
4232              if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
4233                {
4234                   ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
4235                   goto eng_err;
4236                }
4237           }
4238         else
4239           {
4240              ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
4241              goto eng_err;
4242           }
4243      }
4244
4245    if (!_ecore_wl2_devices_setup(ee, ewd))
4246      {
4247         ERR("Failed to create the devices");
4248         goto eng_err;
4249      }
4250
4251    // TIZEN_ONLY(20161228) : tizen_rotation v2
4252       if (wdata->win)
4253         ecore_wl2_window_rotation_changed_callback_set
4254           (wdata->win, ee, _ecore_evas_wl_common_wm_rot_cb_angle_changed);
4255       if (ewd->wl.tz_policy_ext)
4256         ecore_wl2_window_wm_rotation_supported_set(wdata->win, EINA_TRUE);
4257    //
4258
4259    /* TIZEN_ONLY : To use vsync as custom source of animator */
4260    ecore_animator_custom_source_tick_begin_callback_set
4261       (_ecore_wl_animator_vsync_tick_begin, NULL);
4262    ecore_animator_custom_source_tick_end_callback_set
4263       (_ecore_wl_animator_vsync_tick_end, NULL);
4264    ecore_animator_custom_source_tick_quit_callback_set
4265       (_ecore_wl_animator_vsync_tick_quit, NULL);
4266
4267    ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
4268    //
4269
4270    _ecore_evas_wl_common_wm_rotation_protocol_set(ee);
4271    _ecore_evas_wl_selection_init(ee);
4272
4273    ecore_evas_done(ee, EINA_FALSE);
4274
4275    wdata->sync_handler =
4276      ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _ee_cb_sync_done, ee);
4277
4278    ee_list = eina_list_append(ee_list, ee);
4279
4280    ee->draw_block = EINA_TRUE;
4281
4282    return ee;
4283
4284 eng_err:
4285    /* ecore_evas_free() will call ecore_wl2_display_disconnect()
4286     * and free(ee), it will also call ecore_wl2_shutdown(), so we
4287     * take an extra reference here to keep the count right. */
4288    ecore_wl2_init();
4289    ecore_evas_free(ee);
4290    ee = NULL;
4291 w_err:
4292    free(ee);
4293 ee_err:
4294    if (ee) ecore_wl2_display_disconnect(ewd);
4295 conn_err:
4296    ecore_wl2_shutdown();
4297    return NULL;
4298 }