a2387086d9b64d6ea7e105221fde9b1fde385170
[platform/upstream/efl.git] / src / lib / ecore_wl2 / ecore_wl2_window.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include "ecore_wl2_private.h"
6 #include "efl-hints-client-protocol.h"
7
8 // TIZEN_ONLY(20200601): support sync between ui and video
9 #include <wayland-tbm-client.h>
10 //
11
12 //TIZEN_ONLY(20171216): add ecore_wl2_window_find
13 /* local variables */
14 static Eina_Hash *_windows = NULL;
15
16 // TIZEN_ONLY(20190910)
17 static void _opaque_set(Ecore_Wl2_Window *window);
18 //
19
20 // TIZEN_ONLY(20201123)
21 static void _opaque_region_set(Ecore_Wl2_Window *window, struct wl_region *region);
22 //
23
24 // TIZEN_ONLY(20210330): for maintain internal aux hint list
25 typedef struct _Ecore_Wl2_Window_Aux_Hint Ecore_Wl2_Window_Aux_Hint;
26 struct _Ecore_Wl2_Window_Aux_Hint
27 {
28    int id;
29    Eina_Stringshare *hint;
30    Eina_Stringshare *val;
31 };
32 //
33
34 /* internal functions */
35 void
36 _ecore_wl2_window_init(void)
37 {
38    if (!_windows)
39      _windows = eina_hash_string_superfast_new(NULL);
40 }
41
42 void
43 _ecore_wl2_window_shutdown(void)
44 {
45    eina_hash_free(_windows);
46    _windows = NULL;
47 }
48
49 Eina_Hash *
50 _ecore_wl2_window_hash_get(void)
51 {
52    return _windows;
53 }
54
55 static char *
56 _ecore_wl2_window_id_str_get(int win_id)
57 {
58    const char *vals = "qWeRtYuIoP5$&<~";
59    static char id[9];
60    unsigned int val;
61
62    val = (unsigned int)win_id;
63    id[0] = vals[(val >> 28) & 0xf];
64    id[1] = vals[(val >> 24) & 0xf];
65    id[2] = vals[(val >> 20) & 0xf];
66    id[3] = vals[(val >> 16) & 0xf];
67    id[4] = vals[(val >> 12) & 0xf];
68    id[5] = vals[(val >> 8) & 0xf];
69    id[6] = vals[(val >> 4) & 0xf];
70    id[7] = vals[(val) & 0xf];
71    id[8] = 0;
72
73    return id;
74 }
75 //
76 static void _ecore_wl2_window_hide_send(Ecore_Wl2_Window *window);
77
78 void
79 _ecore_wl2_window_semi_free(Ecore_Wl2_Window *window)
80 {
81    if (window->xdg_popup) xdg_popup_destroy(window->xdg_popup);
82    window->xdg_popup = NULL;
83
84    if (window->xdg_toplevel) xdg_toplevel_destroy(window->xdg_toplevel);
85    window->xdg_toplevel = NULL;
86
87    if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface);
88    window->xdg_surface = NULL;
89
90    if (window->zxdg_popup) zxdg_popup_v6_destroy(window->zxdg_popup);
91    window->zxdg_popup = NULL;
92
93    if (window->zxdg_toplevel) zxdg_toplevel_v6_destroy(window->zxdg_toplevel);
94    window->zxdg_toplevel = NULL;
95
96    if (window->zxdg_surface) zxdg_surface_v6_destroy(window->zxdg_surface);
97    window->zxdg_surface = NULL;
98
99    if (window->www_surface)
100      www_surface_destroy(window->www_surface);
101    window->www_surface = NULL;
102
103    if (window->surface) wl_surface_destroy(window->surface);
104    window->surface = NULL;
105    window->surface_id = -1;
106
107    if (window->callback) wl_callback_destroy(window->callback);
108    window->callback = NULL;
109
110    window->outputs = eina_list_free(window->outputs);
111
112    ecore_wl2_window_surface_flush(window, EINA_TRUE);
113
114    window->commit_pending = EINA_FALSE;
115 }
116
117 static void
118 _ecore_wl2_window_activate_send(Ecore_Wl2_Window *window)
119 {
120    Ecore_Wl2_Event_Window_Activate *ev;
121
122    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Activate));
123    if (!ev) return;
124
125    ev->win = window->id;
126    if (window->parent)
127      ev->parent_win = window->parent->id;
128    ev->event_win = window->id;
129    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ACTIVATE, ev, NULL, NULL);
130 }
131
132 static void
133 _ecore_wl2_window_deactivate_send(Ecore_Wl2_Window *window)
134 {
135    Ecore_Wl2_Event_Window_Deactivate *ev;
136
137    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Deactivate));
138    if (!ev) return;
139
140    ev->win = window->id;
141    if (window->parent)
142      ev->parent_win = window->parent->id;
143    ev->event_win = window->id;
144    ecore_event_add(ECORE_WL2_EVENT_WINDOW_DEACTIVATE, ev, NULL, NULL);
145 }
146
147 static void
148 _ecore_wl2_window_configure_send(Ecore_Wl2_Window *win)
149 {
150    Ecore_Wl2_Event_Window_Configure *ev;
151    int size_type = 0;
152
153    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Configure));
154    if (!ev) return;
155
156    ev->win = win->id;
157    ev->event_win = win->id;
158
159 // TIZEN_ONLY(20171112): support tizen_position
160    ev->x = win->set_config.geometry.x;
161    ev->y = win->set_config.geometry.y;
162 //
163
164 // TIZEN_ONLY(220421/220905): modify event size
165    if (win->def_config.serial == win->req_config.serial)
166      {
167         // this means that this function is called by internal function not display server's configure
168         ev->w = 0;
169         ev->h = 0;
170         size_type = 1;
171      }
172    else
173      {
174         if (win->def_config.fullscreen || win->def_config.maximized)
175           {
176              ev->w = win->def_config.geometry.w;
177              ev->h = win->def_config.geometry.h;
178              size_type = 2;
179           }
180         else
181           {
182              if ((win->def_config.fullscreen != win->req_config.fullscreen) ||
183                  (win->def_config.maximized != win->req_config.maximized))
184                {
185                   // this means that window unset fullscreen or maximized.
186                   // use saved geometry
187                   ev->w = win->saved.w;
188                   ev->h = win->saved.h;
189                   size_type = 3;
190                }
191              else
192                {
193                   if (win->def_config.geometry.w || win->def_config.geometry.h)
194                     {
195                        ev->w = win->def_config.geometry.w;
196                        ev->h = win->def_config.geometry.h;
197                        size_type = 4;
198                     }
199                   else
200                     {
201                        // this means that display server didn't consider client's size.
202                        ev->w = 0;
203                        ev->h = 0;
204                        size_type = 5;
205                     }
206                }
207           }
208      }
209 /*
210    if ((win->set_config.geometry.w == win->def_config.geometry.w) &&
211        (win->set_config.geometry.h == win->def_config.geometry.h))
212      ev->w = ev->h = 0;
213    else if ((!win->def_config.geometry.w) && (!win->def_config.geometry.h) &&
214             (!win->def_config.fullscreen) &&
215             (!win->def_config.maximized) &&
216             ((win->def_config.fullscreen != win->req_config.fullscreen) ||
217              (win->def_config.maximized != win->req_config.maximized)))
218      ev->w = win->saved.w, ev->h = win->saved.h;
219    else
220      ev->w = win->def_config.geometry.w, ev->h = win->def_config.geometry.h;
221 */
222 //
223
224    ev->edges = !!win->def_config.resizing;
225    if (win->def_config.fullscreen)
226      ev->states |= ECORE_WL2_WINDOW_STATE_FULLSCREEN;
227    if (win->def_config.maximized)
228      ev->states |= ECORE_WL2_WINDOW_STATE_MAXIMIZED;
229
230    win->req_config = win->def_config;
231
232    ERR("[WINDOW] Generate WINDOW_CONFIGURE event.. win:%d, states:%d, geo(%d,%d,%dx%d), type:%d", win->resource_id, ev->states, ev->x, ev->y, ev->w, ev->h, size_type);
233    ecore_event_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL);
234
235    if (win->def_config.focused)
236      _ecore_wl2_window_activate_send(win);
237    else
238      _ecore_wl2_window_deactivate_send(win);
239 }
240
241 //TIZEN_ONLY(20180201) : add function to set window size by client.
242 static void
243 _ecore_wl2_window_configure_send_by_client(Ecore_Wl2_Window *win)
244 {
245    Ecore_Wl2_Event_Window_Configure *ev;
246
247    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Configure));
248    if (!ev) return;
249
250    ev->win = win->id;
251    ev->event_win = win->id;
252    ev->x = win->set_config.geometry.x;
253    ev->y = win->set_config.geometry.y;
254    ev->w = win->set_config.geometry.w;
255    ev->h = win->set_config.geometry.h;
256    ev->edges = !!win->req_config.resizing;
257
258    ecore_event_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL);
259 }
260 //
261
262 static void
263 _configure_complete(Ecore_Wl2_Window *window)
264 {
265    Ecore_Wl2_Event_Window_Configure_Complete *ev;
266
267    window->pending.configure = EINA_FALSE;
268
269    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Configure_Complete));
270    if (!ev) return;
271
272    ev->win = window->id;
273    ecore_event_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE_COMPLETE, ev, NULL, NULL);
274
275 }
276
277 #include "window_v6.x"
278
279 static void
280 _www_surface_end_drag(void *data, struct www_surface *www_surface EINA_UNUSED)
281 {
282    Ecore_Wl2_Window *window = data;
283    Ecore_Wl2_Event_Window_WWW_Drag *ev;
284
285    ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW_Drag));
286    EINA_SAFETY_ON_NULL_RETURN(ev);
287    ev->window = window->id;
288    ev->dragging = 0;
289
290    ecore_event_add(_ecore_wl2_event_window_www_drag, ev, NULL, NULL);
291 }
292
293 static void
294 _www_surface_start_drag(void *data, struct www_surface *www_surface EINA_UNUSED)
295 {
296    Ecore_Wl2_Window *window = data;
297    Ecore_Wl2_Event_Window_WWW_Drag *ev;
298
299    ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW_Drag));
300    EINA_SAFETY_ON_NULL_RETURN(ev);
301    ev->window = window->id;
302    ev->dragging = 1;
303
304    ecore_event_add(_ecore_wl2_event_window_www_drag, ev, NULL, NULL);
305 }
306
307 static void
308 _www_surface_status(void *data, struct www_surface *www_surface EINA_UNUSED, int32_t x_rel, int32_t y_rel, uint32_t timestamp)
309 {
310    Ecore_Wl2_Window *window = data;
311    Ecore_Wl2_Event_Window_WWW *ev;
312
313    ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW));
314    EINA_SAFETY_ON_NULL_RETURN(ev);
315    ev->window = window->id;
316    ev->x_rel = x_rel;
317    ev->y_rel = y_rel;
318    ev->timestamp = timestamp;
319
320    ecore_event_add(_ecore_wl2_event_window_www, ev, NULL, NULL);
321 }
322
323 static struct www_surface_listener _www_surface_listener =
324 {
325    .status = _www_surface_status,
326    .start_drag = _www_surface_start_drag,
327    .end_drag = _www_surface_end_drag,
328 };
329
330 void
331 _ecore_wl2_window_www_surface_init(Ecore_Wl2_Window *window)
332 {
333    if (!window->surface) return;
334    if (!window->display->wl.www) return;
335    if (window->www_surface) return;
336    window->www_surface = www_create(window->display->wl.www, window->surface);
337    www_surface_set_user_data(window->www_surface, window);
338    www_surface_add_listener(window->www_surface, &_www_surface_listener,
339                             window);
340 }
341
342
343 static void
344 _xdg_surface_cb_configure(void *data, struct xdg_surface *xdg_surface EINA_UNUSED, uint32_t serial)
345 {
346    Ecore_Wl2_Window *window;
347
348    window = data;
349    window->def_config.serial = serial;
350
351    if (window->pending.configure)
352      {
353         window->saved.w = window->set_config.geometry.w;
354         window->saved.h = window->set_config.geometry.h;
355      }
356    if (window->pending.configure && window->updating)
357      ERR("Window shouldn't be rendering before initial configure");
358
359    // TIZEN_ONLY(20200922) : update window's saved size
360    if (!window->def_config.fullscreen && !window->def_config.maximized)
361      {
362         if (window->pending.geom)
363           {
364              window->saved.w = window->set_config.geometry.w;
365              window->saved.h = window->set_config.geometry.h;
366           }
367      }
368    //
369
370    if (!window->updating)
371      _ecore_wl2_window_configure_send(window);
372
373    if (window->pending.configure)
374      _configure_complete(window);
375 }
376
377 static const struct xdg_surface_listener _xdg_surface_listener =
378 {
379    _xdg_surface_cb_configure,
380 };
381
382 static void
383 _xdg_toplevel_cb_configure(void *data, struct xdg_toplevel *xdg_toplevel EINA_UNUSED, int32_t width, int32_t height, struct wl_array *states)
384 {
385    Ecore_Wl2_Window *win = data;
386    uint32_t *s;
387
388    win->def_config.minimized = EINA_FALSE;
389    win->def_config.maximized = EINA_FALSE;
390    win->def_config.fullscreen = EINA_FALSE;
391    win->def_config.focused = EINA_FALSE;
392    win->def_config.resizing = EINA_FALSE;
393    win->def_config.geometry.w = width;
394    win->def_config.geometry.h = height;
395
396    wl_array_for_each(s, states)
397      {
398         switch (*s)
399           {
400            case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED:
401              win->def_config.maximized = EINA_TRUE;
402              break;
403            case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN:
404              win->def_config.fullscreen = EINA_TRUE;
405              break;
406            case ZXDG_TOPLEVEL_V6_STATE_RESIZING:
407              win->def_config.resizing = EINA_TRUE;
408              break;
409            case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED:
410              win->def_config.focused = EINA_TRUE;
411              win->def_config.minimized = EINA_FALSE;
412            default:
413              break;
414           }
415      }
416
417    if ((!width) && (!height) && (!win->def_config.fullscreen) && (!win->def_config.maximized) &&
418             ((win->def_config.fullscreen != win->set_config.fullscreen) || (win->def_config.maximized != win->set_config.maximized)))
419      width = win->saved.w, height = win->saved.h;
420
421    _ecore_wl2_window_configure_send(win);
422    //, width, height, !!win->def_config.resizing,
423    //                                 win->def_config.fullscreen, win->def_config.maximized);
424
425    if (win->def_config.focused)
426      _ecore_wl2_window_activate_send(win);
427    else
428      _ecore_wl2_window_deactivate_send(win);
429 }
430
431 static void
432 _xdg_toplevel_cb_close(void *data, struct xdg_toplevel *xdg_toplevel EINA_UNUSED)
433 {
434    Ecore_Wl2_Window *win;
435
436    win = data;
437    if (!win) return;
438    if (win->cb_close)
439      {
440         win->cb_close(win->cb_close_data, win);
441         win->cb_close = NULL;
442      }
443    ecore_wl2_window_free(win);
444 }
445
446 static const struct xdg_toplevel_listener _xdg_toplevel_listener =
447 {
448    _xdg_toplevel_cb_configure,
449    _xdg_toplevel_cb_close,
450 };
451
452 static void
453 _xdg_popup_cb_configure(void *data, struct xdg_popup *xdg_popup EINA_UNUSED, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED, int32_t width, int32_t height)
454 {
455    Ecore_Wl2_Window *win = data;
456    win->def_config.geometry.w = width;
457    win->def_config.geometry.h = height;
458 }
459
460 static void
461 _xdg_popup_cb_done(void *data, struct xdg_popup *xdg_popup EINA_UNUSED)
462 {
463    Ecore_Wl2_Window *win;
464
465    win = data;
466    if (!win) return;
467
468    if (win->grab) _ecore_wl2_input_ungrab(win->grab);
469
470    _ecore_wl2_window_hide_send(win);
471 }
472
473 static const struct xdg_popup_listener _xdg_popup_listener =
474 {
475    _xdg_popup_cb_configure,
476    _xdg_popup_cb_done,
477 };
478
479 static void
480 _ecore_wl2_window_xdg_popup_create(Ecore_Wl2_Window *win)
481 {
482    int gw, gh;
483    struct xdg_positioner *pos;
484
485    EINA_SAFETY_ON_NULL_RETURN(win->parent);
486    if (!win->parent->zxdg_surface) return;
487
488    pos = xdg_wm_base_create_positioner(win->display->wl.xdg_wm_base);
489    if (!pos) return;
490
491    ecore_wl2_window_geometry_get(win, NULL, NULL, &gw, &gh);
492    xdg_positioner_set_anchor_rect(pos, 0, 0, 1, 1);
493    xdg_positioner_set_size(pos, gw, gh);
494    xdg_positioner_set_anchor(pos, XDG_POSITIONER_ANCHOR_TOP_LEFT);
495    xdg_positioner_set_gravity(pos, ZXDG_POSITIONER_V6_ANCHOR_BOTTOM |
496                                   ZXDG_POSITIONER_V6_ANCHOR_RIGHT);
497
498    win->xdg_popup = xdg_surface_get_popup(win->xdg_surface,
499                                win->parent->xdg_surface, pos);
500
501    xdg_positioner_destroy(pos);
502    if (win->grab)
503      xdg_popup_grab(win->xdg_popup, win->grab->wl.seat,
504                         wl_display_get_serial(win->display->wl.display));
505    xdg_popup_set_user_data(win->xdg_popup, win);
506    xdg_popup_add_listener(win->xdg_popup, &_xdg_popup_listener, win);
507
508    win->pending.configure = EINA_TRUE;
509
510    ecore_wl2_window_commit(win, EINA_TRUE);
511 }
512
513 static void
514 _window_shell_surface_create(Ecore_Wl2_Window *window)
515 {
516    if (window->xdg_surface) return;
517    window->xdg_surface =
518      xdg_wm_base_get_xdg_surface(window->display->wl.xdg_wm_base,
519                                    window->surface);
520    xdg_surface_set_user_data(window->xdg_surface, window);
521    xdg_surface_add_listener(window->xdg_surface,
522                                 &_xdg_surface_listener, window);
523
524    window->xdg_configure_ack = xdg_surface_ack_configure;
525    window->pending.configure = EINA_TRUE;
526    if (window->display->wl.efl_hints)
527      {
528         if (window->aspect.set)
529           efl_hints_set_aspect(window->display->wl.efl_hints, window->xdg_surface,
530             window->aspect.w, window->aspect.h, window->aspect.aspect);
531         if (window->weight.set)
532           efl_hints_set_weight(window->display->wl.efl_hints, window->xdg_surface,
533             window->weight.w, window->weight.h);
534      }
535
536    if (window->type == ECORE_WL2_WINDOW_TYPE_MENU)
537      _ecore_wl2_window_xdg_popup_create(window);
538    else
539      {
540         struct xdg_toplevel *ptop = NULL;
541
542         window->xdg_toplevel =
543           xdg_surface_get_toplevel(window->xdg_surface);
544         xdg_toplevel_set_user_data(window->xdg_toplevel, window);
545         xdg_toplevel_add_listener(window->xdg_toplevel,
546                                       &_xdg_toplevel_listener, window);
547
548         if (window->title)
549           xdg_toplevel_set_title(window->xdg_toplevel, window->title);
550         if (window->class)
551           xdg_toplevel_set_app_id(window->xdg_toplevel, window->class);
552
553         window->xdg_set_min_size = xdg_toplevel_set_min_size;
554         window->xdg_set_max_size = xdg_toplevel_set_max_size;
555
556         if (window->parent)
557           ptop = window->parent->xdg_toplevel;
558
559         if (ptop)
560           xdg_toplevel_set_parent(window->xdg_toplevel, ptop);
561
562         if (window->set_config.maximized)
563           xdg_toplevel_set_maximized(window->xdg_toplevel);
564
565         if (window->set_config.fullscreen)
566           xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
567      }
568
569    ecore_wl2_window_commit(window, EINA_TRUE);
570 }
571
572 //TIZEN_ONLY(20150424) : tizen_visibility
573 static void
574 _tizen_visibility_cb_notify(void *data, struct tizen_visibility *tizen_visibility EINA_UNUSED, uint32_t visibility)
575 {
576    Ecore_Wl2_Window *win;
577    Ecore_Wl2_Event_Window_Visibility_Change *ev;
578
579    if (!(win = data)) return;
580    if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Visibility_Change)))) return;
581
582    ev->win = win->id;
583    if (visibility == TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED)
584      ev->fully_obscured = 1;
585    else
586      ev->fully_obscured = 0;
587
588    if (win->cb_visibility) win->cb_visibility(win->cb_visibility_data, win, !ev->fully_obscured);
589
590    ecore_event_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, ev, NULL, NULL);
591 }
592
593 static void
594 _tizen_visibility_cb_changed(void *data, struct tizen_visibility *tizen_visibility EINA_UNUSED, uint32_t type, uint32_t option)
595 {
596    Ecore_Wl2_Window *win = (Ecore_Wl2_Window *)data;
597    Ecore_Wl2_Event_Window_Pre_Visibility_Change *ev;
598
599    EINA_SAFETY_ON_NULL_RETURN(win);
600
601    if (type == TIZEN_VISIBILITY_VISIBILITY_PRE_UNOBSCURED)
602      {
603         ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Pre_Visibility_Change));
604         EINA_SAFETY_ON_NULL_RETURN(ev);
605
606         ev->win = win->id;
607         ev->type = ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED;
608         ev->option = option;
609
610         ecore_event_add(ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, ev, NULL, NULL);
611      }
612 }
613
614 static const struct tizen_visibility_listener _tizen_visibility_listener =
615 {
616    _tizen_visibility_cb_notify,
617    _tizen_visibility_cb_changed,
618 };
619
620 static void
621 _tizen_position_cb_changed(void *data, struct tizen_position *tizen_position EINA_UNUSED, int32_t x, int32_t y)
622 {
623    Ecore_Wl2_Window *win;
624
625    if (!(win = data)) return;
626
627    win->def_config.geometry.x = x;
628    win->def_config.geometry.y = y;
629
630    if (win->set_config.fullscreen) return;
631    if (win->set_config.maximized) return;
632
633    if ((x != win->set_config.geometry.x) || (y != win->set_config.geometry.y))
634      {
635         win->set_config.geometry.x = x;
636         win->set_config.geometry.y = y;
637
638         _ecore_wl2_window_configure_send(win);
639      }
640 }
641
642 static const struct tizen_position_listener _tizen_position_listener =
643 {
644    _tizen_position_cb_changed,
645 };
646
647 static void
648 _tizen_rotation_preferred_angle_set(Ecore_Wl2_Window *window, int rot)
649 {
650    enum tizen_rotation_angle tz_angle = TIZEN_ROTATION_ANGLE_NONE;
651
652    if (!window) return;
653
654    switch (rot)
655      {
656       case 0:
657          tz_angle = TIZEN_ROTATION_ANGLE_0;
658          break;
659       case 90:
660          tz_angle = TIZEN_ROTATION_ANGLE_90;
661          break;
662       case 180:
663          tz_angle = TIZEN_ROTATION_ANGLE_180;
664          break;
665       case 270:
666          tz_angle = TIZEN_ROTATION_ANGLE_270;
667          break;
668       default:
669          break;
670      }
671
672    if (window->tz_rotation)
673      tizen_rotation_set_preferred_angle(window->tz_rotation, (uint32_t)tz_angle);
674 }
675
676 static void
677 _tizen_rotation_available_angles_set(Ecore_Wl2_Window *window, const int *rots, unsigned int count)
678 {
679    uint32_t angles = 0;
680    unsigned int i = 0;
681
682    if (!window) return;
683
684    for (i = 0; i < count ; i++)
685      {
686         switch (rots[i])
687           {
688            case 0:
689               angles |= (uint32_t)TIZEN_ROTATION_ANGLE_0;
690               break;
691            case 90:
692               angles |= (uint32_t)TIZEN_ROTATION_ANGLE_90;
693               break;
694            case 180:
695               angles |= (uint32_t)TIZEN_ROTATION_ANGLE_180;
696               break;
697            case 270:
698               angles |= (uint32_t)TIZEN_ROTATION_ANGLE_270;
699               break;
700            default:
701               break;
702           }
703      }
704
705    if (window->tz_rotation)
706      tizen_rotation_set_available_angles(window->tz_rotation, angles);
707 }
708
709 static void
710 _ecore_wl_window_cb_available_angles_done(void *data EINA_UNUSED, struct tizen_rotation *tizen_rotation EINA_UNUSED, uint32_t angles EINA_UNUSED)
711 {
712    return;
713 }
714
715 static void
716 _ecore_wl_window_cb_preferred_angle_done(void *data EINA_UNUSED, struct tizen_rotation *tizen_rotation EINA_UNUSED, uint32_t angle EINA_UNUSED)
717 {
718    return;
719 }
720
721 static void
722 _ecore_wl_window_cb_angle_change(void *data, struct tizen_rotation *tizen_rotation EINA_UNUSED, uint32_t angle, uint32_t serial)
723 {
724    Ecore_Wl2_Window *win;
725    Ecore_Wl2_Event_Window_Rotation *ev;
726    int i = 0;
727
728    if (!(win = data)) return;
729    if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation)))) return;
730    DBG("PendingRotation: wayland rotation callback angle=%d serial=%d", angle, serial);
731
732    win->wm_rot.serial = serial;
733
734    ev->win = win->id;
735    ev->w = win->def_config.geometry.w;
736    ev->h = win->def_config.geometry.h;
737
738    //TIZEN_ONLY(20190128): Use set_config geometry
739    if (ev->w == 0 && ev->h == 0)
740      {
741         ev->w = win->set_config.geometry.w;
742         ev->h = win->set_config.geometry.h;
743      }
744    //
745
746    switch (angle)
747      {
748       case TIZEN_ROTATION_ANGLE_0:
749          ev->angle = 0;
750          break;
751       case TIZEN_ROTATION_ANGLE_90:
752          ev->angle = 90;
753          break;
754       case TIZEN_ROTATION_ANGLE_180:
755          ev->angle = 180;
756          break;
757       case TIZEN_ROTATION_ANGLE_270:
758          ev->angle = 270;
759          break;
760       default:
761          ev->angle = 0;
762          break;
763      }
764
765    i = ev->angle / 90;
766    if (win->wm_rot.geometry_hints[i].valid)
767      {
768         ev->w = win->wm_rot.geometry_hints[i].w;
769         ev->h = win->wm_rot.geometry_hints[i].h;
770      }
771
772    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATE, ev, NULL, NULL);
773 // TIZEN_ONLY(20170212): pend rotation until app set rotation
774    //this code don't need. This code will be added opensource code.
775    //ecore_wl2_window_rotation_set(win, ev->angle);
776 //
777 }
778
779 static void
780 _ecore_wl_window_cb_angle_change_with_resize(void *data, struct tizen_rotation *tizen_rotation EINA_UNUSED, uint32_t angle, uint32_t serial, uint32_t width, uint32_t height)
781 {
782    Ecore_Wl2_Window *win = (Ecore_Wl2_Window *)data;
783    int rot = 0;
784    Ecore_Wl2_Event_Window_Rotation *ev = NULL;
785
786    EINA_SAFETY_ON_NULL_RETURN(win);
787
788    switch (angle)
789      {
790        case TIZEN_ROTATION_ANGLE_0:   rot =   0; break;
791        case TIZEN_ROTATION_ANGLE_90:  rot =  90; break;
792        case TIZEN_ROTATION_ANGLE_180: rot = 180; break;
793        case TIZEN_ROTATION_ANGLE_270: rot = 270; break;
794        default:                       rot =   0; break;
795      }
796
797    if (win->cb_rot_changed)
798      {
799         win->wm_rot.serial = serial;
800
801         ecore_wl2_window_rotation_set(win, rot);
802         win->cb_rot_changed(win, rot, 0, width, height, win->cb_rot_changed_data);
803      }
804
805    if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation)))) return;
806
807    win->wm_rot.serial = serial;
808
809    ev->win = win->id;
810    ev->w = width;
811    ev->h = height;
812    ev->angle = rot;
813    ev->resize = EINA_TRUE;
814
815    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATE, ev, NULL, NULL);
816 }
817
818 static const struct tizen_rotation_listener _ecore_tizen_rotation_listener =
819 {
820    _ecore_wl_window_cb_available_angles_done,
821    _ecore_wl_window_cb_preferred_angle_done,
822    _ecore_wl_window_cb_angle_change,
823    _ecore_wl_window_cb_angle_change_with_resize,
824 };
825
826 static void
827 _tizen_resource_cb_resource_id(void *data, struct tizen_resource *tizen_resource EINA_UNUSED, uint32_t id)
828 {
829    Ecore_Wl2_Window *win;
830    Ecore_Wl2_Event_Window_Show *ev;
831
832    if (!(win = data)) return;
833    if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Show)))) return;
834
835    ev->win = win->id;
836    if (win->parent)
837      ev->parent_win = win->parent->id;
838    else
839      ev->parent_win = 0;
840    ev->event_win = win->id;
841    ev->data[0] = (unsigned int)id;
842    win->resource_id = (unsigned int)id;
843    ecore_event_add(ECORE_WL2_EVENT_WINDOW_SHOW, ev, NULL, NULL);
844 }
845
846 static const struct tizen_resource_listener _tizen_resource_listener =
847 {
848    _tizen_resource_cb_resource_id,
849 };
850 //
851
852 //TIZEN_ONLY(20200707): support tizen_renderer_surface
853 static void
854 _tizen_renderer_surface_cb_redraw_request(void *data, struct tizen_renderer_surface *renderer_surface EINA_UNUSED)
855 {
856    Ecore_Wl2_Window *win;
857    Ecore_Wl2_Event_Window_Redraw_Request *ev;
858
859    if (!(win = data)) return;
860    if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Redraw_Request)))) return;
861
862    ev->win = win->id;
863
864    ecore_event_add(ECORE_WL2_EVENT_WINDOW_REDRAW_REQUEST, ev, NULL, NULL);
865 }
866
867 static const struct tizen_renderer_surface_listener _tizen_renderer_surface_listener =
868 {
869    _tizen_renderer_surface_cb_redraw_request,
870 };
871 //
872
873 // TIZEN_ONLY(20171112) : support tizen protocols
874 // to initialize wayland tizen extention protocols after surface creation
875 // such as tizen_policy, tizen_position, tizen_rotation, tizen_resource
876 // and handle transient parent(by tizen_policy) for surfaces without shell or xdg_shell
877 void
878 _ecore_wl2_window_tz_ext_init(Ecore_Wl2_Window *window)
879 {
880    if (!window) return;
881    if (!window->surface) return;
882    if (!window->display) return;
883
884    if (window->display->wl.tz_policy)
885      {
886         if (!window->tz_visibility)
887           {
888              window->tz_visibility =
889                tizen_policy_get_visibility(window->display->wl.tz_policy,
890                                             window->surface);
891              if (!window->tz_visibility) return;
892              tizen_visibility_add_listener(window->tz_visibility,
893                                            &_tizen_visibility_listener,
894                                            window);
895           }
896
897         if (!window->tz_position)
898           {
899
900              window->tz_position =
901                tizen_policy_get_position(window->display->wl.tz_policy,
902                                           window->surface);
903
904              if (!window->tz_position) return;
905              tizen_position_add_listener(window->tz_position,
906                                          &_tizen_position_listener, window);
907              if (window->surface)
908                tizen_position_set(window->tz_position,
909                                   window->set_config.geometry.x, window->set_config.geometry.y);
910           }
911
912         if (window->role)
913           {
914              if (window->surface)
915                tizen_policy_set_role(window->display->wl.tz_policy,
916                                      window->surface,
917                                      window->role);
918           }
919
920         if (window->focus_skip)
921           {
922              if (window->surface)
923                tizen_policy_set_focus_skip(window->display->wl.tz_policy, window->surface);
924           }
925         else
926           {
927              if (window->surface)
928                tizen_policy_unset_focus_skip(window->display->wl.tz_policy, window->surface);
929           }
930
931         if (window->floating)
932           {
933              if (window->surface)
934                tizen_policy_set_floating_mode(window->display->wl.tz_policy,
935                                               window->surface);
936           }
937      }
938
939    if (window->display->wl.tz_policy_ext && !window->tz_rotation)
940      {
941         int i = 0, x, y, w, h, rot;
942         enum tizen_rotation_angle angle = TIZEN_ROTATION_ANGLE_NONE;
943
944         window->tz_rotation =
945            tizen_policy_ext_get_rotation(window->display->wl.tz_policy_ext,
946                                          window->surface);
947         if (!window->tz_rotation) return;
948
949         tizen_rotation_add_listener(window->tz_rotation,
950                                     &_ecore_tizen_rotation_listener, window);
951
952         if (window->wm_rot.preferred_rot != TIZEN_ROTATION_ANGLE_NONE)
953           {
954              _tizen_rotation_preferred_angle_set(window, window->wm_rot.preferred_rot);
955           }
956
957         if (window->wm_rot.count)
958           {
959              _tizen_rotation_available_angles_set(window, window->wm_rot.available_rots, window->wm_rot.count);
960           }
961
962         rot = ecore_wl2_window_rotation_get(window);
963         for (i = 0; i <= 3; i++)
964           {
965              if (!window->wm_rot.geometry_hints[i].valid) continue;
966
967              x = window->wm_rot.geometry_hints[i].x;
968              y = window->wm_rot.geometry_hints[i].y;
969              w = window->wm_rot.geometry_hints[i].w;
970              h = window->wm_rot.geometry_hints[i].h;
971
972              switch (i)
973                {
974                 case 0:
975                    angle = TIZEN_ROTATION_ANGLE_0;
976                    break;
977                 case 1:
978                    angle = TIZEN_ROTATION_ANGLE_90;
979                    break;
980                 case 2:
981                    angle = TIZEN_ROTATION_ANGLE_180;
982                    break;
983                 case 3:
984                    angle = TIZEN_ROTATION_ANGLE_270;
985                    break;
986                }
987              tizen_rotation_set_geometry_hint(window->tz_rotation,
988                                               (uint32_t)angle, x, y, w, h);
989
990              if ((rot == (i * 90)) &&
991                  ((window->set_config.geometry.w != w) || (window->set_config.geometry.h != h)))
992                {
993                   //TIZEN_ONLY(20180201) : add function to set window size by client.
994                   window->set_config.geometry.w = w;
995                   window->set_config.geometry.h = h;
996                   _ecore_wl2_window_configure_send_by_client(window);
997                   //
998                }
999           }
1000      }
1001
1002    if (window->display->wl.tz_surf && !window->tz_resource)
1003      {
1004         window->tz_resource =
1005           tizen_surface_get_tizen_resource(window->display->wl.tz_surf, window->surface);
1006         if (!window->tz_resource) return;
1007
1008         tizen_resource_add_listener(window->tz_resource,
1009                                     &_tizen_resource_listener, window);
1010
1011      }
1012
1013    if (window->parent)
1014      {
1015         if (window->zxdg_surface && window->parent->zxdg_surface)
1016           {
1017              // already handled above code
1018           }
1019         else if (window->display->wl.tz_policy && window->surface && window->parent->surface)
1020           {
1021              uint32_t ver = wl_proxy_get_version((struct wl_proxy *)window->display->wl.tz_policy);
1022              if (ver >= TIZEN_POLICY_SET_PARENT_WITH_BELOW_SINCE_VERSION)
1023                {
1024                   // for transient_for below
1025                   if (window->below_child)
1026                     tizen_policy_set_parent_with_below(window->display->wl.tz_policy, window->surface, window->parent->surface);
1027                   else
1028                     tizen_policy_set_parent(window->display->wl.tz_policy, window->surface, window->parent->surface);
1029                }
1030              else if (ver >= 3)
1031                tizen_policy_set_parent(window->display->wl.tz_policy, window->surface, window->parent->surface);
1032           }
1033      }
1034
1035    if (window->display->wl.tz_renderer && !window->tz_renderer_surface)
1036      {
1037         window->tz_renderer_surface =
1038           tizen_renderer_get_renderer_surface(window->display->wl.tz_renderer, window->surface);
1039         if (!window->tz_renderer_surface) return;
1040
1041         tizen_renderer_surface_add_listener(window->tz_renderer_surface,
1042                                     &_tizen_renderer_surface_listener, window);
1043      }
1044 }
1045 // END of TIZEN_ONLY(20171112) : support tizen protocols
1046
1047 void
1048 _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window)
1049 {
1050    if (!window->surface) return;
1051    if (window->display->wl.xdg_wm_base) _window_shell_surface_create(window);
1052    if (window->display->wl.zxdg_shell) _window_v6_shell_surface_create(window);
1053
1054    if (window->display->wl.session_recovery)
1055      {
1056         if (window->uuid)
1057           {
1058              int gx, gy, gw, gh;
1059
1060              zwp_e_session_recovery_set_uuid(window->display->wl.session_recovery,
1061                                              window->surface, window->uuid);
1062
1063              ecore_wl2_window_geometry_get(window, &gx, &gy, &gw, &gh);
1064              if (window->xdg_surface)
1065                xdg_surface_set_window_geometry(window->xdg_surface,
1066                                                gx, gy, gw, gh);
1067              if (window->zxdg_surface)
1068                zxdg_surface_v6_set_window_geometry(window->zxdg_surface,
1069                                                    gx, gy, gw, gh);
1070
1071              ecore_wl2_window_opaque_region_set(window,
1072                                                 window->opaque.x,
1073                                                 window->opaque.y,
1074                                                 window->opaque.w,
1075                                                 window->opaque.h);
1076           }
1077         else
1078           zwp_e_session_recovery_get_uuid(window->display->wl.session_recovery, window->surface);
1079      }
1080 }
1081
1082 static void
1083 _surface_enter(void *data, struct wl_surface *surf EINA_UNUSED, struct wl_output *op)
1084 {
1085    Ecore_Wl2_Window *win;
1086    Ecore_Wl2_Output *output;
1087
1088    win = data;
1089
1090    output = _ecore_wl2_output_find(win->display, op);
1091    EINA_SAFETY_ON_NULL_RETURN(output);
1092
1093    win->outputs = eina_list_append(win->outputs, output);
1094 }
1095
1096 static void
1097 _surface_leave(void *data, struct wl_surface *surf EINA_UNUSED, struct wl_output *op)
1098 {
1099    Ecore_Wl2_Window *win;
1100    Ecore_Wl2_Output *output;
1101
1102    win = data;
1103    output = _ecore_wl2_output_find(win->display, op);
1104    EINA_SAFETY_ON_NULL_RETURN(output);
1105
1106    win->outputs = eina_list_remove(win->outputs, output);
1107    if (!win->outputs)
1108      {
1109         Ecore_Wl2_Event_Window_Offscreen *ev;
1110         ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Offscreen));
1111         if (ev)
1112           {
1113              ev->win = win->id;
1114              ecore_event_add(ECORE_WL2_EVENT_WINDOW_OFFSCREEN, ev, NULL, NULL);
1115           }
1116      }
1117 }
1118
1119 static const struct wl_surface_listener _surface_listener =
1120 {
1121    _surface_enter,
1122    _surface_leave,
1123 };
1124
1125 void
1126 _ecore_wl2_window_surface_create(Ecore_Wl2_Window *window)
1127 {
1128    if (!window->display->wl.compositor) return;
1129
1130    if (!window->surface)
1131      {
1132         window->surface =
1133           wl_compositor_create_surface(window->display->wl.compositor);
1134         if (!window->surface)
1135           {
1136              ERR("Failed to create surface for window");
1137              return;
1138           }
1139         wl_surface_set_user_data(window->surface, window);
1140
1141         //TIZEN_ONLY(20171115): support output transform
1142         if (window->display->wl.tz_screen_rotation)
1143           tizen_screen_rotation_get_ignore_output_transform(window->display->wl.tz_screen_rotation, window->surface);
1144         //
1145
1146         window->surface_id =
1147           wl_proxy_get_id((struct wl_proxy *)window->surface);
1148
1149         wl_surface_add_listener(window->surface, &_surface_listener, window);
1150         if (window->display->wl.efl_aux_hints)
1151           {
1152              efl_aux_hints_get_supported_aux_hints(window->display->wl.efl_aux_hints, window->surface);
1153              if (_ecore_wl2_display_sync_get())
1154                wl_display_roundtrip(window->display->wl.display);
1155           }
1156      }
1157 }
1158
1159 static void
1160 _ecore_wl2_window_show_send(Ecore_Wl2_Window *window)
1161 {
1162    Ecore_Wl2_Event_Window_Show *ev;
1163
1164    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Show));
1165    if (!ev) return;
1166
1167    ev->win = window->id;
1168    if (window->parent)
1169      ev->parent_win = window->parent->id;
1170    ev->event_win = window->id;
1171    window->visible = EINA_TRUE;
1172    ecore_event_add(ECORE_WL2_EVENT_WINDOW_SHOW, ev, NULL, NULL);
1173 }
1174
1175 static void
1176 _ecore_wl2_window_hide_send(Ecore_Wl2_Window *window)
1177 {
1178    Ecore_Wl2_Event_Window_Hide *ev;
1179
1180    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Hide));
1181    if (!ev) return;
1182
1183    ev->win = window->id;
1184    if (window->parent)
1185      ev->parent_win = window->parent->id;
1186    ev->event_win = window->id;
1187    window->visible = EINA_FALSE;
1188    ecore_event_add(ECORE_WL2_EVENT_WINDOW_HIDE, ev, NULL, NULL);
1189 }
1190
1191 static void
1192 _ecore_wl2_window_create_destroy_send(Ecore_Wl2_Window *window, Eina_Bool create)
1193 {
1194    Ecore_Wl2_Event_Window_Common *ev;
1195
1196    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Common));
1197    if (!ev) return;
1198
1199    ev->win = window->id;
1200    if (window->parent)
1201      ev->parent_win = window->parent->id;
1202    ev->event_win = window->id;
1203
1204    if (create) ecore_event_add(ECORE_WL2_EVENT_WINDOW_CREATE, ev, NULL, NULL);
1205    else ecore_event_add(ECORE_WL2_EVENT_WINDOW_DESTROY, ev, NULL, NULL);
1206 }
1207
1208 EAPI Ecore_Wl2_Window *
1209 ecore_wl2_window_new(Ecore_Wl2_Display *display, Ecore_Wl2_Window *parent, int x, int y, int w, int h)
1210 {
1211    Ecore_Wl2_Window *win;
1212    static int _win_id = 1;
1213
1214    EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
1215    if (display->pid) CRI("CANNOT CREATE WINDOW WITH SERVER DISPLAY");
1216
1217    /* try to allocate space for window structure */
1218    win = calloc(1, sizeof(Ecore_Wl2_Window));
1219    if (!win) return NULL;
1220    display->refs++;
1221
1222    win->display = display;
1223    win->parent = parent;
1224    win->id = _win_id++;
1225
1226    win->set_config.geometry.x = x;
1227    win->set_config.geometry.y = y;
1228    win->set_config.geometry.w = w;
1229    win->set_config.geometry.h = h;
1230
1231    win->opaque.x = x;
1232    win->opaque.y = y;
1233    win->opaque.w = w;
1234    win->opaque.h = h;
1235
1236    // TIZEN_ONLY(20180202) : Set default type to keep backward compat.
1237    win->type = ECORE_WL2_WINDOW_TYPE_TOPLEVEL;
1238    // END
1239
1240    //TIZEN_ONLY(20171115): support output transform
1241    win->ignore_output_transform = EINA_TRUE;
1242    //
1243
1244    win->pending.configure = EINA_TRUE;
1245    display->windows =
1246      eina_inlist_append(display->windows, EINA_INLIST_GET(win));
1247
1248    _ecore_wl2_window_surface_create(win);
1249
1250 //TIZEN_ONLY(20171216): add ecore_wl2_window_find
1251    eina_hash_add(_windows, _ecore_wl2_window_id_str_get(win->id), win);
1252 //
1253
1254    _ecore_wl2_input_devices_send(ecore_wl2_input_default_input_get(display), win);
1255
1256    _ecore_wl2_window_create_destroy_send(win, EINA_TRUE);
1257
1258    return win;
1259 }
1260
1261 EAPI int
1262 ecore_wl2_window_id_get(Ecore_Wl2_Window *window)
1263 {
1264    EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
1265    return window->id;
1266 }
1267
1268 EAPI void
1269 ecore_wl2_window_close_callback_set(Ecore_Wl2_Window *window, void (*cb) (void *data, Ecore_Wl2_Window *win), void *data)
1270 {
1271    EINA_SAFETY_ON_NULL_RETURN(window);
1272    window->cb_close = cb;
1273    window->cb_close_data = data;
1274 }
1275
1276 EAPI void
1277 ecore_wl2_window_visibility_callback_set(Ecore_Wl2_Window *window, void (*cb) (void *data, Ecore_Wl2_Window *win, Eina_Bool visibility), void *data)
1278 {
1279    EINA_SAFETY_ON_NULL_RETURN(window);
1280    window->cb_visibility = cb;
1281    window->cb_visibility_data = data;
1282 }
1283
1284 EAPI struct wl_surface *
1285 ecore_wl2_window_surface_get(Ecore_Wl2_Window *window)
1286 {
1287    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1288
1289    _ecore_wl2_window_surface_create(window);
1290
1291    return window->surface;
1292 }
1293
1294 //TIZEN_ONLY(20200309): The 3rd party app may needs native surface handle.
1295 EAPI void *
1296 ecore_wl2_window_native_surface_get(Ecore_Wl2_Window *window)
1297 {
1298    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1299
1300    _ecore_wl2_window_surface_create(window);
1301
1302    return (void *)window->surface;
1303 }
1304 //
1305
1306 EAPI int
1307 ecore_wl2_window_surface_id_get(Ecore_Wl2_Window *window)
1308 {
1309    EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
1310    return window->surface_id;
1311 }
1312
1313 EAPI void
1314 ecore_wl2_window_show(Ecore_Wl2_Window *window)
1315 {
1316    EINA_SAFETY_ON_NULL_RETURN(window);
1317
1318    _ecore_wl2_window_surface_create(window);
1319
1320    if (window->input_set)
1321      ecore_wl2_window_input_region_set(window, window->input_rect.x,
1322                                        window->input_rect.y,
1323                                        window->input_rect.w,
1324                                        window->input_rect.h);
1325    if (window->opaque_set)
1326      ecore_wl2_window_opaque_region_set(window, window->opaque.x,
1327                                         window->opaque.y, window->opaque.w,
1328                                         window->opaque.h);
1329
1330    if ((window->type != ECORE_WL2_WINDOW_TYPE_DND) &&
1331        (window->type != ECORE_WL2_WINDOW_TYPE_NONE))
1332      {
1333         _ecore_wl2_window_shell_surface_init(window);
1334         _ecore_wl2_window_tz_ext_init(window);  // TIZEN_ONLY(20171112) : support tizen protocols after surface creation
1335         _ecore_wl2_window_www_surface_init(window);
1336         _ecore_wl2_window_show_send(window);
1337      }
1338    else
1339       {
1340         _ecore_wl2_window_tz_ext_init(window); // TIZEN_ONLY(20171112) : support tizen protocols after surface creation
1341         _configure_complete(window);
1342      }
1343
1344 // TIZEN_ONLY(20201125) : support tizen protocol to notify show request
1345 #ifdef TIZEN_POLICY_SHOW_SINCE_VERSION
1346    if (window->display->wl.tz_policy && window->surface)
1347      {
1348         uint32_t ver = wl_proxy_get_version((struct wl_proxy *)window->display->wl.tz_policy);
1349         if (ver >= TIZEN_POLICY_SHOW_SINCE_VERSION)
1350           tizen_policy_show(window->display->wl.tz_policy, window->surface);
1351      }
1352 #endif
1353 //
1354  }
1355
1356 EAPI void
1357 ecore_wl2_window_hide(Ecore_Wl2_Window *window)
1358 {
1359    EINA_SAFETY_ON_NULL_RETURN(window);
1360
1361 // TIZEN_ONLY(20201125) : support tizen protocol to notify hide request
1362 #ifdef TIZEN_POLICY_HIDE_SINCE_VERSION
1363    if (window->display->wl.tz_policy && window->surface)
1364      {
1365         uint32_t ver = wl_proxy_get_version((struct wl_proxy *)window->display->wl.tz_policy);
1366         if (ver >= TIZEN_POLICY_HIDE_SINCE_VERSION)
1367           tizen_policy_hide(window->display->wl.tz_policy, window->surface);
1368      }
1369 #endif
1370 //
1371
1372    _ecore_wl2_window_hide_send(window);
1373
1374    // TIZEN_ONLY(20171112) : support tizen protocols
1375    if (window->tz_visibility) tizen_visibility_destroy(window->tz_visibility);
1376    window->tz_visibility = NULL;
1377
1378    if (window->tz_resource) tizen_resource_destroy(window->tz_resource);
1379    window->tz_resource = NULL;
1380    //
1381
1382    if (window->commit_pending)
1383      {
1384         /* We've probably been hidden while an animator
1385          * is ticking.  Cancel the callback.
1386          */
1387         window->commit_pending = EINA_FALSE;
1388         if (window->callback)
1389           {
1390              wl_callback_destroy(window->callback);
1391              window->callback = NULL;
1392           }
1393      }
1394
1395    if (window->surface)
1396      {
1397         wl_surface_attach(window->surface, NULL, 0, 0);
1398         ecore_wl2_window_commit(window, EINA_TRUE);
1399         window->commit_pending = EINA_FALSE;
1400      }
1401
1402    /* The commit added a callback, disconnect it */
1403    if (window->callback)
1404      {
1405         wl_callback_destroy(window->callback);
1406         window->callback = NULL;
1407      }
1408
1409    // TIZEN_ONLY(20180614) : destroy shell surface and its role
1410    if (window->zxdg_popup) zxdg_popup_v6_destroy(window->zxdg_popup);
1411    window->zxdg_popup = NULL;
1412
1413    if (window->zxdg_toplevel) zxdg_toplevel_v6_destroy(window->zxdg_toplevel);
1414    window->zxdg_toplevel = NULL;
1415
1416    if (window->zxdg_surface) zxdg_surface_v6_destroy(window->zxdg_surface);
1417    window->zxdg_surface = NULL;
1418    // END of TIZEN_ONLY(20180614)
1419
1420    // TIZEN_ONLY(20181011) : destroy shell surface and its role
1421    if (window->xdg_popup) xdg_popup_destroy(window->xdg_popup);
1422    window->xdg_popup = NULL;
1423
1424    if (window->xdg_toplevel) xdg_toplevel_destroy(window->xdg_toplevel);
1425    window->xdg_toplevel = NULL;
1426
1427    if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface);
1428    window->xdg_surface = NULL;
1429    // END of TIZEN_ONLY(20181011)
1430
1431    window->set_config.serial = 0;
1432    window->req_config.serial = 0;
1433    window->def_config.serial = 0;
1434    window->zxdg_configure_ack = NULL;
1435    window->xdg_configure_ack = NULL;
1436    window->xdg_set_min_size = NULL;
1437    window->xdg_set_max_size = NULL;
1438    window->zxdg_set_min_size = NULL;
1439    window->zxdg_set_max_size = NULL;
1440 }
1441
1442 static void
1443 _ecore_wl2_window_aux_hint_free(Ecore_Wl2_Window *win)
1444 {
1445    const char *supported;
1446
1447    EINA_LIST_FREE(win->supported_aux_hints, supported)
1448      if (supported) eina_stringshare_del(supported);
1449 }
1450
1451 // TIZEN_ONLY(20200601): support sync between ui and video
1452 static void
1453 _ecore_wl2_window_video_surface_destroy(Ecore_Wl2_Window *win)
1454 {
1455    if (win->video.viewport)
1456      {
1457         tizen_viewport_destroy(win->video.viewport);
1458         win->video.viewport = NULL;
1459      }
1460    if (win->video.wl_buffer)
1461      {
1462         wayland_tbm_client_destroy_buffer(win->tbm_client, win->video.wl_buffer);
1463         win->video.wl_buffer = NULL;
1464      }
1465
1466    if (win->video.tbm_surface)
1467      {
1468         tbm_surface_destroy(win->video.tbm_surface);
1469         win->video.tbm_surface = NULL;
1470      }
1471
1472    if (win->video.subsurface)
1473      {
1474         wl_subsurface_destroy(win->video.subsurface);
1475         win->video.subsurface = NULL;
1476      }
1477    if (win->video.surface)
1478      {
1479         wl_surface_destroy(win->video.surface);
1480         win->video.surface = NULL;
1481      }
1482 }
1483 //
1484
1485 EAPI void
1486 ecore_wl2_window_free(Ecore_Wl2_Window *window)
1487 {
1488    Ecore_Wl2_Display *display;
1489    Ecore_Wl2_Input *input;
1490    Ecore_Wl2_Subsurface *subsurf;
1491    Eina_Inlist *tmp;
1492    Ecore_Wl2_Window_Aux_Hint *hint;
1493
1494    EINA_SAFETY_ON_NULL_RETURN(window);
1495
1496    // TIZEN_ONLY(20210330): for maintain internal aux hint list
1497    EINA_LIST_FREE(window->aux_hints, hint)
1498      {
1499         eina_stringshare_del(hint->hint);
1500         eina_stringshare_del(hint->val);
1501      }
1502    //
1503
1504 //TIZEN_ONLY(20171216): add ecore_wl2_window_find
1505    eina_hash_del(_windows, _ecore_wl2_window_id_str_get(window->id), window);
1506 //
1507
1508    if (window->visible) _ecore_wl2_window_hide_send(window);
1509
1510    _ecore_wl2_window_create_destroy_send(window, EINA_FALSE);
1511
1512    display = window->display;
1513
1514    EINA_INLIST_FOREACH(display->inputs, input)
1515       _ecore_wl2_input_window_remove(input, window);
1516
1517    EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp, subsurf)
1518      _ecore_wl2_subsurf_free(subsurf);
1519
1520    _ecore_wl2_window_aux_hint_free(window);
1521
1522    // TIZEN_ONLY(20171112) : support tizen protocols
1523    if (window->tz_visibility) tizen_visibility_destroy(window->tz_visibility);
1524    window->tz_visibility = NULL;
1525
1526    if (window->tz_position) tizen_position_destroy(window->tz_position);
1527    window->tz_position = NULL;
1528
1529    if (window->tz_rotation) tizen_rotation_destroy(window->tz_rotation);
1530    window->tz_rotation = NULL;
1531
1532    if (window->tz_resource) tizen_resource_destroy(window->tz_resource);
1533    window->tz_resource = NULL;
1534    //
1535
1536    // TIZEN_ONLY(20200601): support sync between ui and video
1537    _ecore_wl2_window_video_surface_destroy(window);
1538
1539    if (window->tbm_client)
1540      {
1541         wayland_tbm_client_deinit(window->tbm_client);
1542         window->tbm_client = NULL;
1543      }
1544    //
1545
1546    if (window->callback) wl_callback_destroy(window->callback);
1547    window->callback = NULL;
1548
1549    if (window->uuid && window->surface && window->display->wl.session_recovery)
1550      zwp_e_session_recovery_destroy_uuid(window->display->wl.session_recovery,
1551                                          window->surface, window->uuid);
1552
1553    _ecore_wl2_window_semi_free(window);
1554
1555    eina_stringshare_replace(&window->uuid, NULL);
1556
1557    if (window->title) eina_stringshare_del(window->title);
1558    if (window->class) eina_stringshare_del(window->class);
1559    if (window->role) eina_stringshare_del(window->role);
1560    // TIZEN_ONLY(20160201) : support to handle input rectangle
1561    if (window->input_region) wl_region_destroy(window->input_region);
1562    window->input_region = NULL;
1563    //
1564
1565    if (window->wm_rot.available_rots) free(window->wm_rot.available_rots);
1566    window->wm_rot.available_rots = NULL;
1567
1568    display->windows =
1569      eina_inlist_remove(display->windows, EINA_INLIST_GET(window));
1570
1571    ecore_wl2_display_disconnect(window->display);
1572    free(window);
1573 }
1574
1575 EAPI void
1576 ecore_wl2_window_move(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
1577 {
1578    EINA_SAFETY_ON_NULL_RETURN(window);
1579    EINA_SAFETY_ON_NULL_RETURN(window->display->inputs);
1580
1581    if (!input)
1582      {
1583         ERR("NULL input parameter is deprecated");
1584         input = EINA_INLIST_CONTAINER_GET(window->display->inputs, Ecore_Wl2_Input);
1585      }
1586    if (window->xdg_toplevel)
1587      xdg_toplevel_move(window->xdg_toplevel, input->wl.seat,
1588                            window->display->serial);
1589    if (window->zxdg_toplevel)
1590      zxdg_toplevel_v6_move(window->zxdg_toplevel, input->wl.seat,
1591                            window->display->serial);
1592    ecore_wl2_display_flush(window->display);
1593
1594    _ecore_wl2_input_ungrab(input);
1595 }
1596
1597 EAPI void
1598 ecore_wl2_window_resize(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input, int location)
1599 {
1600    EINA_SAFETY_ON_NULL_RETURN(window);
1601    EINA_SAFETY_ON_NULL_RETURN(window->display->inputs);
1602
1603    if (!input)
1604      {
1605         ERR("NULL input parameter is deprecated");
1606         input = EINA_INLIST_CONTAINER_GET(window->display->inputs, Ecore_Wl2_Input);
1607      }
1608
1609    if (window->xdg_toplevel)
1610      xdg_toplevel_resize(window->xdg_toplevel, input->wl.seat,
1611                              window->display->serial, location);
1612    if (window->zxdg_toplevel)
1613      zxdg_toplevel_v6_resize(window->zxdg_toplevel, input->wl.seat,
1614                              window->display->serial, location);
1615    ecore_wl2_display_flush(window->display);
1616
1617    _ecore_wl2_input_ungrab(input);
1618 }
1619
1620 EAPI void
1621 ecore_wl2_window_raise(Ecore_Wl2_Window *window)
1622 {
1623    EINA_SAFETY_ON_NULL_RETURN(window);
1624    EINA_SAFETY_ON_NULL_RETURN(window->display);
1625
1626 // TIZEN_ONLY(20171114)
1627 /*
1628    if (window->zxdg_toplevel)
1629      {
1630         struct wl_array states;
1631         uint32_t *s;
1632
1633         wl_array_init(&states);
1634         s = wl_array_add(&states, sizeof(*s));
1635         *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
1636         _zxdg_toplevel_cb_configure(window, window->zxdg_toplevel,
1637                                     window->set_config.geometry.w,
1638                                     window->set_config.geometry.h, &states);
1639         wl_array_release(&states);
1640      }
1641 */
1642    if ((window->surface) && (window->display->wl.tz_policy))
1643      tizen_policy_raise(window->display->wl.tz_policy, window->surface);
1644 //
1645 }
1646
1647 EAPI void
1648 ecore_wl2_window_lower(Ecore_Wl2_Window *window)
1649 {
1650    Ecore_Wl2_Event_Window_Lower *ev;
1651
1652    EINA_SAFETY_ON_NULL_RETURN(window);
1653    EINA_SAFETY_ON_NULL_RETURN(window->display);
1654
1655    /* FIXME: This should lower the xdg surface also */
1656    if (window->display->wl.tz_policy)
1657      {
1658         tizen_policy_lower(window->display->wl.tz_policy, window->surface);
1659
1660         if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Lower)))) return;
1661
1662         ev->win = window->id;
1663         ecore_event_add(ECORE_WL2_EVENT_WINDOW_LOWER, ev, NULL, NULL);
1664      }
1665 }
1666
1667 EAPI void
1668 ecore_wl2_window_activate(Ecore_Wl2_Window *window)
1669 {
1670    Eina_Bool iconic;
1671
1672    EINA_SAFETY_ON_NULL_RETURN(window);
1673    EINA_SAFETY_ON_NULL_RETURN(window->display);
1674
1675    iconic = ecore_wl2_window_iconified_get(window);
1676    if (iconic)
1677      ecore_wl2_window_iconified_set(window, EINA_FALSE);
1678
1679    if (window->display->wl.tz_policy)
1680      tizen_policy_activate(window->display->wl.tz_policy, window->surface);
1681 }
1682
1683 EAPI void
1684 ecore_wl2_window_parent_set(Ecore_Wl2_Window *window, Ecore_Wl2_Window *parent)
1685 {
1686    EINA_SAFETY_ON_NULL_RETURN(window);
1687    window->parent = parent;
1688 // TIZEN_ONLY(20210903): for transient_for below
1689    window->below_child = EINA_FALSE;
1690 //
1691
1692 // TIZEN_ONLY(20171114)
1693    if (window->parent)
1694      {
1695         if (window->zxdg_surface && window->parent->zxdg_surface)
1696           {
1697              struct zxdg_toplevel_v6 *ptop = NULL;
1698
1699              ptop = window->parent->zxdg_toplevel;
1700              if (ptop)
1701                zxdg_toplevel_v6_set_parent(window->zxdg_toplevel, ptop);
1702           }
1703         else if (window->display->wl.tz_policy && window->surface && window->parent->surface)
1704           {
1705              uint32_t ver = wl_proxy_get_version((struct wl_proxy *)window->display->wl.tz_policy);
1706              if (ver >= 3)
1707                tizen_policy_set_parent(window->display->wl.tz_policy, window->surface, window->parent->surface);
1708           }
1709      }
1710    else
1711      {
1712         if (window->zxdg_surface)
1713           zxdg_toplevel_v6_set_parent(window->zxdg_toplevel, NULL);
1714      }
1715 //
1716 }
1717
1718 // TIZEN_ONLY(20210721) : for below child
1719 static void
1720 _ecore_wl2_window_parent_set_with_below(Ecore_Wl2_Window *window, Ecore_Wl2_Window *parent)
1721 {
1722    window->parent = parent;
1723    window->below_child = EINA_TRUE;
1724    if (window->parent)
1725      {
1726         if (window->parent->surface)
1727           tizen_policy_set_parent_with_below(window->display->wl.tz_policy, window->surface, window->parent->surface);
1728         else
1729           ERR("Fail to set parent below. Parent window's surface doesn't exist.");
1730      }
1731    else
1732      {
1733         tizen_policy_set_parent_with_below(window->display->wl.tz_policy, window->surface, NULL);
1734      }
1735 }
1736
1737 EAPI void
1738 ecore_wl2_window_transient_parent_set(Ecore_Wl2_Window *window, Ecore_Wl2_Window *parent, Eina_Bool place_below)
1739 {
1740    EINA_SAFETY_ON_NULL_RETURN(window);
1741    EINA_SAFETY_ON_NULL_RETURN(window->surface);
1742    EINA_SAFETY_ON_NULL_RETURN(window->display->wl.tz_policy);
1743
1744    uint32_t ver = wl_proxy_get_version((struct wl_proxy *)window->display->wl.tz_policy);
1745    if (ver < TIZEN_POLICY_SET_PARENT_WITH_BELOW_SINCE_VERSION)
1746      {
1747         ERR("ecore_wl2_window_transient_parent_set is not supported in this version:%d (required version:%d)",
1748             ver, TIZEN_POLICY_SET_PARENT_WITH_BELOW_SINCE_VERSION);
1749         ecore_wl2_window_parent_set(window, parent);
1750         return;
1751      }
1752
1753    if (place_below)
1754      _ecore_wl2_window_parent_set_with_below(window, parent);
1755    else
1756      ecore_wl2_window_parent_set(window, parent);
1757 }
1758 //
1759
1760 EAPI void
1761 ecore_wl2_window_stack_mode_set(Ecore_Wl2_Window *window, Ecore_Wl2_Window_Stack_Mode mode)
1762 {
1763    EINA_SAFETY_ON_NULL_RETURN(window);
1764    EINA_SAFETY_ON_NULL_RETURN(window->display);
1765
1766    if ((window->surface) && (window->display->wl.tz_policy))
1767      tizen_policy_set_stack_mode(window->display->wl.tz_policy, window->surface, mode);
1768 }
1769
1770 EAPI void
1771 ecore_wl2_window_position_set(Ecore_Wl2_Window *window, int x, int y)
1772 {
1773    EINA_SAFETY_ON_NULL_RETURN(window);
1774
1775    if ((window->set_config.geometry.x != x) ||
1776        (window->set_config.geometry.y != y))
1777      window->pending.geom = EINA_TRUE;
1778
1779    window->set_config.geometry.x = x;
1780    window->set_config.geometry.y = y;
1781
1782    if ((window->surface) && (window->tz_position))
1783      {
1784         if ((window->def_config.geometry.x != x) || (window->def_config.geometry.y != y))
1785           tizen_position_set(window->tz_position, x, y);
1786      }
1787 }
1788
1789 EAPI int
1790 ecore_wl2_window_active_angle_get(Ecore_Wl2_Window *window)
1791 {
1792    struct wl_surface *surface = NULL;
1793
1794    EINA_SAFETY_ON_NULL_RETURN_VAL(window, 0);
1795    EINA_SAFETY_ON_NULL_RETURN_VAL(window->display, 0);
1796
1797    if (!window->display->wl.tz_policy_ext) return 0;
1798
1799    surface = ecore_wl2_window_surface_get(window);
1800
1801    tizen_policy_ext_get_active_angle(window->display->wl.tz_policy_ext, surface);
1802    ecore_wl2_display_sync(window->display);
1803
1804    return window->display->active_angle;
1805 }
1806 //
1807
1808 EAPI Eina_Bool
1809 ecore_wl2_window_alpha_get(Ecore_Wl2_Window *window)
1810 {
1811    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1812
1813    return window->alpha;
1814 }
1815
1816 EAPI void
1817 ecore_wl2_window_alpha_set(Ecore_Wl2_Window *window, Eina_Bool alpha)
1818 {
1819    Ecore_Wl2_Surface *surf = NULL;
1820
1821    EINA_SAFETY_ON_NULL_RETURN(window);
1822
1823    if (window->alpha == alpha) return;
1824
1825    window->alpha = alpha;
1826    surf = window->wl2_surface;
1827    if (surf)
1828      ecore_wl2_surface_reconfigure(surf, surf->w, surf->h, 0, alpha);
1829
1830 // TIZEN_ONLY(20170203)
1831    if (!window->alpha)
1832      {
1833         ecore_wl2_window_opaque_region_set(window, window->opaque.x,
1834                                            window->opaque.y, window->opaque.w,
1835                                            window->opaque.h);
1836 // TIZEN_ONLY(20190910) : set opaque_set and pending.opaque value by force
1837         window->opaque_set = window->opaque.x || window->opaque.y || window->opaque.w || window->opaque.h;
1838         _opaque_set(window);
1839 //
1840      }
1841    else if (window->surface)
1842      _opaque_region_set(window, NULL);
1843 //
1844 }
1845
1846 EAPI void
1847 ecore_wl2_window_transparent_set(Ecore_Wl2_Window *window, Eina_Bool transparent)
1848 {
1849    EINA_SAFETY_ON_NULL_RETURN(window);
1850
1851    if (window->transparent == transparent) return;
1852
1853    window->transparent = transparent;
1854
1855    if (!window->transparent)
1856      {
1857         ecore_wl2_window_opaque_region_set(window, window->opaque.x,
1858                                            window->opaque.y, window->opaque.w,
1859                                            window->opaque.h);
1860 // TIZEN_ONLY(20190910) : set opaque_set and pending.opaque value by force
1861         window->opaque_set = window->opaque.x || window->opaque.y || window->opaque.w || window->opaque.h;
1862         _opaque_set(window);
1863 //
1864      }
1865 // TIZEN_ONLY(20170203)
1866 /*
1867    else
1868      ecore_wl2_window_opaque_region_set(window, 0, 0, 0, 0);
1869 */
1870    else if (window->surface)
1871      _opaque_region_set(window, NULL);
1872 //
1873 }
1874
1875 // TIZEN_ONLY(20171108) : Get a window's transparent property
1876 EAPI Eina_Bool
1877 ecore_wl2_window_transparent_get(Ecore_Wl2_Window *window)
1878 {
1879    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1880
1881    return window->transparent;
1882 }
1883 //
1884
1885 EAPI void
1886 ecore_wl2_window_opaque_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
1887 {
1888    int nx = 0, ny = 0, nw = 0, nh = 0;
1889
1890    EINA_SAFETY_ON_NULL_RETURN(window);
1891
1892    switch (window->rotation)
1893      {
1894       case 0:
1895         nx = x;
1896         ny = y;
1897         nw = w;
1898         nh = h;
1899         break;
1900       case 90:
1901         nx = y;
1902         ny = x;
1903         nw = h;
1904         nh = w;
1905         break;
1906       case 180:
1907         nx = x;
1908         ny = x + y;
1909         nw = w;
1910         nh = h;
1911         break;
1912       case 270:
1913         nx = x + y;
1914         ny = x;
1915         nw = h;
1916         nh = w;
1917         break;
1918       default:
1919         break;
1920      }
1921
1922    if ((window->opaque.x == nx) && (window->opaque.y == ny) &&
1923        (window->opaque.w == nw) && (window->opaque.h == nh))
1924      return;
1925
1926    window->opaque.x = nx;
1927    window->opaque.y = ny;
1928    window->opaque.w = nw;
1929    window->opaque.h = nh;
1930
1931 // TIZEN_ONLY(20180412) : check transparent and alpha value
1932    if ((window->transparent) || (window->alpha))
1933      return;
1934 //
1935
1936    window->opaque_set = x || y || w || h;
1937    window->pending.opaque = EINA_TRUE;
1938 }
1939
1940 // TIZEN_ONLY(20160201) : support to handle input rectangle
1941 EAPI void
1942 ecore_wl2_window_input_rect_set(Ecore_Wl2_Window *win, Eina_Rectangle *input_rect)
1943 {
1944    if (!win) return;
1945    if (!input_rect) return;
1946    if (win->input_region)
1947      {
1948         wl_region_destroy(win->input_region);
1949         win->input_region = NULL;
1950      }
1951
1952    win->input_rect.x = input_rect->x;
1953    win->input_rect.y = input_rect->y;
1954    win->input_rect.w = input_rect->w;
1955    win->input_rect.h = input_rect->h;
1956
1957    if (win->type != ECORE_WL2_WINDOW_TYPE_DND)
1958      {
1959         struct wl_region *region;
1960         region = wl_compositor_create_region(win->display->wl.compositor);
1961         if (!region) return;
1962
1963         wl_region_add(region, input_rect->x, input_rect->y, input_rect->w, input_rect->h);
1964         wl_surface_set_input_region(win->surface, region);
1965         wl_region_destroy(region);
1966      }
1967 }
1968
1969 EAPI void
1970 ecore_wl2_window_input_rect_add(Ecore_Wl2_Window *win, Eina_Rectangle *input_rect)
1971 {
1972    if (!win) return;
1973    if (!input_rect) return;
1974    if (input_rect->x < 0 || input_rect->y < 0) return;
1975
1976    if (win->type != ECORE_WL2_WINDOW_TYPE_DND)
1977      {
1978         if (!win->input_region)
1979           {
1980              struct wl_region *region;
1981              region = wl_compositor_create_region(win->display->wl.compositor);
1982              if (!region) return;
1983
1984              win->input_region = region;
1985           }
1986
1987         wl_region_add(win->input_region, input_rect->x, input_rect->y, input_rect->w, input_rect->h);
1988         wl_surface_set_input_region(win->surface, win->input_region);
1989      }
1990 }
1991
1992 EAPI void
1993 ecore_wl2_window_input_rect_subtract(Ecore_Wl2_Window *win, Eina_Rectangle *input_rect)
1994 {
1995    if (!win) return;
1996    if (!input_rect) return;
1997    if (input_rect->x < 0 || input_rect->y < 0) return;
1998    if (!win->input_region) return;
1999
2000    if (win->type != ECORE_WL2_WINDOW_TYPE_DND)
2001      {
2002         wl_region_subtract(win->input_region, input_rect->x, input_rect->y, input_rect->w, input_rect->h);
2003         wl_surface_set_input_region(win->surface, win->input_region);
2004      }
2005 }
2006 //
2007
2008 EAPI void
2009 ecore_wl2_window_opaque_region_get(Ecore_Wl2_Window *window, int *x, int *y, int *w, int *h)
2010 {
2011    EINA_SAFETY_ON_NULL_RETURN(window);
2012
2013    if (x) *x = window->opaque.x;
2014    if (y) *y = window->opaque.y;
2015    if (w) *w = window->opaque.w;
2016    if (h) *h = window->opaque.h;
2017 }
2018
2019 EAPI void
2020 ecore_wl2_window_input_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
2021 {
2022    int nx = 0, ny = 0, nw = 0, nh = 0;
2023
2024    EINA_SAFETY_ON_NULL_RETURN(window);
2025
2026    switch (window->rotation)
2027      {
2028       case 0:
2029         nx = x;
2030         ny = y;
2031         nw = w;
2032         nh = h;
2033         break;
2034       case 90:
2035         nx = y;
2036         ny = x;
2037         nw = h;
2038         nh = w;
2039         break;
2040       case 180:
2041         nx = x;
2042         ny = x + y;
2043         nw = w;
2044         nh = h;
2045         break;
2046       case 270:
2047         nx = x + y;
2048         ny = x;
2049         nw = h;
2050         nh = w;
2051         break;
2052       default:
2053         break;
2054      }
2055
2056    if ((window->input_rect.x == nx) && (window->input_rect.y == ny) &&
2057        (window->input_rect.w == nw) && (window->input_rect.h == nh))
2058      return;
2059
2060    window->input_rect.x = nx;
2061    window->input_rect.y = ny;
2062    window->input_rect.w = nw;
2063    window->input_rect.h = nh;
2064    window->input_set = x || y || w || h;
2065    window->pending.input = EINA_TRUE;
2066 }
2067
2068 EAPI void
2069 ecore_wl2_window_input_region_get(Ecore_Wl2_Window *window, int *x, int *y, int *w, int *h)
2070 {
2071    EINA_SAFETY_ON_NULL_RETURN(window);
2072
2073    if (x) *x = window->input_rect.x;
2074    if (y) *y = window->input_rect.y;
2075    if (w) *w = window->input_rect.w;
2076    if (h) *h = window->input_rect.h;
2077 }
2078
2079 EAPI Eina_Bool
2080 ecore_wl2_window_maximized_get(Ecore_Wl2_Window *window)
2081 {
2082    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2083
2084    return window->set_config.maximized;
2085 }
2086
2087 static Eina_Bool
2088 _ecore_wl2_window_maximized_direction_set(Ecore_Wl2_Window *window, Ecore_Wl2_Maximize_Direction direction)
2089 {
2090    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2091    EINA_SAFETY_ON_NULL_RETURN_VAL(window->surface, EINA_FALSE);
2092    EINA_SAFETY_ON_NULL_RETURN_VAL(window->display->wl.tz_policy, EINA_FALSE);
2093
2094    window->maximize_direction = direction;
2095
2096    uint32_t ver = wl_proxy_get_version((struct wl_proxy *)window->display->wl.tz_policy);
2097
2098 #ifdef TIZEN_POLICY_SET_MAXIMIZE_DIRECTION_SINCE_VERSION
2099    if (ver < TIZEN_POLICY_SET_MAXIMIZE_DIRECTION_SINCE_VERSION)
2100      {
2101         ERR("[WINDOW] Maximize direction is not supported on this version(%d). It is supported since version %d.",
2102             ver, TIZEN_POLICY_SET_MAXIMIZE_DIRECTION_SINCE_VERSION);
2103         return EINA_FALSE;
2104      }
2105
2106    tizen_policy_set_maximize_direction(window->display->wl.tz_policy, window->surface, direction);
2107
2108    return EINA_TRUE;
2109 #else
2110    return EINA_FALSE;
2111 #endif
2112 }
2113
2114 EAPI void
2115 ecore_wl2_window_maximized_set_with_direction(Ecore_Wl2_Window *window, Ecore_Wl2_Maximize_Direction direction)
2116 {
2117    Eina_Bool maximized = EINA_TRUE;
2118    Eina_Bool changed_maximize_state = EINA_FALSE;
2119
2120    EINA_SAFETY_ON_NULL_RETURN(window);
2121
2122    if (window->maximize_direction == direction)
2123      {
2124         ERR("[WINDOW] win:%d, SAME direction:%d... so return.......", window->resource_id, direction);
2125         return;
2126      }
2127
2128    _ecore_wl2_window_maximized_direction_set(window, direction);
2129
2130    if (direction == ECORE_WL2_MAXIMIZE_DIRECTION_NONE)
2131      maximized = EINA_FALSE;
2132
2133    if (window->set_config.maximized != maximized)
2134      changed_maximize_state = EINA_TRUE;
2135
2136    window->set_config.maximized = maximized;
2137    if (window->updating)
2138      {
2139         window->pending.maximized = EINA_TRUE;
2140         return;
2141      }
2142
2143    if (changed_maximize_state)
2144      {
2145         if (maximized)
2146           {
2147              if (!window->set_config.fullscreen)
2148                window->saved = window->set_config.geometry;
2149
2150              if (window->xdg_toplevel)
2151                xdg_toplevel_set_maximized(window->xdg_toplevel);
2152              if (window->zxdg_toplevel)
2153                zxdg_toplevel_v6_set_maximized(window->zxdg_toplevel);
2154           }
2155         else
2156           {
2157              if (window->xdg_toplevel)
2158                xdg_toplevel_unset_maximized(window->xdg_toplevel);
2159              if (window->zxdg_toplevel)
2160                zxdg_toplevel_v6_unset_maximized(window->zxdg_toplevel);
2161           }
2162      }
2163
2164    /* TIZEN_ONLY(20190522): The window properties of ecore_evas are updated in
2165     * _ecore_evas_wl_common_cb_window_configure.
2166     * To call _ecore_evas_wl_common_cb_window_configure,
2167     * ECORE_WL2_EVENT_WINDOW_CONFIGURE event is added.
2168     * To add ECORE_WL2_EVENT_WINDOW_CONFIGURE event,
2169     * _ecore_wl2_window_configure_send is called. */
2170    _ecore_wl2_window_configure_send(window);
2171    /* END of TIZEN_ONLY(20190522) */
2172    ecore_wl2_display_flush(window->display);
2173 }
2174
2175 EAPI void
2176 ecore_wl2_window_maximized_set(Ecore_Wl2_Window *window, Eina_Bool maximized)
2177 {
2178    if (maximized)
2179      ecore_wl2_window_maximized_set_with_direction(window, ECORE_WL2_MAXIMIZE_DIRECTION_ALL);
2180    else
2181      ecore_wl2_window_maximized_set_with_direction(window, ECORE_WL2_MAXIMIZE_DIRECTION_NONE);
2182 }
2183
2184 EAPI Eina_Bool
2185 ecore_wl2_window_fullscreen_get(Ecore_Wl2_Window *window)
2186 {
2187    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2188
2189    return window->set_config.fullscreen;
2190 }
2191
2192 EAPI void
2193 ecore_wl2_window_fullscreen_set(Ecore_Wl2_Window *window, Eina_Bool fullscreen)
2194 {
2195    Eina_Bool prev;
2196
2197    EINA_SAFETY_ON_NULL_RETURN(window);
2198
2199    prev = window->set_config.fullscreen;
2200    fullscreen = !!fullscreen;
2201    if (prev == fullscreen) return;
2202
2203    window->set_config.fullscreen = fullscreen;
2204    if (window->updating)
2205      {
2206         window->pending.fullscreen = EINA_TRUE;
2207         return;
2208      }
2209
2210    if (fullscreen)
2211      {
2212         if (!window->set_config.maximized)
2213           window->saved = window->set_config.geometry;
2214
2215         if (window->xdg_toplevel)
2216           xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
2217         if (window->zxdg_toplevel)
2218           zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL);
2219      }
2220    else
2221      {
2222         if (window->xdg_toplevel)
2223           xdg_toplevel_unset_fullscreen(window->xdg_toplevel);
2224         if (window->zxdg_toplevel)
2225           zxdg_toplevel_v6_unset_fullscreen(window->zxdg_toplevel);
2226      }
2227    /* TIZEN_ONLY(20190522): The window properties of ecore_evas are updated in
2228     * _ecore_evas_wl_common_cb_window_configure.
2229     * To call _ecore_evas_wl_common_cb_window_configure,
2230     * ECORE_WL2_EVENT_WINDOW_CONFIGURE event is added.
2231     * To add ECORE_WL2_EVENT_WINDOW_CONFIGURE event,
2232     * _ecore_wl2_window_configure_send is called. */
2233    _ecore_wl2_window_configure_send(window);
2234    /* END of TIZEN_ONLY(20190522) */
2235    ecore_wl2_display_flush(window->display);
2236 }
2237
2238 EAPI int
2239 ecore_wl2_window_rotation_get(Ecore_Wl2_Window *window)
2240 {
2241    EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
2242
2243    return window->rotation;
2244 }
2245
2246 EAPI void
2247 ecore_wl2_window_rotation_set(Ecore_Wl2_Window *window, int rotation)
2248 {
2249    EINA_SAFETY_ON_NULL_RETURN(window);
2250
2251    window->rotation = rotation;
2252 }
2253
2254 EAPI void
2255 ecore_wl2_window_title_set(Ecore_Wl2_Window *window, const char *title)
2256 {
2257    EINA_SAFETY_ON_NULL_RETURN(window);
2258
2259    eina_stringshare_replace(&window->title, title);
2260    if (!window->title) return;
2261    if (!window->xdg_toplevel && !window->zxdg_toplevel) return;
2262
2263    if (window->xdg_toplevel)
2264      xdg_toplevel_set_title(window->xdg_toplevel, window->title);
2265    if (window->zxdg_toplevel)
2266      zxdg_toplevel_v6_set_title(window->zxdg_toplevel, window->title);
2267    ecore_wl2_display_flush(window->display);
2268 }
2269
2270 EAPI const char *
2271 ecore_wl2_window_title_get(Ecore_Wl2_Window *window)
2272 {
2273    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2274
2275    return window->title ? window->title : NULL;
2276 }
2277
2278 EAPI void
2279 ecore_wl2_window_class_set(Ecore_Wl2_Window *window, const char *clas)
2280 {
2281    EINA_SAFETY_ON_NULL_RETURN(window);
2282
2283    eina_stringshare_replace(&window->class, clas);
2284    if (!window->class) return;
2285    if (!window->xdg_toplevel && !window->zxdg_toplevel) return;
2286
2287    if (window->xdg_toplevel)
2288      xdg_toplevel_set_app_id(window->xdg_toplevel, window->class);
2289    if (window->zxdg_toplevel)
2290      zxdg_toplevel_v6_set_app_id(window->zxdg_toplevel, window->class);
2291    ecore_wl2_display_flush(window->display);
2292 }
2293
2294 EAPI const char *
2295 ecore_wl2_window_class_get(Ecore_Wl2_Window *window)
2296 {
2297    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2298
2299    return window->class ? window->class : NULL;
2300 }
2301
2302 EAPI void
2303 ecore_wl2_window_geometry_get(Ecore_Wl2_Window *window, int *x, int *y, int *w, int *h)
2304 {
2305    EINA_SAFETY_ON_NULL_RETURN(window);
2306
2307    if (x) *x = window->set_config.geometry.x;
2308    if (y) *y = window->set_config.geometry.y;
2309    if (w) *w = window->set_config.geometry.w;
2310    if (h) *h = window->set_config.geometry.h;
2311 }
2312
2313 EAPI void
2314 ecore_wl2_window_geometry_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
2315 {
2316    EINA_SAFETY_ON_NULL_RETURN(window);
2317
2318    if ((window->set_config.geometry.x == x) &&
2319        (window->set_config.geometry.y == y) &&
2320        (window->set_config.geometry.w == w) &&
2321        (window->set_config.geometry.h == h))
2322      return;
2323
2324    window->set_config.geometry.x = x;
2325    window->set_config.geometry.y = y;
2326    window->set_config.geometry.w = w;
2327    window->set_config.geometry.h = h;
2328    window->pending.geom = EINA_TRUE;
2329 }
2330
2331 //TIZEN_ONLY(20220325): added min / max size set to window
2332 EAPI void
2333 ecore_wl2_window_minimum_size_set(Ecore_Wl2_Window *window, int w, int h)
2334 {
2335    EINA_SAFETY_ON_NULL_RETURN(window);
2336
2337    if (window->zxdg_set_min_size && window->zxdg_toplevel)
2338      {
2339         window->zxdg_set_min_size(window->zxdg_toplevel, w, h);
2340         window->pending.min = 0;
2341         return;
2342      }
2343    if (window->xdg_set_min_size && window->xdg_toplevel)
2344      {
2345         window->xdg_set_min_size(window->xdg_toplevel, w, h);
2346         window->pending.min = 0;
2347         return;
2348      }
2349 }
2350
2351 EAPI void
2352 ecore_wl2_window_maximum_size_set(Ecore_Wl2_Window *window, int w, int h)
2353 {
2354    EINA_SAFETY_ON_NULL_RETURN(window);
2355
2356    if (window->zxdg_set_max_size && window->zxdg_toplevel)
2357      {
2358         window->zxdg_set_max_size(window->zxdg_toplevel, w, h);
2359         window->pending.max = 0;
2360         return;
2361      }
2362    if (window->xdg_set_max_size && window->xdg_toplevel)
2363      {
2364         window->xdg_set_max_size(window->xdg_toplevel, w, h);
2365         window->pending.max = 0;
2366         return;
2367      }
2368 }
2369 //
2370
2371 EAPI Eina_Bool
2372 ecore_wl2_window_iconified_get(Ecore_Wl2_Window *window)
2373 {
2374    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2375
2376    // TIZEN_ONLY(20150822)
2377    if (window->display->wl.tz_policy)
2378      return window->iconified;
2379    else
2380    //
2381    return window->set_config.minimized;
2382 }
2383
2384 // TIZEN_ONLY(20151231) : handling iconic state on tizen
2385 static void
2386 _ecore_wl2_window_iconified_set(Ecore_Wl2_Window *window, Eina_Bool iconified, Eina_Bool send_event)
2387 {
2388    Eina_Bool prev;
2389
2390    EINA_SAFETY_ON_NULL_RETURN(window);
2391
2392    prev = window->set_config.minimized;
2393    iconified = !!iconified;
2394    if (prev == iconified) return;
2395
2396    window->set_config.minimized = iconified;
2397
2398    if (iconified)
2399      {
2400         if ((window->surface) && (window->display->wl.tz_policy))
2401           {
2402              if (send_event)
2403                tizen_policy_iconify(window->display->wl.tz_policy, window->surface);
2404              window->iconified = EINA_TRUE;
2405           }
2406
2407         else if (window->zxdg_toplevel)
2408           zxdg_toplevel_v6_set_minimized(window->zxdg_toplevel);
2409      }
2410    else
2411      {
2412         if ((window->surface) && (window->display->wl.tz_policy))
2413           {
2414              if (send_event)
2415                tizen_policy_uniconify(window->display->wl.tz_policy, window->surface);
2416              window->iconified = EINA_FALSE;
2417           }
2418
2419         else if (window->zxdg_toplevel)
2420           {
2421              struct wl_array states;
2422              uint32_t *s;
2423
2424              wl_array_init(&states);
2425              s = wl_array_add(&states, sizeof(*s));
2426              *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
2427              _zxdg_toplevel_cb_configure(window, window->zxdg_toplevel,
2428                                          window->saved.w,
2429                                          window->saved.h, &states);
2430              wl_array_release(&states);
2431           }
2432      }
2433
2434    if (send_event)
2435      {
2436         Ecore_Wl2_Event_Window_Iconify_State_Change *ev;
2437
2438         if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Iconify_State_Change)))) return;
2439         ev->win = window->id;
2440         ev->iconified = iconified;
2441         ev->force = 0;
2442         ecore_event_add(ECORE_WL2_EVENT_WINDOW_ICONIFY_STATE_CHANGE, ev, NULL, NULL);
2443      }
2444 }
2445 //
2446
2447 EAPI void
2448 ecore_wl2_window_iconified_set(Ecore_Wl2_Window *window, Eina_Bool iconified)
2449 {
2450    // TIZEN_ONLY(20151231) : handling iconic state on tizen
2451    /*
2452    Eina_Bool prev;
2453
2454    EINA_SAFETY_ON_NULL_RETURN(window);
2455
2456    prev = window->set_config.minimized;
2457    iconified = !!iconified;
2458    if (prev == iconified) return;
2459
2460    window->set_config.minimized = iconified;
2461
2462    if (iconified)
2463      {
2464         if (window->xdg_toplevel)
2465           xdg_toplevel_set_minimized(window->xdg_toplevel);
2466         if (window->zxdg_toplevel)
2467           zxdg_toplevel_v6_set_minimized(window->zxdg_toplevel);
2468         ecore_wl2_display_flush(window->display);
2469      }
2470    */
2471    _ecore_wl2_window_iconified_set(window, iconified, EINA_TRUE);
2472    //
2473 }
2474
2475 // TIZEN_ONLY(20151231) : handling iconic state on tizen
2476 EAPI void
2477 ecore_wl2_window_iconify_state_update(Ecore_Wl2_Window *window, Eina_Bool iconified, Eina_Bool send_event)
2478 {
2479    _ecore_wl2_window_iconified_set(window, iconified, send_event);
2480 }
2481 //
2482
2483 //TIZEN_ONLY(20171216): add ecore_wl2_window_find
2484 EAPI Ecore_Wl2_Window *
2485 ecore_wl2_window_find(unsigned int id)
2486 {
2487    Ecore_Wl2_Window *win = NULL;
2488
2489    if (!_windows) return NULL;
2490    win = eina_hash_find(_windows, _ecore_wl2_window_id_str_get(id));
2491    return win;
2492 }
2493 //
2494
2495 //TIZEN_ONLY(20180202): Fix to send a proper window type value to the server
2496 static inline uint32_t
2497 _convert_to_tzsh_type(Ecore_Wl2_Window_Type type)
2498 {
2499    switch (type)
2500      {
2501         case ECORE_WL2_WINDOW_TYPE_NONE:
2502           return TIZEN_POLICY_WIN_TYPE_NONE;
2503         case ECORE_WL2_WINDOW_TYPE_TOPLEVEL:
2504           return TIZEN_POLICY_WIN_TYPE_TOPLEVEL;
2505         case ECORE_WL2_WINDOW_TYPE_MENU:
2506           return TIZEN_POLICY_WIN_TYPE_MENU;
2507         case ECORE_WL2_WINDOW_TYPE_DND:
2508           return TIZEN_POLICY_WIN_TYPE_DND;
2509         case ECORE_WL2_WINDOW_TYPE_CUSTOM:
2510           return TIZEN_POLICY_WIN_TYPE_CUSTOM;
2511         case ECORE_WL2_WINDOW_TYPE_NOTIFICATION:
2512           return TIZEN_POLICY_WIN_TYPE_NOTIFICATION;
2513         case ECORE_WL2_WINDOW_TYPE_UTILITY:
2514           return TIZEN_POLICY_WIN_TYPE_UTILITY;
2515         case ECORE_WL2_WINDOW_TYPE_DIALOG:
2516           return TIZEN_POLICY_WIN_TYPE_DIALOG;
2517         case ECORE_WL2_WINDOW_TYPE_DOCK:
2518           return TIZEN_POLICY_WIN_TYPE_DOCK;
2519         case ECORE_WL2_WINDOW_TYPE_SPLASH:
2520           return TIZEN_POLICY_WIN_TYPE_SPLASH;
2521         case ECORE_WL2_WINDOW_TYPE_DESKTOP:
2522           return TIZEN_POLICY_WIN_TYPE_DESKTOP;
2523         default:
2524           return TIZEN_POLICY_WIN_TYPE_NONE;
2525      }
2526 }
2527 //
2528
2529 EAPI void
2530 ecore_wl2_window_type_set(Ecore_Wl2_Window *window, Ecore_Wl2_Window_Type type)
2531 {
2532    EINA_SAFETY_ON_NULL_RETURN(window);
2533    window->type = type;
2534
2535    // TIZEN_ONLY(20180202): Fix to send a proper window type value to the server
2536    uint32_t tzsh_type;
2537    tzsh_type = _convert_to_tzsh_type(type);
2538    //
2539
2540 // TIZEN_ONLY(20171114)
2541    if ((window->surface) && (window->display->wl.tz_policy))
2542      tizen_policy_set_type(window->display->wl.tz_policy, window->surface, (uint32_t)tzsh_type);
2543 //
2544 }
2545
2546 EAPI void
2547 ecore_wl2_window_popup_input_set(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
2548 {
2549    EINA_SAFETY_ON_NULL_RETURN(window);
2550    EINA_SAFETY_ON_NULL_RETURN(input);
2551    EINA_SAFETY_ON_TRUE_RETURN(window->type != ECORE_WL2_WINDOW_TYPE_MENU);
2552    window->grab = input;
2553 }
2554
2555 EAPI Ecore_Wl2_Input *
2556 ecore_wl2_window_popup_input_get(Ecore_Wl2_Window *window)
2557 {
2558    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2559
2560    return window->grab;
2561 }
2562
2563 EAPI Ecore_Wl2_Display *
2564 ecore_wl2_window_display_get(const Ecore_Wl2_Window *window)
2565 {
2566    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2567    EINA_SAFETY_ON_NULL_RETURN_VAL(window->display, NULL);
2568
2569    if (window->display->recovering) return NULL;
2570
2571    return window->display;
2572 }
2573
2574 EAPI Eina_Bool
2575 ecore_wl2_window_shell_surface_exists(Ecore_Wl2_Window *window)
2576 {
2577    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2578    return !!window->zxdg_surface || !!window->xdg_surface;
2579 }
2580
2581 // TIZEN_ONLY(171108) : get shell surface of a given window
2582 EAPI struct zxdg_surface_v6 *
2583 ecore_wl2_window_shell_surface_get(Ecore_Wl2_Window *window)
2584 {
2585    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2586    return window->zxdg_surface;
2587 }
2588 //
2589
2590 EAPI Eina_Bool
2591 ecore_wl2_window_activated_get(const Ecore_Wl2_Window *window)
2592 {
2593    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2594    return window->req_config.focused;
2595 }
2596
2597 EAPI Ecore_Wl2_Output *
2598 ecore_wl2_window_output_find(Ecore_Wl2_Window *window)
2599 {
2600    Ecore_Wl2_Output *out;
2601    Eina_Inlist *tmp;
2602    int x = 0, y = 0;
2603
2604    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2605
2606    x = window->set_config.geometry.x;
2607    y = window->set_config.geometry.y;
2608
2609    EINA_INLIST_FOREACH_SAFE(window->display->outputs, tmp, out)
2610      {
2611         int ox, oy, ow, oh;
2612
2613         ox = out->geometry.x;
2614         oy = out->geometry.y;
2615
2616         switch (out->transform)
2617           {
2618            case WL_OUTPUT_TRANSFORM_90:
2619            case WL_OUTPUT_TRANSFORM_270:
2620            case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2621            case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2622              ow = out->geometry.h;
2623              oh = out->geometry.w;
2624              break;
2625            default:
2626              ow = out->geometry.w;
2627              oh = out->geometry.h;
2628              break;
2629           }
2630
2631         if (((x >= ox) && (x < ow)) && ((y >= oy) && (y < oh)))
2632           return out;
2633      }
2634
2635    return NULL;
2636 }
2637
2638 EAPI void
2639 ecore_wl2_window_buffer_transform_set(Ecore_Wl2_Window *window, int transform)
2640 {
2641    EINA_SAFETY_ON_NULL_RETURN(window);
2642
2643    wl_surface_set_buffer_transform(window->surface, transform);
2644 }
2645
2646 EAPI void
2647 ecore_wl2_window_wm_rotation_supported_set(Ecore_Wl2_Window *window, Eina_Bool enabled)
2648 {
2649    EINA_SAFETY_ON_NULL_RETURN(window);
2650    window->wm_rot.supported = enabled;
2651 }
2652
2653 EAPI Eina_Bool
2654 ecore_wl2_window_wm_rotation_supported_get(Ecore_Wl2_Window *window)
2655 {
2656    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2657    return window->wm_rot.supported;
2658 }
2659
2660 EAPI void
2661 ecore_wl2_window_rotation_app_set(Ecore_Wl2_Window *window, Eina_Bool set)
2662 {
2663    EINA_SAFETY_ON_NULL_RETURN(window);
2664    window->wm_rot.app_set = set;
2665 }
2666
2667 EAPI Eina_Bool
2668 ecore_wl2_window_rotation_app_get(Ecore_Wl2_Window *window)
2669 {
2670    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2671    return window->wm_rot.app_set;
2672 }
2673
2674 EAPI void
2675 ecore_wl2_window_preferred_rotation_set(Ecore_Wl2_Window *window, int rot)
2676 {
2677    EINA_SAFETY_ON_NULL_RETURN(window);
2678    window->wm_rot.preferred_rot = rot;
2679
2680    // TIZEN_ONLY
2681    _tizen_rotation_preferred_angle_set(window, window->wm_rot.preferred_rot);
2682    //
2683 }
2684
2685 EAPI int
2686 ecore_wl2_window_preferred_rotation_get(Ecore_Wl2_Window *window)
2687 {
2688    EINA_SAFETY_ON_NULL_RETURN_VAL(window, 0);
2689    return window->wm_rot.preferred_rot;
2690 }
2691
2692 EAPI void
2693 ecore_wl2_window_available_rotations_set(Ecore_Wl2_Window *window, const int *rots, unsigned int count)
2694 {
2695    unsigned int i = 0;
2696    EINA_SAFETY_ON_NULL_RETURN(window);
2697
2698    // TIZEN_ONLY
2699    _tizen_rotation_available_angles_set(window, rots, count);
2700    //
2701
2702    if (window->wm_rot.available_rots)
2703      {
2704         free(window->wm_rot.available_rots);
2705         window->wm_rot.available_rots = NULL;
2706      }
2707    window->wm_rot.count = count;
2708
2709    if (count >= 1)
2710      {
2711         window->wm_rot.available_rots = calloc(count, sizeof(int));
2712         if (!window->wm_rot.available_rots) return;
2713
2714         for (; i < count; i++)
2715           window->wm_rot.available_rots[i] = ((int *)rots)[i];
2716      }
2717 }
2718
2719 EAPI Eina_Bool
2720 ecore_wl2_window_available_rotations_get(Ecore_Wl2_Window *window, int **rots, unsigned int *count)
2721 {
2722    unsigned int i = 0;
2723    int *val = NULL;
2724
2725    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2726
2727    *rots = NULL;
2728    *count = window->wm_rot.count;
2729
2730    if (window->wm_rot.count >= 1)
2731      {
2732         val = calloc(window->wm_rot.count, sizeof(int));
2733         if (!val) return EINA_FALSE;
2734
2735         for (; i < window->wm_rot.count; i++)
2736           val[i] = ((int *)window->wm_rot.available_rots)[i];
2737
2738         *rots = val;
2739         return EINA_TRUE;
2740      }
2741
2742    return EINA_FALSE;
2743 }
2744
2745 EAPI void
2746 ecore_wl2_window_rotation_change_prepare_send(Ecore_Wl2_Window *window, int rot, int w, int h, Eina_Bool resize)
2747 {
2748    Ecore_Wl2_Event_Window_Rotation_Change_Prepare *ev;
2749
2750    EINA_SAFETY_ON_NULL_RETURN(window);
2751
2752    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Prepare));
2753    if (!ev) return;
2754
2755    ev->win = window->id;
2756    ev->rotation = rot;
2757    ev->w = w;
2758    ev->h = h;
2759    ev->resize = resize;
2760
2761    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_PREPARE, ev, NULL, NULL);
2762 }
2763
2764 EAPI void
2765 ecore_wl2_window_rotation_change_prepare_done_send(Ecore_Wl2_Window *window, int rot)
2766 {
2767    Ecore_Wl2_Event_Window_Rotation_Change_Prepare_Done *ev;
2768
2769    EINA_SAFETY_ON_NULL_RETURN(window);
2770
2771    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Prepare_Done));
2772    if (!ev) return;
2773
2774    ev->win = window->id;
2775    ev->rotation = rot;
2776    ev->w = 0;
2777    ev->h = 0;
2778    ev->resize = 0;
2779
2780    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_PREPARE_DONE,
2781                    ev, NULL, NULL);
2782 }
2783
2784 EAPI void
2785 ecore_wl2_window_rotation_change_request_send(Ecore_Wl2_Window *window, int rot)
2786 {
2787    Ecore_Wl2_Event_Window_Rotation_Change_Request *ev;
2788
2789    EINA_SAFETY_ON_NULL_RETURN(window);
2790
2791    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Request));
2792    if (!ev) return;
2793
2794    ev->win = window->id;
2795    ev->rotation = rot;
2796    ev->w = 0;
2797    ev->h = 0;
2798    ev->resize = 0;
2799
2800    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_REQUEST,
2801                    ev, NULL, NULL);
2802 }
2803
2804 EAPI void
2805 ecore_wl2_window_rotation_change_done_send(Ecore_Wl2_Window *window, int rot, int w, int h)
2806 {
2807    Ecore_Wl2_Event_Window_Rotation_Change_Done *ev;
2808
2809    EINA_SAFETY_ON_NULL_RETURN(window);
2810
2811    // TIZEN_ONLY
2812    if (window->tz_rotation)
2813      tizen_rotation_ack_angle_change(window->tz_rotation, window->wm_rot.serial);
2814    //
2815
2816    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Done));
2817    if (!ev) return;
2818
2819    ev->win = window->id;
2820    ev->rotation = rot;
2821    ev->w = w;
2822    ev->h = h;
2823    ev->resize = 0;
2824
2825    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_DONE,
2826                    ev, NULL, NULL);
2827 }
2828
2829 // TIZEN_ONLY
2830 EAPI void
2831 ecore_wl2_window_rotation_geometry_set(Ecore_Wl2_Window *win, int rot, int x, int y, int w, int h)
2832 {
2833    int i = 0;
2834    int rotation = 0;
2835    enum tizen_rotation_angle angle = TIZEN_ROTATION_ANGLE_NONE;
2836
2837    if (!win) return;
2838
2839    if ((rot % 90 != 0) || (rot / 90 > 3) || (rot < 0)) return;
2840
2841    i = rot / 90;
2842    win->wm_rot.geometry_hints[i].x = x;
2843    win->wm_rot.geometry_hints[i].y = y;
2844    win->wm_rot.geometry_hints[i].w = w;
2845    win->wm_rot.geometry_hints[i].h = h;
2846    win->wm_rot.geometry_hints[i].valid = EINA_TRUE;
2847
2848    if (!win->tz_rotation) return;
2849    switch (rot)
2850      {
2851       case 0:
2852          angle = TIZEN_ROTATION_ANGLE_0;
2853          break;
2854       case 90:
2855          angle = TIZEN_ROTATION_ANGLE_90;
2856          break;
2857       case 180:
2858          angle = TIZEN_ROTATION_ANGLE_180;
2859          break;
2860       case 270:
2861          angle = TIZEN_ROTATION_ANGLE_270;
2862          break;
2863       default:
2864          break;
2865      }
2866    tizen_rotation_set_geometry_hint(win->tz_rotation,
2867                                     (uint32_t)angle, x, y, w, h);
2868
2869    rotation = ecore_wl2_window_rotation_get(win);
2870    if ((rotation % 90 != 0) || (rotation / 90 > 3) || (rotation < 0)) return;
2871    if ((i == (rotation / 90)) &&
2872        ((win->set_config.geometry.w != w) || (win->set_config.geometry.h != h)))
2873      {
2874         //TIZEN_ONLY(20180201) : add function to set window size by client.
2875         win->set_config.geometry.w = w;
2876         win->set_config.geometry.h = h;
2877         _ecore_wl2_window_configure_send_by_client(win);
2878         //
2879      }
2880 }
2881
2882 EAPI void
2883 ecore_wl2_window_rotation_changed_callback_set(Ecore_Wl2_Window *win, void *data, void (*func)(Ecore_Wl2_Window *win, int rot, Eina_Bool resize, int w, int h, void *data))
2884 {
2885    if (!win) return;
2886
2887    win->cb_rot_changed = func;
2888    win->cb_rot_changed_data = data;
2889 }
2890 //
2891
2892 // TIZEN_ONLY(20210330): for maintain internal aux hint list
2893 static Ecore_Wl2_Window_Aux_Hint *
2894 _ecore_wl2_window_aux_hint_get_by_id(Ecore_Wl2_Window *win, int id)
2895 {
2896    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
2897    Eina_List *l = NULL;
2898
2899    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
2900
2901    EINA_LIST_REVERSE_FOREACH(win->aux_hints, l, ewah)
2902      {
2903         if (ewah->id == id)
2904           return ewah;
2905      }
2906
2907    return NULL;
2908 }
2909
2910 static Ecore_Wl2_Window_Aux_Hint *
2911 _ecore_wl2_window_aux_hint_get_by_hint(Ecore_Wl2_Window *win, const char *hint)
2912 {
2913    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
2914    Eina_List *l = NULL;
2915    size_t hint_len = 0;
2916
2917    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
2918
2919    hint_len = strlen(hint);
2920    EINA_LIST_REVERSE_FOREACH(win->aux_hints, l, ewah)
2921      {
2922         if ((strlen(ewah->hint) == hint_len) &&
2923             !strncmp(ewah->hint, hint, hint_len))
2924           return ewah;
2925      }
2926
2927    return NULL;
2928 }
2929
2930 static Eina_Bool
2931 _ecore_wl2_window_aux_hint_list_add(Ecore_Wl2_Window *win, int id, const char *hint, const char *val)
2932 {
2933    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
2934
2935    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
2936
2937    ewah = _ecore_wl2_window_aux_hint_get_by_id(win, id);
2938    if (ewah)
2939      {
2940         eina_stringshare_del(ewah->hint);
2941         eina_stringshare_del(ewah->val);
2942         ewah->hint = eina_stringshare_add(hint);
2943         ewah->val = eina_stringshare_add(val);
2944         return EINA_TRUE;
2945      }
2946
2947    ewah = (Ecore_Wl2_Window_Aux_Hint *)calloc(1, sizeof(Ecore_Wl2_Window_Aux_Hint));
2948    EINA_SAFETY_ON_NULL_RETURN_VAL(ewah, EINA_FALSE);
2949
2950    ewah->hint = eina_stringshare_add(hint);
2951    ewah->val = eina_stringshare_add(val);
2952    ewah->id = id;
2953    win->aux_hints = eina_list_append(win->aux_hints, ewah);
2954
2955    return EINA_TRUE;
2956 }
2957
2958 static Eina_Bool
2959 _ecore_wl2_window_aux_hint_list_change(Ecore_Wl2_Window *win, Ecore_Wl2_Window_Aux_Hint *ewah, const char *val)
2960 {
2961    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
2962    EINA_SAFETY_ON_NULL_RETURN_VAL(ewah, EINA_FALSE);
2963
2964    eina_stringshare_del(ewah->val);
2965    ewah->val = eina_stringshare_add(val);
2966
2967    return EINA_TRUE;
2968 }
2969
2970 static Eina_Bool
2971 _ecore_wl2_window_aux_hint_list_del(Ecore_Wl2_Window *win, Ecore_Wl2_Window_Aux_Hint *ewah)
2972 {
2973    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
2974    EINA_SAFETY_ON_NULL_RETURN_VAL(ewah, EINA_FALSE);
2975
2976    eina_stringshare_del(ewah->hint);
2977    eina_stringshare_del(ewah->val);
2978    win->aux_hints = eina_list_remove(win->aux_hints, ewah);
2979
2980    return EINA_TRUE;
2981 }
2982 // END OF TIZEN_ONLY
2983
2984 // TIZEN_ONLY(20210330): support aux hint generate
2985 static int
2986 _cb_aux_hint_sort(const void *data1, const void *data2)
2987 {
2988    const Ecore_Wl2_Window_Aux_Hint *ewah1 = (const Ecore_Wl2_Window_Aux_Hint *) data1;
2989    const Ecore_Wl2_Window_Aux_Hint *ewah2 = (const Ecore_Wl2_Window_Aux_Hint *) data2;
2990
2991    if (!ewah1 || !ewah2) return 0;
2992
2993    if (ewah1->id > ewah2->id) return 1;
2994    else if (ewah1->id == ewah2->id) return 0;
2995    else return -1;
2996 }
2997
2998 static int
2999 _ecore_wl2_window_aux_hint_id_assign(Ecore_Wl2_Window *win)
3000 {
3001    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3002    Eina_List *ewah_sorted_list = NULL, *l = NULL;
3003    int id = 0;
3004
3005    ewah_sorted_list = eina_list_clone(win->aux_hints);
3006    ewah_sorted_list = eina_list_sort(ewah_sorted_list, 0, _cb_aux_hint_sort);
3007
3008    EINA_LIST_FOREACH(ewah_sorted_list, l, ewah)
3009      {
3010         if (ewah->id < 0) continue;
3011
3012         if (ewah->id == id)
3013           {
3014              id++;
3015              continue;
3016           }
3017         else
3018           break;
3019      }
3020
3021    eina_list_free(ewah_sorted_list);
3022
3023    return id;
3024 }
3025
3026 EAPI int
3027 ecore_wl2_window_aux_hint_generate(Ecore_Wl2_Window *win, const char *hint, const char *val)
3028 {
3029    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3030    int id = -1;
3031
3032    EINA_SAFETY_ON_NULL_RETURN_VAL(win, -1);
3033
3034    ewah = _ecore_wl2_window_aux_hint_get_by_hint(win, hint);
3035    if (ewah)
3036      {
3037         ecore_wl2_window_aux_hint_change(win, ewah->id, val);
3038         return ewah->id;
3039      }
3040
3041    id = _ecore_wl2_window_aux_hint_id_assign(win);
3042    if (id < 0) return -1;
3043
3044    if (!_ecore_wl2_window_aux_hint_list_add(win, id, hint, val))
3045      return -1;
3046
3047    // add aux hint
3048    if ((win->surface) && (win->display->wl.tz_policy))
3049      tizen_policy_add_aux_hint(win->display->wl.tz_policy, win->surface, id, hint, val);
3050
3051    if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return id;
3052
3053    efl_aux_hints_add_aux_hint(win->display->wl.efl_aux_hints, win->surface, id, hint, val);
3054    ecore_wl2_display_flush(win->display);
3055
3056    return id;
3057 }
3058
3059 EAPI int
3060 ecore_wl2_window_aux_hint_id_get(Ecore_Wl2_Window *win, const char *hint)
3061 {
3062    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3063
3064    ewah = _ecore_wl2_window_aux_hint_get_by_hint(win, hint);
3065    if (ewah)
3066      return ewah->id;
3067    return -1;
3068 }
3069
3070 EAPI const char *
3071 ecore_wl2_window_aux_hint_value_get(Ecore_Wl2_Window *win, int id)
3072 {
3073    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3074
3075    ewah = _ecore_wl2_window_aux_hint_get_by_id(win, id);
3076    if (ewah)
3077      return ewah->val;
3078    return NULL;
3079 }
3080 // END OF TIZEN_ONLY
3081
3082 EAPI Eina_List *
3083 ecore_wl2_window_aux_hints_supported_get(Ecore_Wl2_Window *win)
3084 {
3085    Eina_List *res = NULL;
3086    Eina_List *ll;
3087    char *supported_hint = NULL;
3088    const char *hint = NULL;
3089
3090    if (!win) return NULL;
3091    if (!win->surface) return NULL;
3092
3093    // TIZEN_ONLY : To use tizen protocols
3094    if (win->display->wl.tz_policy)
3095      {
3096         tizen_policy_get_supported_aux_hints(win->display->wl.tz_policy, win->surface);
3097         ecore_wl2_display_sync(win->display);
3098      }
3099    //
3100
3101    EINA_LIST_FOREACH(win->supported_aux_hints, ll, supported_hint)
3102      {
3103         hint = eina_stringshare_add(supported_hint);
3104         res = eina_list_append(res, hint);
3105      }
3106    return res;
3107 }
3108
3109 EAPI void
3110 ecore_wl2_window_aux_hint_add(Ecore_Wl2_Window *win, int id, const char *hint, const char *val)
3111 {
3112    if (!win) return;
3113
3114    // TIZEN_ONLY : To use tizen protocols
3115    if ((win->surface) && (win->display->wl.tz_policy))
3116      tizen_policy_add_aux_hint(win->display->wl.tz_policy, win->surface, id, hint, val);
3117    //
3118
3119    // TIZEN_ONLY(20210330): for maintain internal aux hint list
3120    _ecore_wl2_window_aux_hint_list_add(win, id, hint, val);
3121    //
3122
3123    if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return;
3124
3125    efl_aux_hints_add_aux_hint(win->display->wl.efl_aux_hints, win->surface, id, hint, val);
3126    ecore_wl2_display_flush(win->display);
3127 }
3128
3129 EAPI void
3130 ecore_wl2_window_aux_hint_change(Ecore_Wl2_Window *win, int id, const char *val)
3131 {
3132    if (!win) return;
3133
3134    // TIZEN_ONLY : To use tizen protocols
3135    if ((win->surface) && (win->display->wl.tz_policy))
3136      tizen_policy_change_aux_hint(win->display->wl.tz_policy, win->surface, id, val);
3137    //
3138
3139    // TIZEN_ONLY(20210330): for maintain internal aux hint list
3140    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3141    ewah = _ecore_wl2_window_aux_hint_get_by_id(win, id);
3142    if (ewah)
3143      _ecore_wl2_window_aux_hint_list_change(win, ewah, val);
3144    //
3145
3146    if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return;
3147
3148    efl_aux_hints_change_aux_hint(win->display->wl.efl_aux_hints, win->surface, id, val);
3149    ecore_wl2_display_flush(win->display);
3150 }
3151
3152 EAPI void
3153 ecore_wl2_window_aux_hint_del(Ecore_Wl2_Window *win, int id)
3154 {
3155    if (!win) return;
3156
3157    // TIZEN_ONLY : To use tizen protocols
3158    if ((win->surface) && (win->display->wl.tz_policy))
3159      tizen_policy_del_aux_hint(win->display->wl.tz_policy, win->surface, id);
3160    //
3161
3162    // TIZEN_ONLY(20210330): for maintain internal aux hint list
3163    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3164    ewah = _ecore_wl2_window_aux_hint_get_by_id(win, id);
3165    if (ewah)
3166      _ecore_wl2_window_aux_hint_list_del(win, ewah);
3167    //
3168
3169    if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return;
3170
3171    efl_aux_hints_del_aux_hint(win->display->wl.efl_aux_hints, win->surface, id);
3172    ecore_wl2_display_flush(win->display);
3173 }
3174
3175 EAPI void
3176 ecore_wl2_window_focus_skip_set(Ecore_Wl2_Window *window, Eina_Bool focus_skip)
3177 {
3178    EINA_SAFETY_ON_NULL_RETURN(window);
3179
3180    // TIZEN_ONLY(20171112)
3181    if (window->focus_skip != focus_skip)
3182      {
3183         if ((window->surface) && (window->display->wl.tz_policy))
3184           {
3185              if (focus_skip)
3186                tizen_policy_set_focus_skip(window->display->wl.tz_policy, window->surface);
3187              else
3188                tizen_policy_unset_focus_skip(window->display->wl.tz_policy, window->surface);
3189           }
3190      }
3191    //
3192
3193    window->focus_skip = focus_skip;
3194 }
3195
3196 EAPI Eina_Bool
3197 ecore_wl2_window_focus_skip_get(Ecore_Wl2_Window *window)
3198 {
3199    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
3200    return window->focus_skip;
3201 }
3202
3203 EAPI void
3204 ecore_wl2_window_role_set(Ecore_Wl2_Window *window, const char *role)
3205 {
3206    EINA_SAFETY_ON_NULL_RETURN(window);
3207    eina_stringshare_replace(&window->role, role);
3208
3209    // TIZEN_ONLY(20171112)
3210    if ((window->surface) && (window->display->wl.tz_policy))
3211      tizen_policy_set_role(window->display->wl.tz_policy, window->surface, window->role);
3212    //
3213 }
3214
3215 EAPI const char *
3216 ecore_wl2_window_role_get(Ecore_Wl2_Window *window)
3217 {
3218    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
3219
3220    return window->role ? window->role : NULL;
3221 }
3222
3223 EAPI void
3224 ecore_wl2_window_floating_mode_set(Ecore_Wl2_Window *window, Eina_Bool floating)
3225 {
3226    EINA_SAFETY_ON_NULL_RETURN(window);
3227    window->floating = floating;
3228
3229    // TIZEN_ONLY(20171112)
3230    if ((window->surface) && (window->display->wl.tz_policy))
3231      {
3232         if (floating)
3233           tizen_policy_set_floating_mode(window->display->wl.tz_policy,
3234                                          window->surface);
3235         else
3236           tizen_policy_unset_floating_mode(window->display->wl.tz_policy,
3237                                            window->surface);
3238      }
3239    //
3240 }
3241
3242 EAPI Eina_Bool
3243 ecore_wl2_window_floating_mode_get(Ecore_Wl2_Window *window)
3244 {
3245    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
3246    return window->floating;
3247 }
3248
3249 // TIZEN_ONLY(20150703) : support conformant
3250 EAPI void
3251 ecore_wl2_window_conformant_set(Ecore_Wl2_Window *win, unsigned int is_conformant)
3252 {
3253    if (!win) return;
3254    if (!win->surface) return;
3255    if (!win->display) return;
3256    if (!win->display->wl.tz_policy) return;
3257
3258    if (is_conformant)
3259      tizen_policy_set_conformant(win->display->wl.tz_policy, win->surface);
3260    else
3261      tizen_policy_unset_conformant(win->display->wl.tz_policy, win->surface);
3262 }
3263
3264 EAPI Eina_Bool
3265 ecore_wl2_window_conformant_get(Ecore_Wl2_Window *win)
3266 {
3267    if (!win) return EINA_FALSE;
3268    if (!win->surface) return EINA_FALSE;
3269    if (!win->display) return EINA_FALSE;
3270    if (!win->display->wl.tz_policy) return EINA_FALSE;
3271
3272    tizen_policy_get_conformant(win->display->wl.tz_policy, win->surface);
3273    ecore_wl2_display_sync(win->display);
3274
3275    return win->conformant;
3276 }
3277 //
3278
3279 // TIZEN_ONLY(20171108) : add functions for indicator
3280 EAPI void
3281 ecore_wl2_window_indicator_geometry_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
3282 {
3283    if(!win) return;
3284
3285    win->indicator.x = x;
3286    win->indicator.y = y;
3287    win->indicator.w = w;
3288    win->indicator.h = h;
3289 }
3290
3291 EAPI Eina_Bool
3292 ecore_wl2_window_indicator_geometry_get(Ecore_Wl2_Window *win, int *x, int *y, int *w, int *h)
3293 {
3294    if(!win) return EINA_FALSE;
3295
3296    if (x)
3297      *x = win->indicator.x;
3298    if (y)
3299      *y = win->indicator.y;
3300    if (w)
3301      *w = win->indicator.w;
3302    if (h)
3303      *h = win->indicator.h;
3304
3305    return EINA_TRUE;
3306 }
3307
3308 EAPI void
3309 ecore_wl2_window_indicator_state_set(Ecore_Wl2_Window *win, Ecore_Wl2_Indicator_State state)
3310 {
3311    int32_t ind_state;
3312
3313    if (!win) return;
3314    if (!win->surface) return;
3315    if (!win->display->wl.tz_indicator) return;
3316
3317    if (state == ECORE_WL2_INDICATOR_STATE_ON)
3318      ind_state = TIZEN_INDICATOR_STATE_ON;
3319    else if (state == ECORE_WL2_INDICATOR_STATE_OFF)
3320      ind_state = TIZEN_INDICATOR_STATE_OFF;
3321    else
3322      ind_state = TIZEN_INDICATOR_STATE_UNKNOWN;
3323
3324    tizen_indicator_set_state(win->display->wl.tz_indicator, win->surface, ind_state);
3325
3326    win->indicator.state = state;
3327 }
3328
3329 EAPI Ecore_Wl2_Indicator_State
3330 ecore_wl2_window_indicator_state_get(Ecore_Wl2_Window *win)
3331 {
3332    if (!win) return EINA_FALSE;
3333
3334    return win->indicator.state;
3335 }
3336
3337 EAPI void
3338 ecore_wl2_window_indicator_opacity_set(Ecore_Wl2_Window *win, Ecore_Wl2_Indicator_Opacity_Mode mode)
3339 {
3340    int32_t op_mode;
3341
3342    if (!win) return;
3343    if (!win->surface) return;
3344    if (!win->display->wl.tz_indicator) return;
3345
3346    switch (mode)
3347      {
3348       case ECORE_WL2_INDICATOR_OPAQUE:
3349          op_mode = TIZEN_INDICATOR_OPACITY_MODE_OPAQUE;
3350          break;
3351
3352       case ECORE_WL2_INDICATOR_TRANSLUCENT:
3353          op_mode = TIZEN_INDICATOR_OPACITY_MODE_TRANSLUCENT;
3354          break;
3355
3356       case ECORE_WL2_INDICATOR_TRANSPARENT:
3357          op_mode = TIZEN_INDICATOR_OPACITY_MODE_TRANSPARENT;
3358          break;
3359
3360       case ECORE_WL2_INDICATOR_BG_TRANSPARENT:
3361          op_mode = TIZEN_INDICATOR_OPACITY_MODE_BG_TRANSPARENT;
3362          break;
3363
3364       default:
3365          op_mode = TIZEN_INDICATOR_OPACITY_MODE_OPAQUE;
3366          break;
3367      }
3368
3369    tizen_indicator_set_opacity_mode(win->display->wl.tz_indicator, win->surface, op_mode);
3370
3371    win->indicator.mode = mode;
3372 }
3373
3374 EAPI Ecore_Wl2_Indicator_Opacity_Mode
3375 ecore_wl2_window_indicator_opacity_get(Ecore_Wl2_Window *win)
3376 {
3377    if (!win) return EINA_FALSE;
3378
3379    return win->indicator.mode;
3380 }
3381
3382 EAPI void
3383 ecore_wl2_indicator_visible_type_set(Ecore_Wl2_Window *win, Ecore_Wl2_Indicator_Visible_Type type)
3384 {
3385    int32_t vis_type;
3386
3387    if (!win) return;
3388    if (!win->surface) return;
3389    if (!win->display->wl.tz_indicator) return;
3390
3391    if (type == ECORE_WL2_INDICATOR_VISIBLE_TYPE_SHOWN)
3392      vis_type = TIZEN_INDICATOR_VISIBLE_TYPE_SHOWN;
3393    else
3394      vis_type = TIZEN_INDICATOR_VISIBLE_TYPE_HIDDEN;
3395
3396    tizen_indicator_set_visible_type(win->display->wl.tz_indicator, win->surface, vis_type);
3397
3398    win->indicator.type = type;
3399 }
3400
3401 EAPI Ecore_Wl2_Indicator_Visible_Type
3402 ecore_wl2_indicator_visible_type_get(Ecore_Wl2_Window *win)
3403 {
3404    if (!win) return EINA_FALSE;
3405
3406    return win->indicator.type;
3407 }
3408 //
3409
3410 // TIZEN_ONLY(20171108) : add functions for clipboard
3411 EAPI void
3412 ecore_wl2_window_clipboard_geometry_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
3413 {
3414    if(!win) return;
3415
3416    win->clipboard.x = x;
3417    win->clipboard.y = y;
3418    win->clipboard.w = w;
3419    win->clipboard.h = h;
3420 }
3421
3422 EAPI Eina_Bool
3423 ecore_wl2_window_clipboard_geometry_get(Ecore_Wl2_Window *win, int *x, int *y, int *w, int *h)
3424 {
3425    if (!win) return EINA_FALSE;
3426
3427    if (x)
3428      *x = win->clipboard.x;
3429    if (y)
3430      *y = win->clipboard.y;
3431    if (w)
3432      *w = win->clipboard.w;
3433    if (h)
3434      *h = win->clipboard.h;
3435
3436    return EINA_TRUE;
3437 }
3438
3439 EAPI void
3440 ecore_wl2_window_clipboard_state_set(Ecore_Wl2_Window *win, Ecore_Wl2_Clipboard_State state)
3441 {
3442    if (!win) return;
3443
3444    win->clipboard.state = state;
3445 }
3446
3447 EAPI Ecore_Wl2_Clipboard_State
3448 ecore_wl2_window_clipboard_state_get(Ecore_Wl2_Window *win)
3449 {
3450    if (!win) return EINA_FALSE;
3451
3452    return win->clipboard.state;
3453 }
3454
3455 EAPI void
3456 ecore_wl2_clipboard_show(Ecore_Wl2_Window *win)
3457 {
3458    if (!win) return;
3459    if (!win->surface) return;
3460    if (!win->display->wl.tz_clipboard) return;
3461
3462    tizen_clipboard_show(win->display->wl.tz_clipboard, win->surface);
3463 }
3464
3465 EAPI void
3466 ecore_wl2_clipboard_hide(Ecore_Wl2_Window *win)
3467 {
3468    if (!win) return;
3469    if (!win->surface) return;
3470    if (!win->display->wl.tz_clipboard) return;
3471
3472    tizen_clipboard_hide(win->display->wl.tz_clipboard, win->surface);
3473 }
3474
3475 EAPI Eina_Bool
3476 ecore_wl2_clipboard_data_only_set(Eina_Bool data_only)
3477 {
3478    Ecore_Wl2_Display *ewd = NULL;
3479    Ecore_Wl2_Input *input = NULL;
3480
3481    ewd = ecore_wl2_connected_display_get(NULL);
3482    if (!ewd) return EINA_FALSE;
3483    input = ecore_wl2_input_default_input_get(ewd);
3484    if (!input) return EINA_FALSE;
3485
3486    if (!ewd->wl.tz_clipboard) return EINA_FALSE;
3487
3488    tizen_clipboard_set_data_only(ewd->wl.tz_clipboard, data_only);
3489    ecore_wl2_display_sync(ewd);
3490
3491    return input->is_data_only;
3492 }
3493 //
3494
3495 // TIZEN_ONLY(20171108) : add functions for keyboard
3496 EAPI void
3497 ecore_wl2_window_keyboard_geometry_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
3498 {
3499    if(!win) return;
3500
3501    win->keyboard.x= x;
3502    win->keyboard.y = y;
3503    win->keyboard.w = w;
3504    win->keyboard.h = h;
3505 }
3506
3507 EAPI Eina_Bool
3508 ecore_wl2_window_keyboard_geometry_get(Ecore_Wl2_Window *win, int *x, int *y, int *w, int *h)
3509 {
3510    if (!win) return EINA_FALSE;
3511
3512    if (x)
3513      *x = win->keyboard.x;
3514    if (y)
3515      *y = win->keyboard.y;
3516    if (w)
3517      *w = win->keyboard.w;
3518    if (h)
3519      *h = win->keyboard.h;
3520
3521    return EINA_TRUE;
3522 }
3523
3524 EAPI void
3525 ecore_wl2_window_keyboard_state_set(Ecore_Wl2_Window *win, Ecore_Wl2_Virtual_Keyboard_State state)
3526 {
3527    if (!win) return;
3528
3529    win->keyboard.state = state;
3530 }
3531
3532 EAPI Ecore_Wl2_Virtual_Keyboard_State
3533 ecore_wl2_window_keyboard_state_get(Ecore_Wl2_Window *win)
3534 {
3535    if (!win) return EINA_FALSE;
3536
3537    return win->keyboard.state;
3538 }
3539 //
3540
3541 EAPI void
3542 ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int aspect)
3543 {
3544    EINA_SAFETY_ON_NULL_RETURN(window);
3545    EINA_SAFETY_ON_TRUE_RETURN(w < 1);
3546    EINA_SAFETY_ON_TRUE_RETURN(h < 1);
3547
3548    if ((window->aspect.aspect == aspect) && (window->aspect.w == w) &&
3549        (window->aspect.h == h))
3550      return;
3551
3552    window->aspect.w = w;
3553    window->aspect.h = h;
3554    window->aspect.aspect = aspect;
3555    window->aspect.set = 1;
3556    if (!window->display->wl.efl_hints) return;
3557    if (window->xdg_surface)
3558      efl_hints_set_aspect(window->display->wl.efl_hints,
3559                           window->xdg_surface, w, h, aspect);
3560    ecore_wl2_display_flush(window->display);
3561 }
3562
3563 EAPI void
3564 ecore_wl2_window_aspect_get(Ecore_Wl2_Window *window, int *w, int *h, unsigned int *aspect)
3565 {
3566    EINA_SAFETY_ON_NULL_RETURN(window);
3567
3568    if (w) *w = window->aspect.w;
3569    if (h) *h = window->aspect.h;
3570    if (aspect) *aspect = window->aspect.aspect;
3571 }
3572
3573 EAPI void
3574 ecore_wl2_window_weight_set(Ecore_Wl2_Window *window, double w, double h)
3575 {
3576    int ww, hh;
3577    EINA_SAFETY_ON_NULL_RETURN(window);
3578
3579    ww = lround(w * 100);
3580    hh = lround(h * 100);
3581
3582    if ((window->weight.w == ww) && (window->weight.h == hh))
3583      return;
3584
3585    window->weight.w = ww;
3586    window->weight.h = hh;
3587    window->weight.set = 1;
3588    if (!window->display->wl.efl_hints) return;
3589    if (window->xdg_surface)
3590      efl_hints_set_weight(window->display->wl.efl_hints,
3591                           window->xdg_surface, ww, hh);
3592    ecore_wl2_display_flush(window->display);
3593 }
3594
3595 static void
3596 _frame_cb(void *data, struct wl_callback *callback, uint32_t timestamp)
3597 {
3598    Ecore_Wl2_Frame_Cb_Handle *cb;
3599    Ecore_Wl2_Window *window;
3600    Eina_Inlist *l;
3601
3602    window = data;
3603    window->commit_pending = EINA_FALSE;
3604    wl_callback_destroy(callback);
3605    window->callback = NULL;
3606    EINA_INLIST_FOREACH_SAFE(window->frame_callbacks, l, cb)
3607      cb->cb(window, timestamp, cb->data);
3608 }
3609
3610 static struct wl_callback_listener _frame_listener =
3611 {
3612    _frame_cb
3613 };
3614
3615 static void
3616 _maximized_set(Ecore_Wl2_Window *window)
3617 {
3618    EINA_SAFETY_ON_FALSE_RETURN(window->zxdg_toplevel || window->xdg_toplevel);
3619
3620    if (window->set_config.maximized)
3621      {
3622         window->saved = window->set_config.geometry;
3623         if (window->xdg_toplevel)
3624           xdg_toplevel_set_maximized(window->xdg_toplevel);
3625         if (window->zxdg_toplevel)
3626           zxdg_toplevel_v6_set_maximized(window->zxdg_toplevel);
3627      }
3628    else
3629      {
3630         if (window->xdg_toplevel)
3631           xdg_toplevel_unset_maximized(window->xdg_toplevel);
3632         if (window->zxdg_toplevel)
3633           zxdg_toplevel_v6_unset_maximized(window->zxdg_toplevel);
3634      }
3635 }
3636
3637 static void
3638 _fullscreen_set(Ecore_Wl2_Window *window)
3639 {
3640    EINA_SAFETY_ON_FALSE_RETURN(window->zxdg_toplevel || window->xdg_toplevel);
3641
3642    if (window->set_config.fullscreen)
3643      {
3644         window->saved = window->set_config.geometry;
3645         if (window->xdg_toplevel)
3646           xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
3647         if (window->zxdg_toplevel)
3648           zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL);
3649      }
3650    else
3651      {
3652         if (window->xdg_toplevel)
3653           xdg_toplevel_unset_fullscreen(window->xdg_toplevel);
3654         if (window->zxdg_toplevel)
3655           zxdg_toplevel_v6_unset_fullscreen(window->zxdg_toplevel);
3656      }
3657 }
3658
3659 static struct wl_region *
3660 _region_create(struct wl_compositor *comp, int x, int y, int w, int h)
3661 {
3662    struct wl_region *out;
3663
3664    out = wl_compositor_create_region(comp);
3665    if (!out)
3666      {
3667         ERR("Failed to create region");
3668         return NULL;
3669      }
3670
3671    wl_region_add(out, x, y, w, h);
3672
3673    return out;
3674 }
3675
3676 static void
3677 _regions_set(Ecore_Wl2_Window *window)
3678 {
3679    struct wl_region *region = NULL;
3680
3681    if (window->pending.opaque)
3682      {
3683         if (window->opaque_set)
3684           {
3685              region = _region_create(window->display->wl.compositor,
3686                                      window->opaque.x, window->opaque.y,
3687                                      window->opaque.w, window->opaque.h);
3688              if (!region) return;
3689           }
3690         // TIZEN_ONLY(20201123)
3691         /*
3692         wl_surface_set_opaque_region(window->surface, region);
3693         */
3694         _opaque_region_set(window, region);
3695         //
3696      }
3697
3698    if (!window->pending.input) goto out;
3699    if (window->type == ECORE_WL2_WINDOW_TYPE_DND) goto out;
3700
3701    if (!window->input_set)
3702      {
3703         wl_surface_set_input_region(window->surface, NULL);
3704         goto out;
3705      }
3706
3707    if (region && (window->opaque.x == window->input_rect.x) &&
3708        (window->opaque.y == window->input_rect.y) &&
3709        (window->opaque.w == window->input_rect.w) &&
3710        (window->opaque.h == window->input_rect.h))
3711      {
3712         wl_surface_set_input_region(window->surface, region);
3713         goto out;
3714      }
3715    if (region) wl_region_destroy(region);
3716
3717    region = _region_create(window->display->wl.compositor,
3718                            window->input_rect.x, window->input_rect.y,
3719                            window->input_rect.w, window->input_rect.h);
3720    if (!region) return;
3721    wl_surface_set_input_region(window->surface, region);
3722
3723 out:
3724    if (region) wl_region_destroy(region);
3725 }
3726
3727 // TIZEN_ONLY(20201123)
3728 static void
3729 _opaque_region_set(Ecore_Wl2_Window *window, struct wl_region *region)
3730 {
3731    if (!window) return;
3732    if (!window->surface) return;
3733
3734    wl_surface_set_opaque_region(window->surface, region);
3735
3736    window->pending.opaque = EINA_FALSE;
3737 }
3738 //
3739
3740 // TIZEN_ONLY(20190910)
3741 static void
3742 _opaque_set(Ecore_Wl2_Window *window)
3743 {
3744    struct wl_region *region;
3745
3746    if (!window->opaque_set)
3747      {
3748         if (window->surface)
3749           _opaque_region_set(window, NULL);
3750         return;
3751      }
3752
3753    region = wl_compositor_create_region(window->display->wl.compositor);
3754    if (!region)
3755      {
3756         ERR("Failed to create opaque region");
3757         return;
3758      }
3759
3760    wl_region_add(region, window->opaque.x, window->opaque.y,
3761                  window->opaque.w, window->opaque.h);
3762    _opaque_region_set(window, region);
3763    wl_region_destroy(region);
3764 }
3765 //
3766
3767 EAPI void
3768 ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush)
3769 {
3770    EINA_SAFETY_ON_NULL_RETURN(window);
3771    EINA_SAFETY_ON_NULL_RETURN(window->surface);
3772
3773    if (window->commit_pending)
3774      {
3775         if (window->callback)
3776           wl_callback_destroy(window->callback);
3777         window->callback = NULL;
3778         WRN("Commit before previous commit processed");
3779      }
3780    if (!window->pending.configure)
3781      {
3782         if (window->has_buffer)
3783           window->commit_pending = EINA_TRUE;
3784         if (!window->callback)
3785           {
3786              window->callback = wl_surface_frame(window->surface);
3787              wl_callback_add_listener(window->callback, &_frame_listener, window);
3788           }
3789         /* Dispatch any state we've been saving along the way */
3790         if (window->pending.geom)
3791           {
3792              int gx, gy, gw, gh;
3793
3794              ecore_wl2_window_geometry_get(window, &gx, &gy, &gw, &gh);
3795              if (window->xdg_toplevel)
3796                xdg_surface_set_window_geometry(window->xdg_surface,
3797                                                gx, gy, gw, gh);
3798              if (window->zxdg_surface)
3799                zxdg_surface_v6_set_window_geometry(window->zxdg_surface,
3800                                                    gx, gy, gw, gh);
3801
3802              // TIZEN_ONLY(20220421) : update window's saved size only un-fullscreen and unmaximize state
3803              if (!window->set_config.fullscreen && !window->set_config.maximized)
3804                {
3805                   window->saved.w = window->set_config.geometry.w;
3806                   window->saved.h = window->set_config.geometry.h;
3807                }
3808              //
3809           }
3810         if (window->pending.opaque || window->pending.input)
3811           _regions_set(window);
3812
3813         if (window->pending.maximized)
3814           _maximized_set(window);
3815
3816         if (window->pending.fullscreen)
3817           _fullscreen_set(window);
3818
3819         window->pending.geom = EINA_FALSE;
3820         window->pending.opaque = EINA_FALSE;
3821         window->pending.input = EINA_FALSE;
3822         window->pending.maximized = EINA_FALSE;
3823         window->pending.fullscreen = EINA_FALSE;
3824      }
3825
3826    if (window->req_config.serial != window->set_config.serial)
3827      {
3828         if (window->xdg_configure_ack && window->xdg_surface)
3829            window->xdg_configure_ack(window->xdg_surface,
3830                                       window->req_config.serial);
3831         if (window->zxdg_configure_ack && window->zxdg_surface)
3832            window->zxdg_configure_ack(window->zxdg_surface,
3833                                       window->req_config.serial);
3834         window->set_config.serial = window->req_config.serial;
3835      }
3836    if (flush)
3837      {
3838         wl_surface_commit(window->surface);
3839         ecore_wl2_display_flush(window->display);
3840      }
3841
3842    if (!window->updating) return;
3843
3844    window->updating = EINA_FALSE;
3845    if (window->def_config.serial != window->set_config.serial)
3846       _ecore_wl2_window_configure_send(window);
3847 }
3848
3849 EAPI void
3850 ecore_wl2_window_false_commit(Ecore_Wl2_Window *window)
3851 {
3852    EINA_SAFETY_ON_NULL_RETURN(window);
3853    EINA_SAFETY_ON_NULL_RETURN(window->surface);
3854    EINA_SAFETY_ON_TRUE_RETURN(window->pending.configure);
3855    EINA_SAFETY_ON_TRUE_RETURN(window->commit_pending);
3856
3857    if (!window->callback)
3858      {
3859         window->callback = wl_surface_frame(window->surface);
3860         wl_callback_add_listener(window->callback, &_frame_listener, window);
3861      }
3862    wl_surface_commit(window->surface);
3863    ecore_wl2_display_flush(window->display);
3864    if (window->has_buffer)
3865      window->commit_pending = EINA_TRUE;
3866 }
3867
3868 EAPI Eina_Bool
3869 ecore_wl2_window_pending_get(Ecore_Wl2_Window *window)
3870 {
3871    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
3872
3873    return window->commit_pending;
3874 }
3875
3876 EAPI Ecore_Wl2_Frame_Cb_Handle *
3877 ecore_wl2_window_frame_callback_add(Ecore_Wl2_Window *window, Ecore_Wl2_Frame_Cb cb, void *data)
3878 {
3879    Ecore_Wl2_Frame_Cb_Handle *callback;
3880
3881    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
3882    EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
3883
3884    callback = malloc(sizeof(*callback));
3885    EINA_SAFETY_ON_NULL_RETURN_VAL(callback, NULL);
3886    callback->cb = cb;
3887    callback->data = data;
3888    callback->win = window;
3889    window->frame_callbacks =
3890      eina_inlist_append(window->frame_callbacks, EINA_INLIST_GET(callback));
3891    return callback;
3892 }
3893
3894 EAPI void
3895 ecore_wl2_window_frame_callback_del(Ecore_Wl2_Frame_Cb_Handle *handle)
3896 {
3897    EINA_SAFETY_ON_NULL_RETURN(handle);
3898
3899    handle->win->frame_callbacks =
3900      eina_inlist_remove(handle->win->frame_callbacks, EINA_INLIST_GET(handle));
3901    free(handle);
3902 }
3903
3904 EAPI void
3905 ecore_wl2_window_buffer_attach(Ecore_Wl2_Window *win, void *buffer, int x, int y, Eina_Bool implicit)
3906 {
3907    EINA_SAFETY_ON_NULL_RETURN(win);
3908    EINA_SAFETY_ON_NULL_RETURN(win->surface);
3909
3910    /* FIXME: Haven't given any thought to x and y since we always use 0... */
3911    if (!implicit) wl_surface_attach(win->surface, buffer, x, y);
3912    win->buffer = buffer;
3913    if (!implicit && !buffer)
3914      win->has_buffer = EINA_FALSE;
3915    else
3916      win->has_buffer = EINA_TRUE;
3917 }
3918
3919 EAPI Eina_Bool
3920 ecore_wl2_window_resizing_get(Ecore_Wl2_Window *window)
3921 {
3922    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
3923
3924    return window->req_config.resizing;
3925 }
3926
3927 EAPI void
3928 ecore_wl2_window_update_begin(Ecore_Wl2_Window *window)
3929 {
3930    EINA_SAFETY_ON_NULL_RETURN(window);
3931    EINA_SAFETY_ON_TRUE_RETURN(window->updating);
3932
3933    window->updating = EINA_TRUE;
3934 }
3935
3936 EAPI void
3937 ecore_wl2_window_damage(Ecore_Wl2_Window *window, Eina_Rectangle *rects, unsigned int count)
3938 {
3939    void (*damage)(struct wl_surface *, int32_t, int32_t, int32_t, int32_t);
3940    unsigned int k;
3941    int compositor_version;
3942
3943    EINA_SAFETY_ON_NULL_RETURN(window);
3944
3945    compositor_version = window->display->wl.compositor_version;
3946
3947    if (compositor_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
3948      damage = wl_surface_damage_buffer;
3949    else
3950      damage = wl_surface_damage;
3951
3952    if ((rects) && (count > 0))
3953      for (k = 0; k < count; k++)
3954        damage(window->surface, rects[k].x, rects[k].y, rects[k].w, rects[k].h);
3955    else
3956      damage(window->surface, 0, 0, INT_MAX, INT_MAX);
3957 }
3958
3959 EAPI void
3960 ecore_wl2_window_surface_flush(Ecore_Wl2_Window *window, Eina_Bool purge)
3961 {
3962    EINA_SAFETY_ON_NULL_RETURN(window);
3963
3964    if (!window->wl2_surface) return;
3965    ecore_wl2_surface_flush(window->wl2_surface, purge);
3966 }
3967
3968 EAPI Ecore_Wl2_Window_Type
3969 ecore_wl2_window_type_get(Ecore_Wl2_Window *window)
3970 {
3971    EINA_SAFETY_ON_NULL_RETURN_VAL(window, ECORE_WL2_WINDOW_TYPE_NONE);
3972    return window->type;
3973 }
3974
3975 EAPI Ecore_Wl2_Window *
3976 ecore_wl2_window_surface_find(struct wl_surface *surface)
3977 {
3978    Ecore_Wl2_Display *ewd;
3979    Ecore_Wl2_Window *win;
3980
3981    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL);
3982
3983    ewd = ecore_wl2_connected_display_get(NULL);
3984    EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL);
3985
3986    win = ecore_wl2_display_window_find_by_surface(ewd, surface);
3987    return win;
3988 }
3989
3990 // TIZEN_ONLY(20171107): add ecore_wl2_window_input_get() EAPI
3991 EAPI Ecore_Wl2_Input *
3992 ecore_wl2_window_input_get(Ecore_Wl2_Window *win)
3993 {
3994    Ecore_Wl2_Input *input;
3995
3996    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
3997    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, NULL);
3998
3999    EINA_INLIST_FOREACH(win->display->inputs, input)
4000      {
4001         if (input->focus.pointer) return input;
4002         //This code will be changed after adding ecore_wl2_window_keyboard_get API
4003         if (input->focus.keyboard) return input;
4004      }
4005
4006    return NULL;
4007 }
4008 //
4009
4010 // TIZEN_ONLY(20200326): add ecore_wl2_window_pointer_get() EAPI
4011 EAPI Ecore_Wl2_Input *
4012 ecore_wl2_window_pointer_get(Ecore_Wl2_Window *win)
4013 {
4014    Ecore_Wl2_Input *input;
4015
4016    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
4017    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, NULL);
4018
4019    EINA_INLIST_FOREACH(win->display->inputs, input)
4020      if (input->focus.pointer == win) return input;
4021
4022    return NULL;
4023 }
4024 //
4025
4026 // TIZEN_ONLY(20200326): add ecore_wl2_window_keyboard_get() EAPI
4027 EAPI Ecore_Wl2_Input *
4028 ecore_wl2_window_keyboard_get(Ecore_Wl2_Window *win)
4029 {
4030    Ecore_Wl2_Input *input;
4031
4032    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
4033    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, NULL);
4034
4035    EINA_INLIST_FOREACH(win->display->inputs, input)
4036      if (input->focus.keyboard == win) return input;
4037
4038    return NULL;
4039 }
4040 //
4041
4042 // TIZEN_ONLY(20171114): support a pointer warp
4043 EAPI Eina_Bool
4044 ecore_wl2_window_pointer_warp(Ecore_Wl2_Window *win, int x, int y)
4045 {
4046    Ecore_Wl2_Display *ewd;
4047
4048    /* FIXME: visible is not merged yet. */
4049    //if (!win || !win->surface || !win->visible) return EINA_FALSE;
4050    if (!win || !win->surface) return EINA_FALSE;
4051
4052    ewd = win->display;
4053    if (!ewd || !ewd->wl.tz_input_device_manager) return EINA_FALSE;
4054
4055    tizen_input_device_manager_pointer_warp(ewd->wl.tz_input_device_manager,
4056                                            win->surface, wl_fixed_from_int(x), wl_fixed_from_int(y));
4057
4058    return EINA_TRUE;
4059 }
4060 //
4061
4062 // TIZEN_ONLY(20200601): support sync between ui and video
4063 /* The video surface created in ecore_wl2 is used for informing the video area.
4064    And there is another video surface created on the player side. The player
4065    video surface is filled with video data, and the garbage data of ecore_wl2
4066    video surface can interfere with video data. So fill it with zero here. */
4067 Eina_Bool
4068 buffer_fill_zero(tbm_surface_h surface)
4069 {
4070    tbm_surface_info_s info;
4071    int *img, ret;
4072    unsigned int height, stride;
4073
4074    ret = tbm_surface_map(surface, TBM_OPTION_WRITE, &info);
4075    if (ret != TBM_SURFACE_ERROR_NONE)
4076      return EINA_FALSE;
4077
4078    img = (int *)info.planes[0].ptr;
4079    height = tbm_surface_get_height(surface);
4080    stride = info.planes[0].stride;
4081
4082    memset(img, 0x0, sizeof(int) * stride * height);
4083
4084    tbm_surface_unmap(surface);
4085
4086    return EINA_TRUE;
4087 }
4088
4089
4090 EAPI Eina_Bool
4091 ecore_wl2_window_video_surface_create(Ecore_Wl2_Window *win)
4092 {
4093    Ecore_Wl2_Display *display;
4094
4095    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4096    if (win->video.surface) return EINA_TRUE;
4097
4098    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
4099    display = win->display;
4100
4101    EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.compositor, EINA_FALSE);
4102    EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.subcompositor, EINA_FALSE);
4103    EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.tz_policy, EINA_FALSE);
4104
4105    win->video.surface = wl_compositor_create_surface(display->wl.compositor);
4106
4107    if (!win->video.surface)
4108      {
4109         ERR("Failed to create video surface");
4110         return EINA_FALSE;
4111      }
4112
4113    win->video.subsurface =
4114      wl_subcompositor_get_subsurface(display->wl.subcompositor,
4115                                      win->video.surface, win->surface);
4116
4117    if (!win->video.subsurface)
4118      {
4119         ERR("Failed to create video subsurface");
4120         goto get_subsurf_err;
4121      }
4122
4123    tizen_policy_place_subsurface_below_parent(display->wl.tz_policy, win->video.subsurface);
4124
4125    if (!win->tbm_client)
4126      {
4127         win->tbm_client = wayland_tbm_client_init(display->wl.display);
4128         if (!win->tbm_client)
4129           {
4130              ERR("Failed to init wayland tbm client");
4131              goto client_init_err;
4132           }
4133      }
4134
4135    win->video.tbm_surface = tbm_surface_create(1, 1, TBM_FORMAT_ARGB8888);
4136    if (!win->video.tbm_surface)
4137      {
4138         ERR("Failed to create tbm surface");
4139         goto client_init_err;
4140      }
4141
4142    win->video.wl_buffer = wayland_tbm_client_create_buffer(win->tbm_client,
4143                                                           win->video.tbm_surface);
4144    if (!win->video.wl_buffer)
4145      {
4146         ERR("Failed to create buffer of tbm client");
4147         goto create_buf_err;
4148      }
4149
4150    if (!buffer_fill_zero(win->video.tbm_surface))
4151      {
4152         ERR("Failed to fill buffer to zero");
4153         goto buf_fill_err;
4154      }
4155
4156    /* A sub-surface is initially in the synchronized mode. */
4157    win->video.sync = EINA_TRUE;
4158
4159    /* need to attach surface */
4160    wl_surface_attach(win->video.surface, win->video.wl_buffer, 0, 0);
4161    wl_surface_commit(win->video.surface);
4162
4163    return EINA_TRUE;
4164
4165 buf_fill_err:
4166    wayland_tbm_client_destroy_buffer(win->tbm_client, win->video.wl_buffer);
4167    win->video.wl_buffer = NULL;
4168
4169 create_buf_err:
4170    tbm_surface_destroy(win->video.tbm_surface);
4171    win->video.tbm_surface = NULL;
4172
4173 client_init_err:
4174    wl_subsurface_destroy(win->video.subsurface);
4175    win->video.subsurface = NULL;
4176
4177 get_subsurf_err:
4178    wl_surface_destroy(win->video.surface);
4179    win->video.surface = NULL;
4180
4181    return EINA_FALSE;
4182 }
4183
4184 EAPI void *
4185 ecore_wl2_window_video_surface_get(Ecore_Wl2_Window *win)
4186 {
4187    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
4188    return win->video.surface;
4189 }
4190
4191 EAPI Eina_Bool
4192 ecore_wl2_window_video_surface_destroy(Ecore_Wl2_Window *win)
4193 {
4194    Ecore_Wl2_Display *display;
4195
4196    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4197    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
4198
4199    display = win->display;
4200
4201    if (display->wl.tz_video)
4202      {
4203         tizen_video_destroy(display->wl.tz_video);
4204         display->wl.tz_video = NULL;
4205      }
4206
4207    _ecore_wl2_window_video_surface_destroy(win);
4208
4209    return EINA_TRUE;
4210 }
4211
4212 EAPI Eina_Bool
4213 ecore_wl2_window_video_surface_sync_set(Ecore_Wl2_Window *win, Eina_Bool sync)
4214 {
4215    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4216    EINA_SAFETY_ON_NULL_RETURN_VAL(win->video.subsurface, EINA_FALSE);
4217
4218    sync = !!sync;
4219    if (win->video.sync == sync) return EINA_TRUE;
4220
4221    win->video.sync = sync;
4222
4223    if (sync)
4224      wl_subsurface_set_sync(win->video.subsurface);
4225    else
4226      wl_subsurface_set_desync(win->video.subsurface);
4227
4228    return EINA_TRUE;
4229 }
4230
4231 EAPI Eina_Bool
4232 ecore_wl2_window_video_surface_destination_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
4233 {
4234    Ecore_Wl2_Display *display;
4235    struct wl_registry *registry;
4236    Eina_Iterator *globals;
4237    Ecore_Wl2_Global *global;
4238
4239    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4240    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
4241    EINA_SAFETY_ON_NULL_RETURN_VAL(win->video.surface, EINA_FALSE);
4242
4243    display = win->display;
4244
4245    if (!win->video.viewport)
4246      {
4247         if (!display->wl.tz_video)
4248           {
4249              registry = ecore_wl2_display_registry_get(display);
4250              if (!registry) return EINA_FALSE;
4251
4252              globals = ecore_wl2_display_globals_get(display);
4253              if (!globals) return EINA_FALSE;
4254
4255              EINA_ITERATOR_FOREACH(globals, global)
4256                {
4257                   if (strcmp(global->interface, "tizen_video") == 0)
4258                     {
4259                        display->wl.tz_video = wl_registry_bind(registry, global->id, &tizen_video_interface, 1);
4260                        break;
4261                     }
4262                }
4263           }
4264
4265         if (!display->wl.tz_video)
4266           {
4267              ERR("Failed to bind tizen video interface");
4268              return EINA_FALSE;
4269           }
4270
4271         win->video.viewport = tizen_video_get_viewport(display->wl.tz_video, win->video.surface);
4272      }
4273
4274    if (!win->video.viewport)
4275      {
4276         ERR("Failed to get video viewport");
4277         return EINA_FALSE;
4278      }
4279
4280    tizen_viewport_set_destination(win->video.viewport, x, y, w, h);
4281    wl_surface_commit(win->video.surface);
4282
4283    return EINA_TRUE;
4284 }
4285
4286 EAPI int
4287 ecore_wl2_window_render_sync_fd_create(Ecore_Wl2_Window *win, Ecore_Wl2_Window_Render_Sync_Type sync_type)
4288 {
4289    int sync_fd = -1;
4290
4291    EINA_SAFETY_ON_NULL_RETURN_VAL(win, sync_fd);
4292    EINA_SAFETY_ON_NULL_RETURN_VAL(win->egl_win, sync_fd);
4293
4294    switch (sync_type)
4295      {
4296       case ECORE_WL2_WINDOW_RENDER_SYNC_COMMIT:
4297         sync_fd = wl_egl_window_tizen_create_commit_sync_fd(win->egl_win->native_win);
4298         break;
4299       case ECORE_WL2_WINDOW_RENDER_SYNC_PRESENT:
4300         sync_fd = wl_egl_window_tizen_create_presentation_sync_fd(win->egl_win->native_win);
4301         break;
4302       default:
4303         break;
4304      }
4305
4306    return sync_fd;
4307 }
4308 //
4309
4310 //TIZEN_ONLY: ecore_wl2: add ecore_wl_window_video_has
4311 EAPI void
4312 ecore_wl2_window_video_has(Ecore_Wl2_Window *window, Eina_Bool has)
4313 {
4314    Ecore_Wl2_Display *display;
4315    uint32_t ver;
4316
4317    EINA_SAFETY_ON_NULL_RETURN(window);
4318
4319    display = window->display;
4320    if (!display->wl.tz_policy) return;
4321
4322    ver = wl_proxy_get_version((struct wl_proxy *)display->wl.tz_policy);
4323
4324    if (ver >= 7)
4325      tizen_policy_has_video(display->wl.tz_policy, window->surface, has);
4326 }
4327 //
4328
4329 //TIZEN_ONLY(20171115): support output transform
4330 void
4331 _ecore_wl2_window_ignore_output_transform_set(Ecore_Wl2_Window *window, Eina_Bool ignore)
4332 {
4333    if (!window) return;
4334
4335    window->ignore_output_transform = ignore;
4336 }
4337
4338 EAPI Eina_Bool
4339 ecore_wl2_window_ignore_output_transform_get(Ecore_Wl2_Window *window)
4340 {
4341    return window->ignore_output_transform;
4342 }
4343 //
4344
4345 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4346 EAPI void
4347 ecore_wl2_window_pointer_set(Ecore_Wl2_Window *win, struct wl_surface *surface, int hot_x, int hot_y)
4348 {
4349    Ecore_Wl2_Input *input;
4350
4351    if (!win) return;
4352
4353    win->pointer.surface = surface;
4354    win->pointer.hot_x = hot_x;
4355    win->pointer.hot_y = hot_y;
4356    win->pointer.set = EINA_TRUE;
4357
4358    if ((input = win->pointer.device))
4359      ecore_wl2_input_pointer_set(input, surface, hot_x, hot_y);
4360 }
4361
4362 EAPI void
4363 ecore_wl2_window_cursor_from_name_set(Ecore_Wl2_Window *win, const char *cursor_name)
4364 {
4365    Ecore_Wl2_Input *input;
4366
4367    if (!win) return;
4368
4369    win->pointer.set = EINA_FALSE;
4370
4371    if (!(input = win->pointer.device))
4372      return;
4373
4374    eina_stringshare_replace(&win->pointer.cursor_name, cursor_name);
4375
4376    if ((input->cursor.name) && (strcmp(input->cursor.name, win->pointer.cursor_name)))
4377      ecore_wl2_input_cursor_from_name_set(input, cursor_name);
4378 }
4379
4380 EAPI void
4381 ecore_wl2_window_cursor_default_restore(Ecore_Wl2_Window *win)
4382 {
4383    Ecore_Wl2_Input *input;
4384
4385    if (!win) return;
4386
4387    win->pointer.set = EINA_FALSE;
4388
4389    if ((input = win->pointer.device))
4390      ecore_wl2_input_cursor_default_restore(input);
4391 }
4392 //
4393
4394 //TIZEN_ONLY(20180810): support client demand move resize
4395 EAPI void
4396 ecore_wl2_window_sync_geometry_set(Ecore_Wl2_Window *window, uint32_t serial, int x, int y, int w, int h)
4397 {
4398    if (!window) return;
4399
4400    if ((window->set_config.geometry.x != x) ||
4401        (window->set_config.geometry.y != y) ||
4402        (window->set_config.geometry.w != w) ||
4403        (window->set_config.geometry.h != h))
4404      window->pending.geom = EINA_TRUE;
4405
4406    window->set_config.geometry.x = x;
4407    window->set_config.geometry.y = y;
4408    window->set_config.geometry.w = w;
4409    window->set_config.geometry.h = h;
4410
4411    if (window->display->wl.tz_moveresize)
4412      tizen_move_resize_set_geometry(window->display->wl.tz_moveresize, window->surface, serial, x, y, w, h);
4413
4414    // TIZEN_ONLY(20190807): Support for wl_egl interface
4415    if (window->egl_win)
4416      {
4417         window->egl_win->sync_geom.serial = serial;
4418         window->egl_win->sync_geom.w = w;
4419         window->egl_win->sync_geom.h = h;
4420
4421         wl_egl_window_tizen_set_window_serial(window->egl_win->native_win, serial);
4422      }
4423    //
4424 }
4425 //
4426
4427 // TIZEN_ONLY(20190807): Support for wl_egl interface
4428 EAPI Ecore_Wl2_Egl_Window *
4429 ecore_wl2_egl_window_create(Ecore_Wl2_Window *window, int w, int h)
4430 {
4431    Ecore_Wl2_Egl_Window *egl_win = NULL;
4432    struct wl_egl_window *native_win = NULL;
4433    int cap = WL_EGL_WINDOW_TIZEN_CAPABILITY_NONE;
4434
4435    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
4436    EINA_SAFETY_ON_NULL_RETURN_VAL(window->surface, NULL);
4437    EINA_SAFETY_ON_FALSE_RETURN_VAL((window->egl_win == NULL), NULL);
4438    EINA_SAFETY_ON_FALSE_RETURN_VAL((w >= 0), NULL);
4439    EINA_SAFETY_ON_FALSE_RETURN_VAL((h >= 0), NULL);
4440
4441    native_win = wl_egl_window_create(window->surface, w, h);
4442    EINA_SAFETY_ON_NULL_RETURN_VAL(native_win, NULL);
4443
4444    egl_win = calloc(1, sizeof(Ecore_Wl2_Egl_Window));
4445    EINA_SAFETY_ON_NULL_GOTO(egl_win, failed);
4446
4447    egl_win->win = window;
4448    egl_win->native_win = native_win;
4449    egl_win->w = w;
4450    egl_win->h = h;
4451
4452    window->egl_win = egl_win;
4453
4454    cap = wl_egl_window_tizen_get_capabilities(native_win);
4455    if (cap == WL_EGL_WINDOW_TIZEN_CAPABILITY_ROTATION_SUPPORTED)
4456      egl_win->support_pre_rotation = EINA_TRUE;
4457
4458    return egl_win;
4459
4460 failed:
4461    if (native_win) wl_egl_window_destroy(native_win);
4462    return NULL;
4463 }
4464
4465 EAPI void
4466 ecore_wl2_egl_window_destroy(Ecore_Wl2_Egl_Window *egl_win)
4467 {
4468    EINA_SAFETY_ON_NULL_RETURN(egl_win);
4469
4470    if (egl_win->native_win)
4471      wl_egl_window_destroy(egl_win->native_win);
4472
4473    if (egl_win->win)
4474      egl_win->win->egl_win = NULL;
4475
4476    memset(egl_win, 0, sizeof(Ecore_Wl2_Egl_Window));
4477    free(egl_win);
4478 }
4479
4480 EAPI void *
4481 ecore_wl2_egl_window_native_get(Ecore_Wl2_Egl_Window *egl_win)
4482 {
4483    EINA_SAFETY_ON_NULL_RETURN_VAL(egl_win, NULL);
4484    return (void *)egl_win->native_win;
4485 }
4486
4487 EAPI void
4488 ecore_wl2_egl_window_resize_with_rotation(Ecore_Wl2_Egl_Window *egl_win, int dx, int dy, int w, int h, int rotation)
4489 {
4490    int rot = rotation % 360;
4491
4492    EINA_SAFETY_ON_NULL_RETURN(egl_win);
4493
4494    egl_win->rot.buffer = rot;
4495    egl_win->rot.win = rot;
4496    egl_win->dx = dx;
4497    egl_win->dy = dy;
4498    egl_win->w = w;
4499    egl_win->h = h;
4500
4501    if (egl_win->support_pre_rotation)
4502      wl_egl_window_tizen_set_rotation(egl_win->native_win, egl_win->rot.win);
4503
4504    //TIZEN_ONLY(20171115): support output transform
4505    /* buffer_transform: screen rotation + window rotation
4506     * window_transform: window rotation only
4507     * We have to let the display server know the window rotation value
4508     * because the display server needs to calcuate the screen rotation value
4509     * from buffer_transform value.
4510     */
4511    wl_egl_window_tizen_set_buffer_transform(egl_win->native_win, egl_win->rot.buffer / 90);
4512    wl_egl_window_tizen_set_window_transform(egl_win->native_win, egl_win->rot.win / 90);
4513    //
4514
4515    if ((egl_win->rot.buffer == 90) || (egl_win->rot.buffer == 270))
4516      wl_egl_window_resize(egl_win->native_win, h, w, dx, dy);
4517    else
4518      wl_egl_window_resize(egl_win->native_win, w, h, dx, dy);
4519 }
4520 //
4521
4522 //TIZEN_ONLY(20220322): add resource id to window attribute
4523 EAPI unsigned int
4524 ecore_wl2_window_resource_id_get(Ecore_Wl2_Window *window)
4525 {
4526    EINA_SAFETY_ON_NULL_RETURN_VAL(window, 0);
4527    return window->resource_id;
4528 }
4529 //