ecore_wl2_window: set a saved size imediately if maximizing window is pended
[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         if (changed_maximize_state && maximized)
2140           {
2141              window->saved = window->set_config.geometry;
2142           }
2143         window->pending.maximized = EINA_TRUE;
2144         return;
2145      }
2146
2147    if (changed_maximize_state)
2148      {
2149         if (maximized)
2150           {
2151              if (!window->set_config.fullscreen)
2152                window->saved = window->set_config.geometry;
2153
2154              if (window->xdg_toplevel)
2155                xdg_toplevel_set_maximized(window->xdg_toplevel);
2156              if (window->zxdg_toplevel)
2157                zxdg_toplevel_v6_set_maximized(window->zxdg_toplevel);
2158           }
2159         else
2160           {
2161              if (window->xdg_toplevel)
2162                xdg_toplevel_unset_maximized(window->xdg_toplevel);
2163              if (window->zxdg_toplevel)
2164                zxdg_toplevel_v6_unset_maximized(window->zxdg_toplevel);
2165           }
2166      }
2167
2168    /* TIZEN_ONLY(20190522): The window properties of ecore_evas are updated in
2169     * _ecore_evas_wl_common_cb_window_configure.
2170     * To call _ecore_evas_wl_common_cb_window_configure,
2171     * ECORE_WL2_EVENT_WINDOW_CONFIGURE event is added.
2172     * To add ECORE_WL2_EVENT_WINDOW_CONFIGURE event,
2173     * _ecore_wl2_window_configure_send is called. */
2174    _ecore_wl2_window_configure_send(window);
2175    /* END of TIZEN_ONLY(20190522) */
2176    ecore_wl2_display_flush(window->display);
2177 }
2178
2179 EAPI void
2180 ecore_wl2_window_maximized_set(Ecore_Wl2_Window *window, Eina_Bool maximized)
2181 {
2182    if (maximized)
2183      ecore_wl2_window_maximized_set_with_direction(window, ECORE_WL2_MAXIMIZE_DIRECTION_ALL);
2184    else
2185      ecore_wl2_window_maximized_set_with_direction(window, ECORE_WL2_MAXIMIZE_DIRECTION_NONE);
2186 }
2187
2188 EAPI Eina_Bool
2189 ecore_wl2_window_fullscreen_get(Ecore_Wl2_Window *window)
2190 {
2191    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2192
2193    return window->set_config.fullscreen;
2194 }
2195
2196 EAPI void
2197 ecore_wl2_window_fullscreen_set(Ecore_Wl2_Window *window, Eina_Bool fullscreen)
2198 {
2199    Eina_Bool prev;
2200
2201    EINA_SAFETY_ON_NULL_RETURN(window);
2202
2203    prev = window->set_config.fullscreen;
2204    fullscreen = !!fullscreen;
2205    if (prev == fullscreen) return;
2206
2207    window->set_config.fullscreen = fullscreen;
2208    if (window->updating)
2209      {
2210         window->pending.fullscreen = EINA_TRUE;
2211         return;
2212      }
2213
2214    if (fullscreen)
2215      {
2216         if (!window->set_config.maximized)
2217           window->saved = window->set_config.geometry;
2218
2219         if (window->xdg_toplevel)
2220           xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
2221         if (window->zxdg_toplevel)
2222           zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL);
2223      }
2224    else
2225      {
2226         if (window->xdg_toplevel)
2227           xdg_toplevel_unset_fullscreen(window->xdg_toplevel);
2228         if (window->zxdg_toplevel)
2229           zxdg_toplevel_v6_unset_fullscreen(window->zxdg_toplevel);
2230      }
2231    /* TIZEN_ONLY(20190522): The window properties of ecore_evas are updated in
2232     * _ecore_evas_wl_common_cb_window_configure.
2233     * To call _ecore_evas_wl_common_cb_window_configure,
2234     * ECORE_WL2_EVENT_WINDOW_CONFIGURE event is added.
2235     * To add ECORE_WL2_EVENT_WINDOW_CONFIGURE event,
2236     * _ecore_wl2_window_configure_send is called. */
2237    _ecore_wl2_window_configure_send(window);
2238    /* END of TIZEN_ONLY(20190522) */
2239    ecore_wl2_display_flush(window->display);
2240 }
2241
2242 EAPI int
2243 ecore_wl2_window_rotation_get(Ecore_Wl2_Window *window)
2244 {
2245    EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
2246
2247    return window->rotation;
2248 }
2249
2250 EAPI void
2251 ecore_wl2_window_rotation_set(Ecore_Wl2_Window *window, int rotation)
2252 {
2253    EINA_SAFETY_ON_NULL_RETURN(window);
2254
2255    window->rotation = rotation;
2256 }
2257
2258 EAPI void
2259 ecore_wl2_window_title_set(Ecore_Wl2_Window *window, const char *title)
2260 {
2261    EINA_SAFETY_ON_NULL_RETURN(window);
2262
2263    eina_stringshare_replace(&window->title, title);
2264    if (!window->title) return;
2265    if (!window->xdg_toplevel && !window->zxdg_toplevel) return;
2266
2267    if (window->xdg_toplevel)
2268      xdg_toplevel_set_title(window->xdg_toplevel, window->title);
2269    if (window->zxdg_toplevel)
2270      zxdg_toplevel_v6_set_title(window->zxdg_toplevel, window->title);
2271    ecore_wl2_display_flush(window->display);
2272 }
2273
2274 EAPI const char *
2275 ecore_wl2_window_title_get(Ecore_Wl2_Window *window)
2276 {
2277    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2278
2279    return window->title ? window->title : NULL;
2280 }
2281
2282 EAPI void
2283 ecore_wl2_window_class_set(Ecore_Wl2_Window *window, const char *clas)
2284 {
2285    EINA_SAFETY_ON_NULL_RETURN(window);
2286
2287    eina_stringshare_replace(&window->class, clas);
2288    if (!window->class) return;
2289    if (!window->xdg_toplevel && !window->zxdg_toplevel) return;
2290
2291    if (window->xdg_toplevel)
2292      xdg_toplevel_set_app_id(window->xdg_toplevel, window->class);
2293    if (window->zxdg_toplevel)
2294      zxdg_toplevel_v6_set_app_id(window->zxdg_toplevel, window->class);
2295    ecore_wl2_display_flush(window->display);
2296 }
2297
2298 EAPI const char *
2299 ecore_wl2_window_class_get(Ecore_Wl2_Window *window)
2300 {
2301    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2302
2303    return window->class ? window->class : NULL;
2304 }
2305
2306 EAPI void
2307 ecore_wl2_window_geometry_get(Ecore_Wl2_Window *window, int *x, int *y, int *w, int *h)
2308 {
2309    EINA_SAFETY_ON_NULL_RETURN(window);
2310
2311    if (x) *x = window->set_config.geometry.x;
2312    if (y) *y = window->set_config.geometry.y;
2313    if (w) *w = window->set_config.geometry.w;
2314    if (h) *h = window->set_config.geometry.h;
2315 }
2316
2317 EAPI void
2318 ecore_wl2_window_geometry_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
2319 {
2320    EINA_SAFETY_ON_NULL_RETURN(window);
2321
2322    if ((window->set_config.geometry.x == x) &&
2323        (window->set_config.geometry.y == y) &&
2324        (window->set_config.geometry.w == w) &&
2325        (window->set_config.geometry.h == h))
2326      return;
2327
2328    window->set_config.geometry.x = x;
2329    window->set_config.geometry.y = y;
2330    window->set_config.geometry.w = w;
2331    window->set_config.geometry.h = h;
2332    window->pending.geom = EINA_TRUE;
2333 }
2334
2335 //TIZEN_ONLY(20220325): added min / max size set to window
2336 EAPI void
2337 ecore_wl2_window_minimum_size_set(Ecore_Wl2_Window *window, int w, int h)
2338 {
2339    EINA_SAFETY_ON_NULL_RETURN(window);
2340
2341    if (window->zxdg_set_min_size && window->zxdg_toplevel)
2342      {
2343         window->zxdg_set_min_size(window->zxdg_toplevel, w, h);
2344         window->pending.min = 0;
2345         return;
2346      }
2347    if (window->xdg_set_min_size && window->xdg_toplevel)
2348      {
2349         window->xdg_set_min_size(window->xdg_toplevel, w, h);
2350         window->pending.min = 0;
2351         return;
2352      }
2353 }
2354
2355 EAPI void
2356 ecore_wl2_window_maximum_size_set(Ecore_Wl2_Window *window, int w, int h)
2357 {
2358    EINA_SAFETY_ON_NULL_RETURN(window);
2359
2360    if (window->zxdg_set_max_size && window->zxdg_toplevel)
2361      {
2362         window->zxdg_set_max_size(window->zxdg_toplevel, w, h);
2363         window->pending.max = 0;
2364         return;
2365      }
2366    if (window->xdg_set_max_size && window->xdg_toplevel)
2367      {
2368         window->xdg_set_max_size(window->xdg_toplevel, w, h);
2369         window->pending.max = 0;
2370         return;
2371      }
2372 }
2373 //
2374
2375 EAPI Eina_Bool
2376 ecore_wl2_window_iconified_get(Ecore_Wl2_Window *window)
2377 {
2378    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2379
2380    // TIZEN_ONLY(20150822)
2381    if (window->display->wl.tz_policy)
2382      return window->iconified;
2383    else
2384    //
2385    return window->set_config.minimized;
2386 }
2387
2388 // TIZEN_ONLY(20151231) : handling iconic state on tizen
2389 static void
2390 _ecore_wl2_window_iconified_set(Ecore_Wl2_Window *window, Eina_Bool iconified, Eina_Bool send_event)
2391 {
2392    Eina_Bool prev;
2393
2394    EINA_SAFETY_ON_NULL_RETURN(window);
2395
2396    prev = window->set_config.minimized;
2397    iconified = !!iconified;
2398    if (prev == iconified) return;
2399
2400    window->set_config.minimized = iconified;
2401
2402    if (iconified)
2403      {
2404         if ((window->surface) && (window->display->wl.tz_policy))
2405           {
2406              if (send_event)
2407                tizen_policy_iconify(window->display->wl.tz_policy, window->surface);
2408              window->iconified = EINA_TRUE;
2409           }
2410
2411         else if (window->zxdg_toplevel)
2412           zxdg_toplevel_v6_set_minimized(window->zxdg_toplevel);
2413      }
2414    else
2415      {
2416         if ((window->surface) && (window->display->wl.tz_policy))
2417           {
2418              if (send_event)
2419                tizen_policy_uniconify(window->display->wl.tz_policy, window->surface);
2420              window->iconified = EINA_FALSE;
2421           }
2422
2423         else if (window->zxdg_toplevel)
2424           {
2425              struct wl_array states;
2426              uint32_t *s;
2427
2428              wl_array_init(&states);
2429              s = wl_array_add(&states, sizeof(*s));
2430              *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
2431              _zxdg_toplevel_cb_configure(window, window->zxdg_toplevel,
2432                                          window->saved.w,
2433                                          window->saved.h, &states);
2434              wl_array_release(&states);
2435           }
2436      }
2437
2438    if (send_event)
2439      {
2440         Ecore_Wl2_Event_Window_Iconify_State_Change *ev;
2441
2442         if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Iconify_State_Change)))) return;
2443         ev->win = window->id;
2444         ev->iconified = iconified;
2445         ev->force = 0;
2446         ecore_event_add(ECORE_WL2_EVENT_WINDOW_ICONIFY_STATE_CHANGE, ev, NULL, NULL);
2447      }
2448 }
2449 //
2450
2451 EAPI void
2452 ecore_wl2_window_iconified_set(Ecore_Wl2_Window *window, Eina_Bool iconified)
2453 {
2454    // TIZEN_ONLY(20151231) : handling iconic state on tizen
2455    /*
2456    Eina_Bool prev;
2457
2458    EINA_SAFETY_ON_NULL_RETURN(window);
2459
2460    prev = window->set_config.minimized;
2461    iconified = !!iconified;
2462    if (prev == iconified) return;
2463
2464    window->set_config.minimized = iconified;
2465
2466    if (iconified)
2467      {
2468         if (window->xdg_toplevel)
2469           xdg_toplevel_set_minimized(window->xdg_toplevel);
2470         if (window->zxdg_toplevel)
2471           zxdg_toplevel_v6_set_minimized(window->zxdg_toplevel);
2472         ecore_wl2_display_flush(window->display);
2473      }
2474    */
2475    _ecore_wl2_window_iconified_set(window, iconified, EINA_TRUE);
2476    //
2477 }
2478
2479 // TIZEN_ONLY(20151231) : handling iconic state on tizen
2480 EAPI void
2481 ecore_wl2_window_iconify_state_update(Ecore_Wl2_Window *window, Eina_Bool iconified, Eina_Bool send_event)
2482 {
2483    _ecore_wl2_window_iconified_set(window, iconified, send_event);
2484 }
2485 //
2486
2487 //TIZEN_ONLY(20171216): add ecore_wl2_window_find
2488 EAPI Ecore_Wl2_Window *
2489 ecore_wl2_window_find(unsigned int id)
2490 {
2491    Ecore_Wl2_Window *win = NULL;
2492
2493    if (!_windows) return NULL;
2494    win = eina_hash_find(_windows, _ecore_wl2_window_id_str_get(id));
2495    return win;
2496 }
2497 //
2498
2499 //TIZEN_ONLY(20180202): Fix to send a proper window type value to the server
2500 static inline uint32_t
2501 _convert_to_tzsh_type(Ecore_Wl2_Window_Type type)
2502 {
2503    switch (type)
2504      {
2505         case ECORE_WL2_WINDOW_TYPE_NONE:
2506           return TIZEN_POLICY_WIN_TYPE_NONE;
2507         case ECORE_WL2_WINDOW_TYPE_TOPLEVEL:
2508           return TIZEN_POLICY_WIN_TYPE_TOPLEVEL;
2509         case ECORE_WL2_WINDOW_TYPE_MENU:
2510           return TIZEN_POLICY_WIN_TYPE_MENU;
2511         case ECORE_WL2_WINDOW_TYPE_DND:
2512           return TIZEN_POLICY_WIN_TYPE_DND;
2513         case ECORE_WL2_WINDOW_TYPE_CUSTOM:
2514           return TIZEN_POLICY_WIN_TYPE_CUSTOM;
2515         case ECORE_WL2_WINDOW_TYPE_NOTIFICATION:
2516           return TIZEN_POLICY_WIN_TYPE_NOTIFICATION;
2517         case ECORE_WL2_WINDOW_TYPE_UTILITY:
2518           return TIZEN_POLICY_WIN_TYPE_UTILITY;
2519         case ECORE_WL2_WINDOW_TYPE_DIALOG:
2520           return TIZEN_POLICY_WIN_TYPE_DIALOG;
2521         case ECORE_WL2_WINDOW_TYPE_DOCK:
2522           return TIZEN_POLICY_WIN_TYPE_DOCK;
2523         case ECORE_WL2_WINDOW_TYPE_SPLASH:
2524           return TIZEN_POLICY_WIN_TYPE_SPLASH;
2525         case ECORE_WL2_WINDOW_TYPE_DESKTOP:
2526           return TIZEN_POLICY_WIN_TYPE_DESKTOP;
2527         default:
2528           return TIZEN_POLICY_WIN_TYPE_NONE;
2529      }
2530 }
2531 //
2532
2533 EAPI void
2534 ecore_wl2_window_type_set(Ecore_Wl2_Window *window, Ecore_Wl2_Window_Type type)
2535 {
2536    EINA_SAFETY_ON_NULL_RETURN(window);
2537    window->type = type;
2538
2539    // TIZEN_ONLY(20180202): Fix to send a proper window type value to the server
2540    uint32_t tzsh_type;
2541    tzsh_type = _convert_to_tzsh_type(type);
2542    //
2543
2544 // TIZEN_ONLY(20171114)
2545    if ((window->surface) && (window->display->wl.tz_policy))
2546      tizen_policy_set_type(window->display->wl.tz_policy, window->surface, (uint32_t)tzsh_type);
2547 //
2548 }
2549
2550 EAPI void
2551 ecore_wl2_window_popup_input_set(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
2552 {
2553    EINA_SAFETY_ON_NULL_RETURN(window);
2554    EINA_SAFETY_ON_NULL_RETURN(input);
2555    EINA_SAFETY_ON_TRUE_RETURN(window->type != ECORE_WL2_WINDOW_TYPE_MENU);
2556    window->grab = input;
2557 }
2558
2559 EAPI Ecore_Wl2_Input *
2560 ecore_wl2_window_popup_input_get(Ecore_Wl2_Window *window)
2561 {
2562    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2563
2564    return window->grab;
2565 }
2566
2567 EAPI Ecore_Wl2_Display *
2568 ecore_wl2_window_display_get(const Ecore_Wl2_Window *window)
2569 {
2570    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2571    EINA_SAFETY_ON_NULL_RETURN_VAL(window->display, NULL);
2572
2573    if (window->display->recovering) return NULL;
2574
2575    return window->display;
2576 }
2577
2578 EAPI Eina_Bool
2579 ecore_wl2_window_shell_surface_exists(Ecore_Wl2_Window *window)
2580 {
2581    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2582    return !!window->zxdg_surface || !!window->xdg_surface;
2583 }
2584
2585 // TIZEN_ONLY(171108) : get shell surface of a given window
2586 EAPI struct zxdg_surface_v6 *
2587 ecore_wl2_window_shell_surface_get(Ecore_Wl2_Window *window)
2588 {
2589    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2590    return window->zxdg_surface;
2591 }
2592 //
2593
2594 EAPI Eina_Bool
2595 ecore_wl2_window_activated_get(const Ecore_Wl2_Window *window)
2596 {
2597    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2598    return window->req_config.focused;
2599 }
2600
2601 EAPI Ecore_Wl2_Output *
2602 ecore_wl2_window_output_find(Ecore_Wl2_Window *window)
2603 {
2604    Ecore_Wl2_Output *out;
2605    Eina_Inlist *tmp;
2606    int x = 0, y = 0;
2607
2608    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
2609
2610    x = window->set_config.geometry.x;
2611    y = window->set_config.geometry.y;
2612
2613    EINA_INLIST_FOREACH_SAFE(window->display->outputs, tmp, out)
2614      {
2615         int ox, oy, ow, oh;
2616
2617         ox = out->geometry.x;
2618         oy = out->geometry.y;
2619
2620         switch (out->transform)
2621           {
2622            case WL_OUTPUT_TRANSFORM_90:
2623            case WL_OUTPUT_TRANSFORM_270:
2624            case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2625            case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2626              ow = out->geometry.h;
2627              oh = out->geometry.w;
2628              break;
2629            default:
2630              ow = out->geometry.w;
2631              oh = out->geometry.h;
2632              break;
2633           }
2634
2635         if (((x >= ox) && (x < ow)) && ((y >= oy) && (y < oh)))
2636           return out;
2637      }
2638
2639    return NULL;
2640 }
2641
2642 EAPI void
2643 ecore_wl2_window_buffer_transform_set(Ecore_Wl2_Window *window, int transform)
2644 {
2645    EINA_SAFETY_ON_NULL_RETURN(window);
2646
2647    wl_surface_set_buffer_transform(window->surface, transform);
2648 }
2649
2650 EAPI void
2651 ecore_wl2_window_wm_rotation_supported_set(Ecore_Wl2_Window *window, Eina_Bool enabled)
2652 {
2653    EINA_SAFETY_ON_NULL_RETURN(window);
2654    window->wm_rot.supported = enabled;
2655 }
2656
2657 EAPI Eina_Bool
2658 ecore_wl2_window_wm_rotation_supported_get(Ecore_Wl2_Window *window)
2659 {
2660    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2661    return window->wm_rot.supported;
2662 }
2663
2664 EAPI void
2665 ecore_wl2_window_rotation_app_set(Ecore_Wl2_Window *window, Eina_Bool set)
2666 {
2667    EINA_SAFETY_ON_NULL_RETURN(window);
2668    window->wm_rot.app_set = set;
2669 }
2670
2671 EAPI Eina_Bool
2672 ecore_wl2_window_rotation_app_get(Ecore_Wl2_Window *window)
2673 {
2674    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2675    return window->wm_rot.app_set;
2676 }
2677
2678 EAPI void
2679 ecore_wl2_window_preferred_rotation_set(Ecore_Wl2_Window *window, int rot)
2680 {
2681    EINA_SAFETY_ON_NULL_RETURN(window);
2682    window->wm_rot.preferred_rot = rot;
2683
2684    // TIZEN_ONLY
2685    _tizen_rotation_preferred_angle_set(window, window->wm_rot.preferred_rot);
2686    //
2687 }
2688
2689 EAPI int
2690 ecore_wl2_window_preferred_rotation_get(Ecore_Wl2_Window *window)
2691 {
2692    EINA_SAFETY_ON_NULL_RETURN_VAL(window, 0);
2693    return window->wm_rot.preferred_rot;
2694 }
2695
2696 EAPI void
2697 ecore_wl2_window_available_rotations_set(Ecore_Wl2_Window *window, const int *rots, unsigned int count)
2698 {
2699    unsigned int i = 0;
2700    EINA_SAFETY_ON_NULL_RETURN(window);
2701
2702    // TIZEN_ONLY
2703    _tizen_rotation_available_angles_set(window, rots, count);
2704    //
2705
2706    if (window->wm_rot.available_rots)
2707      {
2708         free(window->wm_rot.available_rots);
2709         window->wm_rot.available_rots = NULL;
2710      }
2711    window->wm_rot.count = count;
2712
2713    if (count >= 1)
2714      {
2715         window->wm_rot.available_rots = calloc(count, sizeof(int));
2716         if (!window->wm_rot.available_rots) return;
2717
2718         for (; i < count; i++)
2719           window->wm_rot.available_rots[i] = ((int *)rots)[i];
2720      }
2721 }
2722
2723 EAPI Eina_Bool
2724 ecore_wl2_window_available_rotations_get(Ecore_Wl2_Window *window, int **rots, unsigned int *count)
2725 {
2726    unsigned int i = 0;
2727    int *val = NULL;
2728
2729    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
2730
2731    *rots = NULL;
2732    *count = window->wm_rot.count;
2733
2734    if (window->wm_rot.count >= 1)
2735      {
2736         val = calloc(window->wm_rot.count, sizeof(int));
2737         if (!val) return EINA_FALSE;
2738
2739         for (; i < window->wm_rot.count; i++)
2740           val[i] = ((int *)window->wm_rot.available_rots)[i];
2741
2742         *rots = val;
2743         return EINA_TRUE;
2744      }
2745
2746    return EINA_FALSE;
2747 }
2748
2749 EAPI void
2750 ecore_wl2_window_rotation_change_prepare_send(Ecore_Wl2_Window *window, int rot, int w, int h, Eina_Bool resize)
2751 {
2752    Ecore_Wl2_Event_Window_Rotation_Change_Prepare *ev;
2753
2754    EINA_SAFETY_ON_NULL_RETURN(window);
2755
2756    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Prepare));
2757    if (!ev) return;
2758
2759    ev->win = window->id;
2760    ev->rotation = rot;
2761    ev->w = w;
2762    ev->h = h;
2763    ev->resize = resize;
2764
2765    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_PREPARE, ev, NULL, NULL);
2766 }
2767
2768 EAPI void
2769 ecore_wl2_window_rotation_change_prepare_done_send(Ecore_Wl2_Window *window, int rot)
2770 {
2771    Ecore_Wl2_Event_Window_Rotation_Change_Prepare_Done *ev;
2772
2773    EINA_SAFETY_ON_NULL_RETURN(window);
2774
2775    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Prepare_Done));
2776    if (!ev) return;
2777
2778    ev->win = window->id;
2779    ev->rotation = rot;
2780    ev->w = 0;
2781    ev->h = 0;
2782    ev->resize = 0;
2783
2784    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_PREPARE_DONE,
2785                    ev, NULL, NULL);
2786 }
2787
2788 EAPI void
2789 ecore_wl2_window_rotation_change_request_send(Ecore_Wl2_Window *window, int rot)
2790 {
2791    Ecore_Wl2_Event_Window_Rotation_Change_Request *ev;
2792
2793    EINA_SAFETY_ON_NULL_RETURN(window);
2794
2795    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Request));
2796    if (!ev) return;
2797
2798    ev->win = window->id;
2799    ev->rotation = rot;
2800    ev->w = 0;
2801    ev->h = 0;
2802    ev->resize = 0;
2803
2804    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_REQUEST,
2805                    ev, NULL, NULL);
2806 }
2807
2808 EAPI void
2809 ecore_wl2_window_rotation_change_done_send(Ecore_Wl2_Window *window, int rot, int w, int h)
2810 {
2811    Ecore_Wl2_Event_Window_Rotation_Change_Done *ev;
2812
2813    EINA_SAFETY_ON_NULL_RETURN(window);
2814
2815    // TIZEN_ONLY
2816    if (window->tz_rotation)
2817      tizen_rotation_ack_angle_change(window->tz_rotation, window->wm_rot.serial);
2818    //
2819
2820    ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Done));
2821    if (!ev) return;
2822
2823    ev->win = window->id;
2824    ev->rotation = rot;
2825    ev->w = w;
2826    ev->h = h;
2827    ev->resize = 0;
2828
2829    ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_DONE,
2830                    ev, NULL, NULL);
2831 }
2832
2833 // TIZEN_ONLY
2834 EAPI void
2835 ecore_wl2_window_rotation_geometry_set(Ecore_Wl2_Window *win, int rot, int x, int y, int w, int h)
2836 {
2837    int i = 0;
2838    int rotation = 0;
2839    enum tizen_rotation_angle angle = TIZEN_ROTATION_ANGLE_NONE;
2840
2841    if (!win) return;
2842
2843    if ((rot % 90 != 0) || (rot / 90 > 3) || (rot < 0)) return;
2844
2845    i = rot / 90;
2846    win->wm_rot.geometry_hints[i].x = x;
2847    win->wm_rot.geometry_hints[i].y = y;
2848    win->wm_rot.geometry_hints[i].w = w;
2849    win->wm_rot.geometry_hints[i].h = h;
2850    win->wm_rot.geometry_hints[i].valid = EINA_TRUE;
2851
2852    if (!win->tz_rotation) return;
2853    switch (rot)
2854      {
2855       case 0:
2856          angle = TIZEN_ROTATION_ANGLE_0;
2857          break;
2858       case 90:
2859          angle = TIZEN_ROTATION_ANGLE_90;
2860          break;
2861       case 180:
2862          angle = TIZEN_ROTATION_ANGLE_180;
2863          break;
2864       case 270:
2865          angle = TIZEN_ROTATION_ANGLE_270;
2866          break;
2867       default:
2868          break;
2869      }
2870    tizen_rotation_set_geometry_hint(win->tz_rotation,
2871                                     (uint32_t)angle, x, y, w, h);
2872
2873    rotation = ecore_wl2_window_rotation_get(win);
2874    if ((rotation % 90 != 0) || (rotation / 90 > 3) || (rotation < 0)) return;
2875    if ((i == (rotation / 90)) &&
2876        ((win->set_config.geometry.w != w) || (win->set_config.geometry.h != h)))
2877      {
2878         //TIZEN_ONLY(20180201) : add function to set window size by client.
2879         win->set_config.geometry.w = w;
2880         win->set_config.geometry.h = h;
2881         _ecore_wl2_window_configure_send_by_client(win);
2882         //
2883      }
2884 }
2885
2886 EAPI void
2887 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))
2888 {
2889    if (!win) return;
2890
2891    win->cb_rot_changed = func;
2892    win->cb_rot_changed_data = data;
2893 }
2894 //
2895
2896 // TIZEN_ONLY(20210330): for maintain internal aux hint list
2897 static Ecore_Wl2_Window_Aux_Hint *
2898 _ecore_wl2_window_aux_hint_get_by_id(Ecore_Wl2_Window *win, int id)
2899 {
2900    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
2901    Eina_List *l = NULL;
2902
2903    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
2904
2905    EINA_LIST_REVERSE_FOREACH(win->aux_hints, l, ewah)
2906      {
2907         if (ewah->id == id)
2908           return ewah;
2909      }
2910
2911    return NULL;
2912 }
2913
2914 static Ecore_Wl2_Window_Aux_Hint *
2915 _ecore_wl2_window_aux_hint_get_by_hint(Ecore_Wl2_Window *win, const char *hint)
2916 {
2917    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
2918    Eina_List *l = NULL;
2919    size_t hint_len = 0;
2920
2921    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
2922
2923    hint_len = strlen(hint);
2924    EINA_LIST_REVERSE_FOREACH(win->aux_hints, l, ewah)
2925      {
2926         if ((strlen(ewah->hint) == hint_len) &&
2927             !strncmp(ewah->hint, hint, hint_len))
2928           return ewah;
2929      }
2930
2931    return NULL;
2932 }
2933
2934 static Eina_Bool
2935 _ecore_wl2_window_aux_hint_list_add(Ecore_Wl2_Window *win, int id, const char *hint, const char *val)
2936 {
2937    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
2938
2939    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
2940
2941    ewah = _ecore_wl2_window_aux_hint_get_by_id(win, id);
2942    if (ewah)
2943      {
2944         eina_stringshare_del(ewah->hint);
2945         eina_stringshare_del(ewah->val);
2946         ewah->hint = eina_stringshare_add(hint);
2947         ewah->val = eina_stringshare_add(val);
2948         return EINA_TRUE;
2949      }
2950
2951    ewah = (Ecore_Wl2_Window_Aux_Hint *)calloc(1, sizeof(Ecore_Wl2_Window_Aux_Hint));
2952    EINA_SAFETY_ON_NULL_RETURN_VAL(ewah, EINA_FALSE);
2953
2954    ewah->hint = eina_stringshare_add(hint);
2955    ewah->val = eina_stringshare_add(val);
2956    ewah->id = id;
2957    win->aux_hints = eina_list_append(win->aux_hints, ewah);
2958
2959    return EINA_TRUE;
2960 }
2961
2962 static Eina_Bool
2963 _ecore_wl2_window_aux_hint_list_change(Ecore_Wl2_Window *win, Ecore_Wl2_Window_Aux_Hint *ewah, const char *val)
2964 {
2965    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
2966    EINA_SAFETY_ON_NULL_RETURN_VAL(ewah, EINA_FALSE);
2967
2968    eina_stringshare_del(ewah->val);
2969    ewah->val = eina_stringshare_add(val);
2970
2971    return EINA_TRUE;
2972 }
2973
2974 static Eina_Bool
2975 _ecore_wl2_window_aux_hint_list_del(Ecore_Wl2_Window *win, Ecore_Wl2_Window_Aux_Hint *ewah)
2976 {
2977    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
2978    EINA_SAFETY_ON_NULL_RETURN_VAL(ewah, EINA_FALSE);
2979
2980    eina_stringshare_del(ewah->hint);
2981    eina_stringshare_del(ewah->val);
2982    win->aux_hints = eina_list_remove(win->aux_hints, ewah);
2983
2984    return EINA_TRUE;
2985 }
2986 // END OF TIZEN_ONLY
2987
2988 // TIZEN_ONLY(20210330): support aux hint generate
2989 static int
2990 _cb_aux_hint_sort(const void *data1, const void *data2)
2991 {
2992    const Ecore_Wl2_Window_Aux_Hint *ewah1 = (const Ecore_Wl2_Window_Aux_Hint *) data1;
2993    const Ecore_Wl2_Window_Aux_Hint *ewah2 = (const Ecore_Wl2_Window_Aux_Hint *) data2;
2994
2995    if (!ewah1 || !ewah2) return 0;
2996
2997    if (ewah1->id > ewah2->id) return 1;
2998    else if (ewah1->id == ewah2->id) return 0;
2999    else return -1;
3000 }
3001
3002 static int
3003 _ecore_wl2_window_aux_hint_id_assign(Ecore_Wl2_Window *win)
3004 {
3005    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3006    Eina_List *ewah_sorted_list = NULL, *l = NULL;
3007    int id = 0;
3008
3009    ewah_sorted_list = eina_list_clone(win->aux_hints);
3010    ewah_sorted_list = eina_list_sort(ewah_sorted_list, 0, _cb_aux_hint_sort);
3011
3012    EINA_LIST_FOREACH(ewah_sorted_list, l, ewah)
3013      {
3014         if (ewah->id < 0) continue;
3015
3016         if (ewah->id == id)
3017           {
3018              id++;
3019              continue;
3020           }
3021         else
3022           break;
3023      }
3024
3025    eina_list_free(ewah_sorted_list);
3026
3027    return id;
3028 }
3029
3030 EAPI int
3031 ecore_wl2_window_aux_hint_generate(Ecore_Wl2_Window *win, const char *hint, const char *val)
3032 {
3033    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3034    int id = -1;
3035
3036    EINA_SAFETY_ON_NULL_RETURN_VAL(win, -1);
3037
3038    ewah = _ecore_wl2_window_aux_hint_get_by_hint(win, hint);
3039    if (ewah)
3040      {
3041         ecore_wl2_window_aux_hint_change(win, ewah->id, val);
3042         return ewah->id;
3043      }
3044
3045    id = _ecore_wl2_window_aux_hint_id_assign(win);
3046    if (id < 0) return -1;
3047
3048    if (!_ecore_wl2_window_aux_hint_list_add(win, id, hint, val))
3049      return -1;
3050
3051    // add aux hint
3052    if ((win->surface) && (win->display->wl.tz_policy))
3053      tizen_policy_add_aux_hint(win->display->wl.tz_policy, win->surface, id, hint, val);
3054
3055    if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return id;
3056
3057    efl_aux_hints_add_aux_hint(win->display->wl.efl_aux_hints, win->surface, id, hint, val);
3058    ecore_wl2_display_flush(win->display);
3059
3060    return id;
3061 }
3062
3063 EAPI int
3064 ecore_wl2_window_aux_hint_id_get(Ecore_Wl2_Window *win, const char *hint)
3065 {
3066    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3067
3068    ewah = _ecore_wl2_window_aux_hint_get_by_hint(win, hint);
3069    if (ewah)
3070      return ewah->id;
3071    return -1;
3072 }
3073
3074 EAPI const char *
3075 ecore_wl2_window_aux_hint_value_get(Ecore_Wl2_Window *win, int id)
3076 {
3077    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3078
3079    ewah = _ecore_wl2_window_aux_hint_get_by_id(win, id);
3080    if (ewah)
3081      return ewah->val;
3082    return NULL;
3083 }
3084 // END OF TIZEN_ONLY
3085
3086 EAPI Eina_List *
3087 ecore_wl2_window_aux_hints_supported_get(Ecore_Wl2_Window *win)
3088 {
3089    Eina_List *res = NULL;
3090    Eina_List *ll;
3091    char *supported_hint = NULL;
3092    const char *hint = NULL;
3093
3094    if (!win) return NULL;
3095    if (!win->surface) return NULL;
3096
3097    // TIZEN_ONLY : To use tizen protocols
3098    if (win->display->wl.tz_policy)
3099      {
3100         tizen_policy_get_supported_aux_hints(win->display->wl.tz_policy, win->surface);
3101         ecore_wl2_display_sync(win->display);
3102      }
3103    //
3104
3105    EINA_LIST_FOREACH(win->supported_aux_hints, ll, supported_hint)
3106      {
3107         hint = eina_stringshare_add(supported_hint);
3108         res = eina_list_append(res, hint);
3109      }
3110    return res;
3111 }
3112
3113 EAPI void
3114 ecore_wl2_window_aux_hint_add(Ecore_Wl2_Window *win, int id, const char *hint, const char *val)
3115 {
3116    if (!win) return;
3117
3118    // TIZEN_ONLY : To use tizen protocols
3119    if ((win->surface) && (win->display->wl.tz_policy))
3120      tizen_policy_add_aux_hint(win->display->wl.tz_policy, win->surface, id, hint, val);
3121    //
3122
3123    // TIZEN_ONLY(20210330): for maintain internal aux hint list
3124    _ecore_wl2_window_aux_hint_list_add(win, id, hint, val);
3125    //
3126
3127    if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return;
3128
3129    efl_aux_hints_add_aux_hint(win->display->wl.efl_aux_hints, win->surface, id, hint, val);
3130    ecore_wl2_display_flush(win->display);
3131 }
3132
3133 EAPI void
3134 ecore_wl2_window_aux_hint_change(Ecore_Wl2_Window *win, int id, const char *val)
3135 {
3136    if (!win) return;
3137
3138    // TIZEN_ONLY : To use tizen protocols
3139    if ((win->surface) && (win->display->wl.tz_policy))
3140      tizen_policy_change_aux_hint(win->display->wl.tz_policy, win->surface, id, val);
3141    //
3142
3143    // TIZEN_ONLY(20210330): for maintain internal aux hint list
3144    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3145    ewah = _ecore_wl2_window_aux_hint_get_by_id(win, id);
3146    if (ewah)
3147      _ecore_wl2_window_aux_hint_list_change(win, ewah, val);
3148    //
3149
3150    if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return;
3151
3152    efl_aux_hints_change_aux_hint(win->display->wl.efl_aux_hints, win->surface, id, val);
3153    ecore_wl2_display_flush(win->display);
3154 }
3155
3156 EAPI void
3157 ecore_wl2_window_aux_hint_del(Ecore_Wl2_Window *win, int id)
3158 {
3159    if (!win) return;
3160
3161    // TIZEN_ONLY : To use tizen protocols
3162    if ((win->surface) && (win->display->wl.tz_policy))
3163      tizen_policy_del_aux_hint(win->display->wl.tz_policy, win->surface, id);
3164    //
3165
3166    // TIZEN_ONLY(20210330): for maintain internal aux hint list
3167    Ecore_Wl2_Window_Aux_Hint *ewah = NULL;
3168    ewah = _ecore_wl2_window_aux_hint_get_by_id(win, id);
3169    if (ewah)
3170      _ecore_wl2_window_aux_hint_list_del(win, ewah);
3171    //
3172
3173    if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return;
3174
3175    efl_aux_hints_del_aux_hint(win->display->wl.efl_aux_hints, win->surface, id);
3176    ecore_wl2_display_flush(win->display);
3177 }
3178
3179 EAPI void
3180 ecore_wl2_window_focus_skip_set(Ecore_Wl2_Window *window, Eina_Bool focus_skip)
3181 {
3182    EINA_SAFETY_ON_NULL_RETURN(window);
3183
3184    // TIZEN_ONLY(20171112)
3185    if (window->focus_skip != focus_skip)
3186      {
3187         if ((window->surface) && (window->display->wl.tz_policy))
3188           {
3189              if (focus_skip)
3190                tizen_policy_set_focus_skip(window->display->wl.tz_policy, window->surface);
3191              else
3192                tizen_policy_unset_focus_skip(window->display->wl.tz_policy, window->surface);
3193           }
3194      }
3195    //
3196
3197    window->focus_skip = focus_skip;
3198 }
3199
3200 EAPI Eina_Bool
3201 ecore_wl2_window_focus_skip_get(Ecore_Wl2_Window *window)
3202 {
3203    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
3204    return window->focus_skip;
3205 }
3206
3207 EAPI void
3208 ecore_wl2_window_role_set(Ecore_Wl2_Window *window, const char *role)
3209 {
3210    EINA_SAFETY_ON_NULL_RETURN(window);
3211    eina_stringshare_replace(&window->role, role);
3212
3213    // TIZEN_ONLY(20171112)
3214    if ((window->surface) && (window->display->wl.tz_policy))
3215      tizen_policy_set_role(window->display->wl.tz_policy, window->surface, window->role);
3216    //
3217 }
3218
3219 EAPI const char *
3220 ecore_wl2_window_role_get(Ecore_Wl2_Window *window)
3221 {
3222    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
3223
3224    return window->role ? window->role : NULL;
3225 }
3226
3227 EAPI void
3228 ecore_wl2_window_floating_mode_set(Ecore_Wl2_Window *window, Eina_Bool floating)
3229 {
3230    EINA_SAFETY_ON_NULL_RETURN(window);
3231    window->floating = floating;
3232
3233    // TIZEN_ONLY(20171112)
3234    if ((window->surface) && (window->display->wl.tz_policy))
3235      {
3236         if (floating)
3237           tizen_policy_set_floating_mode(window->display->wl.tz_policy,
3238                                          window->surface);
3239         else
3240           tizen_policy_unset_floating_mode(window->display->wl.tz_policy,
3241                                            window->surface);
3242      }
3243    //
3244 }
3245
3246 EAPI Eina_Bool
3247 ecore_wl2_window_floating_mode_get(Ecore_Wl2_Window *window)
3248 {
3249    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
3250    return window->floating;
3251 }
3252
3253 // TIZEN_ONLY(20150703) : support conformant
3254 EAPI void
3255 ecore_wl2_window_conformant_set(Ecore_Wl2_Window *win, unsigned int is_conformant)
3256 {
3257    if (!win) return;
3258    if (!win->surface) return;
3259    if (!win->display) return;
3260    if (!win->display->wl.tz_policy) return;
3261
3262    if (is_conformant)
3263      tizen_policy_set_conformant(win->display->wl.tz_policy, win->surface);
3264    else
3265      tizen_policy_unset_conformant(win->display->wl.tz_policy, win->surface);
3266 }
3267
3268 EAPI Eina_Bool
3269 ecore_wl2_window_conformant_get(Ecore_Wl2_Window *win)
3270 {
3271    if (!win) return EINA_FALSE;
3272    if (!win->surface) return EINA_FALSE;
3273    if (!win->display) return EINA_FALSE;
3274    if (!win->display->wl.tz_policy) return EINA_FALSE;
3275
3276    tizen_policy_get_conformant(win->display->wl.tz_policy, win->surface);
3277    ecore_wl2_display_sync(win->display);
3278
3279    return win->conformant;
3280 }
3281 //
3282
3283 // TIZEN_ONLY(20171108) : add functions for indicator
3284 EAPI void
3285 ecore_wl2_window_indicator_geometry_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
3286 {
3287    if(!win) return;
3288
3289    win->indicator.x = x;
3290    win->indicator.y = y;
3291    win->indicator.w = w;
3292    win->indicator.h = h;
3293 }
3294
3295 EAPI Eina_Bool
3296 ecore_wl2_window_indicator_geometry_get(Ecore_Wl2_Window *win, int *x, int *y, int *w, int *h)
3297 {
3298    if(!win) return EINA_FALSE;
3299
3300    if (x)
3301      *x = win->indicator.x;
3302    if (y)
3303      *y = win->indicator.y;
3304    if (w)
3305      *w = win->indicator.w;
3306    if (h)
3307      *h = win->indicator.h;
3308
3309    return EINA_TRUE;
3310 }
3311
3312 EAPI void
3313 ecore_wl2_window_indicator_state_set(Ecore_Wl2_Window *win, Ecore_Wl2_Indicator_State state)
3314 {
3315    int32_t ind_state;
3316
3317    if (!win) return;
3318    if (!win->surface) return;
3319    if (!win->display->wl.tz_indicator) return;
3320
3321    if (state == ECORE_WL2_INDICATOR_STATE_ON)
3322      ind_state = TIZEN_INDICATOR_STATE_ON;
3323    else if (state == ECORE_WL2_INDICATOR_STATE_OFF)
3324      ind_state = TIZEN_INDICATOR_STATE_OFF;
3325    else
3326      ind_state = TIZEN_INDICATOR_STATE_UNKNOWN;
3327
3328    tizen_indicator_set_state(win->display->wl.tz_indicator, win->surface, ind_state);
3329
3330    win->indicator.state = state;
3331 }
3332
3333 EAPI Ecore_Wl2_Indicator_State
3334 ecore_wl2_window_indicator_state_get(Ecore_Wl2_Window *win)
3335 {
3336    if (!win) return EINA_FALSE;
3337
3338    return win->indicator.state;
3339 }
3340
3341 EAPI void
3342 ecore_wl2_window_indicator_opacity_set(Ecore_Wl2_Window *win, Ecore_Wl2_Indicator_Opacity_Mode mode)
3343 {
3344    int32_t op_mode;
3345
3346    if (!win) return;
3347    if (!win->surface) return;
3348    if (!win->display->wl.tz_indicator) return;
3349
3350    switch (mode)
3351      {
3352       case ECORE_WL2_INDICATOR_OPAQUE:
3353          op_mode = TIZEN_INDICATOR_OPACITY_MODE_OPAQUE;
3354          break;
3355
3356       case ECORE_WL2_INDICATOR_TRANSLUCENT:
3357          op_mode = TIZEN_INDICATOR_OPACITY_MODE_TRANSLUCENT;
3358          break;
3359
3360       case ECORE_WL2_INDICATOR_TRANSPARENT:
3361          op_mode = TIZEN_INDICATOR_OPACITY_MODE_TRANSPARENT;
3362          break;
3363
3364       case ECORE_WL2_INDICATOR_BG_TRANSPARENT:
3365          op_mode = TIZEN_INDICATOR_OPACITY_MODE_BG_TRANSPARENT;
3366          break;
3367
3368       default:
3369          op_mode = TIZEN_INDICATOR_OPACITY_MODE_OPAQUE;
3370          break;
3371      }
3372
3373    tizen_indicator_set_opacity_mode(win->display->wl.tz_indicator, win->surface, op_mode);
3374
3375    win->indicator.mode = mode;
3376 }
3377
3378 EAPI Ecore_Wl2_Indicator_Opacity_Mode
3379 ecore_wl2_window_indicator_opacity_get(Ecore_Wl2_Window *win)
3380 {
3381    if (!win) return EINA_FALSE;
3382
3383    return win->indicator.mode;
3384 }
3385
3386 EAPI void
3387 ecore_wl2_indicator_visible_type_set(Ecore_Wl2_Window *win, Ecore_Wl2_Indicator_Visible_Type type)
3388 {
3389    int32_t vis_type;
3390
3391    if (!win) return;
3392    if (!win->surface) return;
3393    if (!win->display->wl.tz_indicator) return;
3394
3395    if (type == ECORE_WL2_INDICATOR_VISIBLE_TYPE_SHOWN)
3396      vis_type = TIZEN_INDICATOR_VISIBLE_TYPE_SHOWN;
3397    else
3398      vis_type = TIZEN_INDICATOR_VISIBLE_TYPE_HIDDEN;
3399
3400    tizen_indicator_set_visible_type(win->display->wl.tz_indicator, win->surface, vis_type);
3401
3402    win->indicator.type = type;
3403 }
3404
3405 EAPI Ecore_Wl2_Indicator_Visible_Type
3406 ecore_wl2_indicator_visible_type_get(Ecore_Wl2_Window *win)
3407 {
3408    if (!win) return EINA_FALSE;
3409
3410    return win->indicator.type;
3411 }
3412 //
3413
3414 // TIZEN_ONLY(20171108) : add functions for clipboard
3415 EAPI void
3416 ecore_wl2_window_clipboard_geometry_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
3417 {
3418    if(!win) return;
3419
3420    win->clipboard.x = x;
3421    win->clipboard.y = y;
3422    win->clipboard.w = w;
3423    win->clipboard.h = h;
3424 }
3425
3426 EAPI Eina_Bool
3427 ecore_wl2_window_clipboard_geometry_get(Ecore_Wl2_Window *win, int *x, int *y, int *w, int *h)
3428 {
3429    if (!win) return EINA_FALSE;
3430
3431    if (x)
3432      *x = win->clipboard.x;
3433    if (y)
3434      *y = win->clipboard.y;
3435    if (w)
3436      *w = win->clipboard.w;
3437    if (h)
3438      *h = win->clipboard.h;
3439
3440    return EINA_TRUE;
3441 }
3442
3443 EAPI void
3444 ecore_wl2_window_clipboard_state_set(Ecore_Wl2_Window *win, Ecore_Wl2_Clipboard_State state)
3445 {
3446    if (!win) return;
3447
3448    win->clipboard.state = state;
3449 }
3450
3451 EAPI Ecore_Wl2_Clipboard_State
3452 ecore_wl2_window_clipboard_state_get(Ecore_Wl2_Window *win)
3453 {
3454    if (!win) return EINA_FALSE;
3455
3456    return win->clipboard.state;
3457 }
3458
3459 EAPI void
3460 ecore_wl2_clipboard_show(Ecore_Wl2_Window *win)
3461 {
3462    if (!win) return;
3463    if (!win->surface) return;
3464    if (!win->display->wl.tz_clipboard) return;
3465
3466    tizen_clipboard_show(win->display->wl.tz_clipboard, win->surface);
3467 }
3468
3469 EAPI void
3470 ecore_wl2_clipboard_hide(Ecore_Wl2_Window *win)
3471 {
3472    if (!win) return;
3473    if (!win->surface) return;
3474    if (!win->display->wl.tz_clipboard) return;
3475
3476    tizen_clipboard_hide(win->display->wl.tz_clipboard, win->surface);
3477 }
3478
3479 EAPI Eina_Bool
3480 ecore_wl2_clipboard_data_only_set(Eina_Bool data_only)
3481 {
3482    Ecore_Wl2_Display *ewd = NULL;
3483    Ecore_Wl2_Input *input = NULL;
3484
3485    ewd = ecore_wl2_connected_display_get(NULL);
3486    if (!ewd) return EINA_FALSE;
3487    input = ecore_wl2_input_default_input_get(ewd);
3488    if (!input) return EINA_FALSE;
3489
3490    if (!ewd->wl.tz_clipboard) return EINA_FALSE;
3491
3492    tizen_clipboard_set_data_only(ewd->wl.tz_clipboard, data_only);
3493    ecore_wl2_display_sync(ewd);
3494
3495    return input->is_data_only;
3496 }
3497 //
3498
3499 // TIZEN_ONLY(20171108) : add functions for keyboard
3500 EAPI void
3501 ecore_wl2_window_keyboard_geometry_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
3502 {
3503    if(!win) return;
3504
3505    win->keyboard.x= x;
3506    win->keyboard.y = y;
3507    win->keyboard.w = w;
3508    win->keyboard.h = h;
3509 }
3510
3511 EAPI Eina_Bool
3512 ecore_wl2_window_keyboard_geometry_get(Ecore_Wl2_Window *win, int *x, int *y, int *w, int *h)
3513 {
3514    if (!win) return EINA_FALSE;
3515
3516    if (x)
3517      *x = win->keyboard.x;
3518    if (y)
3519      *y = win->keyboard.y;
3520    if (w)
3521      *w = win->keyboard.w;
3522    if (h)
3523      *h = win->keyboard.h;
3524
3525    return EINA_TRUE;
3526 }
3527
3528 EAPI void
3529 ecore_wl2_window_keyboard_state_set(Ecore_Wl2_Window *win, Ecore_Wl2_Virtual_Keyboard_State state)
3530 {
3531    if (!win) return;
3532
3533    win->keyboard.state = state;
3534 }
3535
3536 EAPI Ecore_Wl2_Virtual_Keyboard_State
3537 ecore_wl2_window_keyboard_state_get(Ecore_Wl2_Window *win)
3538 {
3539    if (!win) return EINA_FALSE;
3540
3541    return win->keyboard.state;
3542 }
3543 //
3544
3545 EAPI void
3546 ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int aspect)
3547 {
3548    EINA_SAFETY_ON_NULL_RETURN(window);
3549    EINA_SAFETY_ON_TRUE_RETURN(w < 1);
3550    EINA_SAFETY_ON_TRUE_RETURN(h < 1);
3551
3552    if ((window->aspect.aspect == aspect) && (window->aspect.w == w) &&
3553        (window->aspect.h == h))
3554      return;
3555
3556    window->aspect.w = w;
3557    window->aspect.h = h;
3558    window->aspect.aspect = aspect;
3559    window->aspect.set = 1;
3560    if (!window->display->wl.efl_hints) return;
3561    if (window->xdg_surface)
3562      efl_hints_set_aspect(window->display->wl.efl_hints,
3563                           window->xdg_surface, w, h, aspect);
3564    ecore_wl2_display_flush(window->display);
3565 }
3566
3567 EAPI void
3568 ecore_wl2_window_aspect_get(Ecore_Wl2_Window *window, int *w, int *h, unsigned int *aspect)
3569 {
3570    EINA_SAFETY_ON_NULL_RETURN(window);
3571
3572    if (w) *w = window->aspect.w;
3573    if (h) *h = window->aspect.h;
3574    if (aspect) *aspect = window->aspect.aspect;
3575 }
3576
3577 EAPI void
3578 ecore_wl2_window_weight_set(Ecore_Wl2_Window *window, double w, double h)
3579 {
3580    int ww, hh;
3581    EINA_SAFETY_ON_NULL_RETURN(window);
3582
3583    ww = lround(w * 100);
3584    hh = lround(h * 100);
3585
3586    if ((window->weight.w == ww) && (window->weight.h == hh))
3587      return;
3588
3589    window->weight.w = ww;
3590    window->weight.h = hh;
3591    window->weight.set = 1;
3592    if (!window->display->wl.efl_hints) return;
3593    if (window->xdg_surface)
3594      efl_hints_set_weight(window->display->wl.efl_hints,
3595                           window->xdg_surface, ww, hh);
3596    ecore_wl2_display_flush(window->display);
3597 }
3598
3599 static void
3600 _frame_cb(void *data, struct wl_callback *callback, uint32_t timestamp)
3601 {
3602    Ecore_Wl2_Frame_Cb_Handle *cb;
3603    Ecore_Wl2_Window *window;
3604    Eina_Inlist *l;
3605
3606    window = data;
3607    window->commit_pending = EINA_FALSE;
3608    wl_callback_destroy(callback);
3609    window->callback = NULL;
3610    EINA_INLIST_FOREACH_SAFE(window->frame_callbacks, l, cb)
3611      cb->cb(window, timestamp, cb->data);
3612 }
3613
3614 static struct wl_callback_listener _frame_listener =
3615 {
3616    _frame_cb
3617 };
3618
3619 static void
3620 _maximized_set(Ecore_Wl2_Window *window)
3621 {
3622    EINA_SAFETY_ON_FALSE_RETURN(window->zxdg_toplevel || window->xdg_toplevel);
3623
3624    if (window->set_config.maximized)
3625      {
3626         if (window->xdg_toplevel)
3627           xdg_toplevel_set_maximized(window->xdg_toplevel);
3628         if (window->zxdg_toplevel)
3629           zxdg_toplevel_v6_set_maximized(window->zxdg_toplevel);
3630      }
3631    else
3632      {
3633         if (window->xdg_toplevel)
3634           xdg_toplevel_unset_maximized(window->xdg_toplevel);
3635         if (window->zxdg_toplevel)
3636           zxdg_toplevel_v6_unset_maximized(window->zxdg_toplevel);
3637      }
3638 }
3639
3640 static void
3641 _fullscreen_set(Ecore_Wl2_Window *window)
3642 {
3643    EINA_SAFETY_ON_FALSE_RETURN(window->zxdg_toplevel || window->xdg_toplevel);
3644
3645    if (window->set_config.fullscreen)
3646      {
3647         window->saved = window->set_config.geometry;
3648         if (window->xdg_toplevel)
3649           xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
3650         if (window->zxdg_toplevel)
3651           zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL);
3652      }
3653    else
3654      {
3655         if (window->xdg_toplevel)
3656           xdg_toplevel_unset_fullscreen(window->xdg_toplevel);
3657         if (window->zxdg_toplevel)
3658           zxdg_toplevel_v6_unset_fullscreen(window->zxdg_toplevel);
3659      }
3660 }
3661
3662 static struct wl_region *
3663 _region_create(struct wl_compositor *comp, int x, int y, int w, int h)
3664 {
3665    struct wl_region *out;
3666
3667    out = wl_compositor_create_region(comp);
3668    if (!out)
3669      {
3670         ERR("Failed to create region");
3671         return NULL;
3672      }
3673
3674    wl_region_add(out, x, y, w, h);
3675
3676    return out;
3677 }
3678
3679 static void
3680 _regions_set(Ecore_Wl2_Window *window)
3681 {
3682    struct wl_region *region = NULL;
3683
3684    if (window->pending.opaque)
3685      {
3686         if (window->opaque_set)
3687           {
3688              region = _region_create(window->display->wl.compositor,
3689                                      window->opaque.x, window->opaque.y,
3690                                      window->opaque.w, window->opaque.h);
3691              if (!region) return;
3692           }
3693         // TIZEN_ONLY(20201123)
3694         /*
3695         wl_surface_set_opaque_region(window->surface, region);
3696         */
3697         _opaque_region_set(window, region);
3698         //
3699      }
3700
3701    if (!window->pending.input) goto out;
3702    if (window->type == ECORE_WL2_WINDOW_TYPE_DND) goto out;
3703
3704    if (!window->input_set)
3705      {
3706         wl_surface_set_input_region(window->surface, NULL);
3707         goto out;
3708      }
3709
3710    if (region && (window->opaque.x == window->input_rect.x) &&
3711        (window->opaque.y == window->input_rect.y) &&
3712        (window->opaque.w == window->input_rect.w) &&
3713        (window->opaque.h == window->input_rect.h))
3714      {
3715         wl_surface_set_input_region(window->surface, region);
3716         goto out;
3717      }
3718    if (region) wl_region_destroy(region);
3719
3720    region = _region_create(window->display->wl.compositor,
3721                            window->input_rect.x, window->input_rect.y,
3722                            window->input_rect.w, window->input_rect.h);
3723    if (!region) return;
3724    wl_surface_set_input_region(window->surface, region);
3725
3726 out:
3727    if (region) wl_region_destroy(region);
3728 }
3729
3730 // TIZEN_ONLY(20201123)
3731 static void
3732 _opaque_region_set(Ecore_Wl2_Window *window, struct wl_region *region)
3733 {
3734    if (!window) return;
3735    if (!window->surface) return;
3736
3737    wl_surface_set_opaque_region(window->surface, region);
3738
3739    window->pending.opaque = EINA_FALSE;
3740 }
3741 //
3742
3743 // TIZEN_ONLY(20190910)
3744 static void
3745 _opaque_set(Ecore_Wl2_Window *window)
3746 {
3747    struct wl_region *region;
3748
3749    if (!window->opaque_set)
3750      {
3751         if (window->surface)
3752           _opaque_region_set(window, NULL);
3753         return;
3754      }
3755
3756    region = wl_compositor_create_region(window->display->wl.compositor);
3757    if (!region)
3758      {
3759         ERR("Failed to create opaque region");
3760         return;
3761      }
3762
3763    wl_region_add(region, window->opaque.x, window->opaque.y,
3764                  window->opaque.w, window->opaque.h);
3765    _opaque_region_set(window, region);
3766    wl_region_destroy(region);
3767 }
3768 //
3769
3770 EAPI void
3771 ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush)
3772 {
3773    EINA_SAFETY_ON_NULL_RETURN(window);
3774    EINA_SAFETY_ON_NULL_RETURN(window->surface);
3775
3776    if (window->commit_pending)
3777      {
3778         if (window->callback)
3779           wl_callback_destroy(window->callback);
3780         window->callback = NULL;
3781         WRN("Commit before previous commit processed");
3782      }
3783    if (!window->pending.configure)
3784      {
3785         if (window->has_buffer)
3786           window->commit_pending = EINA_TRUE;
3787         if (!window->callback)
3788           {
3789              window->callback = wl_surface_frame(window->surface);
3790              wl_callback_add_listener(window->callback, &_frame_listener, window);
3791           }
3792         /* Dispatch any state we've been saving along the way */
3793         if (window->pending.geom)
3794           {
3795              int gx, gy, gw, gh;
3796
3797              ecore_wl2_window_geometry_get(window, &gx, &gy, &gw, &gh);
3798              if (window->xdg_toplevel)
3799                xdg_surface_set_window_geometry(window->xdg_surface,
3800                                                gx, gy, gw, gh);
3801              if (window->zxdg_surface)
3802                zxdg_surface_v6_set_window_geometry(window->zxdg_surface,
3803                                                    gx, gy, gw, gh);
3804
3805              // TIZEN_ONLY(20220421) : update window's saved size only un-fullscreen and unmaximize state
3806              if (!window->set_config.fullscreen && !window->set_config.maximized)
3807                {
3808                   window->saved.w = window->set_config.geometry.w;
3809                   window->saved.h = window->set_config.geometry.h;
3810                }
3811              //
3812           }
3813         if (window->pending.opaque || window->pending.input)
3814           _regions_set(window);
3815
3816         if (window->pending.maximized)
3817           _maximized_set(window);
3818
3819         if (window->pending.fullscreen)
3820           _fullscreen_set(window);
3821
3822         window->pending.geom = EINA_FALSE;
3823         window->pending.opaque = EINA_FALSE;
3824         window->pending.input = EINA_FALSE;
3825         window->pending.maximized = EINA_FALSE;
3826         window->pending.fullscreen = EINA_FALSE;
3827      }
3828
3829    if (window->req_config.serial != window->set_config.serial)
3830      {
3831         if (window->xdg_configure_ack && window->xdg_surface)
3832            window->xdg_configure_ack(window->xdg_surface,
3833                                       window->req_config.serial);
3834         if (window->zxdg_configure_ack && window->zxdg_surface)
3835            window->zxdg_configure_ack(window->zxdg_surface,
3836                                       window->req_config.serial);
3837         window->set_config.serial = window->req_config.serial;
3838      }
3839    if (flush)
3840      {
3841         wl_surface_commit(window->surface);
3842         ecore_wl2_display_flush(window->display);
3843      }
3844
3845    if (!window->updating) return;
3846
3847    window->updating = EINA_FALSE;
3848    if (window->def_config.serial != window->set_config.serial)
3849       _ecore_wl2_window_configure_send(window);
3850 }
3851
3852 EAPI void
3853 ecore_wl2_window_false_commit(Ecore_Wl2_Window *window)
3854 {
3855    EINA_SAFETY_ON_NULL_RETURN(window);
3856    EINA_SAFETY_ON_NULL_RETURN(window->surface);
3857    EINA_SAFETY_ON_TRUE_RETURN(window->pending.configure);
3858    EINA_SAFETY_ON_TRUE_RETURN(window->commit_pending);
3859
3860    if (!window->callback)
3861      {
3862         window->callback = wl_surface_frame(window->surface);
3863         wl_callback_add_listener(window->callback, &_frame_listener, window);
3864      }
3865    wl_surface_commit(window->surface);
3866    ecore_wl2_display_flush(window->display);
3867    if (window->has_buffer)
3868      window->commit_pending = EINA_TRUE;
3869 }
3870
3871 EAPI Eina_Bool
3872 ecore_wl2_window_pending_get(Ecore_Wl2_Window *window)
3873 {
3874    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
3875
3876    return window->commit_pending;
3877 }
3878
3879 EAPI Ecore_Wl2_Frame_Cb_Handle *
3880 ecore_wl2_window_frame_callback_add(Ecore_Wl2_Window *window, Ecore_Wl2_Frame_Cb cb, void *data)
3881 {
3882    Ecore_Wl2_Frame_Cb_Handle *callback;
3883
3884    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
3885    EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
3886
3887    callback = malloc(sizeof(*callback));
3888    EINA_SAFETY_ON_NULL_RETURN_VAL(callback, NULL);
3889    callback->cb = cb;
3890    callback->data = data;
3891    callback->win = window;
3892    window->frame_callbacks =
3893      eina_inlist_append(window->frame_callbacks, EINA_INLIST_GET(callback));
3894    return callback;
3895 }
3896
3897 EAPI void
3898 ecore_wl2_window_frame_callback_del(Ecore_Wl2_Frame_Cb_Handle *handle)
3899 {
3900    EINA_SAFETY_ON_NULL_RETURN(handle);
3901
3902    handle->win->frame_callbacks =
3903      eina_inlist_remove(handle->win->frame_callbacks, EINA_INLIST_GET(handle));
3904    free(handle);
3905 }
3906
3907 EAPI void
3908 ecore_wl2_window_buffer_attach(Ecore_Wl2_Window *win, void *buffer, int x, int y, Eina_Bool implicit)
3909 {
3910    EINA_SAFETY_ON_NULL_RETURN(win);
3911    EINA_SAFETY_ON_NULL_RETURN(win->surface);
3912
3913    /* FIXME: Haven't given any thought to x and y since we always use 0... */
3914    if (!implicit) wl_surface_attach(win->surface, buffer, x, y);
3915    win->buffer = buffer;
3916    if (!implicit && !buffer)
3917      win->has_buffer = EINA_FALSE;
3918    else
3919      win->has_buffer = EINA_TRUE;
3920 }
3921
3922 EAPI Eina_Bool
3923 ecore_wl2_window_resizing_get(Ecore_Wl2_Window *window)
3924 {
3925    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
3926
3927    return window->req_config.resizing;
3928 }
3929
3930 EAPI void
3931 ecore_wl2_window_update_begin(Ecore_Wl2_Window *window)
3932 {
3933    EINA_SAFETY_ON_NULL_RETURN(window);
3934    EINA_SAFETY_ON_TRUE_RETURN(window->updating);
3935
3936    window->updating = EINA_TRUE;
3937 }
3938
3939 EAPI void
3940 ecore_wl2_window_damage(Ecore_Wl2_Window *window, Eina_Rectangle *rects, unsigned int count)
3941 {
3942    void (*damage)(struct wl_surface *, int32_t, int32_t, int32_t, int32_t);
3943    unsigned int k;
3944    int compositor_version;
3945
3946    EINA_SAFETY_ON_NULL_RETURN(window);
3947
3948    compositor_version = window->display->wl.compositor_version;
3949
3950    if (compositor_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
3951      damage = wl_surface_damage_buffer;
3952    else
3953      damage = wl_surface_damage;
3954
3955    if ((rects) && (count > 0))
3956      for (k = 0; k < count; k++)
3957        damage(window->surface, rects[k].x, rects[k].y, rects[k].w, rects[k].h);
3958    else
3959      damage(window->surface, 0, 0, INT_MAX, INT_MAX);
3960 }
3961
3962 EAPI void
3963 ecore_wl2_window_surface_flush(Ecore_Wl2_Window *window, Eina_Bool purge)
3964 {
3965    EINA_SAFETY_ON_NULL_RETURN(window);
3966
3967    if (!window->wl2_surface) return;
3968    ecore_wl2_surface_flush(window->wl2_surface, purge);
3969 }
3970
3971 EAPI Ecore_Wl2_Window_Type
3972 ecore_wl2_window_type_get(Ecore_Wl2_Window *window)
3973 {
3974    EINA_SAFETY_ON_NULL_RETURN_VAL(window, ECORE_WL2_WINDOW_TYPE_NONE);
3975    return window->type;
3976 }
3977
3978 EAPI Ecore_Wl2_Window *
3979 ecore_wl2_window_surface_find(struct wl_surface *surface)
3980 {
3981    Ecore_Wl2_Display *ewd;
3982    Ecore_Wl2_Window *win;
3983
3984    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL);
3985
3986    ewd = ecore_wl2_connected_display_get(NULL);
3987    EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL);
3988
3989    win = ecore_wl2_display_window_find_by_surface(ewd, surface);
3990    return win;
3991 }
3992
3993 // TIZEN_ONLY(20171107): add ecore_wl2_window_input_get() EAPI
3994 EAPI Ecore_Wl2_Input *
3995 ecore_wl2_window_input_get(Ecore_Wl2_Window *win)
3996 {
3997    Ecore_Wl2_Input *input;
3998
3999    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
4000    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, NULL);
4001
4002    EINA_INLIST_FOREACH(win->display->inputs, input)
4003      {
4004         if (input->focus.pointer) return input;
4005         //This code will be changed after adding ecore_wl2_window_keyboard_get API
4006         if (input->focus.keyboard) return input;
4007      }
4008
4009    return NULL;
4010 }
4011 //
4012
4013 // TIZEN_ONLY(20200326): add ecore_wl2_window_pointer_get() EAPI
4014 EAPI Ecore_Wl2_Input *
4015 ecore_wl2_window_pointer_get(Ecore_Wl2_Window *win)
4016 {
4017    Ecore_Wl2_Input *input;
4018
4019    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
4020    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, NULL);
4021
4022    EINA_INLIST_FOREACH(win->display->inputs, input)
4023      if (input->focus.pointer == win) return input;
4024
4025    return NULL;
4026 }
4027 //
4028
4029 // TIZEN_ONLY(20200326): add ecore_wl2_window_keyboard_get() EAPI
4030 EAPI Ecore_Wl2_Input *
4031 ecore_wl2_window_keyboard_get(Ecore_Wl2_Window *win)
4032 {
4033    Ecore_Wl2_Input *input;
4034
4035    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
4036    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, NULL);
4037
4038    EINA_INLIST_FOREACH(win->display->inputs, input)
4039      if (input->focus.keyboard == win) return input;
4040
4041    return NULL;
4042 }
4043 //
4044
4045 // TIZEN_ONLY(20171114): support a pointer warp
4046 EAPI Eina_Bool
4047 ecore_wl2_window_pointer_warp(Ecore_Wl2_Window *win, int x, int y)
4048 {
4049    Ecore_Wl2_Display *ewd;
4050
4051    /* FIXME: visible is not merged yet. */
4052    //if (!win || !win->surface || !win->visible) return EINA_FALSE;
4053    if (!win || !win->surface) return EINA_FALSE;
4054
4055    ewd = win->display;
4056    if (!ewd || !ewd->wl.tz_input_device_manager) return EINA_FALSE;
4057
4058    tizen_input_device_manager_pointer_warp(ewd->wl.tz_input_device_manager,
4059                                            win->surface, wl_fixed_from_int(x), wl_fixed_from_int(y));
4060
4061    return EINA_TRUE;
4062 }
4063 //
4064
4065 // TIZEN_ONLY(20200601): support sync between ui and video
4066 /* The video surface created in ecore_wl2 is used for informing the video area.
4067    And there is another video surface created on the player side. The player
4068    video surface is filled with video data, and the garbage data of ecore_wl2
4069    video surface can interfere with video data. So fill it with zero here. */
4070 Eina_Bool
4071 buffer_fill_zero(tbm_surface_h surface)
4072 {
4073    tbm_surface_info_s info;
4074    int *img, ret;
4075    unsigned int height, stride;
4076
4077    ret = tbm_surface_map(surface, TBM_OPTION_WRITE, &info);
4078    if (ret != TBM_SURFACE_ERROR_NONE)
4079      return EINA_FALSE;
4080
4081    img = (int *)info.planes[0].ptr;
4082    height = tbm_surface_get_height(surface);
4083    stride = info.planes[0].stride;
4084
4085    memset(img, 0x0, sizeof(int) * stride * height);
4086
4087    tbm_surface_unmap(surface);
4088
4089    return EINA_TRUE;
4090 }
4091
4092
4093 EAPI Eina_Bool
4094 ecore_wl2_window_video_surface_create(Ecore_Wl2_Window *win)
4095 {
4096    Ecore_Wl2_Display *display;
4097
4098    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4099    if (win->video.surface) return EINA_TRUE;
4100
4101    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
4102    display = win->display;
4103
4104    EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.compositor, EINA_FALSE);
4105    EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.subcompositor, EINA_FALSE);
4106    EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.tz_policy, EINA_FALSE);
4107
4108    win->video.surface = wl_compositor_create_surface(display->wl.compositor);
4109
4110    if (!win->video.surface)
4111      {
4112         ERR("Failed to create video surface");
4113         return EINA_FALSE;
4114      }
4115
4116    win->video.subsurface =
4117      wl_subcompositor_get_subsurface(display->wl.subcompositor,
4118                                      win->video.surface, win->surface);
4119
4120    if (!win->video.subsurface)
4121      {
4122         ERR("Failed to create video subsurface");
4123         goto get_subsurf_err;
4124      }
4125
4126    tizen_policy_place_subsurface_below_parent(display->wl.tz_policy, win->video.subsurface);
4127
4128    if (!win->tbm_client)
4129      {
4130         win->tbm_client = wayland_tbm_client_init(display->wl.display);
4131         if (!win->tbm_client)
4132           {
4133              ERR("Failed to init wayland tbm client");
4134              goto client_init_err;
4135           }
4136      }
4137
4138    win->video.tbm_surface = tbm_surface_create(1, 1, TBM_FORMAT_ARGB8888);
4139    if (!win->video.tbm_surface)
4140      {
4141         ERR("Failed to create tbm surface");
4142         goto client_init_err;
4143      }
4144
4145    win->video.wl_buffer = wayland_tbm_client_create_buffer(win->tbm_client,
4146                                                           win->video.tbm_surface);
4147    if (!win->video.wl_buffer)
4148      {
4149         ERR("Failed to create buffer of tbm client");
4150         goto create_buf_err;
4151      }
4152
4153    if (!buffer_fill_zero(win->video.tbm_surface))
4154      {
4155         ERR("Failed to fill buffer to zero");
4156         goto buf_fill_err;
4157      }
4158
4159    /* A sub-surface is initially in the synchronized mode. */
4160    win->video.sync = EINA_TRUE;
4161
4162    /* need to attach surface */
4163    wl_surface_attach(win->video.surface, win->video.wl_buffer, 0, 0);
4164    wl_surface_commit(win->video.surface);
4165
4166    return EINA_TRUE;
4167
4168 buf_fill_err:
4169    wayland_tbm_client_destroy_buffer(win->tbm_client, win->video.wl_buffer);
4170    win->video.wl_buffer = NULL;
4171
4172 create_buf_err:
4173    tbm_surface_destroy(win->video.tbm_surface);
4174    win->video.tbm_surface = NULL;
4175
4176 client_init_err:
4177    wl_subsurface_destroy(win->video.subsurface);
4178    win->video.subsurface = NULL;
4179
4180 get_subsurf_err:
4181    wl_surface_destroy(win->video.surface);
4182    win->video.surface = NULL;
4183
4184    return EINA_FALSE;
4185 }
4186
4187 EAPI void *
4188 ecore_wl2_window_video_surface_get(Ecore_Wl2_Window *win)
4189 {
4190    EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
4191    return win->video.surface;
4192 }
4193
4194 EAPI Eina_Bool
4195 ecore_wl2_window_video_surface_destroy(Ecore_Wl2_Window *win)
4196 {
4197    Ecore_Wl2_Display *display;
4198
4199    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4200    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
4201
4202    display = win->display;
4203
4204    if (display->wl.tz_video)
4205      {
4206         tizen_video_destroy(display->wl.tz_video);
4207         display->wl.tz_video = NULL;
4208      }
4209
4210    _ecore_wl2_window_video_surface_destroy(win);
4211
4212    return EINA_TRUE;
4213 }
4214
4215 EAPI Eina_Bool
4216 ecore_wl2_window_video_surface_sync_set(Ecore_Wl2_Window *win, Eina_Bool sync)
4217 {
4218    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4219    EINA_SAFETY_ON_NULL_RETURN_VAL(win->video.subsurface, EINA_FALSE);
4220
4221    sync = !!sync;
4222    if (win->video.sync == sync) return EINA_TRUE;
4223
4224    win->video.sync = sync;
4225
4226    if (sync)
4227      wl_subsurface_set_sync(win->video.subsurface);
4228    else
4229      wl_subsurface_set_desync(win->video.subsurface);
4230
4231    return EINA_TRUE;
4232 }
4233
4234 EAPI Eina_Bool
4235 ecore_wl2_window_video_surface_destination_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
4236 {
4237    Ecore_Wl2_Display *display;
4238    struct wl_registry *registry;
4239    Eina_Iterator *globals;
4240    Ecore_Wl2_Global *global;
4241
4242    EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
4243    EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
4244    EINA_SAFETY_ON_NULL_RETURN_VAL(win->video.surface, EINA_FALSE);
4245
4246    display = win->display;
4247
4248    if (!win->video.viewport)
4249      {
4250         if (!display->wl.tz_video)
4251           {
4252              registry = ecore_wl2_display_registry_get(display);
4253              if (!registry) return EINA_FALSE;
4254
4255              globals = ecore_wl2_display_globals_get(display);
4256              if (!globals) return EINA_FALSE;
4257
4258              EINA_ITERATOR_FOREACH(globals, global)
4259                {
4260                   if (strcmp(global->interface, "tizen_video") == 0)
4261                     {
4262                        display->wl.tz_video = wl_registry_bind(registry, global->id, &tizen_video_interface, 1);
4263                        break;
4264                     }
4265                }
4266           }
4267
4268         if (!display->wl.tz_video)
4269           {
4270              ERR("Failed to bind tizen video interface");
4271              return EINA_FALSE;
4272           }
4273
4274         win->video.viewport = tizen_video_get_viewport(display->wl.tz_video, win->video.surface);
4275      }
4276
4277    if (!win->video.viewport)
4278      {
4279         ERR("Failed to get video viewport");
4280         return EINA_FALSE;
4281      }
4282
4283    tizen_viewport_set_destination(win->video.viewport, x, y, w, h);
4284    wl_surface_commit(win->video.surface);
4285
4286    return EINA_TRUE;
4287 }
4288
4289 EAPI int
4290 ecore_wl2_window_render_sync_fd_create(Ecore_Wl2_Window *win, Ecore_Wl2_Window_Render_Sync_Type sync_type)
4291 {
4292    int sync_fd = -1;
4293
4294    EINA_SAFETY_ON_NULL_RETURN_VAL(win, sync_fd);
4295    EINA_SAFETY_ON_NULL_RETURN_VAL(win->egl_win, sync_fd);
4296
4297    switch (sync_type)
4298      {
4299       case ECORE_WL2_WINDOW_RENDER_SYNC_COMMIT:
4300         sync_fd = wl_egl_window_tizen_create_commit_sync_fd(win->egl_win->native_win);
4301         break;
4302       case ECORE_WL2_WINDOW_RENDER_SYNC_PRESENT:
4303         sync_fd = wl_egl_window_tizen_create_presentation_sync_fd(win->egl_win->native_win);
4304         break;
4305       default:
4306         break;
4307      }
4308
4309    return sync_fd;
4310 }
4311 //
4312
4313 //TIZEN_ONLY: ecore_wl2: add ecore_wl_window_video_has
4314 EAPI void
4315 ecore_wl2_window_video_has(Ecore_Wl2_Window *window, Eina_Bool has)
4316 {
4317    Ecore_Wl2_Display *display;
4318    uint32_t ver;
4319
4320    EINA_SAFETY_ON_NULL_RETURN(window);
4321
4322    display = window->display;
4323    if (!display->wl.tz_policy) return;
4324
4325    ver = wl_proxy_get_version((struct wl_proxy *)display->wl.tz_policy);
4326
4327    if (ver >= 7)
4328      tizen_policy_has_video(display->wl.tz_policy, window->surface, has);
4329 }
4330 //
4331
4332 //TIZEN_ONLY(20171115): support output transform
4333 void
4334 _ecore_wl2_window_ignore_output_transform_set(Ecore_Wl2_Window *window, Eina_Bool ignore)
4335 {
4336    if (!window) return;
4337
4338    window->ignore_output_transform = ignore;
4339 }
4340
4341 EAPI Eina_Bool
4342 ecore_wl2_window_ignore_output_transform_get(Ecore_Wl2_Window *window)
4343 {
4344    return window->ignore_output_transform;
4345 }
4346 //
4347
4348 // TIZEN_ONLY(20171207): add functions to set client's custom cursors
4349 EAPI void
4350 ecore_wl2_window_pointer_set(Ecore_Wl2_Window *win, struct wl_surface *surface, int hot_x, int hot_y)
4351 {
4352    Ecore_Wl2_Input *input;
4353
4354    if (!win) return;
4355
4356    win->pointer.surface = surface;
4357    win->pointer.hot_x = hot_x;
4358    win->pointer.hot_y = hot_y;
4359    win->pointer.set = EINA_TRUE;
4360
4361    if ((input = win->pointer.device))
4362      ecore_wl2_input_pointer_set(input, surface, hot_x, hot_y);
4363 }
4364
4365 EAPI void
4366 ecore_wl2_window_cursor_from_name_set(Ecore_Wl2_Window *win, const char *cursor_name)
4367 {
4368    Ecore_Wl2_Input *input;
4369
4370    if (!win) return;
4371
4372    win->pointer.set = EINA_FALSE;
4373
4374    if (!(input = win->pointer.device))
4375      return;
4376
4377    eina_stringshare_replace(&win->pointer.cursor_name, cursor_name);
4378
4379    if ((input->cursor.name) && (strcmp(input->cursor.name, win->pointer.cursor_name)))
4380      ecore_wl2_input_cursor_from_name_set(input, cursor_name);
4381 }
4382
4383 EAPI void
4384 ecore_wl2_window_cursor_default_restore(Ecore_Wl2_Window *win)
4385 {
4386    Ecore_Wl2_Input *input;
4387
4388    if (!win) return;
4389
4390    win->pointer.set = EINA_FALSE;
4391
4392    if ((input = win->pointer.device))
4393      ecore_wl2_input_cursor_default_restore(input);
4394 }
4395 //
4396
4397 //TIZEN_ONLY(20180810): support client demand move resize
4398 EAPI void
4399 ecore_wl2_window_sync_geometry_set(Ecore_Wl2_Window *window, uint32_t serial, int x, int y, int w, int h)
4400 {
4401    if (!window) return;
4402
4403    if ((window->set_config.geometry.x != x) ||
4404        (window->set_config.geometry.y != y) ||
4405        (window->set_config.geometry.w != w) ||
4406        (window->set_config.geometry.h != h))
4407      window->pending.geom = EINA_TRUE;
4408
4409    window->set_config.geometry.x = x;
4410    window->set_config.geometry.y = y;
4411    window->set_config.geometry.w = w;
4412    window->set_config.geometry.h = h;
4413
4414    if (window->display->wl.tz_moveresize)
4415      tizen_move_resize_set_geometry(window->display->wl.tz_moveresize, window->surface, serial, x, y, w, h);
4416
4417    // TIZEN_ONLY(20190807): Support for wl_egl interface
4418    if (window->egl_win)
4419      {
4420         window->egl_win->sync_geom.serial = serial;
4421         window->egl_win->sync_geom.w = w;
4422         window->egl_win->sync_geom.h = h;
4423
4424         wl_egl_window_tizen_set_window_serial(window->egl_win->native_win, serial);
4425      }
4426    //
4427 }
4428 //
4429
4430 // TIZEN_ONLY(20190807): Support for wl_egl interface
4431 EAPI Ecore_Wl2_Egl_Window *
4432 ecore_wl2_egl_window_create(Ecore_Wl2_Window *window, int w, int h)
4433 {
4434    Ecore_Wl2_Egl_Window *egl_win = NULL;
4435    struct wl_egl_window *native_win = NULL;
4436    int cap = WL_EGL_WINDOW_TIZEN_CAPABILITY_NONE;
4437
4438    EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
4439    EINA_SAFETY_ON_NULL_RETURN_VAL(window->surface, NULL);
4440    EINA_SAFETY_ON_FALSE_RETURN_VAL((window->egl_win == NULL), NULL);
4441    EINA_SAFETY_ON_FALSE_RETURN_VAL((w >= 0), NULL);
4442    EINA_SAFETY_ON_FALSE_RETURN_VAL((h >= 0), NULL);
4443
4444    native_win = wl_egl_window_create(window->surface, w, h);
4445    EINA_SAFETY_ON_NULL_RETURN_VAL(native_win, NULL);
4446
4447    egl_win = calloc(1, sizeof(Ecore_Wl2_Egl_Window));
4448    EINA_SAFETY_ON_NULL_GOTO(egl_win, failed);
4449
4450    egl_win->win = window;
4451    egl_win->native_win = native_win;
4452    egl_win->w = w;
4453    egl_win->h = h;
4454
4455    window->egl_win = egl_win;
4456
4457    cap = wl_egl_window_tizen_get_capabilities(native_win);
4458    if (cap == WL_EGL_WINDOW_TIZEN_CAPABILITY_ROTATION_SUPPORTED)
4459      egl_win->support_pre_rotation = EINA_TRUE;
4460
4461    return egl_win;
4462
4463 failed:
4464    if (native_win) wl_egl_window_destroy(native_win);
4465    return NULL;
4466 }
4467
4468 EAPI void
4469 ecore_wl2_egl_window_destroy(Ecore_Wl2_Egl_Window *egl_win)
4470 {
4471    EINA_SAFETY_ON_NULL_RETURN(egl_win);
4472
4473    if (egl_win->native_win)
4474      wl_egl_window_destroy(egl_win->native_win);
4475
4476    if (egl_win->win)
4477      egl_win->win->egl_win = NULL;
4478
4479    memset(egl_win, 0, sizeof(Ecore_Wl2_Egl_Window));
4480    free(egl_win);
4481 }
4482
4483 EAPI void *
4484 ecore_wl2_egl_window_native_get(Ecore_Wl2_Egl_Window *egl_win)
4485 {
4486    EINA_SAFETY_ON_NULL_RETURN_VAL(egl_win, NULL);
4487    return (void *)egl_win->native_win;
4488 }
4489
4490 EAPI void
4491 ecore_wl2_egl_window_resize_with_rotation(Ecore_Wl2_Egl_Window *egl_win, int dx, int dy, int w, int h, int rotation)
4492 {
4493    int rot = rotation % 360;
4494
4495    EINA_SAFETY_ON_NULL_RETURN(egl_win);
4496
4497    egl_win->rot.buffer = rot;
4498    egl_win->rot.win = rot;
4499    egl_win->dx = dx;
4500    egl_win->dy = dy;
4501    egl_win->w = w;
4502    egl_win->h = h;
4503
4504    if (egl_win->support_pre_rotation)
4505      wl_egl_window_tizen_set_rotation(egl_win->native_win, egl_win->rot.win);
4506
4507    //TIZEN_ONLY(20171115): support output transform
4508    /* buffer_transform: screen rotation + window rotation
4509     * window_transform: window rotation only
4510     * We have to let the display server know the window rotation value
4511     * because the display server needs to calcuate the screen rotation value
4512     * from buffer_transform value.
4513     */
4514    wl_egl_window_tizen_set_buffer_transform(egl_win->native_win, egl_win->rot.buffer / 90);
4515    wl_egl_window_tizen_set_window_transform(egl_win->native_win, egl_win->rot.win / 90);
4516    //
4517
4518    if ((egl_win->rot.buffer == 90) || (egl_win->rot.buffer == 270))
4519      wl_egl_window_resize(egl_win->native_win, h, w, dx, dy);
4520    else
4521      wl_egl_window_resize(egl_win->native_win, w, h, dx, dy);
4522 }
4523 //
4524
4525 //TIZEN_ONLY(20220322): add resource id to window attribute
4526 EAPI unsigned int
4527 ecore_wl2_window_resource_id_get(Ecore_Wl2_Window *window)
4528 {
4529    EINA_SAFETY_ON_NULL_RETURN_VAL(window, 0);
4530    return window->resource_id;
4531 }
4532 //