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