elm_win: fix build error
[platform/upstream/elementary.git] / src / lib / elm_win.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
7 #define ELM_WIN_PROTECTED
8
9 #include <Elementary.h>
10 #include <Elementary_Cursor.h>
11
12 #include "elm_priv.h"
13 #include "elm_widget_menu.h"
14
15 #define MY_CLASS ELM_WIN_CLASS
16
17 #define MY_CLASS_NAME "Elm_Win"
18 #define MY_CLASS_NAME_LEGACY "elm_win"
19
20 static const Elm_Win_Trap *trap = NULL;
21
22 #define TRAP(sd, name, ...)                                             \
23   do                                                                    \
24     {                                                                   \
25        if (sd->type != ELM_WIN_FAKE)                                    \
26          if ((!trap) || (!trap->name) ||                                \
27              ((trap->name) &&                                           \
28               (trap->name(sd->trap_data, sd->obj, ## __VA_ARGS__))))    \
29            ecore_evas_##name(sd->ee, ##__VA_ARGS__);                    \
30     }                                                                   \
31   while (0)
32
33 #define ELM_WIN_DATA_GET(o, sd) \
34   Elm_Win_Data * sd = eo_data_scope_get(o, MY_CLASS)
35
36 #define ELM_WIN_DATA_GET_OR_RETURN(o, ptr)           \
37   ELM_WIN_DATA_GET(o, ptr);                          \
38   if (!ptr)                                          \
39     {                                                \
40        CRI("No widget data for object %p (%s)", \
41                 o, evas_object_type_get(o));         \
42        return;                                       \
43     }
44
45 #define ELM_WIN_DATA_GET_OR_RETURN_VAL(o, ptr, val)  \
46   ELM_WIN_DATA_GET(o, ptr);                          \
47   if (!ptr)                                          \
48     {                                                \
49        CRI("No widget data for object %p (%s)", \
50                 o, evas_object_type_get(o));         \
51        return val;                                   \
52     }
53
54 #define ELM_WIN_CHECK(obj)                                             \
55   if (!obj || !eo_isa(obj, MY_CLASS)) \
56     return
57
58 #define DECREMENT_MODALITY()                                    \
59   EINA_LIST_FOREACH(_elm_win_list, l, current)                  \
60     {                                                           \
61        ELM_WIN_DATA_GET_OR_RETURN(current, cursd);              \
62        if ((obj != current) && (cursd->modal_count > 0))        \
63          {                                                      \
64             cursd->modal_count--;                               \
65          }                                                      \
66        if (cursd->modal_count == 0)                             \
67          {                                                      \
68             edje_object_signal_emit(cursd->edje, \
69                         "elm,action,hide_blocker", "elm");      \
70             eo_do(cursd->main_menu, eo_event_callback_call      \
71               (ELM_MENU_EVENT_ELM_ACTION_UNBLOCK_MENU, NULL));  \
72          }                                                      \
73     }
74
75 #define INCREMENT_MODALITY()                                    \
76   EINA_LIST_FOREACH(_elm_win_list, l, current)                  \
77     {                                                           \
78        ELM_WIN_DATA_GET_OR_RETURN(current, cursd);              \
79        if (obj != current)                                      \
80          {                                                      \
81             cursd->modal_count++;                               \
82          }                                                      \
83        if (cursd->modal_count > 0)                              \
84          {                                                      \
85             edje_object_signal_emit(cursd->edje, \
86                              "elm,action,show_blocker", "elm"); \
87             eo_do(cursd->main_menu, eo_event_callback_call      \
88               (ELM_WIN_EVENT_ELM_ACTION_BLOCK_MENU, NULL));     \
89          }                                                      \
90     }
91
92 #define ENGINE_GET() (_elm_preferred_engine ? _elm_preferred_engine : _elm_config->engine)
93
94 typedef struct _Elm_Win_Data Elm_Win_Data;
95
96 struct _Elm_Win_Data
97 {
98    Ecore_Evas           *ee;
99    Evas                 *evas;
100    Evas_Object          *parent; /* parent *window* object*/
101    Evas_Object          *img_obj, *frame_obj;
102    Evas_Object          *client_obj; /* rect representing the client */
103    Eo                   *edje; /**< edje object for a window layout */
104    Eo                   *box;
105    Evas_Object          *obj; /* The object itself */
106 #ifdef HAVE_ELEMENTARY_X
107    struct
108    {
109       Ecore_X_Window       xwin;
110       Ecore_Event_Handler *client_message_handler;
111       Ecore_Event_Handler *property_handler;
112    } x;
113 #endif
114 #ifdef HAVE_ELEMENTARY_WAYLAND
115    struct
116    {
117       Ecore_Wl_Window *win;
118       Eina_Bool opaque_dirty : 1;
119       Ecore_Event_Handler *effect_start_handler;
120       Ecore_Event_Handler *effect_end_handler;
121    } wl;
122 #endif
123
124    Ecore_Job                     *deferred_resize_job;
125    Ecore_Job                     *deferred_child_eval_job;
126
127    Elm_Win_Type                   type;
128    Elm_Win_Keyboard_Mode          kbdmode;
129    Elm_Win_Indicator_Mode         indmode;
130    Elm_Win_Indicator_Opacity_Mode ind_o_mode;
131    Eina_Rectangle kbd;
132    Eina_Rectangle ind;
133    struct
134    {
135       const char  *info;
136       Ecore_Timer *timer;
137       int          repeat_count;
138       int          shot_counter;
139    } shot;
140    int                            resize_location;
141    int                           *autodel_clear, rot;
142    struct
143    {
144       int x, y;
145    } screen;
146    struct
147    {
148 #if 0
149       Ecore_Evas  *ee;
150 #endif
151       Evas        *evas;
152       Evas_Object *obj, *hot_obj;
153       int          hot_x, hot_y;
154    } pointer;
155    struct
156    {
157       Evas_Object *fobj; /* focus highlight edje object */
158
159       struct
160       {
161          Evas_Object *target;
162          Eina_Bool    visible : 1;
163          Eina_Bool    in_theme: 1; /**< focus highlight is handled by theme.
164                                      this is set true if edc data item "focus_highlight" is set to "on" during focus in callback. */
165       } cur, prev;
166
167       const char  *style;
168       Ecore_Job   *reconf_job;
169
170       Eina_Bool    enabled : 1;
171       Eina_Bool    theme_changed : 1; /* set true when the focus theme is changed */
172       Eina_Bool    animate : 1; /* set true when the focus highlight animate is enabled */
173       Eina_Bool    animate_supported : 1; /* set true when the focus highlight animate is supported by theme */
174       Eina_Bool    geometry_changed : 1;
175       Eina_Bool    auto_enabled : 1;
176       Eina_Bool    auto_animate : 1;
177    } focus_highlight;
178    //TIZEN_ONLY(20160404) Accessibility Highlight Frame added (99248ce)
179    struct
180    {
181       Evas_Object *fobj; /* accessibility highlight edje object */
182
183       struct
184       {
185          Evas_Object *target;
186       } cur, prev;
187
188    } accessibility_highlight;
189    //
190    Evas_Object *icon;
191    const char  *title;
192    const char  *icon_name;
193    const char  *role;
194    const char  *frame_style;
195    Eina_Stringshare *name;
196
197    Evas_Object *main_menu;
198
199    struct
200    {
201       const char  *name;
202       const char **available_list;
203       unsigned int count;
204    } profile;
205    struct
206    {
207       int          preferred_rot; /* indicates preferred rotation value, -1 means invalid. */
208       int         *rots; /* indicates available rotations */
209       unsigned int count; /* number of elements in available rotations */
210       Eina_Bool    wm_supported : 1; /* set true when the window manager support window rotation */
211       Eina_Bool    use : 1; /* set ture when application use window manager rotation. */
212    } wm_rot;
213
214    Eo *socket_proxy; /* reference object to atspi object in separate process @since 1.15 */
215
216    void *trap_data;
217
218    struct
219      {
220         Ecore_Animator *obj;
221         unsigned short wants;
222      } animator;
223
224    double       aspect;
225    int          size_base_w, size_base_h;
226    int          size_step_w, size_step_h;
227    int          norender;
228    int          modal_count;
229    Eina_Bool    urgent : 1;
230    Eina_Bool    modal : 1;
231    Eina_Bool    demand_attention : 1;
232    Eina_Bool    autodel : 1;
233    Eina_Bool    autohide : 1;
234    Eina_Bool    constrain : 1;
235    Eina_Bool    resizing : 1;
236    Eina_Bool    iconified : 1;
237    Eina_Bool    withdrawn : 1;
238    Eina_Bool    sticky : 1;
239    Eina_Bool    fullscreen : 1;
240    Eina_Bool    maximized : 1;
241    Eina_Bool    skip_focus : 1;
242    Eina_Bool    floating : 1;
243    Eina_Bool    noblank : 1;
244    Eina_Bool    theme_alpha : 1; /**< alpha value fetched by a theme. this has higher priority than application_alpha */
245    Eina_Bool    application_alpha : 1; /**< alpha value set by an elm_win_alpha_set() api. this has lower priority than theme_alpha */
246    Eina_Bool    obscured :1;
247    Eina_Bool    borderless : 1;
248 };
249
250 static const char SIG_DELETE_REQUEST[] = "delete,request";
251 static const char SIG_FOCUS_OUT[] = "focus,out"; // deprecated. use "unfocused" instead.
252 static const char SIG_FOCUS_IN[] = "focus,in"; // deprecated. use "focused" instead.
253 static const char SIG_MOVED[] = "moved";
254 static const char SIG_WITHDRAWN[] = "withdrawn";
255 static const char SIG_ICONIFIED[] = "iconified";
256 static const char SIG_NORMAL[] = "normal";
257 static const char SIG_STICK[] = "stick";
258 static const char SIG_UNSTICK[] = "unstick";
259 static const char SIG_FULLSCREEN[] = "fullscreen";
260 static const char SIG_UNFULLSCREEN[] = "unfullscreen";
261 static const char SIG_MAXIMIZED[] = "maximized";
262 static const char SIG_UNMAXIMIZED[] = "unmaximized";
263 static const char SIG_IOERR[] = "ioerr";
264 static const char SIG_INDICATOR_PROP_CHANGED[] = "indicator,prop,changed";
265 static const char SIG_ROTATION_CHANGED[] = "rotation,changed";
266 static const char SIG_PROFILE_CHANGED[] = "profile,changed";
267 static const char SIG_WM_ROTATION_CHANGED[] = "wm,rotation,changed";
268 #ifdef HAVE_ELEMENTARY_WAYLAND
269 static const char SIG_CONFORMANT_CHANGED[] = "conformant,changed";
270 #endif
271 static const char SIG_AUX_HINT_ALLOWED[] = "aux,hint,allowed";
272 static const char SIG_VISIBILITY_CHANGED[] = "visibility,changed";
273 static const char SIG_EFFECT_STARTED[] = "effect,started";
274 static const char SIG_EFFECT_DONE[] = "effect,done";
275
276 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
277    {SIG_DELETE_REQUEST, ""},
278    {SIG_FOCUS_OUT, ""},
279    {SIG_FOCUS_IN, ""},
280    {SIG_MOVED, ""},
281    {SIG_WITHDRAWN, ""},
282    {SIG_ICONIFIED, ""},
283    {SIG_NORMAL, ""},
284    {SIG_STICK, ""},
285    {SIG_UNSTICK, ""},
286    {SIG_FULLSCREEN, ""},
287    {SIG_UNFULLSCREEN, ""},
288    {SIG_MAXIMIZED, ""},
289    {SIG_UNMAXIMIZED, ""},
290    {SIG_IOERR, ""},
291    {SIG_INDICATOR_PROP_CHANGED, ""},
292    {SIG_ROTATION_CHANGED, ""},
293    {SIG_PROFILE_CHANGED, ""},
294    {SIG_WM_ROTATION_CHANGED, ""},
295    {SIG_WIDGET_FOCUSED, ""}, /**< handled by elm_widget */
296    {SIG_WIDGET_UNFOCUSED, ""}, /**< handled by elm_widget */
297 #ifdef HAVE_ELEMENTARY_WAYLAND
298    {SIG_CONFORMANT_CHANGED, ""},
299 #endif
300    {SIG_AUX_HINT_ALLOWED, ""},
301    {SIG_VISIBILITY_CHANGED, ""},
302    {SIG_EFFECT_STARTED, ""},
303    {SIG_EFFECT_DONE, ""},
304    {NULL, NULL}
305 };
306
307 static Eina_Bool _key_action_return(Evas_Object *obj, const char *params);
308 static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
309
310 static const Elm_Action key_actions[] = {
311    {"return", _key_action_return},
312    {"move", _key_action_move},
313    {NULL, NULL}
314 };
315
316 Eina_List *_elm_win_list = NULL;
317 int _elm_win_deferred_free = 0;
318
319 static int _elm_win_count = 0;
320
321 // TIZEN_ONLY(20160218): Improve launching performance.
322 static Evas_Object *_precreated_win_obj = NULL;
323 //
324
325 static Eina_Bool _elm_win_auto_throttled = EINA_FALSE;
326
327 static Ecore_Timer *_elm_win_state_eval_timer = NULL;
328
329 static void
330 _elm_win_on_resize_obj_changed_size_hints(void *data,
331                                           Evas *e,
332                                           Evas_Object *obj,
333                                           void *event_info);
334 static void
335 _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj);
336 static Eina_Bool _elm_win_theme_internal(Eo *obj, Elm_Win_Data *sd);
337 static void
338 _elm_win_borderless_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool borderless);
339
340 #ifdef HAVE_ELEMENTARY_X
341 static void _elm_win_xwin_update(Elm_Win_Data *sd);
342 #endif
343
344 EAPI double _elm_startup_time = 0;
345
346 static void
347 _elm_win_first_frame_do(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
348 {
349    double end = ecore_time_unix_get();
350    char *first = data;
351
352    switch (*first)
353      {
354       case 'A': abort();
355       case 'E':
356       case 'D': exit(-1);
357       case 'T': fprintf(stderr, "Startup time: '%f' - '%f' = '%f' sec\n", end, _elm_startup_time, end - _elm_startup_time);
358                 break;
359      }
360
361    evas_event_callback_del_full(e, EVAS_CALLBACK_RENDER_POST, _elm_win_first_frame_do, data);
362 }
363
364 static void
365 _win_noblank_eval(void)
366 {
367    Eina_List *l;
368    Evas_Object *obj;
369    int noblanks = 0;
370    Eina_Bool change = EINA_FALSE;
371
372 #ifdef HAVE_ELEMENTARY_X
373    EINA_LIST_FOREACH(_elm_win_list, l, obj)
374      {
375         ELM_WIN_DATA_GET(obj, sd);
376
377         if (sd->x.xwin)
378           {
379              if ((sd->noblank) && (!sd->iconified) && (!sd->withdrawn) &&
380                  evas_object_visible_get(obj))
381                noblanks++;
382
383              change = EINA_TRUE;
384           }
385      }
386
387    if (!change) return;
388
389    if (noblanks > 0) ecore_x_screensaver_suspend();
390    else ecore_x_screensaver_resume();
391 #endif
392 #ifdef HAVE_ELEMENTARY_WAYLAND
393    // XXX: no wl implementation of this yet - maybe higher up at prop level
394 #endif
395 }
396
397 static Elm_Process_State _elm_process_state = ELM_PROCESS_STATE_FOREGROUND;
398
399 EAPI Elm_Process_State
400 elm_process_state_get(void)
401 {
402    return _elm_process_state;
403 }
404
405 static void
406 _elm_win_apply_alpha(Eo *obj, Elm_Win_Data *sd)
407 {
408    Eina_Bool enabled;
409
410    enabled = sd->theme_alpha | sd->application_alpha;
411    if (sd->img_obj)
412      {
413         evas_object_image_alpha_set(sd->img_obj, enabled);
414         ecore_evas_alpha_set(sd->ee, enabled);
415      }
416    else
417      {
418 #ifdef HAVE_ELEMENTARY_X
419         if (sd->x.xwin)
420           {
421              if (enabled)
422                {
423                   if (!ecore_x_screen_is_composited(0))
424                     elm_win_shaped_set(obj, enabled);
425                   else
426                     TRAP(sd, alpha_set, enabled);
427                }
428              else
429                TRAP(sd, alpha_set, enabled);
430              _elm_win_xwin_update(sd);
431           }
432         else
433 #endif
434           TRAP(sd, alpha_set, enabled);
435      }
436 }
437
438 static Eina_Bool
439 _elm_win_state_eval(void *data EINA_UNUSED)
440 {
441    Eina_List *l;
442    Evas_Object *obj;
443    int _elm_win_count_shown = 0;
444    int _elm_win_count_iconified = 0;
445    int _elm_win_count_withdrawn = 0;
446    Eina_Bool throttle = EINA_FALSE;
447
448    _elm_win_state_eval_timer = NULL;
449
450    EINA_LIST_FOREACH(_elm_win_list, l, obj)
451      {
452         if (_elm_config->auto_norender_withdrawn)
453           {
454              if ((elm_win_withdrawn_get(obj)) ||
455                  ((elm_win_iconified_get(obj) &&
456                    (_elm_config->auto_norender_iconified_same_as_withdrawn))))
457                {
458                   if (!evas_object_data_get(obj, "__win_auto_norender"))
459                     {
460                        Evas *evas = evas_object_evas_get(obj);
461
462                        elm_win_norender_push(obj);
463                        evas_object_data_set(obj, "__win_auto_norender", obj);
464
465                        if (_elm_config->auto_flush_withdrawn)
466                          {
467                             edje_file_cache_flush();
468                             edje_collection_cache_flush();
469                             evas_image_cache_flush(evas);
470                             evas_font_cache_flush(evas);
471                          }
472                        if (_elm_config->auto_dump_withdrawn)
473                          {
474                             evas_render_dump(evas);
475                          }
476                     }
477                   continue;
478                }
479           }
480         if (evas_object_data_get(obj, "__win_auto_norender"))
481           {
482              elm_win_norender_pop(obj);
483              evas_object_data_del(obj, "__win_auto_norender");
484           }
485      }
486    if (((_elm_config->auto_throttle) &&
487         (elm_policy_get(ELM_POLICY_THROTTLE) != ELM_POLICY_THROTTLE_NEVER)) ||
488         (elm_policy_get(ELM_POLICY_THROTTLE) == ELM_POLICY_THROTTLE_HIDDEN_ALWAYS))
489      throttle = EINA_TRUE;
490    if (_elm_win_count == 0)
491      {
492         if (_elm_win_auto_throttled)
493           {
494              _elm_process_state = ELM_PROCESS_STATE_FOREGROUND;
495              ecore_event_add(ELM_EVENT_PROCESS_FOREGROUND, NULL, NULL, NULL);
496              if (throttle)
497                ecore_throttle_adjust(-_elm_config->auto_throttle_amount);
498              _elm_win_auto_throttled = EINA_FALSE;
499           }
500      }
501    else
502      {
503         EINA_LIST_FOREACH(_elm_win_list, l, obj)
504           {
505              if (elm_win_withdrawn_get(obj)) _elm_win_count_withdrawn++;
506              else if (elm_win_iconified_get(obj)) _elm_win_count_iconified++;
507              else if (evas_object_visible_get(obj)) _elm_win_count_shown++;
508           }
509         if (_elm_win_count_shown <= 0)
510           {
511              if (!_elm_win_auto_throttled)
512                {
513                   _elm_process_state = ELM_PROCESS_STATE_BACKGROUND;
514                   ecore_event_add(ELM_EVENT_PROCESS_BACKGROUND, NULL, NULL, NULL);
515                   if (throttle)
516                     ecore_throttle_adjust(_elm_config->auto_throttle_amount);
517                   _elm_win_auto_throttled = EINA_TRUE;
518                }
519           }
520         else
521           {
522              if (_elm_win_auto_throttled)
523                {
524                   _elm_process_state = ELM_PROCESS_STATE_FOREGROUND;
525                   ecore_event_add(ELM_EVENT_PROCESS_FOREGROUND, NULL, NULL, NULL);
526                   if (throttle)
527                     ecore_throttle_adjust(-_elm_config->auto_throttle_amount);
528                   _elm_win_auto_throttled = EINA_FALSE;
529                }
530           }
531      }
532    _win_noblank_eval();
533    return EINA_FALSE;
534 }
535
536 static Eina_Bool
537 _elm_win_policy_quit_triggered(Eo* triggering_obj)
538 {
539    if ((!_elm_win_list) &&
540        (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
541      {
542         return EINA_TRUE;
543      }
544
545    if (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN)
546      {
547         Eina_List *l;
548         Evas_Object *win;
549
550         EINA_LIST_FOREACH(_elm_win_list, l, win)
551           if (win != triggering_obj && evas_object_visible_get(win) == EINA_TRUE)
552             {
553                return EINA_FALSE;
554             }
555         return EINA_TRUE;
556      }
557
558    return EINA_FALSE;
559 }
560
561 static void
562 _elm_win_flush_cache_and_exit(Eo *obj)
563 {
564    edje_file_cache_flush();
565    edje_collection_cache_flush();
566    evas_image_cache_flush(evas_object_evas_get(obj));
567    evas_font_cache_flush(evas_object_evas_get(obj));
568    elm_exit();
569 }
570
571 static void
572 _elm_win_state_eval_queue(void)
573 {
574    if (_elm_win_state_eval_timer) ecore_timer_del(_elm_win_state_eval_timer);
575    _elm_win_state_eval_timer = ecore_timer_add(0.5, _elm_win_state_eval, NULL);
576 }
577
578 // example shot spec (wait 0.1 sec then save as my-window.png):
579 // ELM_ENGINE="shot:delay=0.1:file=my-window.png"
580
581 static double
582 _shot_delay_get(Elm_Win_Data *sd)
583 {
584    char *p, *pd;
585    char *d = strdup(sd->shot.info);
586
587    if (!d) return 0.5;
588    for (p = (char *)sd->shot.info; *p; p++)
589      {
590         if (!strncmp(p, "delay=", 6))
591           {
592              double v;
593
594              for (pd = d, p += 6; (*p) && (*p != ':'); p++, pd++)
595                {
596                   *pd = *p;
597                }
598              *pd = 0;
599              v = _elm_atof(d);
600              free(d);
601              return v;
602           }
603      }
604    free(d);
605
606    return 0.5;
607 }
608
609 static char *
610 _shot_file_get(Elm_Win_Data *sd)
611 {
612    char *p;
613    char *tmp = strdup(sd->shot.info);
614    char *repname = NULL;
615
616    if (!tmp) return NULL;
617
618    for (p = (char *)sd->shot.info; *p; p++)
619      {
620         if (!strncmp(p, "file=", 5))
621           {
622              strcpy(tmp, p + 5);
623              if (!sd->shot.repeat_count) return tmp;
624              else
625                {
626                   char *dotptr = strrchr(tmp, '.');
627                   if (dotptr)
628                     {
629                        size_t size = sizeof(char) * (strlen(tmp) + 16);
630                        repname = malloc(size);
631                        strncpy(repname, tmp, dotptr - tmp);
632                        snprintf(repname + (dotptr - tmp), size -
633                                 (dotptr - tmp), "%03i",
634                                 sd->shot.shot_counter + 1);
635                        strcat(repname, dotptr);
636                        free(tmp);
637                        return repname;
638                     }
639                }
640           }
641      }
642    free(tmp);
643    if (!sd->shot.repeat_count) return strdup("out.png");
644
645    repname = malloc(sizeof(char) * 24);
646    snprintf(repname, sizeof(char) * 24, "out%03i.png",
647             sd->shot.shot_counter + 1);
648
649    return repname;
650 }
651
652 static int
653 _shot_repeat_count_get(Elm_Win_Data *sd)
654 {
655    char *p, *pd;
656    char *d = strdup(sd->shot.info);
657
658    if (!d) return 0;
659    for (p = (char *)sd->shot.info; *p; p++)
660      {
661         if (!strncmp(p, "repeat=", 7))
662           {
663              int v;
664
665              for (pd = d, p += 7; (*p) && (*p != ':'); p++, pd++)
666                {
667                   *pd = *p;
668                }
669              *pd = 0;
670              v = atoi(d);
671              if (v < 0) v = 0;
672              if (v > 1000) v = 999;
673              free(d);
674              return v;
675           }
676      }
677    free(d);
678
679    return 0;
680 }
681
682 static char *
683 _shot_key_get(Elm_Win_Data *sd EINA_UNUSED)
684 {
685    return NULL;
686 }
687
688 static char *
689 _shot_flags_get(Elm_Win_Data *sd EINA_UNUSED)
690 {
691    return NULL;
692 }
693
694 static void
695 _shot_do(Elm_Win_Data *sd)
696 {
697    Ecore_Evas *ee;
698    Evas_Object *o;
699    unsigned int *pixels;
700    int w, h;
701    char *file, *key, *flags;
702
703    ecore_evas_manual_render(sd->ee);
704    pixels = (void *)ecore_evas_buffer_pixels_get(sd->ee);
705    if (!pixels) return;
706
707    ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
708    if ((w < 1) || (h < 1)) return;
709
710    file = _shot_file_get(sd);
711    if (!file) return;
712
713    key = _shot_key_get(sd);
714    flags = _shot_flags_get(sd);
715    ee = ecore_evas_buffer_new(1, 1);
716    o = evas_object_image_add(ecore_evas_get(ee));
717    evas_object_image_alpha_set(o,
718                                sd->theme_alpha | sd->application_alpha);
719    evas_object_image_size_set(o, w, h);
720    evas_object_image_data_set(o, pixels);
721    if (!evas_object_image_save(o, file, key, flags))
722      {
723         ERR("Cannot save window to '%s' (key '%s', flags '%s')",
724             file, key, flags);
725      }
726    free(file);
727    free(key);
728    free(flags);
729    ecore_evas_free(ee);
730    if (sd->shot.repeat_count) sd->shot.shot_counter++;
731 }
732
733 static Eina_Bool
734 _shot_delay(void *data)
735 {
736    ELM_WIN_DATA_GET(data, sd);
737
738    _shot_do(sd);
739    if (sd->shot.repeat_count)
740      {
741         int remainshot = (sd->shot.repeat_count - sd->shot.shot_counter);
742         if (remainshot > 0) return EINA_TRUE;
743      }
744    sd->shot.timer = NULL;
745    elm_exit();
746
747    return EINA_FALSE;
748 }
749
750 static void
751 _shot_init(Elm_Win_Data *sd)
752 {
753    if (!sd->shot.info) return;
754
755    sd->shot.repeat_count = _shot_repeat_count_get(sd);
756    sd->shot.shot_counter = 0;
757 }
758
759 static void
760 _shot_handle(Elm_Win_Data *sd)
761 {
762    if (!sd->shot.info) return;
763
764    if (!sd->shot.timer)
765      sd->shot.timer = ecore_timer_add(_shot_delay_get(sd), _shot_delay,
766                                       sd->obj);
767 }
768
769 /* elm-win specific associate, does the trap while ecore_evas_object_associate()
770  * does not.
771  */
772 static Elm_Win_Data *
773 _elm_win_associate_get(const Ecore_Evas *ee)
774 {
775    Evas_Object *obj = ecore_evas_data_get(ee, "elm_win");
776    if (!obj) return NULL;
777    ELM_WIN_DATA_GET(obj, sd);
778    return sd;
779 }
780
781 /* Interceptors Callbacks */
782 static void
783 _elm_win_obj_intercept_raise(void *data, Evas_Object *obj EINA_UNUSED)
784 {
785    ELM_WIN_DATA_GET(data, sd);
786    TRAP(sd, raise);
787 }
788
789 static void
790 _elm_win_obj_intercept_lower(void *data, Evas_Object *obj EINA_UNUSED)
791 {
792    ELM_WIN_DATA_GET(data, sd);
793    TRAP(sd, lower);
794 }
795
796 static void
797 _elm_win_obj_intercept_stack_above(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *above EINA_UNUSED)
798 {
799    INF("TODO: %s", __FUNCTION__);
800 }
801
802 static void
803 _elm_win_obj_intercept_stack_below(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *below EINA_UNUSED)
804 {
805    INF("TODO: %s", __FUNCTION__);
806 }
807
808 static void
809 _elm_win_obj_intercept_layer_set(void *data, Evas_Object *obj EINA_UNUSED, int l)
810 {
811    ELM_WIN_DATA_GET(data, sd);
812    TRAP(sd, layer_set, l);
813 }
814
815 /* Event Callbacks */
816
817 static void
818 _elm_win_obj_callback_changed_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
819 {
820    ELM_WIN_DATA_GET(data, sd);
821    Evas_Coord w, h;
822
823    evas_object_size_hint_min_get(obj, &w, &h);
824    TRAP(sd, size_min_set, w, h);
825
826    evas_object_size_hint_max_get(obj, &w, &h);
827    if (w < 1) w = -1;
828    if (h < 1) h = -1;
829    TRAP(sd, size_max_set, w, h);
830 }
831 /* end of elm-win specific associate */
832
833 static void
834 _elm_win_move(Ecore_Evas *ee)
835 {
836    Elm_Win_Data *sd = _elm_win_associate_get(ee);
837    int x, y;
838
839    if (!sd) return;
840
841    ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
842    sd->screen.x = x;
843    sd->screen.y = y;
844    eo_do(sd->obj, eo_event_callback_call(ELM_WIN_EVENT_MOVED, NULL));
845    evas_nochange_push(evas_object_evas_get(sd->obj));
846    evas_object_move(sd->obj, x, y);
847    evas_nochange_pop(evas_object_evas_get(sd->obj));
848 }
849
850 static void
851 _elm_win_resize_job(void *data)
852 {
853    ELM_WIN_DATA_GET(data, sd);
854    int x, y, w, h;
855
856    sd->deferred_resize_job = NULL;
857    ecore_evas_request_geometry_get(sd->ee, &x, &y, &w, &h);
858    if (sd->constrain)
859      {
860         int sw, sh;
861         ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sw, &sh);
862         w = MIN(w, sw);
863         h = MIN(h, sh);
864      }
865
866    if (sd->frame_obj)
867      {
868         int fx, fy, fw, fh;
869
870         evas_output_framespace_get(sd->evas, &fx, &fy, &fw, &fh);
871         evas_object_move(sd->frame_obj, -fx, -fy);
872         evas_object_resize(sd->frame_obj, w + fw, h + fh);
873      }
874
875    evas_object_resize(sd->obj, w, h);
876    evas_object_resize(sd->edje, w, h);
877
878 #ifdef HAVE_ELEMENTARY_WAYLAND
879    ecore_wl_window_opaque_region_set(sd->wl.win, x, y, w, h);
880 #endif
881 }
882
883 static void
884 _elm_win_resize(Ecore_Evas *ee)
885 {
886    Elm_Win_Data *sd = _elm_win_associate_get(ee);
887    if (!sd) return;
888
889    ecore_job_del(sd->deferred_resize_job);
890    sd->deferred_resize_job = ecore_job_add(_elm_win_resize_job, sd->obj);
891 }
892
893 static void
894 _elm_win_mouse_in(Ecore_Evas *ee)
895 {
896    Elm_Win_Data *sd = _elm_win_associate_get(ee);
897    if (!sd) return;
898
899    if (sd->resizing) sd->resizing = EINA_FALSE;
900 }
901
902 static void
903 _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win_Data *sd)
904 {
905    ELM_SAFE_FREE(sd->focus_highlight.reconf_job, ecore_job_del);
906 }
907
908 static void
909 _elm_win_accessibility_highlight_visible_set(Elm_Win_Data *sd,
910                                      Eina_Bool visible)
911 {
912    Evas_Object *fobj = sd->accessibility_highlight.fobj;
913
914    if (!fobj)
915      return;
916
917    if (visible)
918      {
919         evas_object_show(fobj);
920      }
921    else
922      {
923         evas_object_hide(fobj);
924         evas_object_del(fobj);
925      }
926 }
927
928 static void
929 _elm_win_focus_highlight_visible_set(Elm_Win_Data *sd,
930                                      Eina_Bool visible)
931 {
932    Evas_Object *fobj = sd->focus_highlight.fobj;
933    if (!fobj) return;
934
935    if (visible)
936      {
937         evas_object_show(fobj);
938         edje_object_signal_emit(fobj, "elm,action,focus,show", "elm");
939      }
940    else
941      {
942         edje_object_signal_emit(fobj, "elm,action,focus,hide", "elm");
943      }
944 }
945
946 Evas_Object *
947 _elm_win_focus_highlight_object_get(Evas_Object *obj)
948 {
949    ELM_WIN_DATA_GET(obj, sd);
950
951    return sd->focus_highlight.fobj;
952 }
953
954 static void
955 _elm_win_focus_highlight_anim_setup(Elm_Win_Data *sd,
956                                     Evas_Object *obj)
957 {
958    Evas_Coord tx, ty, tw, th;
959    Evas_Coord px, py, pw, ph;
960    Edje_Message_Int_Set *m;
961    Evas_Object *target = sd->focus_highlight.cur.target;
962
963    evas_object_geometry_get(obj, &px, &py, &pw, &ph);
964    elm_widget_focus_highlight_geometry_get(target, &tx, &ty, &tw, &th);
965    evas_object_move(obj, tx, ty);
966    evas_object_resize(obj, tw, th);
967
968    if ((px == tx) && (py == ty) && (pw == tw) && (ph == th)) return;
969
970    if (!_elm_config->focus_highlight_clip_disable)
971      evas_object_clip_unset(obj);
972
973    m = alloca(sizeof(*m) + (sizeof(int) * 8));
974    m->count = 8;
975    m->val[0] = px - tx;
976    m->val[1] = py - ty;
977    m->val[2] = pw;
978    m->val[3] = ph;
979    m->val[4] = 0;
980    m->val[5] = 0;
981    m->val[6] = tw;
982    m->val[7] = th;
983    edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m);
984 }
985
986 static void
987 _elm_win_accessibility_highlight_simple_setup(Elm_Win_Data *sd,
988                                       Evas_Object *obj)
989 {
990    Evas_Object *clip, *target = sd->accessibility_highlight.cur.target;
991    Evas_Coord x, y, w, h;
992
993    evas_object_geometry_get(target, &x, &y, &w, &h);
994
995    evas_object_move(obj, x, y);
996    evas_object_resize(obj, w, h);
997
998    clip = evas_object_clip_get(target);
999    if (clip) evas_object_clip_set(obj, clip);
1000 }
1001
1002 static void
1003 _elm_win_focus_highlight_simple_setup(Elm_Win_Data *sd,
1004                                       Evas_Object *obj)
1005 {
1006    Evas_Object *clip, *target = sd->focus_highlight.cur.target;
1007    Evas_Coord x, y, w, h;
1008
1009    elm_widget_focus_highlight_geometry_get(target, &x, &y, &w, &h);
1010
1011    evas_object_move(obj, x, y);
1012    evas_object_resize(obj, w, h);
1013
1014    if (!_elm_config->focus_highlight_clip_disable)
1015      {
1016         clip = evas_object_clip_get(target);
1017         if (clip) evas_object_clip_set(obj, clip);
1018      }
1019
1020    edje_object_signal_emit(obj, "elm,state,anim,stop", "elm");
1021 }
1022
1023 static void
1024 _elm_win_focus_prev_target_del(void *data,
1025                                Evas *e EINA_UNUSED,
1026                                Evas_Object *obj EINA_UNUSED,
1027                                void *event_info EINA_UNUSED)
1028 {
1029    ELM_WIN_DATA_GET(data, sd);
1030    sd->focus_highlight.prev.target = NULL;
1031 }
1032
1033 static void
1034 _elm_win_accessibility_highlight_hide(void *data)
1035 {
1036    ELM_WIN_DATA_GET(data, sd);
1037    _elm_win_accessibility_highlight_visible_set(sd, EINA_FALSE);
1038 }
1039
1040 static void
1041 _elm_win_accessibility_highlight_show(void *data)
1042 {
1043    ELM_WIN_DATA_GET(data, sd);
1044    Evas_Object *fobj = sd->accessibility_highlight.fobj;
1045    const char *sig = NULL;
1046    elm_widget_theme_object_set (sd->obj, fobj, "accessibility_highlight", "top", "default");
1047    evas_object_raise(fobj);
1048    _elm_win_accessibility_highlight_simple_setup(sd, fobj);
1049    _elm_win_accessibility_highlight_visible_set(sd, EINA_TRUE);
1050 }
1051
1052
1053 static void
1054 _elm_win_focus_highlight_reconfigure_job(void *data)
1055 {
1056    ELM_WIN_DATA_GET(data, sd);
1057    Evas_Object *target = sd->focus_highlight.cur.target;
1058    Evas_Object *previous = sd->focus_highlight.prev.target;
1059    Evas_Object *fobj = sd->focus_highlight.fobj;
1060    Eina_Bool visible_changed;
1061    Eina_Bool common_visible;
1062    const char *sig = NULL;
1063    const char *focus_style_target = NULL;
1064    const char *focus_style_previous = NULL;
1065
1066    _elm_win_focus_highlight_reconfigure_job_stop(sd);
1067
1068    visible_changed = (sd->focus_highlight.cur.visible !=
1069                       sd->focus_highlight.prev.visible);
1070
1071    if ((target == previous) && (!visible_changed) &&
1072        (!sd->focus_highlight.geometry_changed) &&
1073        (!sd->focus_highlight.theme_changed))
1074      return;
1075
1076    if (previous)
1077      {
1078         evas_object_event_callback_del_full
1079            (previous, EVAS_CALLBACK_DEL, _elm_win_focus_prev_target_del, data);
1080         if (sd->focus_highlight.prev.in_theme)
1081           elm_widget_signal_emit
1082              (previous, "elm,action,focus_highlight,hide", "elm");
1083      }
1084
1085    if (!target)
1086      common_visible = EINA_FALSE;
1087    else if (sd->focus_highlight.cur.in_theme)
1088      {
1089         common_visible = EINA_FALSE;
1090         if (sd->focus_highlight.cur.visible)
1091           sig = "elm,action,focus_highlight,show";
1092         else
1093           sig = "elm,action,focus_highlight,hide";
1094      }
1095    else
1096      common_visible = sd->focus_highlight.cur.visible;
1097
1098    if (sig)
1099      elm_widget_signal_emit(target, sig, "elm");
1100
1101    if ((!target) || (!common_visible) || (sd->focus_highlight.cur.in_theme))
1102      {
1103         if (target)
1104           _elm_win_focus_highlight_simple_setup(sd, fobj);
1105         goto the_end;
1106      }
1107
1108    if (previous)
1109      focus_style_previous = elm_widget_focus_highlight_style_get(previous);
1110    focus_style_target = elm_widget_focus_highlight_style_get(target);
1111
1112    if (sd->focus_highlight.theme_changed ||
1113        (focus_style_target != focus_style_previous))
1114      {
1115         const char *str;
1116
1117         if (focus_style_target)
1118           str = focus_style_target;
1119         else if (sd->focus_highlight.style)
1120           str = sd->focus_highlight.style;
1121         else
1122           str = "default";
1123
1124         elm_widget_theme_object_set
1125           (sd->obj, fobj, "focus_highlight", "top", str);
1126         sd->focus_highlight.theme_changed = EINA_FALSE;
1127
1128         if ((sd->focus_highlight.animate) || (sd->focus_highlight.auto_animate))
1129           {
1130              str = edje_object_data_get(sd->focus_highlight.fobj, "animate");
1131              sd->focus_highlight.animate_supported = ((str) && (!strcmp(str, "on")));
1132           }
1133         else
1134           sd->focus_highlight.animate_supported = EINA_FALSE;
1135      }
1136
1137    if ((sd->focus_highlight.animate_supported) && (previous) &&
1138        (!sd->focus_highlight.prev.in_theme))
1139      _elm_win_focus_highlight_anim_setup(sd, fobj);
1140    else
1141      _elm_win_focus_highlight_simple_setup(sd, fobj);
1142    evas_object_raise(fobj);
1143
1144 the_end:
1145    _elm_win_focus_highlight_visible_set(sd, common_visible);
1146    sd->focus_highlight.geometry_changed = EINA_FALSE;
1147    sd->focus_highlight.prev = sd->focus_highlight.cur;
1148    evas_object_event_callback_add
1149      (sd->focus_highlight.prev.target,
1150       EVAS_CALLBACK_DEL, _elm_win_focus_prev_target_del, data);
1151 }
1152
1153 static void
1154 _elm_win_focus_highlight_reconfigure_job_start(Elm_Win_Data *sd)
1155 {
1156    ecore_job_del(sd->focus_highlight.reconf_job);
1157
1158    sd->focus_highlight.reconf_job = ecore_job_add(
1159        _elm_win_focus_highlight_reconfigure_job, sd->obj);
1160 }
1161
1162 static void
1163 _elm_win_focus_in(Ecore_Evas *ee)
1164 {
1165    Elm_Win_Data *sd = _elm_win_associate_get(ee);
1166    Evas_Object *obj;
1167    unsigned int order = 0;
1168
1169    if ((!sd) || (sd->modal_count)) return;
1170
1171    obj = sd->obj;
1172
1173    _elm_widget_top_win_focused_set(obj, EINA_TRUE);
1174    if (sd->type != ELM_WIN_FAKE)
1175      {
1176         if (!elm_widget_focus_order_get(obj)
1177             || (obj == elm_widget_newest_focus_order_get(obj, &order, EINA_TRUE)))
1178           {
1179              elm_widget_focus_steal(obj, NULL);
1180           }
1181         else
1182           {
1183              Evas_Object *newest = NULL;
1184              unsigned int newest_focus_order = 0;
1185
1186              newest = elm_widget_newest_focus_order_get
1187                (obj, &newest_focus_order, EINA_TRUE);
1188              if ((newest) &&
1189                  _elm_widget_onscreen_is(newest))
1190                {
1191                   if (_elm_win_focus_highlight_object_get(obj))
1192                     elm_widget_focus_restore(obj);
1193                   else if (!elm_object_focus_get(newest))
1194                     elm_widget_focus_restore(obj);
1195                   else
1196                     evas_object_focus_set(obj, EINA_TRUE);
1197                }
1198              else
1199                evas_object_focus_set(obj, EINA_TRUE);
1200           }
1201      }
1202    // FIXME: the event is deprecated but still in use.
1203    // Has to be removed in EFL2.0
1204    evas_object_smart_callback_call(obj, SIG_FOCUS_IN, NULL);
1205    eo_do(obj, eo_event_callback_call(ELM_WIDGET_EVENT_FOCUSED, NULL));
1206    sd->focus_highlight.cur.visible = EINA_TRUE;
1207    _elm_win_focus_highlight_reconfigure_job_start(sd);
1208    if (sd->frame_obj)
1209      {
1210         edje_object_signal_emit(sd->frame_obj, "elm,action,focus", "elm");
1211      }
1212
1213    if (_elm_config->atspi_mode)
1214      {
1215         elm_interface_atspi_window_activated_signal_emit(obj);
1216         elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_ACTIVE, EINA_TRUE);
1217      }
1218
1219    /* do nothing */
1220    /* else if (sd->img_obj) */
1221    /*   { */
1222    /*   } */
1223 }
1224
1225 static void
1226 _elm_win_focus_out(Ecore_Evas *ee)
1227 {
1228    Elm_Win_Data *sd = _elm_win_associate_get(ee);
1229    Evas_Object *obj;
1230
1231    if (!sd) return;
1232
1233    obj = sd->obj;
1234
1235    elm_object_focus_set(obj, EINA_FALSE);
1236    _elm_widget_top_win_focused_set(obj, EINA_FALSE);
1237    // FIXME: the event is deprecated but still in use.
1238    // Has to be removed in EFL2.0
1239    evas_object_smart_callback_call(obj, SIG_FOCUS_OUT, NULL);
1240    eo_do(obj, eo_event_callback_call(ELM_WIDGET_EVENT_UNFOCUSED, NULL));
1241    sd->focus_highlight.cur.visible = EINA_FALSE;
1242    _elm_win_focus_highlight_reconfigure_job_start(sd);
1243    if (sd->frame_obj)
1244      {
1245         edje_object_signal_emit(sd->frame_obj, "elm,action,unfocus", "elm");
1246      }
1247
1248    /* access */
1249    _elm_access_object_highlight_disable(evas_object_evas_get(obj));
1250
1251    if (_elm_config->atspi_mode)
1252      {
1253         elm_interface_atspi_window_deactivated_signal_emit(obj);
1254         elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_ACTIVE, EINA_FALSE);
1255      }
1256
1257    /* do nothing */
1258    /* if (sd->img_obj) */
1259    /*   { */
1260    /*   } */
1261 }
1262
1263 static void
1264 _elm_win_available_profiles_del(Elm_Win_Data *sd)
1265 {
1266    if (!sd->profile.available_list) return;
1267
1268    unsigned int i;
1269    for (i = 0; i < sd->profile.count; i++)
1270      ELM_SAFE_FREE(sd->profile.available_list[i], eina_stringshare_del);
1271    sd->profile.count = 0;
1272    ELM_SAFE_FREE(sd->profile.available_list, free);
1273 }
1274
1275 static void
1276 _elm_win_profile_del(Elm_Win_Data *sd)
1277 {
1278    ELM_SAFE_FREE(sd->profile.name, eina_stringshare_del);
1279 }
1280
1281 static Eina_Bool
1282 _internal_elm_win_profile_set(Elm_Win_Data *sd, const char *profile)
1283 {
1284    Eina_Bool changed = EINA_FALSE;
1285    if (profile)
1286      {
1287         if (sd->profile.name)
1288           {
1289              if (strcmp(sd->profile.name, profile) != 0)
1290                {
1291                   eina_stringshare_replace(&(sd->profile.name), profile);
1292                   changed = EINA_TRUE;
1293                }
1294           }
1295         else
1296           {
1297              sd->profile.name = eina_stringshare_add(profile);
1298              changed = EINA_TRUE;
1299           }
1300      }
1301    else
1302      _elm_win_profile_del(sd);
1303
1304    return changed;
1305 }
1306
1307 static void
1308 _elm_win_profile_update(Elm_Win_Data *sd)
1309 {
1310    if (getenv("ELM_PROFILE")) return;
1311
1312    if (sd->profile.available_list)
1313      {
1314         Eina_Bool found = EINA_FALSE;
1315         if (sd->profile.name)
1316           {
1317              unsigned int i;
1318              for (i = 0; i < sd->profile.count; i++)
1319                {
1320                   if (!strcmp(sd->profile.name,
1321                               sd->profile.available_list[i]))
1322                     {
1323                        found = EINA_TRUE;
1324                        break;
1325                     }
1326                }
1327           }
1328
1329         /* If current profile is not present in an available profiles,
1330          * change current profile to the 1st element of an array.
1331          */
1332         if (!found)
1333           _internal_elm_win_profile_set(sd, sd->profile.available_list[0]);
1334      }
1335
1336    _elm_config_profile_set(sd->profile.name);
1337
1338    /* update sub ee */
1339    Ecore_Evas *ee2;
1340    Eina_List *sub, *l = NULL;
1341
1342    sub = ecore_evas_sub_ecore_evas_list_get(sd->ee);
1343    EINA_LIST_FOREACH(sub, l, ee2)
1344      ecore_evas_window_profile_set(ee2, sd->profile.name);
1345
1346    eo_do(sd->obj, eo_event_callback_call(ELM_WIN_EVENT_PROFILE_CHANGED, NULL));
1347 }
1348
1349 #ifdef HAVE_ELEMENTARY_WAYLAND
1350 static void
1351 _elm_win_opaque_update(Elm_Win_Data *sd)
1352 {
1353    int ox, oy, ow, oh;
1354
1355    if (sd->fullscreen)
1356      {
1357         ecore_evas_geometry_get(sd->ee, NULL, NULL, &ow, &oh);
1358         ecore_wl_window_opaque_region_set(sd->wl.win, 0, 0, ow, oh);
1359         ecore_wl_window_update_location(sd->wl.win, 0, 0);
1360         return;
1361      }
1362
1363    edje_object_part_geometry_get(sd->frame_obj, "elm.spacer.opaque",
1364                                  &ox, &oy, &ow, &oh);
1365    ecore_wl_window_opaque_region_set(sd->wl.win, ox, oy, ow, oh);
1366    ecore_wl_window_update_location(sd->wl.win, sd->screen.x + ox, sd->screen.y + oy);
1367 }
1368 #endif
1369
1370 static void
1371 _elm_win_frame_obj_update(Elm_Win_Data *sd)
1372 {
1373    int fx, fy, fw, fh;
1374    int ox, oy, ow, oh;
1375
1376 #ifdef HAVE_ELEMENTARY_WAYLAND
1377    sd->wl.opaque_dirty = 1;
1378 #endif
1379    if (sd->fullscreen)
1380      {
1381         evas_output_framespace_set(sd->evas, 0, 0, 0, 0);
1382         return;
1383      }
1384
1385    evas_object_geometry_get(sd->frame_obj, &fx, &fy, &fw, &fh);
1386    evas_object_geometry_get(sd->client_obj, &ox, &oy, &ow, &oh);
1387
1388    evas_output_framespace_set(sd->evas, (ox - fx), (oy - fy), (fw - ow), (fh - oh));
1389 }
1390
1391 static void
1392 _elm_win_state_change(Ecore_Evas *ee)
1393 {
1394    Elm_Win_Data *sd = _elm_win_associate_get(ee);
1395    Evas_Object *obj;
1396    Eina_Bool ch_withdrawn = EINA_FALSE;
1397    Eina_Bool ch_sticky = EINA_FALSE;
1398    Eina_Bool ch_iconified = EINA_FALSE;
1399    Eina_Bool ch_fullscreen = EINA_FALSE;
1400    Eina_Bool ch_maximized = EINA_FALSE;
1401    Eina_Bool ch_profile = EINA_FALSE;
1402    Eina_Bool ch_wm_rotation = EINA_FALSE;
1403 #ifdef HAVE_ELEMENTARY_WAYLAND
1404    Eina_Bool ch_conformant  = EINA_FALSE;
1405 #endif
1406    Eina_Bool ch_visibility = EINA_FALSE;
1407    Eina_Bool ch_aux_hint = EINA_FALSE;
1408    Eina_List *aux_hints = NULL;
1409    const char *profile;
1410 #ifdef HAVE_ELEMENTARY_WAYLAND
1411    Conformant_Property property = CONFORMANT_DEFAULT; //TIZEN_ONLY(20160330): add processing properties of window
1412 #endif
1413
1414    if (!sd) return;
1415
1416    obj = sd->obj;
1417
1418    if (sd->withdrawn != ecore_evas_withdrawn_get(sd->ee))
1419      {
1420         sd->withdrawn = ecore_evas_withdrawn_get(sd->ee);
1421         ch_withdrawn = EINA_TRUE;
1422      }
1423    if (sd->sticky != ecore_evas_sticky_get(sd->ee))
1424      {
1425         sd->sticky = ecore_evas_sticky_get(sd->ee);
1426         ch_sticky = EINA_TRUE;
1427      }
1428    if (sd->iconified != ecore_evas_iconified_get(sd->ee))
1429      {
1430         sd->iconified = ecore_evas_iconified_get(sd->ee);
1431         ch_iconified = EINA_TRUE;
1432      }
1433    if (sd->fullscreen != ecore_evas_fullscreen_get(sd->ee))
1434      {
1435         sd->fullscreen = ecore_evas_fullscreen_get(sd->ee);
1436         ch_fullscreen = EINA_TRUE;
1437      }
1438    if (sd->maximized != ecore_evas_maximized_get(sd->ee))
1439      {
1440         sd->maximized = ecore_evas_maximized_get(sd->ee);
1441         ch_maximized = EINA_TRUE;
1442      }
1443
1444    if (ecore_evas_window_profile_supported_get(sd->ee))
1445      {
1446         profile = ecore_evas_window_profile_get(sd->ee);
1447         ch_profile = _internal_elm_win_profile_set(sd, profile);
1448      }
1449
1450    if (sd->wm_rot.use)
1451      {
1452         if (sd->rot != ecore_evas_rotation_get(sd->ee))
1453           {
1454              sd->rot = ecore_evas_rotation_get(sd->ee);
1455              ch_wm_rotation = EINA_TRUE;
1456           }
1457      }
1458
1459    if (sd->obscured != ecore_evas_obscured_get(sd->ee))
1460      {
1461         sd->obscured = ecore_evas_obscured_get(sd->ee);
1462         ch_visibility = EINA_TRUE;
1463      }
1464
1465    aux_hints = ecore_evas_aux_hints_allowed_get(sd->ee);
1466    if (aux_hints)
1467      {
1468         ch_aux_hint = EINA_TRUE;
1469      }
1470
1471 #ifdef HAVE_ELEMENTARY_WAYLAND
1472    int x = 0, y = 0, w = 0, h = 0;
1473    if (sd->indmode != (Elm_Win_Indicator_Mode)ecore_wl_window_indicator_state_get(sd->wl.win))
1474      {
1475         sd->indmode = (Elm_Win_Indicator_Mode)ecore_wl_window_indicator_state_get(sd->wl.win);
1476         ch_conformant = EINA_TRUE;
1477         property |= CONFORMANT_INDICATOR_STATE; //TIZEN_ONLY(20160330): add processing properties of window
1478
1479      }
1480    if (sd->kbdmode != (Elm_Win_Keyboard_Mode)ecore_wl_window_keyboard_state_get(sd->wl.win))
1481      {
1482         sd->kbdmode = (Elm_Win_Keyboard_Mode)ecore_wl_window_keyboard_state_get(sd->wl.win);
1483         ch_conformant = EINA_TRUE;
1484         property |= CONFORMANT_KEYBOARD_STATE; //TIZEN_ONLY(20160330): add processing properties of window
1485
1486      }
1487    if (ecore_wl_window_indicator_geometry_get(sd->wl.win, &x, &y, &w, &h))
1488      {
1489         if ((sd->ind.x != x) || (sd->ind.y != y) || (sd->ind.w != w) || (sd->ind.h != h))
1490           {
1491              sd->ind.x = x;
1492              sd->ind.y = y;
1493              sd->ind.w = w;
1494              sd->ind.h = h;
1495              ch_conformant  = EINA_TRUE;
1496              property |= CONFORMANT_INDICATOR_GEOMETRY; //TIZEN_ONLY(20160330): add processing properties of window
1497
1498           }
1499      }
1500    if (ecore_wl_window_keyboard_geometry_get(sd->wl.win, &x, &y, &w, &h))
1501      {
1502         if ((sd->kbd.x != x) || (sd->kbd.y != y) || (sd->kbd.w != w) || (sd->kbd.h != h))
1503           {
1504              sd->kbd.x = x;
1505              sd->kbd.y = y;
1506              sd->kbd.w = w;
1507              sd->kbd.h = h;
1508              ch_conformant  = EINA_TRUE;
1509              property |= CONFORMANT_KEYBOARD_GEOMETRY; //TIZEN_ONLY(20160330): add processing properties of window
1510
1511           }
1512      }
1513 #endif
1514
1515    _elm_win_state_eval_queue();
1516
1517    if ((ch_withdrawn) || (ch_iconified))
1518      {
1519         if (sd->withdrawn)
1520           eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_WITHDRAWN, NULL));
1521         else if (sd->iconified)
1522           {
1523              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_ICONIFIED, NULL));
1524              if (_elm_config->atspi_mode)
1525                elm_interface_atspi_window_minimized_signal_emit(obj);
1526           }
1527         else
1528           {
1529              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_NORMAL, NULL));
1530              if (_elm_config->atspi_mode)
1531                elm_interface_atspi_window_restored_signal_emit(obj);
1532           }
1533      }
1534    if (ch_sticky)
1535      {
1536         if (sd->sticky)
1537           eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_STICK, NULL));
1538         else
1539           eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_UNSTICK, NULL));
1540      }
1541    if (ch_fullscreen)
1542      {
1543         _elm_win_frame_obj_update(sd);
1544         if (sd->fullscreen)
1545           {
1546              int w, h;
1547
1548              eo_do(obj, eo_event_callback_call
1549                (ELM_WIN_EVENT_FULLSCREEN, NULL));
1550              if (sd->frame_obj)
1551                evas_object_hide(sd->frame_obj);
1552              ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
1553              ecore_evas_resize(sd->ee, w, h);
1554           }
1555         else
1556           {
1557              eo_do(obj, eo_event_callback_call
1558                (ELM_WIN_EVENT_UNFULLSCREEN, NULL));
1559              if (sd->frame_obj)
1560                evas_object_show(sd->frame_obj);
1561           }
1562      }
1563    if (ch_maximized)
1564      {
1565         if (sd->maximized)
1566           {
1567              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_MAXIMIZED, NULL));
1568              if (_elm_config->atspi_mode)
1569                elm_interface_atspi_window_maximized_signal_emit(obj);
1570           }
1571         else
1572           {
1573              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_UNMAXIMIZED, NULL));
1574              if (_elm_config->atspi_mode)
1575                elm_interface_atspi_window_restored_signal_emit(obj);
1576           }
1577      }
1578    if (ch_profile)
1579      {
1580         _elm_win_profile_update(sd);
1581      }
1582    if (ch_wm_rotation)
1583      {
1584         evas_object_size_hint_min_set(obj, -1, -1);
1585         evas_object_size_hint_max_set(obj, -1, -1);
1586 #ifdef HAVE_ELEMENTARY_X
1587         _elm_win_xwin_update(sd);
1588 #endif
1589         elm_widget_orientation_set(obj, sd->rot);
1590         eo_do(obj, eo_event_callback_call
1591           (ELM_WIN_EVENT_ROTATION_CHANGED, NULL));
1592         eo_do(obj, eo_event_callback_call
1593           (ELM_WIN_EVENT_WM_ROTATION_CHANGED, NULL));
1594      }
1595 #ifdef HAVE_ELEMENTARY_WAYLAND
1596    if (ch_conformant)
1597      {
1598         evas_object_smart_callback_call(obj, SIG_CONFORMANT_CHANGED, (void *)property); //TIZEN_ONLY(20160330): add processing properties of window
1599
1600      }
1601 #endif
1602    if (ch_aux_hint)
1603      {
1604         void *id;
1605         Eina_List *l;
1606         EINA_LIST_FOREACH(aux_hints, l, id)
1607           {
1608              evas_object_smart_callback_call(obj, SIG_AUX_HINT_ALLOWED, id);
1609           }
1610         eina_list_free(aux_hints);
1611      }
1612    if (ch_visibility)
1613      {
1614         evas_object_smart_callback_call(obj, SIG_VISIBILITY_CHANGED, (void*)!sd->obscured);
1615      }
1616 }
1617
1618 EOLIAN static Eina_Bool
1619 _elm_win_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Win_Data *_pd EINA_UNUSED)
1620 {
1621    return EINA_TRUE;
1622 }
1623
1624 EOLIAN static Eina_Bool
1625 _elm_win_elm_widget_focus_next(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
1626 {
1627    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1628
1629    const Eina_List *items;
1630    void *(*list_data_get)(const Eina_List *list);
1631
1632    /* Focus chain */
1633    if (wd->subobjs)
1634      {
1635         if (!(items = elm_widget_focus_custom_chain_get(obj)))
1636           {
1637              items = wd->subobjs;
1638              if (!items)
1639                return EINA_FALSE;
1640           }
1641         list_data_get = eina_list_data_get;
1642
1643         elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next, next_item);
1644
1645         if (*next) return EINA_TRUE;
1646      }
1647    *next = (Evas_Object *)obj;
1648    return EINA_FALSE;
1649 }
1650
1651 EOLIAN static Eina_Bool
1652 _elm_win_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Win_Data *_pd EINA_UNUSED)
1653 {
1654    return EINA_TRUE;
1655 }
1656
1657 EOLIAN static Eina_Bool
1658 _elm_win_elm_widget_focus_direction(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED, const Evas_Object *base, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
1659 {
1660    const Eina_List *items;
1661    void *(*list_data_get)(const Eina_List *list);
1662
1663    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1664
1665    /* Focus chain */
1666    if (wd->subobjs)
1667      {
1668         if (!(items = elm_widget_focus_custom_chain_get(obj)))
1669           items = wd->subobjs;
1670
1671         list_data_get = eina_list_data_get;
1672
1673         return elm_widget_focus_list_direction_get
1674                  (obj, base, items, list_data_get, degree, direction, direction_item, weight);
1675      }
1676
1677    return EINA_FALSE;
1678 }
1679
1680 EOLIAN static Eina_Bool
1681 _elm_win_elm_widget_on_focus(Eo *obj, Elm_Win_Data *sd, Elm_Object_Item *item EINA_UNUSED)
1682 {
1683    Eina_Bool int_ret = EINA_FALSE;
1684    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_on_focus(NULL));
1685    if (!int_ret) return EINA_TRUE;
1686
1687    if (sd->img_obj)
1688      evas_object_focus_set(sd->img_obj, elm_widget_focus_get(obj));
1689    else
1690      evas_object_focus_set(obj, elm_widget_focus_get(obj));
1691
1692    return EINA_TRUE;
1693 }
1694
1695 static Eina_Bool
1696 _key_action_return(Evas_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
1697 {
1698    return EINA_FALSE;
1699 }
1700
1701 static Eina_Bool
1702 _key_action_move(Evas_Object *obj, const char *params)
1703 {
1704    const char *dir = params;
1705
1706    _elm_widget_focus_auto_show(obj);
1707    if (!strcmp(dir, "previous"))
1708      elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS);
1709    else if (!strcmp(dir, "next"))
1710      elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
1711    else if (!strcmp(dir, "left"))
1712      elm_widget_focus_cycle(obj, ELM_FOCUS_LEFT);
1713    else if (!strcmp(dir, "right"))
1714      elm_widget_focus_cycle(obj, ELM_FOCUS_RIGHT);
1715    else if (!strcmp(dir, "up"))
1716      elm_widget_focus_cycle(obj, ELM_FOCUS_UP);
1717    else if (!strcmp(dir, "down"))
1718      elm_widget_focus_cycle(obj, ELM_FOCUS_DOWN);
1719    else return EINA_FALSE;
1720
1721    return EINA_TRUE;
1722 }
1723
1724 EOLIAN static Eina_Bool
1725 _elm_win_elm_widget_event(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
1726 {
1727    (void) src;
1728    Evas_Event_Key_Down *ev = event_info;
1729
1730    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
1731    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
1732
1733    if (!_elm_config_key_binding_call(obj, ev, key_actions))
1734      return EINA_FALSE;
1735
1736    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1737    return EINA_TRUE;
1738 }
1739
1740 static void
1741 _deferred_ecore_evas_free(void *data)
1742 {
1743    ecore_evas_free(data);
1744    _elm_win_deferred_free--;
1745 }
1746
1747 EOLIAN static void
1748 _elm_win_evas_object_smart_show(Eo *obj, Elm_Win_Data *sd)
1749 {
1750    if (sd->modal_count) return;
1751    const Eina_List *l;
1752    Evas_Object *current;
1753    Eina_Bool do_eval = EINA_FALSE;
1754
1755    if (!evas_object_visible_get(obj)) do_eval = EINA_TRUE;
1756    eo_do_super(obj, MY_CLASS, evas_obj_smart_show());
1757
1758    if ((sd->modal) && (!evas_object_visible_get(obj)))
1759      {
1760         INCREMENT_MODALITY()
1761      }
1762
1763    evas_smart_objects_calculate(evas_object_evas_get(obj));
1764
1765    TRAP(sd, show);
1766
1767    if (_elm_config->atspi_mode)
1768      {
1769         Eo *bridge = _elm_atspi_bridge_get();
1770         elm_interface_atspi_window_created_signal_emit(obj);
1771         if (bridge)
1772            elm_interface_atspi_accessible_children_changed_added_signal_emit(elm_atspi_bridge_root_get(bridge), obj);
1773      }
1774
1775    if (do_eval)
1776      {
1777         if (_elm_win_state_eval_timer)
1778           {
1779              ecore_timer_del(_elm_win_state_eval_timer);
1780              _elm_win_state_eval_timer = NULL;
1781           }
1782         _elm_win_state_eval(NULL);
1783      }
1784    if (sd->shot.info) _shot_handle(sd);
1785 }
1786
1787 EOLIAN static void
1788 _elm_win_evas_object_smart_hide(Eo *obj, Elm_Win_Data *sd)
1789 {
1790    if (sd->modal_count) return;
1791    const Eina_List *l;
1792    Evas_Object *current;
1793
1794    if (evas_object_visible_get(obj))
1795      _elm_win_state_eval_queue();
1796    eo_do_super(obj, MY_CLASS, evas_obj_smart_hide());
1797
1798    if ((sd->modal) && (evas_object_visible_get(obj)))
1799      {
1800         DECREMENT_MODALITY()
1801      }
1802
1803    TRAP(sd, hide);
1804
1805    if (sd->frame_obj)
1806      {
1807         evas_object_hide(sd->frame_obj);
1808      }
1809    if (sd->img_obj)
1810      {
1811         evas_object_hide(sd->img_obj);
1812      }
1813    if (sd->pointer.obj)
1814      {
1815         evas_object_hide(sd->pointer.obj);
1816 #if 0
1817         ecore_evas_hide(sd->pointer.ee);
1818 #endif
1819      }
1820    if (_elm_config->atspi_mode)
1821      {
1822         Eo *bridge = _elm_atspi_bridge_get();
1823         elm_interface_atspi_window_destroyed_signal_emit(obj);
1824         if (bridge)
1825            elm_interface_atspi_accessible_children_changed_del_signal_emit(elm_atspi_bridge_root_get(bridge), obj);
1826      }
1827
1828    if (_elm_win_policy_quit_triggered(obj))
1829      _elm_win_flush_cache_and_exit(obj);
1830 }
1831
1832 static void
1833 _elm_win_accessibility_highlight_obj_del(void *data,
1834                            Evas *e EINA_UNUSED,
1835                            Evas_Object *obj EINA_UNUSED,
1836                            void *event_info EINA_UNUSED)
1837 {
1838    ELM_WIN_DATA_GET(data, sd);
1839
1840    _elm_win_accessibility_highlight_hide(sd->obj);
1841 }
1842
1843 static void
1844 _elm_win_accessibility_highlight_obj_move(void *data,
1845                            Evas *e EINA_UNUSED,
1846                            Evas_Object *obj EINA_UNUSED,
1847                            void *event_info EINA_UNUSED)
1848 {
1849    ELM_WIN_DATA_GET(data, sd);
1850
1851    _elm_win_accessibility_highlight_show(sd->obj);
1852 }
1853
1854 static void
1855 _elm_win_accessibility_highlight_obj_resize(void *data,
1856                              Evas *e EINA_UNUSED,
1857                              Evas_Object *obj EINA_UNUSED,
1858                              void *event_info EINA_UNUSED)
1859 {
1860    ELM_WIN_DATA_GET(data, sd);
1861    _elm_win_accessibility_highlight_show(sd->obj);
1862
1863 }
1864
1865 static void
1866 _elm_win_on_parent_del(void *data,
1867                        Evas *e EINA_UNUSED,
1868                        Evas_Object *obj,
1869                        void *event_info EINA_UNUSED)
1870 {
1871    ELM_WIN_DATA_GET(data, sd);
1872
1873    if (obj == sd->parent) sd->parent = NULL;
1874 }
1875
1876 static void
1877 _elm_win_focus_target_move(void *data,
1878                            Evas *e EINA_UNUSED,
1879                            Evas_Object *obj EINA_UNUSED,
1880                            void *event_info EINA_UNUSED)
1881 {
1882    ELM_WIN_DATA_GET(data, sd);
1883
1884    sd->focus_highlight.geometry_changed = EINA_TRUE;
1885    _elm_win_focus_highlight_reconfigure_job_start(sd);
1886 }
1887
1888 static void
1889 _elm_win_focus_target_resize(void *data,
1890                              Evas *e EINA_UNUSED,
1891                              Evas_Object *obj EINA_UNUSED,
1892                              void *event_info EINA_UNUSED)
1893 {
1894    ELM_WIN_DATA_GET(data, sd);
1895
1896    sd->focus_highlight.geometry_changed = EINA_TRUE;
1897    _elm_win_focus_highlight_reconfigure_job_start(sd);
1898 }
1899
1900 static void
1901 _elm_win_focus_target_del(void *data,
1902                           Evas *e EINA_UNUSED,
1903                           Evas_Object *obj EINA_UNUSED,
1904                           void *event_info EINA_UNUSED)
1905 {
1906    ELM_WIN_DATA_GET(data, sd);
1907
1908    sd->focus_highlight.cur.target = NULL;
1909
1910    _elm_win_focus_highlight_reconfigure_job_start(sd);
1911 }
1912
1913 static Evas_Object *
1914 _elm_win_focus_target_get(Evas_Object *obj)
1915 {
1916    Evas_Object *o = obj;
1917
1918    do
1919      {
1920         if (elm_widget_is(o))
1921           {
1922              if (!elm_widget_highlight_ignore_get(o))
1923                break;
1924              o = elm_widget_parent_get(o);
1925              if (!o)
1926                o = evas_object_smart_parent_get(o);
1927           }
1928         else
1929           {
1930              o = elm_widget_parent_widget_get(o);
1931              if (!o)
1932                o = evas_object_smart_parent_get(o);
1933           }
1934      }
1935    while (o);
1936
1937    return o;
1938 }
1939
1940 static void
1941 _elm_win_focus_target_callbacks_add(Elm_Win_Data *sd)
1942 {
1943    Evas_Object *obj = sd->focus_highlight.cur.target;
1944    if (!obj) return;
1945
1946    evas_object_event_callback_add
1947      (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd->obj);
1948    evas_object_event_callback_add
1949      (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd->obj);
1950 }
1951
1952 static void
1953 _elm_win_focus_target_callbacks_del(Elm_Win_Data *sd)
1954 {
1955    Evas_Object *obj = sd->focus_highlight.cur.target;
1956
1957    evas_object_event_callback_del_full
1958      (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd->obj);
1959    evas_object_event_callback_del_full
1960      (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd->obj);
1961 }
1962
1963 static void
1964 _elm_win_accessibility_highlight_callbacks_add(Elm_Win_Data *sd)
1965 {
1966    Evas_Object *obj = sd->accessibility_highlight.cur.target;
1967    if (!obj) return;
1968    evas_object_event_callback_add
1969      (obj, EVAS_CALLBACK_DEL, _elm_win_accessibility_highlight_obj_del, sd->obj);
1970    evas_object_event_callback_add
1971      (obj, EVAS_CALLBACK_MOVE, _elm_win_accessibility_highlight_obj_move, sd->obj);
1972    evas_object_event_callback_add
1973      (obj, EVAS_CALLBACK_RESIZE, _elm_win_accessibility_highlight_obj_resize, sd->obj);
1974 }
1975
1976 static void
1977 _elm_win_accessibility_highlight_callbacks_del(Elm_Win_Data *sd)
1978 {
1979    Evas_Object *obj = sd->accessibility_highlight.cur.target;
1980    evas_object_event_callback_del_full
1981      (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd->obj);
1982    evas_object_event_callback_del_full
1983      (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd->obj);
1984    evas_object_event_callback_del_full
1985      (obj, EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
1986 }
1987
1988 static void
1989 _elm_win_object_accessibility_highlight_in(void *data,
1990                                    Evas *e EINA_UNUSED,
1991                                    void *event_info)
1992 {
1993    Evas_Object *obj = event_info, *target;
1994    ELM_WIN_DATA_GET(data, sd);
1995
1996    if (sd->accessibility_highlight.cur.target == obj)
1997      return;
1998
1999    target = _elm_win_focus_target_get(obj);
2000
2001    sd->accessibility_highlight.cur.target = target;
2002    _elm_win_accessibility_highlight_callbacks_add(sd);
2003
2004 }
2005
2006 static void
2007 _elm_win_object_accessibility_highlight_out(void *data,
2008                                     Evas *e EINA_UNUSED,
2009                                     void *event_info EINA_UNUSED)
2010 {
2011    ELM_WIN_DATA_GET(data, sd);
2012
2013    if (!sd->accessibility_highlight.cur.target)
2014      return;
2015    _elm_win_accessibility_highlight_callbacks_del(sd);
2016 }
2017
2018 static void
2019 _elm_win_object_focus_in(void *data,
2020                          Evas *e EINA_UNUSED,
2021                          void *event_info)
2022 {
2023    Evas_Object *obj = event_info, *target;
2024    ELM_WIN_DATA_GET(data, sd);
2025
2026    if (sd->focus_highlight.cur.target == obj)
2027      return;
2028
2029    target = _elm_win_focus_target_get(obj);
2030    sd->focus_highlight.cur.target = target;
2031    if (target && elm_widget_highlight_in_theme_get(target))
2032      sd->focus_highlight.cur.in_theme = EINA_TRUE;
2033    else
2034      _elm_win_focus_target_callbacks_add(sd);
2035
2036    evas_object_event_callback_add
2037      (target, EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
2038
2039    _elm_win_focus_highlight_reconfigure_job_start(sd);
2040 }
2041
2042 static void
2043 _elm_win_object_focus_out(void *data,
2044                           Evas *e EINA_UNUSED,
2045                           void *event_info EINA_UNUSED)
2046 {
2047    ELM_WIN_DATA_GET(data, sd);
2048
2049    if (!sd->focus_highlight.cur.target)
2050      return;
2051
2052    if (!sd->focus_highlight.cur.in_theme)
2053      _elm_win_focus_target_callbacks_del(sd);
2054
2055    evas_object_event_callback_del_full
2056       (sd->focus_highlight.cur.target,
2057        EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
2058
2059    sd->focus_highlight.cur.target = NULL;
2060    sd->focus_highlight.cur.in_theme = EINA_FALSE;
2061
2062    _elm_win_focus_highlight_reconfigure_job_start(sd);
2063 }
2064
2065 static void
2066 _elm_win_focus_highlight_shutdown(Elm_Win_Data *sd)
2067 {
2068    _elm_win_focus_highlight_reconfigure_job_stop(sd);
2069    if (sd->focus_highlight.cur.target)
2070      {
2071         elm_widget_signal_emit(sd->focus_highlight.cur.target,
2072                                "elm,action,focus_highlight,hide", "elm");
2073         _elm_win_focus_target_callbacks_del(sd);
2074         evas_object_event_callback_del_full
2075            (sd->focus_highlight.cur.target,
2076             EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
2077         sd->focus_highlight.cur.target = NULL;
2078      }
2079    ELM_SAFE_FREE(sd->focus_highlight.fobj, evas_object_del);
2080
2081    evas_event_callback_del_full
2082      (sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
2083      _elm_win_object_focus_in, sd->obj);
2084    evas_event_callback_del_full
2085      (sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
2086      _elm_win_object_focus_out, sd->obj);
2087 }
2088
2089 static void
2090 _win_img_hide(void *data,
2091               Evas *e EINA_UNUSED,
2092               Evas_Object *obj EINA_UNUSED,
2093               void *event_info EINA_UNUSED)
2094 {
2095    elm_widget_focus_hide_handle(data);
2096 }
2097
2098 static void
2099 _win_img_mouse_up(void *data,
2100                   Evas *e EINA_UNUSED,
2101                   Evas_Object *obj EINA_UNUSED,
2102                   void *event_info)
2103 {
2104    Evas_Event_Mouse_Up *ev = event_info;
2105    if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
2106      elm_widget_focus_mouse_up_handle(data);
2107 }
2108
2109 static void
2110 _win_img_focus_in(void *data,
2111                   Evas *e EINA_UNUSED,
2112                   Evas_Object *obj EINA_UNUSED,
2113                   void *event_info EINA_UNUSED)
2114 {
2115    elm_widget_focus_steal(data, NULL);
2116 }
2117
2118 static void
2119 _win_img_focus_out(void *data,
2120                    Evas *e EINA_UNUSED,
2121                    Evas_Object *obj EINA_UNUSED,
2122                    void *event_info EINA_UNUSED)
2123 {
2124    elm_widget_focused_object_clear(data);
2125 }
2126
2127 static void
2128 _elm_win_on_img_obj_del(void *data,
2129                         Evas *e EINA_UNUSED,
2130                         Evas_Object *obj EINA_UNUSED,
2131                         void *event_info EINA_UNUSED)
2132 {
2133    ELM_WIN_DATA_GET(data, sd);
2134    _elm_win_img_callbacks_del(sd->obj, sd->img_obj);
2135    sd->img_obj = NULL;
2136 }
2137
2138 static void
2139 _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj)
2140 {
2141    evas_object_event_callback_del_full
2142      (imgobj, EVAS_CALLBACK_DEL, _elm_win_on_img_obj_del, obj);
2143    evas_object_event_callback_del_full
2144      (imgobj, EVAS_CALLBACK_HIDE, _win_img_hide, obj);
2145    evas_object_event_callback_del_full
2146      (imgobj, EVAS_CALLBACK_MOUSE_UP, _win_img_mouse_up, obj);
2147    evas_object_event_callback_del_full
2148      (imgobj, EVAS_CALLBACK_FOCUS_IN, _win_img_focus_in, obj);
2149    evas_object_event_callback_del_full
2150      (imgobj, EVAS_CALLBACK_FOCUS_OUT, _win_img_focus_out, obj);
2151 }
2152
2153 EOLIAN static void
2154 _elm_win_evas_object_smart_del(Eo *obj, Elm_Win_Data *sd)
2155 {
2156    const Eina_List *l;
2157    Evas_Object *current;
2158
2159    if ((sd->modal) && (evas_object_visible_get(obj)))
2160      {
2161        DECREMENT_MODALITY()
2162      }
2163
2164    if ((sd->modal) && (sd->modal_count > 0))
2165      ERR("Deleted modal win was blocked by another modal win which was created after creation of that win.");
2166
2167    evas_object_event_callback_del_full(sd->edje,
2168                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2169                                        _elm_win_on_resize_obj_changed_size_hints,
2170                                        obj);
2171    evas_object_del(sd->box);
2172    evas_object_del(sd->edje);
2173
2174    /* NB: child deletion handled by parent's smart del */
2175
2176    if ((sd->type != ELM_WIN_FAKE) && (trap) && (trap->del))
2177      trap->del(sd->trap_data, obj);
2178
2179    if (sd->parent)
2180      {
2181         evas_object_event_callback_del_full
2182           (sd->parent, EVAS_CALLBACK_DEL, _elm_win_on_parent_del, obj);
2183         sd->parent = NULL;
2184      }
2185
2186    if (sd->autodel_clear) *(sd->autodel_clear) = -1;
2187
2188    if (_elm_config->atspi_mode)
2189      elm_interface_atspi_window_destroyed_signal_emit(obj);
2190
2191    _elm_win_list = eina_list_remove(_elm_win_list, obj);
2192    _elm_win_count--;
2193    _elm_win_state_eval_queue();
2194
2195    if (sd->ee)
2196      {
2197         ecore_evas_callback_delete_request_set(sd->ee, NULL);
2198         ecore_evas_callback_resize_set(sd->ee, NULL);
2199      }
2200
2201    ecore_job_del(sd->deferred_resize_job);
2202    ecore_job_del(sd->deferred_child_eval_job);
2203    eina_stringshare_del(sd->shot.info);
2204    ecore_timer_del(sd->shot.timer);
2205
2206 #ifdef HAVE_ELEMENTARY_X
2207    ecore_event_handler_del(sd->x.client_message_handler);
2208    ecore_event_handler_del(sd->x.property_handler);
2209 #endif
2210 #ifdef HAVE_ELEMENTARY_WAYLAND
2211    ecore_event_handler_del(sd->wl.effect_start_handler);
2212    ecore_event_handler_del(sd->wl.effect_end_handler);
2213 #endif
2214
2215    if (sd->img_obj)
2216      {
2217         _elm_win_img_callbacks_del(obj, sd->img_obj);
2218         sd->img_obj = NULL;
2219      }
2220    else
2221      {
2222         if (sd->ee && (sd->type != ELM_WIN_FAKE))
2223           {
2224              ecore_job_add(_deferred_ecore_evas_free, sd->ee);
2225              _elm_win_deferred_free++;
2226           }
2227      }
2228
2229    _elm_win_focus_highlight_shutdown(sd);
2230    eina_stringshare_del(sd->focus_highlight.style);
2231
2232    eina_stringshare_del(sd->title);
2233    eina_stringshare_del(sd->icon_name);
2234    eina_stringshare_del(sd->role);
2235    eina_stringshare_del(sd->frame_style);
2236    eina_stringshare_del(sd->name);
2237    evas_object_del(sd->icon);
2238    evas_object_del(sd->main_menu);
2239
2240    _elm_win_profile_del(sd);
2241    _elm_win_available_profiles_del(sd);
2242
2243    free(sd->wm_rot.rots);
2244
2245    /* Don't let callback in the air that point to sd */
2246    ecore_evas_callback_delete_request_set(sd->ee, NULL);
2247    ecore_evas_callback_resize_set(sd->ee, NULL);
2248    ecore_evas_callback_mouse_in_set(sd->ee, NULL);
2249    ecore_evas_callback_focus_in_set(sd->ee, NULL);
2250    ecore_evas_callback_focus_out_set(sd->ee, NULL);
2251    ecore_evas_callback_move_set(sd->ee, NULL);
2252    ecore_evas_callback_state_change_set(sd->ee, NULL);
2253
2254    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
2255
2256    if (_elm_win_policy_quit_triggered(obj))
2257      {
2258         _elm_win_flush_cache_and_exit(obj);
2259      }
2260 }
2261
2262 static void
2263 _elm_win_obj_intercept_show(void *data,
2264                             Evas_Object *obj)
2265 {
2266    ELM_WIN_DATA_GET(data, sd);
2267
2268    // this is called to make sure all smart containers have calculated their
2269    // sizes BEFORE we show the window to make sure it initially appears at
2270    // our desired size (ie min size is known first)
2271    evas_smart_objects_calculate(evas_object_evas_get(obj));
2272    if (sd->frame_obj)
2273      {
2274         evas_object_show(sd->frame_obj);
2275      }
2276    if (sd->img_obj)
2277      {
2278         evas_object_show(sd->img_obj);
2279      }
2280    if (sd->pointer.obj)
2281      {
2282 #if 0
2283         ecore_evas_show(sd->pointer.ee);
2284 #endif
2285         evas_object_show(sd->pointer.obj);
2286      }
2287    evas_object_show(obj);
2288 #ifdef HAVE_ELEMENTARY_WAYLAND
2289    int x, y, w, h;
2290
2291    evas_object_geometry_get(obj, &x, &y, &w, &h);
2292    ecore_wl_window_opaque_region_set(sd->wl.win, x, y, w, h);
2293 #endif
2294 #ifdef ELEMENTARY_X
2295    if (sd->type == ELM_WIN_TOOLTIP)
2296      ecore_x_window_shape_input_rectangle_set(sd->x.xwin, 0, 0, 0, 0);
2297 #endif
2298 }
2299
2300 EOLIAN static void
2301 _elm_win_evas_object_smart_move(Eo *obj, Elm_Win_Data *sd, Evas_Coord x, Evas_Coord y)
2302 {
2303    if (sd->img_obj)
2304      {
2305         if ((x != sd->screen.x) || (y != sd->screen.y))
2306           {
2307              sd->screen.x = x;
2308              sd->screen.y = y;
2309              eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_MOVED, NULL));
2310           }
2311         return;
2312      }
2313    else
2314      {
2315         TRAP(sd, move, x, y);
2316         if (!ecore_evas_override_get(sd->ee))  return;
2317      }
2318
2319    eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
2320
2321    if (ecore_evas_override_get(sd->ee))
2322      {
2323         sd->screen.x = x;
2324         sd->screen.y = y;
2325         eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_MOVED, NULL));
2326      }
2327    if (sd->frame_obj)
2328      {
2329 #ifdef HAVE_ELEMENTARY_WAYLAND
2330         ecore_wl_window_update_location(sd->wl.win, x, y);
2331 #endif
2332         sd->screen.x = x;
2333         sd->screen.y = y;
2334      }
2335    if (sd->img_obj)
2336      {
2337         sd->screen.x = x;
2338         sd->screen.y = y;
2339      }
2340 }
2341
2342 EOLIAN static void
2343 _elm_win_evas_object_smart_resize(Eo *obj, Elm_Win_Data *sd, Evas_Coord w, Evas_Coord h)
2344 {
2345    eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
2346
2347    if (sd->img_obj)
2348      {
2349         if (sd->constrain)
2350           {
2351              int sw, sh;
2352
2353              ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sw, &sh);
2354              w = MIN(w, sw);
2355              h = MIN(h, sh);
2356           }
2357         if (w < 1) w = 1;
2358         if (h < 1) h = 1;
2359
2360         evas_object_image_size_set(sd->img_obj, w, h);
2361      }
2362
2363    TRAP(sd, resize, w, h);
2364 }
2365
2366 static void
2367 _elm_win_delete_request(Ecore_Evas *ee)
2368 {
2369    Elm_Win_Data *sd = _elm_win_associate_get(ee);
2370    Evas_Object *obj;
2371
2372    if (!sd) return;
2373
2374    obj = sd->obj;
2375
2376    int autodel = sd->autodel;
2377    sd->autodel_clear = &autodel;
2378    evas_object_ref(obj);
2379    eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_DELETE_REQUEST, NULL));
2380    if (sd->autohide)
2381      evas_object_hide(obj);
2382    // FIXME: if above callback deletes - then the below will be invalid
2383    if (_elm_config->atspi_mode)
2384      elm_interface_atspi_window_destroyed_signal_emit(obj);
2385    if (autodel) evas_object_del(obj);
2386    else sd->autodel_clear = NULL;
2387    evas_object_unref(obj);
2388 }
2389
2390 Ecore_X_Window
2391 _elm_ee_xwin_get(const Ecore_Evas *ee)
2392 {
2393 #ifdef HAVE_ELEMENTARY_X
2394    const char *engine_name;
2395    if (!ee) return 0;
2396
2397    engine_name = ecore_evas_engine_name_get(ee);
2398    if (EINA_UNLIKELY(!engine_name)) return 0;
2399
2400    if (!strcmp(engine_name, ELM_SOFTWARE_X11))
2401      {
2402         return ecore_evas_software_x11_window_get(ee);
2403      }
2404    else if (!strcmp(engine_name, ELM_OPENGL_X11))
2405      {
2406         return ecore_evas_gl_x11_window_get(ee);
2407      }
2408 #else
2409    (void)ee;
2410 #endif
2411    return 0;
2412 }
2413
2414 #ifdef HAVE_ELEMENTARY_X
2415 static void
2416 _internal_elm_win_xwindow_get(Elm_Win_Data *sd)
2417 {
2418    sd->x.xwin = _elm_ee_xwin_get(sd->ee);
2419 }
2420 #endif
2421
2422 Ecore_Wl_Window *
2423 _elm_ee_wlwin_get(const Ecore_Evas *ee)
2424 {
2425 #ifdef HAVE_ELEMENTARY_WAYLAND
2426    const char *engine_name;
2427
2428    if (!ee) return NULL;
2429
2430    engine_name = ecore_evas_engine_name_get(ee);
2431    if (EINA_UNLIKELY(!engine_name)) return NULL;
2432
2433    if ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
2434        (!strcmp(engine_name, ELM_WAYLAND_EGL)))
2435      {
2436         return ecore_evas_wayland_window_get(ee);
2437      }
2438 #else
2439    (void)ee;
2440 #endif
2441    return NULL;
2442 }
2443
2444 #ifdef HAVE_ELEMENTARY_WAYLAND
2445 static void
2446 _elm_win_wlwindow_get(Elm_Win_Data *sd)
2447 {
2448    sd->wl.win = _elm_ee_wlwin_get(sd->ee);
2449 }
2450
2451 static Eina_Bool
2452 _elm_win_wl_effect_start(void *data, int type EINA_UNUSED, void *event)
2453 {
2454    ELM_WIN_DATA_GET(data, sd);
2455    Ecore_Wl_Event_Effect_Start *e = event;
2456
2457    if (!sd->wl.win) return ECORE_CALLBACK_PASS_ON;
2458
2459    if ((ecore_wl_window_id_get(sd->wl.win) != e->win))
2460      return ECORE_CALLBACK_PASS_ON;
2461
2462    evas_object_smart_callback_call(data, SIG_EFFECT_STARTED, (void*)e->type);
2463
2464    return ECORE_CALLBACK_PASS_ON;
2465 }
2466
2467 static Eina_Bool
2468 _elm_win_wl_effect_end(void *data, int type EINA_UNUSED, void *event)
2469 {
2470    ELM_WIN_DATA_GET(data, sd);
2471    Ecore_Wl_Event_Effect_End *e = event;
2472
2473    if (!sd->wl.win) return ECORE_CALLBACK_PASS_ON;
2474
2475    if ((ecore_wl_window_id_get(sd->wl.win) != e->win))
2476      return ECORE_CALLBACK_PASS_ON;
2477
2478    evas_object_smart_callback_call(data, SIG_EFFECT_DONE, (void*)e->type);
2479
2480    return ECORE_CALLBACK_PASS_ON;
2481 }
2482
2483 #endif
2484
2485 #ifdef HAVE_ELEMENTARY_X
2486 static void
2487 _elm_win_xwin_update(Elm_Win_Data *sd)
2488 {
2489    const char *s;
2490
2491    if (sd->type == ELM_WIN_FAKE) return;
2492    _internal_elm_win_xwindow_get(sd);
2493    if (sd->parent)
2494      {
2495         ELM_WIN_DATA_GET(sd->parent, sdp);
2496         if (sdp)
2497           {
2498              if (sd->x.xwin)
2499                ecore_x_icccm_transient_for_set(sd->x.xwin, sdp->x.xwin);
2500           }
2501      }
2502
2503    if (!sd->x.xwin) return;  /* nothing more to do */
2504
2505    s = sd->title;
2506    if (!s) s = _elm_appname;
2507    if (!s) s = "";
2508    if (sd->icon_name) s = sd->icon_name;
2509    ecore_x_icccm_icon_name_set(sd->x.xwin, s);
2510    ecore_x_netwm_icon_name_set(sd->x.xwin, s);
2511
2512    s = sd->role;
2513    if (s) ecore_x_icccm_window_role_set(sd->x.xwin, s);
2514
2515    // set window icon
2516    if (sd->icon)
2517      {
2518         void *data;
2519
2520         data = evas_object_image_data_get(sd->icon, EINA_FALSE);
2521         if (data)
2522           {
2523              Ecore_X_Icon ic;
2524              int w = 0, h = 0, stride, x, y;
2525              unsigned char *p;
2526              unsigned int *p2;
2527
2528              evas_object_image_size_get(sd->icon, &w, &h);
2529              stride = evas_object_image_stride_get(sd->icon);
2530              if ((w > 0) && (h > 0) &&
2531                  (stride >= (int)(w * sizeof(unsigned int))))
2532                {
2533                   ic.width = w;
2534                   ic.height = h;
2535                   ic.data = malloc(w * h * sizeof(unsigned int));
2536
2537                   if (ic.data)
2538                     {
2539                        p = (unsigned char *)data;
2540                        p2 = (unsigned int *)ic.data;
2541                        for (y = 0; y < h; y++)
2542                          {
2543                             for (x = 0; x < w; x++)
2544                               {
2545                                  *p2 = *((unsigned int *)p);
2546                                  p += sizeof(unsigned int);
2547                                  p2++;
2548                               }
2549                             p += (stride - (w * sizeof(unsigned int)));
2550                          }
2551                        ecore_x_netwm_icons_set(sd->x.xwin, &ic, 1);
2552                        free(ic.data);
2553                     }
2554                }
2555              evas_object_image_data_set(sd->icon, data);
2556           }
2557      }
2558
2559    switch (sd->type)
2560      {
2561       case ELM_WIN_BASIC:
2562         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_NORMAL);
2563         break;
2564
2565       case ELM_WIN_DIALOG_BASIC:
2566         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DIALOG);
2567         break;
2568
2569       case ELM_WIN_DESKTOP:
2570         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DESKTOP);
2571         break;
2572
2573       case ELM_WIN_DOCK:
2574         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DOCK);
2575         break;
2576
2577       case ELM_WIN_TOOLBAR:
2578         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_TOOLBAR);
2579         break;
2580
2581       case ELM_WIN_MENU:
2582         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_MENU);
2583         break;
2584
2585       case ELM_WIN_UTILITY:
2586         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_UTILITY);
2587         break;
2588
2589       case ELM_WIN_SPLASH:
2590         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_SPLASH);
2591         break;
2592
2593       case ELM_WIN_DROPDOWN_MENU:
2594         ecore_x_netwm_window_type_set
2595           (sd->x.xwin, ECORE_X_WINDOW_TYPE_DROPDOWN_MENU);
2596         break;
2597
2598       case ELM_WIN_POPUP_MENU:
2599         ecore_x_netwm_window_type_set
2600           (sd->x.xwin, ECORE_X_WINDOW_TYPE_POPUP_MENU);
2601         break;
2602
2603       case ELM_WIN_TOOLTIP:
2604         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_TOOLTIP);
2605         ecore_x_window_shape_input_rectangle_set(sd->x.xwin, 0, 0, 0, 0);
2606         break;
2607
2608       case ELM_WIN_NOTIFICATION:
2609         ecore_x_netwm_window_type_set
2610           (sd->x.xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
2611         break;
2612
2613       case ELM_WIN_COMBO:
2614         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_COMBO);
2615         break;
2616
2617       case ELM_WIN_DND:
2618         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DND);
2619         break;
2620
2621       default:
2622         break;
2623      }
2624    ecore_x_e_virtual_keyboard_state_set
2625      (sd->x.xwin, (Ecore_X_Virtual_Keyboard_State)sd->kbdmode);
2626    if (sd->indmode == ELM_WIN_INDICATOR_SHOW)
2627      ecore_x_e_illume_indicator_state_set
2628        (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON);
2629    else if (sd->indmode == ELM_WIN_INDICATOR_HIDE)
2630      ecore_x_e_illume_indicator_state_set
2631        (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
2632
2633    if ((sd->wm_rot.count) && (sd->wm_rot.rots))
2634      ecore_evas_wm_rotation_available_rotations_set(sd->ee,
2635                                                     sd->wm_rot.rots,
2636                                                     sd->wm_rot.count);
2637    if (sd->wm_rot.preferred_rot != -1)
2638      ecore_evas_wm_rotation_preferred_rotation_set(sd->ee,
2639                                                    sd->wm_rot.preferred_rot);
2640 }
2641
2642 #endif
2643
2644 #ifdef HAVE_ELEMENTARY_WAYLAND
2645 static void
2646 _elm_win_wlwin_update(Elm_Win_Data *sd)
2647 {
2648    switch (sd->type)
2649      {
2650         case ELM_WIN_NOTIFICATION:
2651           ecore_evas_wayland_type_set(sd->ee, ECORE_WL_WINDOW_TYPE_NOTIFICATION);
2652           break;
2653         default:
2654           break;
2655      }
2656 }
2657
2658 #endif
2659
2660 /**
2661   * @internal
2662   *
2663   * Resize the window according to window layout's min and weight.
2664   * If the window layout's weight is 0.0, the window max is limited to layout's
2665   * min size.
2666   *
2667   * This is called when the window layout's weight hint is changed or when the
2668   * window is rotated.
2669   *
2670   * @param obj window object
2671   */
2672 static void
2673 _elm_win_resize_objects_eval(Evas_Object *obj)
2674 {
2675    ELM_WIN_DATA_GET(obj, sd);
2676    Evas_Coord w, h, minw, minh, maxw, maxh;
2677    double wx, wy;
2678
2679    evas_object_size_hint_min_get(sd->edje, &minw, &minh);
2680    if (minw < 1) minw = 1;
2681    if (minh < 1) minh = 1;
2682
2683    evas_object_size_hint_weight_get(sd->edje, &wx, &wy);
2684    if (!wx) maxw = minw;
2685    else maxw = 32767;
2686    if (!wy) maxh = minh;
2687    else maxh = 32767;
2688
2689    evas_object_size_hint_min_set(obj, minw, minh);
2690    evas_object_size_hint_max_set(obj, maxw, maxh);
2691
2692    /* if there are deferred resize job, do the job immediately */
2693    if (sd->deferred_resize_job)
2694      {
2695         ecore_job_del(sd->deferred_resize_job);
2696         sd->deferred_resize_job = NULL;
2697         _elm_win_resize_job(obj);
2698      }
2699
2700    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
2701    if (w < minw) w = minw;
2702    if (h < minh) h = minh;
2703    if (w > maxw) w = maxw;
2704    if (h > maxh) h = maxh;
2705    evas_object_resize(obj, w, h);
2706 }
2707
2708 static void
2709 _elm_win_on_resize_obj_changed_size_hints(void *data,
2710                                           Evas *e EINA_UNUSED,
2711                                           Evas_Object *obj EINA_UNUSED,
2712                                           void *event_info EINA_UNUSED)
2713 {
2714    _elm_win_resize_objects_eval(data);
2715 }
2716
2717 void
2718 _elm_win_shutdown(void)
2719 {
2720    while (_elm_win_list)
2721      {
2722         Eina_List *itr = _elm_win_list;
2723         evas_object_del(itr->data);
2724         if (_elm_win_list == itr)
2725           {
2726              _elm_win_list = eina_list_remove_list(_elm_win_list, _elm_win_list);
2727           }
2728      }
2729    ELM_SAFE_FREE(_elm_win_state_eval_timer, ecore_timer_del);
2730 }
2731
2732 void
2733 _elm_win_rescale(Elm_Theme *th,
2734                  Eina_Bool use_theme)
2735 {
2736    const Eina_List *l;
2737    Evas_Object *obj;
2738
2739    if (!use_theme)
2740      {
2741         EINA_LIST_FOREACH(_elm_win_list, l, obj)
2742           elm_widget_theme(obj);
2743      }
2744    else
2745      {
2746         EINA_LIST_FOREACH(_elm_win_list, l, obj)
2747           elm_widget_theme_specific(obj, th, EINA_FALSE);
2748      }
2749 }
2750
2751 void
2752 _elm_win_access(Eina_Bool is_access)
2753 {
2754    Evas *evas;
2755    const Eina_List *l;
2756    Evas_Object *obj;
2757    Evas_Object *fobj;
2758
2759    EINA_LIST_FOREACH(_elm_win_list, l, obj)
2760      {
2761         elm_widget_access(obj, is_access);
2762
2763          /* floating orphan object. if there are A, B, C objects and user does
2764             as below, then there would be floating orphan objects.
2765
2766               1. elm_object_content_set(layout, A);
2767               2. elm_object_content_set(layout, B);
2768               3. elm_object_content_set(layout, C);
2769
2770             now, the object A and B are floating orphan objects */
2771
2772         fobj = obj;
2773         for (;;)
2774           {
2775              fobj = evas_object_below_get(fobj);
2776              if (!fobj) break;
2777
2778              if (elm_widget_is(fobj) && !elm_widget_parent_get(fobj))
2779                {
2780                   elm_widget_access(fobj, is_access);
2781                }
2782           }
2783
2784         if (!is_access)
2785           {
2786              evas = evas_object_evas_get(obj);
2787             if (evas) _elm_access_object_highlight_disable(evas);
2788           }
2789      }
2790 }
2791
2792 void
2793 _elm_win_translate(void)
2794 {
2795    const Eina_List *l;
2796    Evas_Object *obj;
2797
2798    EINA_LIST_FOREACH(_elm_win_list, l, obj)
2799      elm_widget_translate(obj);
2800 }
2801
2802 void
2803 _elm_win_focus_reconfigure(void)
2804 {
2805    const Eina_List *l;
2806    Evas_Object *obj;
2807
2808    EINA_LIST_FOREACH(_elm_win_list, l, obj)
2809      elm_widget_focus_reconfigure(obj);
2810 }
2811
2812 #ifdef HAVE_ELEMENTARY_X
2813 static Eina_Bool
2814 _elm_win_client_message(void *data,
2815                         int type EINA_UNUSED,
2816                         void *event)
2817 {
2818    ELM_WIN_DATA_GET(data, sd);
2819    Ecore_X_Event_Client_Message *e = event;
2820
2821    if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
2822    if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH)
2823      {
2824         if ((unsigned int)e->data.l[0] == sd->x.xwin)
2825           {
2826              Evas *evas = evas_object_evas_get(sd->obj);
2827              if (evas)
2828                {
2829                   edje_file_cache_flush();
2830                   edje_collection_cache_flush();
2831                   evas_image_cache_flush(evas);
2832                   evas_font_cache_flush(evas);
2833                }
2834           }
2835      }
2836    else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP)
2837      {
2838         if ((unsigned int)e->data.l[0] == sd->x.xwin)
2839           {
2840              Evas *evas = evas_object_evas_get(sd->obj);
2841              if (evas)
2842                {
2843                   edje_file_cache_flush();
2844                   edje_collection_cache_flush();
2845                   evas_image_cache_flush(evas);
2846                   evas_font_cache_flush(evas);
2847                   evas_render_dump(evas);
2848                }
2849           }
2850      }
2851    else if (e->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL)
2852      {
2853         if ((unsigned int)e->data.l[0] == sd->x.xwin)
2854           {
2855              if ((unsigned int)e->data.l[1] ==
2856                  ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT)
2857                {
2858                   // XXX: call right access func
2859                }
2860              else if ((unsigned int)e->data.l[1] ==
2861                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV)
2862                {
2863                   // XXX: call right access func
2864                }
2865              else if ((unsigned int)e->data.l[1] ==
2866                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE)
2867                {
2868                   _elm_access_highlight_object_activate
2869                     (sd->obj, ELM_ACTIVATE_DEFAULT);
2870                }
2871              else if ((unsigned int)e->data.l[1] ==
2872                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ)
2873                {
2874                   /* there would be better way to read highlight object */
2875                   Evas *evas;
2876                   evas = evas_object_evas_get(sd->obj);
2877                   if (!evas) return ECORE_CALLBACK_PASS_ON;
2878
2879                   _elm_access_mouse_event_enabled_set(EINA_TRUE);
2880
2881                   evas_event_feed_mouse_in(evas, 0, NULL);
2882                   evas_event_feed_mouse_move
2883                     (evas, e->data.l[2], e->data.l[3], 0, NULL);
2884
2885                   _elm_access_mouse_event_enabled_set(EINA_FALSE);
2886                }
2887              else if ((unsigned int)e->data.l[1] ==
2888                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT)
2889                {
2890                   _elm_access_highlight_cycle(sd->obj, ELM_FOCUS_NEXT);
2891                }
2892              else if ((unsigned int)e->data.l[1] ==
2893                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV)
2894                {
2895                   _elm_access_highlight_cycle(sd->obj, ELM_FOCUS_PREVIOUS);
2896                }
2897              else if ((unsigned int)e->data.l[1] ==
2898                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP)
2899                {
2900                   _elm_access_highlight_object_activate
2901                     (sd->obj, ELM_ACTIVATE_UP);
2902                }
2903              else if ((unsigned int)e->data.l[1] ==
2904                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN)
2905                {
2906                   _elm_access_highlight_object_activate
2907                     (sd->obj, ELM_ACTIVATE_DOWN);
2908                }
2909           }
2910      }
2911    return ECORE_CALLBACK_PASS_ON;
2912 }
2913
2914 static Eina_Bool
2915 _elm_win_property_change(void *data,
2916                          int type EINA_UNUSED,
2917                          void *event)
2918 {
2919    ELM_WIN_DATA_GET(data, sd);
2920    Ecore_X_Event_Window_Property *e = event;
2921
2922    if (e->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE)
2923      {
2924         if (e->win == sd->x.xwin)
2925           {
2926              sd->indmode = (Elm_Win_Indicator_Mode)ecore_x_e_illume_indicator_state_get(e->win);
2927              eo_do(sd->obj, eo_event_callback_call
2928                (ELM_WIN_EVENT_INDICATOR_PROP_CHANGED, NULL));
2929           }
2930      }
2931    return ECORE_CALLBACK_PASS_ON;
2932 }
2933 #endif
2934
2935 static void
2936 _elm_win_focus_highlight_hide(void *data EINA_UNUSED,
2937                               Evas_Object *obj,
2938                               const char *emission EINA_UNUSED,
2939                               const char *source EINA_UNUSED)
2940 {
2941    evas_object_hide(obj);
2942 }
2943
2944 static void
2945 _elm_win_focus_highlight_anim_end(void *data,
2946                                   Evas_Object *obj,
2947                                   const char *emission EINA_UNUSED,
2948                                   const char *source EINA_UNUSED)
2949 {
2950    ELM_WIN_DATA_GET(data, sd);
2951
2952    _elm_win_focus_highlight_simple_setup(sd, obj);
2953 }
2954
2955 static void
2956 _elm_win_focus_skip_set(Elm_Win_Data *sd, Eina_Bool skip)
2957 {
2958    sd->skip_focus = skip;
2959    TRAP(sd, focus_skip_set, skip);
2960 }
2961
2962 static void
2963 _elm_win_focus_highlight_init(Elm_Win_Data *sd)
2964 {
2965    evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
2966                            _elm_win_object_focus_in, sd->obj);
2967    evas_event_callback_add(sd->evas,
2968                            EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
2969                            _elm_win_object_focus_out, sd->obj);
2970
2971    sd->focus_highlight.cur.target = _elm_win_focus_target_get(evas_focus_get(sd->evas));
2972    if (sd->focus_highlight.cur.target)
2973      {
2974         if (elm_widget_highlight_in_theme_get(sd->focus_highlight.cur.target))
2975           sd->focus_highlight.cur.in_theme = EINA_TRUE;
2976         else
2977           _elm_win_focus_target_callbacks_add(sd);
2978
2979         evas_object_event_callback_add
2980            (sd->focus_highlight.cur.target,
2981             EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
2982      }
2983
2984    sd->focus_highlight.prev.target = NULL;
2985    sd->focus_highlight.fobj = edje_object_add(sd->evas);
2986    sd->focus_highlight.theme_changed = EINA_TRUE;
2987
2988    edje_object_signal_callback_add(sd->focus_highlight.fobj,
2989                                    "elm,action,focus,hide,end", "*",
2990                                    _elm_win_focus_highlight_hide, NULL);
2991    edje_object_signal_callback_add(sd->focus_highlight.fobj,
2992                                    "elm,action,focus,anim,end", "*",
2993                                    _elm_win_focus_highlight_anim_end, sd->obj);
2994    _elm_win_focus_highlight_reconfigure_job_start(sd);
2995 }
2996 static void
2997 _elm_win_accessibility_highlight_init(Elm_Win_Data *sd, Evas_Object *atarget)
2998 {
2999    sd->accessibility_highlight.cur.target = atarget;
3000
3001    sd->accessibility_highlight.prev.target = NULL;
3002    sd->accessibility_highlight.fobj = edje_object_add(sd->evas);
3003    if (atarget)
3004       _elm_win_accessibility_highlight_callbacks_add(sd);
3005 }
3006
3007 static void
3008 _elm_win_frame_cb_move_start(void *data,
3009                              Evas_Object *obj EINA_UNUSED,
3010                              const char *sig EINA_UNUSED,
3011                              const char *source)
3012 {
3013    int ox, oy;
3014
3015    ELM_WIN_DATA_GET(data, sd);
3016
3017    if (!sd) return;
3018
3019 #ifdef HAVE_ELEMENTARY_WAYLAND
3020    if (!strcmp(source, "elm"))
3021      ecore_wl_window_cursor_from_name_set(sd->wl.win, ELM_CURSOR_HAND1);
3022    else
3023      ecore_wl_window_cursor_default_restore(sd->wl.win);
3024 #else
3025    (void)source;
3026 #endif
3027
3028    /* NB: Wayland handles moving surfaces by itself so we cannot
3029     * specify a specific x/y we want. Instead, we will pass in the
3030     * existing x/y values so they can be recorded as 'previous'
3031     * position. The new position will get updated automatically when
3032     * the move is finished */
3033
3034    edje_object_part_geometry_get(sd->frame_obj, "elm.spacer.opaque",
3035                                  &ox, &oy, NULL, NULL);
3036    ecore_evas_wayland_move(sd->ee, ox, oy);
3037 }
3038
3039 static void
3040 _elm_win_frame_cb_move_stop(void *data,
3041                             Evas_Object *obj EINA_UNUSED,
3042                             const char *sig EINA_UNUSED,
3043                             const char *source EINA_UNUSED)
3044 {
3045    ELM_WIN_DATA_GET(data, sd);
3046
3047    if (!sd) return;
3048
3049 #ifdef HAVE_ELEMENTARY_WAYLAND
3050    ecore_wl_window_cursor_default_restore(sd->wl.win);
3051 #endif
3052 }
3053
3054 #ifdef HAVE_ELEMENTARY_WAYLAND
3055 struct _resize_info
3056 {
3057    const char *name;
3058    int location;
3059 };
3060
3061 static struct _resize_info _border_side[4] =
3062 {
3063      { ELM_CURSOR_TOP_SIDE, 1 },
3064      { ELM_CURSOR_LEFT_SIDE, 4 },
3065      { ELM_CURSOR_BOTTOM_SIDE, 2 },
3066      { ELM_CURSOR_RIGHT_SIDE, 8 },
3067 };
3068
3069 static struct _resize_info _border_corner[4] =
3070 {
3071      { ELM_CURSOR_TOP_LEFT_CORNER, 5 },
3072      { ELM_CURSOR_BOTTOM_LEFT_CORNER, 6 },
3073      { ELM_CURSOR_BOTTOM_RIGHT_CORNER, 10 },
3074      { ELM_CURSOR_TOP_RIGHT_CORNER, 9 },
3075 };
3076 #endif
3077
3078 static void
3079 _elm_win_frame_obj_move(void *data,
3080                         Evas *e EINA_UNUSED,
3081                         Evas_Object *obj EINA_UNUSED,
3082                         void *event_info EINA_UNUSED)
3083 {
3084    Elm_Win_Data *sd;
3085
3086    if (!(sd = data)) return;
3087    if (!sd->client_obj) return;
3088
3089    _elm_win_frame_obj_update(sd);
3090 }
3091
3092 static void
3093 _elm_win_frame_obj_resize(void *data,
3094                           Evas *e EINA_UNUSED,
3095                           Evas_Object *obj EINA_UNUSED,
3096                           void *event_info EINA_UNUSED)
3097 {
3098    Elm_Win_Data *sd;
3099
3100    if (!(sd = data)) return;
3101    if (!sd->client_obj) return;
3102
3103    _elm_win_frame_obj_update(sd);
3104 }
3105
3106 static void
3107 _elm_win_frame_cb_resize_show(void *data,
3108                               Evas_Object *obj EINA_UNUSED,
3109                               const char *sig EINA_UNUSED,
3110                               const char *source)
3111 {
3112    ELM_WIN_DATA_GET(data, sd);
3113
3114    if (!sd) return;
3115    if (sd->resizing) return;
3116
3117 #ifdef HAVE_ELEMENTARY_WAYLAND
3118    int i;
3119    i = sd->rot / 90;
3120    if (!strcmp(source, "elm.event.resize.t"))
3121      ecore_wl_window_cursor_from_name_set(sd->wl.win,
3122                                           _border_side[(0 + i) % 4].name);
3123    else if (!strcmp(source, "elm.event.resize.b"))
3124      ecore_wl_window_cursor_from_name_set(sd->wl.win,
3125                                           _border_side[(2 + i) % 4].name);
3126    else if (!strcmp(source, "elm.event.resize.l"))
3127      ecore_wl_window_cursor_from_name_set(sd->wl.win,
3128                                           _border_side[(1 + i) % 4].name);
3129    else if (!strcmp(source, "elm.event.resize.r"))
3130      ecore_wl_window_cursor_from_name_set(sd->wl.win,
3131                                           _border_side[(3 + i) % 4].name);
3132    else if (!strcmp(source, "elm.event.resize.tl"))
3133      ecore_wl_window_cursor_from_name_set(sd->wl.win,
3134                                           _border_corner[(0 + i) % 4].name);
3135    else if (!strcmp(source, "elm.event.resize.tr"))
3136      ecore_wl_window_cursor_from_name_set(sd->wl.win,
3137                                           _border_corner[(3 + i) % 4].name);
3138    else if (!strcmp(source, "elm.event.resize.bl"))
3139      ecore_wl_window_cursor_from_name_set(sd->wl.win,
3140                                           _border_corner[(1 + i) % 4].name);
3141    else if (!strcmp(source, "elm.event.resize.br"))
3142      ecore_wl_window_cursor_from_name_set(sd->wl.win,
3143                                           _border_corner[(2 + i) % 4].name);
3144    else
3145      ecore_wl_window_cursor_default_restore(sd->wl.win);
3146 #else
3147    (void)source;
3148 #endif
3149 }
3150
3151 static void
3152 _elm_win_frame_cb_resize_hide(void *data,
3153                               Evas_Object *obj EINA_UNUSED,
3154                               const char *sig EINA_UNUSED,
3155                               const char *source EINA_UNUSED)
3156 {
3157    ELM_WIN_DATA_GET(data, sd);
3158
3159    if (!sd) return;
3160    if (sd->resizing) return;
3161
3162 #ifdef HAVE_ELEMENTARY_WAYLAND
3163    ecore_wl_window_cursor_default_restore(sd->wl.win);
3164 #endif
3165 }
3166
3167 static void
3168 _elm_win_frame_cb_resize_start(void *data,
3169                                Evas_Object *obj EINA_UNUSED,
3170                                const char *sig EINA_UNUSED,
3171                                const char *source)
3172 {
3173 #ifdef HAVE_ELEMENTARY_WAYLAND
3174    ELM_WIN_DATA_GET(data, sd);
3175    int i;
3176
3177    if (!sd) return;
3178    if (sd->resizing) return;
3179
3180    sd->resizing = EINA_TRUE;
3181    i = sd->rot / 90;
3182    if (!strcmp(source, "elm.event.resize.t"))
3183      sd->resize_location = _border_side[(0 + i) % 4].location;
3184    else if (!strcmp(source, "elm.event.resize.b"))
3185      sd->resize_location = _border_side[(2 + i) % 4].location;
3186    else if (!strcmp(source, "elm.event.resize.l"))
3187      sd->resize_location = _border_side[(1 + i) % 4].location;
3188    else if (!strcmp(source, "elm.event.resize.r"))
3189      sd->resize_location = _border_side[(3 + i) % 4].location;
3190    else if (!strcmp(source, "elm.event.resize.tl"))
3191      sd->resize_location = _border_corner[(0 + i) % 4].location;
3192    else if (!strcmp(source, "elm.event.resize.tr"))
3193      sd->resize_location = _border_corner[(3 + i) % 4].location;
3194    else if (!strcmp(source, "elm.event.resize.bl"))
3195      sd->resize_location = _border_corner[(1 + i) % 4].location;
3196    else if (!strcmp(source, "elm.event.resize.br"))
3197      sd->resize_location = _border_corner[(2 + i) % 4].location;
3198    else
3199      sd->resize_location = 0;
3200
3201    if (sd->resize_location > 0)
3202      ecore_evas_wayland_resize(sd->ee, sd->resize_location);
3203 #else
3204    (void)data;
3205    (void)source;
3206 #endif
3207 }
3208
3209 static void
3210 _elm_win_frame_cb_resize_end(void *data,
3211                              Evas_Object *obj EINA_UNUSED,
3212                              const char *sig EINA_UNUSED,
3213                              const char *source EINA_UNUSED)
3214 {
3215 #ifdef HAVE_ELEMENTARY_WAYLAND
3216    ELM_WIN_DATA_GET(data, sd);
3217
3218    if (!sd) return;
3219    if (sd->resizing) sd->resizing = EINA_FALSE;
3220 #else
3221    (void)data;
3222 #endif
3223 }
3224 static void
3225 _elm_win_frame_cb_minimize(void *data,
3226                            Evas_Object *obj EINA_UNUSED,
3227                            const char *sig EINA_UNUSED,
3228                            const char *source EINA_UNUSED)
3229 {
3230    ELM_WIN_DATA_GET(data, sd);
3231
3232    if (!sd) return;
3233 //   sd->iconified = EINA_TRUE;
3234    TRAP(sd, iconified_set, EINA_TRUE);
3235 }
3236
3237 static void
3238 _elm_win_frame_maximized_state_update(Elm_Win_Data *sd, Eina_Bool maximized)
3239 {
3240    const char *emission;
3241
3242    if (maximized)
3243      emission = "elm,state,maximized";
3244    else
3245      emission = "elm,state,unmaximized";
3246
3247    edje_object_signal_emit(sd->frame_obj, emission, "elm");
3248    edje_object_message_signal_process(sd->frame_obj);
3249    evas_object_smart_calculate(sd->frame_obj);
3250
3251    _elm_win_frame_obj_update(sd);
3252 }
3253
3254 static void
3255 _elm_win_frame_cb_maximize(void *data,
3256                            Evas_Object *obj EINA_UNUSED,
3257                            const char *sig EINA_UNUSED,
3258                            const char *source EINA_UNUSED)
3259 {
3260    Eina_Bool value;
3261    ELM_WIN_DATA_GET(data, sd);
3262
3263    if (!sd) return;
3264    if (sd->maximized) value = EINA_FALSE;
3265    else value = EINA_TRUE;
3266
3267    _elm_win_frame_maximized_state_update(sd, value);
3268
3269    TRAP(sd, maximized_set, value);
3270 }
3271
3272 static void
3273 _elm_win_frame_cb_close(void *data,
3274                         Evas_Object *obj EINA_UNUSED,
3275                         const char *sig EINA_UNUSED,
3276                         const char *source EINA_UNUSED)
3277 {
3278    ELM_WIN_DATA_GET(data, sd);
3279    Evas_Object *win;
3280
3281    /* FIXME: After the current freeze, this should be handled differently.
3282     *
3283     * Ideally, we would want to mimic the X11 backend and use something
3284     * like ECORE_WL_EVENT_WINDOW_DELETE and handle the delete_request
3285     * inside of ecore_evas. That would be the 'proper' way, but since we are
3286     * in a freeze right now, I cannot add a new event value, or a new
3287     * event structure to ecore_wayland.
3288     *
3289     * So yes, this is a temporary 'stop-gap' solution which will be fixed
3290     * when the freeze is over, but it does fix a trac bug for now, and in a
3291     * way which does not break API or the freeze. - dh
3292     */
3293
3294    if (!sd) return;
3295
3296    win = sd->obj;
3297
3298    int autodel = sd->autodel;
3299    sd->autodel_clear = &autodel;
3300    evas_object_ref(win);
3301    eo_do(win, eo_event_callback_call(ELM_WIN_EVENT_DELETE_REQUEST, NULL));
3302    if (sd->autohide)
3303      evas_object_hide(win);
3304    // FIXME: if above callback deletes - then the below will be invalid
3305    if (autodel) evas_object_del(win);
3306    else sd->autodel_clear = NULL;
3307    evas_object_unref(win);
3308 }
3309
3310 #ifdef HAVE_ELEMENTARY_WAYLAND
3311 static void
3312 _elm_win_frame_pre_render(void *data, Evas *e EINA_UNUSED, void *ev EINA_UNUSED)
3313 {
3314    Elm_Win_Data *sd = data;
3315
3316    if (sd->wl.opaque_dirty)
3317      _elm_win_opaque_update(sd);
3318    sd->wl.opaque_dirty = 0;
3319 }
3320 #endif
3321
3322 static void
3323 _elm_win_frame_add(Elm_Win_Data *sd,
3324                    const char *style)
3325 {
3326    Evas_Object *obj = sd->obj;
3327    int w, h, mw, mh;
3328    short layer;
3329
3330    sd->frame_obj = edje_object_add(sd->evas);
3331    layer = evas_object_layer_get(obj);
3332    evas_object_layer_set(sd->frame_obj, layer + 1);
3333    if (!elm_widget_theme_object_set
3334        (sd->obj, sd->frame_obj, "border", "base", style))
3335      {
3336         ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
3337         return;
3338      }
3339
3340    sd->client_obj = evas_object_rectangle_add(sd->evas);
3341    evas_object_color_set(sd->client_obj, 0, 0, 0, 0);
3342    /* NB: Tried pass_events here, but that fails to send events */
3343    evas_object_repeat_events_set(sd->client_obj, EINA_TRUE);
3344    edje_object_part_swallow(sd->frame_obj, "elm.swallow.client",
3345                             sd->client_obj);
3346
3347    evas_object_is_frame_object_set(sd->frame_obj, EINA_TRUE);
3348
3349    if (!sd->icon)
3350      {
3351         Efreet_Desktop *d;
3352
3353         sd->icon = elm_icon_add(sd->obj);
3354
3355         d = efreet_util_desktop_exec_find(_elm_appname);
3356         if (d)
3357           {
3358              elm_icon_standard_set(sd->icon, d->icon);
3359              efreet_desktop_free(d);
3360           }
3361      }
3362
3363    edje_object_part_swallow(sd->frame_obj, "elm.swallow.icon",
3364                             sd->icon);
3365
3366    evas_object_event_callback_add
3367      (sd->frame_obj, EVAS_CALLBACK_MOVE, _elm_win_frame_obj_move, sd);
3368    evas_object_event_callback_add
3369      (sd->frame_obj, EVAS_CALLBACK_RESIZE, _elm_win_frame_obj_resize, sd);
3370 #ifdef HAVE_ELEMENTARY_WAYLAND
3371    evas_event_callback_add(sd->evas, EVAS_CALLBACK_RENDER_PRE, _elm_win_frame_pre_render, sd);
3372 #endif
3373
3374    /* NB: Do NOT remove these calls !! Needed to calculate proper
3375     * framespace on initial show of the window */
3376    edje_object_size_min_calc(sd->frame_obj, &mw, &mh);
3377    evas_object_move(sd->frame_obj, 0, 0);
3378    evas_object_resize(sd->frame_obj, mw, mh);
3379    evas_object_smart_calculate(sd->frame_obj);
3380
3381    edje_object_signal_callback_add
3382      (sd->frame_obj, "elm,action,move,start", "elm",
3383      _elm_win_frame_cb_move_start, obj);
3384    edje_object_signal_callback_add
3385      (sd->frame_obj, "elm,action,move,stop", "elm",
3386      _elm_win_frame_cb_move_stop, obj);
3387    edje_object_signal_callback_add
3388      (sd->frame_obj, "elm,action,resize,show", "*",
3389      _elm_win_frame_cb_resize_show, obj);
3390    edje_object_signal_callback_add
3391      (sd->frame_obj, "elm,action,resize,hide", "*",
3392      _elm_win_frame_cb_resize_hide, obj);
3393    edje_object_signal_callback_add
3394      (sd->frame_obj, "elm,action,resize,start", "*",
3395      _elm_win_frame_cb_resize_start, obj);
3396    edje_object_signal_callback_add
3397      (sd->frame_obj, "elm,action,resize,end", "*",
3398      _elm_win_frame_cb_resize_end, obj);
3399    edje_object_signal_callback_add
3400      (sd->frame_obj, "elm,action,minimize", "elm",
3401      _elm_win_frame_cb_minimize, obj);
3402    edje_object_signal_callback_add
3403      (sd->frame_obj, "elm,action,maximize", "elm",
3404      _elm_win_frame_cb_maximize, obj);
3405    edje_object_signal_callback_add
3406      (sd->frame_obj, "elm,action,close", "elm", _elm_win_frame_cb_close, obj);
3407
3408    if (sd->title)
3409      {
3410         edje_object_part_text_escaped_set
3411           (sd->frame_obj, "elm.text.title", sd->title);
3412      }
3413
3414    ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
3415    ecore_evas_resize(sd->ee, w, h);
3416 }
3417
3418 static void
3419 _elm_win_frame_del(Elm_Win_Data *sd)
3420 {
3421    int w, h;
3422
3423    ELM_SAFE_FREE(sd->client_obj, evas_object_del);
3424
3425    if (sd->frame_obj)
3426      {
3427         evas_object_event_callback_del_full
3428           (sd->frame_obj, EVAS_CALLBACK_MOVE, _elm_win_frame_obj_move, sd);
3429         evas_object_event_callback_del_full
3430           (sd->frame_obj, EVAS_CALLBACK_RESIZE, _elm_win_frame_obj_resize, sd);
3431 #ifdef HAVE_ELEMENTARY_WAYLAND
3432         evas_event_callback_del_full(sd->evas, EVAS_CALLBACK_RENDER_PRE, _elm_win_frame_pre_render, sd);
3433 #endif
3434
3435         edje_object_signal_callback_del
3436           (sd->frame_obj, "elm,action,move,start", "elm",
3437               _elm_win_frame_cb_move_start);
3438         edje_object_signal_callback_del
3439           (sd->frame_obj, "elm,action,move,stop", "elm",
3440               _elm_win_frame_cb_move_stop);
3441         edje_object_signal_callback_del
3442           (sd->frame_obj, "elm,action,resize,show", "*",
3443               _elm_win_frame_cb_resize_show);
3444         edje_object_signal_callback_del
3445           (sd->frame_obj, "elm,action,resize,hide", "*",
3446               _elm_win_frame_cb_resize_hide);
3447         edje_object_signal_callback_del
3448           (sd->frame_obj, "elm,action,resize,start", "*",
3449               _elm_win_frame_cb_resize_start);
3450         edje_object_signal_callback_del
3451           (sd->frame_obj, "elm,action,resize,end", "*",
3452               _elm_win_frame_cb_resize_end);
3453         edje_object_signal_callback_del
3454           (sd->frame_obj, "elm,action,minimize", "elm",
3455               _elm_win_frame_cb_minimize);
3456         edje_object_signal_callback_del
3457           (sd->frame_obj, "elm,action,maximize", "elm",
3458               _elm_win_frame_cb_maximize);
3459         edje_object_signal_callback_del
3460           (sd->frame_obj, "elm,action,close", "elm",
3461               _elm_win_frame_cb_close);
3462
3463         ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
3464      }
3465
3466    evas_output_framespace_set(sd->evas, 0, 0, 0, 0);
3467    ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
3468    ecore_evas_resize(sd->ee, w, h);
3469 }
3470
3471 #ifdef ELM_DEBUG
3472 static void
3473 _debug_key_down(void *data EINA_UNUSED,
3474                 Evas *e EINA_UNUSED,
3475                 Evas_Object *obj,
3476                 void *event_info)
3477 {
3478    Evas_Event_Key_Down *ev = event_info;
3479
3480    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
3481      return;
3482
3483    if ((strcmp(ev->key, "F12")) ||
3484        (!evas_key_modifier_is_set(ev->modifiers, "Control")))
3485      return;
3486
3487    INF("Tree graph generated.");
3488    elm_object_tree_dot_dump(obj, "./dump.dot");
3489 }
3490
3491 #endif
3492
3493 static void
3494 _win_inlined_image_set(Elm_Win_Data *sd)
3495 {
3496    evas_object_image_alpha_set(sd->img_obj, EINA_FALSE);
3497    evas_object_image_filled_set(sd->img_obj, EINA_TRUE);
3498
3499    evas_object_event_callback_add
3500      (sd->img_obj, EVAS_CALLBACK_DEL, _elm_win_on_img_obj_del, sd->obj);
3501    evas_object_event_callback_add
3502      (sd->img_obj, EVAS_CALLBACK_HIDE, _win_img_hide, sd->obj);
3503    evas_object_event_callback_add
3504      (sd->img_obj, EVAS_CALLBACK_MOUSE_UP, _win_img_mouse_up, sd->obj);
3505    evas_object_event_callback_add
3506      (sd->img_obj, EVAS_CALLBACK_FOCUS_IN, _win_img_focus_in, sd->obj);
3507    evas_object_event_callback_add
3508      (sd->img_obj, EVAS_CALLBACK_FOCUS_OUT, _win_img_focus_out, sd->obj);
3509 }
3510
3511 static void
3512 _elm_win_on_icon_del(void *data,
3513                      Evas *e EINA_UNUSED,
3514                      Evas_Object *obj,
3515                      void *event_info EINA_UNUSED)
3516 {
3517    ELM_WIN_DATA_GET(data, sd);
3518
3519    if (sd->icon == obj) sd->icon = NULL;
3520 }
3521
3522 EOLIAN static void
3523 _elm_win_evas_object_smart_add(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED)
3524 {
3525    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
3526
3527    elm_widget_can_focus_set(obj, EINA_TRUE);
3528
3529    elm_widget_highlight_ignore_set(obj, EINA_TRUE);
3530 }
3531
3532 #ifdef HAVE_ELEMENTARY_X
3533 static void
3534 _elm_x_io_err(void *data EINA_UNUSED)
3535 {
3536    Eina_List *l;
3537    Evas_Object *obj;
3538
3539    EINA_LIST_FOREACH(_elm_win_list, l, obj)
3540      eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_IOERR, NULL));
3541    elm_exit();
3542 }
3543 #endif
3544
3545 // TIZEN_ONLY(20160218): Improve launching performance.
3546 EAPI void
3547 elm_win_precreated_object_set(Evas_Object *obj)
3548 {
3549    INF("Set precreated obj(%p).", obj);
3550    _precreated_win_obj = obj;
3551 }
3552
3553 EAPI Evas_Object *
3554 elm_win_precreated_object_get(void)
3555 {
3556    INF("Get precreated obj(%p).", _precreated_win_obj);
3557    return _precreated_win_obj;
3558 }
3559 //
3560
3561 EAPI Evas_Object *
3562 elm_win_add(Evas_Object *parent,
3563             const char *name,
3564             Elm_Win_Type type)
3565 {
3566 // TIZEN_ONLY(20160520):  Add Performance Clock log level
3567    eina_evlog("+ elm_win_add", NULL, 0.0, NULL);
3568
3569 // TIZEN_ONLY(20160218): Improve launching performance.
3570    if (_precreated_win_obj)
3571      {
3572         ELM_WIN_DATA_GET(_precreated_win_obj, sd);
3573
3574         if (sd)
3575           {
3576              if ((sd->type == type) && (sd->parent == parent))
3577                {
3578                   Evas_Object *tmp = _precreated_win_obj;
3579                   TRAP(sd, name_class_set, name, _elm_appname);
3580                   _precreated_win_obj = NULL;
3581                   INF("Return precreated obj(%p).", tmp);
3582
3583 // TIZEN_ONLY(20160520):  Add Performance Clock log level
3584                   eina_evlog("- elm_win_add", NULL, 0.0, NULL);
3585
3586                   return tmp;
3587                }
3588           }
3589      }
3590 //
3591
3592    Evas_Object *obj = eo_add(MY_CLASS, parent,
3593                              elm_obj_win_name_set(name),
3594                              elm_obj_win_type_set(type));
3595 // TIZEN_ONLY(20160520):  Add Performance Clock log level
3596    eina_evlog("- elm_win_add", NULL, 0.0, NULL);
3597
3598
3599    return obj;
3600 }
3601
3602 EAPI Evas_Object *
3603 elm_win_fake_add(Ecore_Evas *ee)
3604 {
3605    return eo_add(MY_CLASS, NULL,
3606          elm_obj_win_fake_canvas_set(ee),
3607          elm_obj_win_name_set(NULL),
3608          elm_obj_win_type_set(ELM_WIN_FAKE));
3609 }
3610
3611 static void
3612 _elm_win_cb_hide(void *data EINA_UNUSED,
3613                  Evas *e EINA_UNUSED,
3614                  Evas_Object *obj EINA_UNUSED,
3615                  void *event_info EINA_UNUSED)
3616 {
3617    _elm_win_state_eval_queue();
3618 }
3619
3620 static void
3621 _elm_win_cb_show(void *data EINA_UNUSED,
3622                  Evas *e EINA_UNUSED,
3623                  Evas_Object *obj EINA_UNUSED,
3624                  void *event_info EINA_UNUSED)
3625 {
3626    _elm_win_state_eval_queue();
3627 }
3628
3629 /**
3630   * @internal
3631   *
3632   * Recalculate the size of window considering its resize objects' weight and
3633   * min size. If any of its resize objects' weight equals to 0.0, window
3634   * layout's weight will be set to 0.0.
3635   *
3636   * @param o box object
3637   * @param p box's private data
3638   * @param data window object
3639   */
3640 static void
3641 _window_layout_stack(Evas_Object *o, Evas_Object_Box_Data *p, void *data)
3642 {
3643    const Eina_List *l;
3644    Evas_Object *child;
3645    Evas_Object_Box_Option *opt;
3646    Evas_Coord x, y, w, h;
3647    double wx, wy;
3648    Evas_Coord minw = -1, minh = -1;
3649    double weight_x = EVAS_HINT_EXPAND;
3650    double weight_y = EVAS_HINT_EXPAND;
3651
3652    EINA_LIST_FOREACH(p->children, l, opt)
3653      {
3654         child = opt->obj;
3655         evas_object_size_hint_weight_get(child, &wx, &wy);
3656         if (wx == 0.0) weight_x = 0;
3657         if (wy == 0.0) weight_y = 0;
3658
3659         evas_object_size_hint_min_get(child, &w, &h);
3660         if (w > minw) minw = w;
3661         if (h > minh) minh = h;
3662      }
3663
3664    evas_object_size_hint_min_set(o, minw, minh);
3665    evas_object_geometry_get(o, &x, &y, &w, &h);
3666    if (w < minw) w = minw;
3667    if (h < minh) h = minh;
3668    evas_object_resize(o, w, h);
3669
3670    EINA_LIST_FOREACH(p->children, l, opt)
3671      {
3672         child = opt->obj;
3673         evas_object_move(child, x, y);
3674         evas_object_resize(child, w, h);
3675      }
3676
3677    ELM_WIN_DATA_GET(data, sd);
3678    evas_object_size_hint_weight_set(sd->edje, weight_x, weight_y);
3679    evas_object_smart_changed(sd->edje);
3680 }
3681
3682 static Eina_Bool
3683 _accel_is_gl(void)
3684 {
3685    const char *env = NULL;
3686    const char *str = NULL;
3687
3688    if (_elm_config->accel) str = _elm_config->accel;
3689    if (_elm_accel_preference) str = _elm_accel_preference;
3690    if ((_elm_config->accel_override) && (_elm_config->accel))
3691      str = _elm_config->accel;
3692    env = getenv("ELM_ACCEL");
3693    if (env) str = env;
3694    if ((str) &&
3695        ((!strcasecmp(str, "gl")) ||
3696         (!strcasecmp(str, "opengl")) ||
3697         (!strcasecmp(str, "3d")) ||
3698         (!strcasecmp(str, "hw")) ||
3699         (!strcasecmp(str, "accel")) ||
3700         (!strcasecmp(str, "hardware"))
3701        ))
3702      return EINA_TRUE;
3703    return EINA_FALSE;
3704 }
3705
3706 static Eina_Bool
3707 _animator_tick_cb(void *_obj)
3708 {
3709    Elm_Win *obj = _obj;
3710    eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_ANIMATOR_TICK, NULL));
3711
3712    return ECORE_CALLBACK_RENEW;
3713 }
3714
3715 static Eina_Bool
3716 _cb_added(void *_data,
3717           Eo *obj,
3718           const Eo_Event_Description *desc EINA_UNUSED,
3719           void *event_info)
3720 {
3721    const Eo_Callback_Array_Item *event = event_info;
3722    Elm_Win_Data *data = _data;
3723
3724    if (event->desc == ELM_WIN_EVENT_ANIMATOR_TICK)
3725      {
3726         data->animator.wants++;
3727         if (data->animator.wants == 1)
3728           {
3729              data->animator.obj = eo_add(ECORE_ANIMATOR_CLASS, obj,
3730                    ecore_animator_constructor(_animator_tick_cb, obj));
3731           }
3732      }
3733
3734    return EO_CALLBACK_CONTINUE;
3735 }
3736
3737 static Eina_Bool
3738 _cb_deled(void *_data,
3739           Eo *obj EINA_UNUSED,
3740           const Eo_Event_Description *desc EINA_UNUSED,
3741           void *event_info)
3742 {
3743    const Eo_Callback_Array_Item *event = event_info;
3744    Elm_Win_Data *data = _data;
3745
3746    if (event->desc == ELM_WIN_EVENT_ANIMATOR_TICK)
3747      {
3748         data->animator.wants--;
3749         if (data->animator.wants == 0)
3750           {
3751              eo_del(data->animator.obj);
3752              data->animator.obj = NULL;
3753           }
3754      }
3755
3756    return EO_CALLBACK_CONTINUE;
3757 }
3758
3759 static Eo *
3760 _elm_win_finalize_internal(Eo *obj, Elm_Win_Data *sd, const char *name, Elm_Win_Type type)
3761 {
3762    sd->obj = obj; // in ctor
3763
3764    Evas_Object *parent = NULL;
3765    Evas *e;
3766    const Eina_List *l;
3767    const char *fontpath, *engine = NULL, *enginelist[32], *disp;
3768    int i, p = 0;
3769
3770    Elm_Win_Data tmp_sd;
3771
3772    eo_do(obj, parent = eo_parent_get());
3773
3774    /* just to store some data while trying out to create a canvas */
3775    memset(&tmp_sd, 0, sizeof(Elm_Win_Data));
3776
3777    switch (type)
3778      {
3779       case ELM_WIN_FAKE:
3780         tmp_sd.ee = sd->ee;
3781         break;
3782       case ELM_WIN_INLINED_IMAGE:
3783         if (!parent) break;
3784           {
3785              e = evas_object_evas_get(parent);
3786              Ecore_Evas *ee;
3787
3788              if (!e) break;
3789
3790              ee = ecore_evas_ecore_evas_get(e);
3791              if (!ee) break;
3792
3793              tmp_sd.img_obj = ecore_evas_object_image_new(ee);
3794              if (!tmp_sd.img_obj) break;
3795
3796              tmp_sd.ee = ecore_evas_object_ecore_evas_get(tmp_sd.img_obj);
3797              if (!tmp_sd.ee)
3798                {
3799                   ELM_SAFE_FREE(tmp_sd.img_obj, evas_object_del);
3800                }
3801           }
3802         break;
3803
3804       case ELM_WIN_SOCKET_IMAGE:
3805         tmp_sd.ee = ecore_evas_extn_socket_new(1, 1);
3806         break;
3807
3808       default:
3809         disp = getenv("ELM_DISPLAY");
3810         if ((disp) && (!strcmp(disp, "ews")))
3811           {
3812              enginelist[p++] = ELM_EWS;
3813           }
3814         else if ((disp) && (!strcmp(disp, "buffer")))
3815           {
3816              enginelist[p++] = ELM_BUFFER;
3817           }
3818         else if ((disp) && (!strcmp(disp, "shot")))
3819           {
3820              enginelist[p++] = ENGINE_GET();
3821           }
3822 // welcome to ifdef hell! :)
3823
3824 #ifdef HAVE_ELEMENTARY_X
3825         else if ((disp) && (!strcmp(disp, "x11")))
3826           {
3827              if (_accel_is_gl())
3828                {
3829                   enginelist[p++] = ELM_OPENGL_X11;
3830                   enginelist[p++] = ELM_SOFTWARE_X11;
3831                }
3832              else
3833                {
3834                   enginelist[p++] = ELM_SOFTWARE_X11;
3835                   enginelist[p++] = ELM_OPENGL_X11;
3836                }
3837           }
3838 #endif
3839
3840 #ifdef HAVE_ELEMENTARY_WAYLAND
3841         else if ((disp) && (!strcmp(disp, "wl")))
3842           {
3843              if (_accel_is_gl())
3844                {
3845                   enginelist[p++] = ELM_WAYLAND_EGL;
3846                   enginelist[p++] = ELM_WAYLAND_SHM;
3847                }
3848              else
3849                {
3850                   enginelist[p++] = ELM_WAYLAND_SHM;
3851                   enginelist[p++] = ELM_WAYLAND_EGL;
3852                }
3853           }
3854 #endif
3855
3856 #ifdef HAVE_ELEMENTARY_WIN32
3857         else if ((disp) && (!strcmp(disp, "win")))
3858           {
3859              enginelist[p++] = ELM_SOFTWARE_WIN32;
3860              enginelist[p++] = ELM_SOFTWARE_DDRAW;
3861           }
3862 #endif
3863
3864 #ifdef HAVE_ELEMENTARY_SDL
3865         else if ((disp) && (!strcmp(disp, "sdl")))
3866           {
3867              if (_accel_is_gl())
3868                {
3869                   enginelist[p++] = ELM_OPENGL_SDL;
3870                   enginelist[p++] = ELM_SOFTWARE_SDL;
3871                }
3872              else
3873                {
3874                   enginelist[p++] = ELM_SOFTWARE_SDL;
3875                   enginelist[p++] = ELM_OPENGL_SDL;
3876                }
3877           }
3878 #endif
3879
3880 #ifdef HAVE_ELEMENTARY_COCOA
3881         else if ((disp) && (!strcmp(disp, "mac")))
3882           {
3883              enginelist[p++] = ELM_OPENGL_COCOA;
3884           }
3885 #endif
3886
3887 #if defined(HAVE_ELEMENTARY_DRM) || defined(HAVE_ELEMENTARY_FB)
3888         else if ((disp) && (!strcmp(disp, "fb")))
3889           {
3890 #ifdef HAVE_ELEMENTARY_DRM
3891              enginelist[p++] = ELM_DRM;
3892 #endif
3893 #ifdef HAVE_ELEMENTARY_FB
3894              enginelist[p++] = ELM_SOFTWARE_FB;
3895 #endif
3896           }
3897 #endif
3898
3899 #ifdef HAVE_ELEMENTARY_PSL1GHT
3900         else if ((disp) && (!strcmp(disp, "ps3")))
3901           {
3902              enginelist[p++] = ELM_SOFTWARE_PSL1GHT;
3903           }
3904 #endif
3905 #ifdef HAVE_ELEMENTARY_X
3906         else if (!_elm_preferred_engine &&
3907                  getenv("DISPLAY") && !getenv("ELM_ENGINE"))
3908           {
3909              if (_accel_is_gl())
3910                {
3911                   enginelist[p++] = ELM_OPENGL_X11;
3912                   enginelist[p++] = ELM_SOFTWARE_X11;
3913                }
3914              else
3915                {
3916                   enginelist[p++] = ELM_SOFTWARE_X11;
3917                   enginelist[p++] = ELM_OPENGL_X11;
3918                }
3919           }
3920 #endif
3921 #ifdef HAVE_ELEMENTARY_WAYLAND
3922         else if (!_elm_preferred_engine &&
3923                  getenv("WAYLAND_DISPLAY") && !getenv("ELM_ENGINE"))
3924           {
3925              if (_accel_is_gl())
3926                {
3927                   enginelist[p++] = ELM_WAYLAND_EGL;
3928                   enginelist[p++] = ELM_WAYLAND_SHM;
3929                }
3930              else
3931                {
3932                   enginelist[p++] = ELM_WAYLAND_SHM;
3933                   enginelist[p++] = ELM_WAYLAND_EGL;
3934                }
3935           }
3936 #endif
3937         else
3938           {
3939              if (_accel_is_gl())
3940                {
3941 // add all engines with selected engine first - if any
3942                   if (ENGINE_GET())
3943                     enginelist[p++] = ENGINE_GET();
3944
3945 // add all engines with gl/accelerated ones first - only engines compiled
3946 #ifdef HAVE_ELEMENTARY_X
3947                   enginelist[p++] = ELM_OPENGL_X11;
3948 #endif
3949 #ifdef HAVE_ELEMENTARY_WAYLAND
3950                   enginelist[p++] = ELM_WAYLAND_EGL;
3951 #endif
3952 #ifdef HAVE_ELEMENTARY_DRM
3953                   enginelist[p++] = ELM_DRM;
3954 #endif
3955 #ifdef HAVE_ELEMENTARY_FB
3956                   enginelist[p++] = ELM_SOFTWARE_FB;
3957 #endif
3958 #ifdef HAVE_ELEMENTARY_COCOA
3959                   enginelist[p++] = ELM_OPENGL_COCOA;
3960 #endif
3961 #ifdef HAVE_ELEMENTARY_SDL
3962                   enginelist[p++] = ELM_OPENGL_SDL;
3963 #endif
3964 #ifdef HAVE_ELEMENTARY_X
3965                   enginelist[p++] = ELM_SOFTWARE_X11;
3966 #endif
3967 #ifdef HAVE_ELEMENTARY_WAYLAND
3968                   enginelist[p++] = ELM_WAYLAND_SHM;
3969 #endif
3970 #ifdef HAVE_ELEMENTARY_WIN32
3971                   enginelist[p++] = ELM_SOFTWARE_WIN32;
3972                   enginelist[p++] = ELM_SOFTWARE_DDRAW;
3973 #endif
3974 #ifdef HAVE_ELEMENTARY_SDL
3975                   enginelist[p++] = ELM_SOFTWARE_SDL;
3976 #endif
3977 #ifdef HAVE_ELEMENTARY_PSL1GHT
3978                   enginelist[p++] = ELM_SOFTWARE_PSL1GHT;
3979 #endif
3980                }
3981              else
3982                {
3983 // add all engines with selected engine first - if any
3984                   if (elm_config_preferred_engine_get())
3985                     enginelist[p++] = elm_config_preferred_engine_get();
3986 // add check _elm_gl_preference whether "none" or not
3987                   else if (_elm_config->engine &&
3988                            elm_config_accel_preference_get() &&
3989                            !strcmp(elm_config_accel_preference_get(),"none"))
3990                     enginelist[p++] = _elm_config->engine;
3991 // add all engines with gl/accelerated ones first - only engines compiled
3992 #ifdef HAVE_ELEMENTARY_X
3993                   enginelist[p++] = ELM_SOFTWARE_X11;
3994 #endif
3995 #ifdef HAVE_ELEMENTARY_WAYLAND
3996                   enginelist[p++] = ELM_WAYLAND_SHM;
3997 #endif
3998 #ifdef HAVE_ELEMENTARY_DRM
3999                   enginelist[p++] = ELM_DRM;
4000 #endif
4001 #ifdef HAVE_ELEMENTARY_FB
4002                   enginelist[p++] = ELM_SOFTWARE_FB;
4003 #endif
4004 #ifdef HAVE_ELEMENTARY_COCOA
4005                   enginelist[p++] = ELM_OPENGL_COCOA;
4006 #endif
4007 #ifdef HAVE_ELEMENTARY_WIN32
4008                   enginelist[p++] = ELM_SOFTWARE_WIN32;
4009                   enginelist[p++] = ELM_SOFTWARE_DDRAW;
4010 #endif
4011 #ifdef HAVE_ELEMENTARY_SDL
4012                   enginelist[p++] = ELM_SOFTWARE_SDL;
4013 #endif
4014 #ifdef HAVE_ELEMENTARY_X
4015                   enginelist[p++] = ELM_OPENGL_X11;
4016 #endif
4017 #ifdef HAVE_ELEMENTARY_WAYLAND
4018                   enginelist[p++] = ELM_WAYLAND_EGL;
4019 #endif
4020 #ifdef HAVE_ELEMENTARY_DRM
4021                   enginelist[p++] = ELM_DRM;
4022 #endif
4023 #ifdef HAVE_ELEMENTARY_SDL
4024                   enginelist[p++] = ELM_OPENGL_SDL;
4025 #endif
4026 #ifdef HAVE_ELEMENTARY_PSL1GHT
4027                   enginelist[p++] = ELM_SOFTWARE_PSL1GHT;
4028 #endif
4029                }
4030           }
4031         enginelist[p++] = NULL;
4032         for (i = 0; i < 30; i++)
4033           {
4034              if ((i > 0) && (!enginelist[i])) break;
4035              if (!strcmp(enginelist[i], ELM_SOFTWARE_X11))
4036                tmp_sd.ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
4037              else if (!strcmp(enginelist[i], ELM_OPENGL_X11))
4038                {
4039                   int opt[20], opt_i = 0;
4040
4041                   if (_elm_config->vsync)
4042                     {
4043                        opt[opt_i++] = ECORE_EVAS_GL_X11_OPT_VSYNC;
4044                        opt[opt_i++] = 1;
4045                     }
4046                   if (_elm_config->gl_depth)
4047                     {
4048                        opt[opt_i++] = ECORE_EVAS_GL_X11_OPT_GL_DEPTH;
4049                        opt[opt_i++] = _elm_config->gl_depth;
4050                     }
4051                   if (_elm_config->gl_stencil)
4052                     {
4053                        opt[opt_i++] = ECORE_EVAS_GL_X11_OPT_GL_STENCIL;
4054                        opt[opt_i++] = _elm_config->gl_stencil;
4055                     }
4056                   if (_elm_config->gl_msaa)
4057                     {
4058                        opt[opt_i++] = ECORE_EVAS_GL_X11_OPT_GL_MSAA;
4059                        opt[opt_i++] = _elm_config->gl_msaa;
4060                     }
4061                   opt[opt_i] = 0;
4062                   if (opt_i > 0)
4063                     tmp_sd.ee = ecore_evas_gl_x11_options_new(NULL, 0, 0, 0, 1, 1, opt);
4064                   else
4065                     tmp_sd.ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1);
4066                }
4067              else if (!strcmp(enginelist[i], ELM_WAYLAND_SHM))
4068                tmp_sd.ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 0, 1, 1, 0);
4069              else if (!strcmp(enginelist[i], ELM_WAYLAND_EGL))
4070                {
4071                   int opt[20], opt_i = 0;
4072
4073                   if (_elm_config->vsync)
4074                     {
4075                        opt[opt_i++] = ECORE_EVAS_OPT_VSYNC;
4076                        opt[opt_i++] = 1;
4077                     }
4078                   if (_elm_config->gl_depth)
4079                     {
4080                        opt[opt_i++] = ECORE_EVAS_OPT_GL_DEPTH;
4081                        opt[opt_i++] = _elm_config->gl_depth;
4082                     }
4083                   if (_elm_config->gl_stencil)
4084                     {
4085                        opt[opt_i++] = ECORE_EVAS_OPT_GL_STENCIL;
4086                        opt[opt_i++] = _elm_config->gl_stencil;
4087                     }
4088                   if (_elm_config->gl_msaa)
4089                     {
4090                        opt[opt_i++] = ECORE_EVAS_OPT_GL_MSAA;
4091                        opt[opt_i++] = _elm_config->gl_msaa;
4092                     }
4093                   opt[opt_i] = 0;
4094                   if (opt_i > 0)
4095                     tmp_sd.ee = ecore_evas_wayland_egl_options_new(NULL, 0, 0, 0, 1, 1, 0, opt);
4096                   else
4097                     tmp_sd.ee = ecore_evas_wayland_egl_new(NULL, 0, 0, 0, 1, 1, 0);
4098                }
4099              else if (!strcmp(enginelist[i], ELM_SOFTWARE_WIN32))
4100                tmp_sd.ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1);
4101              else if (!strcmp(enginelist[i], ELM_SOFTWARE_DDRAW))
4102                tmp_sd.ee = ecore_evas_software_ddraw_new(NULL, 0, 0, 1, 1);
4103              else if (!strcmp(enginelist[i], ELM_SOFTWARE_SDL))
4104                tmp_sd.ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1);
4105              else if (!strcmp(enginelist[i], ELM_OPENGL_SDL))
4106                tmp_sd.ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0);
4107              else if (!strcmp(enginelist[i], ELM_OPENGL_COCOA))
4108                tmp_sd.ee = ecore_evas_cocoa_new(NULL, 1, 1, 0, 0);
4109              else if (!strcmp(enginelist[i], ELM_EWS))
4110                tmp_sd.ee = ecore_evas_ews_new(0, 0, 1, 1);
4111              else if (!strcmp(enginelist[i], ELM_SOFTWARE_FB))
4112                tmp_sd.ee = ecore_evas_fb_new(NULL, 0, 1, 1);
4113              else if (!strcmp(enginelist[i], ELM_BUFFER))
4114                tmp_sd.ee = ecore_evas_buffer_new(1, 1);
4115              else if (!strcmp(enginelist[i], ELM_SOFTWARE_PSL1GHT))
4116                tmp_sd.ee = ecore_evas_psl1ght_new(NULL, 1, 1);
4117              else if (!strcmp(enginelist[i], ELM_DRM))
4118                tmp_sd.ee = ecore_evas_drm_new(NULL, 0, 0, 0, 1, 1);
4119              else if (!strncmp(enginelist[i], "shot:", 5))
4120                {
4121                   tmp_sd.ee = ecore_evas_buffer_new(1, 1);
4122                   ecore_evas_manual_render_set(tmp_sd.ee, EINA_TRUE);
4123                   tmp_sd.shot.info = eina_stringshare_add(ENGINE_GET() + 5);
4124                }
4125              engine = enginelist[i];
4126              if (tmp_sd.ee) break;
4127           }
4128         break;
4129      }
4130
4131    if (!tmp_sd.ee)
4132      {
4133         ERR("Cannot create window.");
4134         return NULL;
4135      }
4136
4137    eo_do(obj, eo_parent_set(ecore_evas_get(tmp_sd.ee)));
4138
4139    eo_do_super(obj, MY_CLASS, eo_constructor());
4140    eo_do(obj,
4141          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
4142          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks));
4143
4144    if (getenv("ELM_FIRST_FRAME"))
4145      evas_event_callback_add(ecore_evas_get(tmp_sd.ee), EVAS_CALLBACK_RENDER_POST,
4146                              _elm_win_first_frame_do, getenv("ELM_FIRST_FRAME"));
4147
4148    /* copying possibly altered fields back */
4149 #define SD_CPY(_field)             \
4150   do                               \
4151     {                              \
4152        sd->_field = tmp_sd._field; \
4153     } while (0)
4154
4155    SD_CPY(ee);
4156    SD_CPY(img_obj);
4157    SD_CPY(shot.info);
4158 #undef SD_CPY
4159
4160    if ((type != ELM_WIN_FAKE) && (trap) && (trap->add))
4161      sd->trap_data = trap->add(obj);
4162
4163    /* complementary actions, which depend on final smart data
4164     * pointer */
4165    if (type == ELM_WIN_INLINED_IMAGE)
4166      _win_inlined_image_set(sd);
4167 #ifdef HAVE_ELEMENTARY_X
4168    else if ((engine) &&
4169             ((!strcmp(engine, ELM_SOFTWARE_X11)) ||
4170              (!strcmp(engine, ELM_OPENGL_X11))))
4171      {
4172         sd->x.client_message_handler = ecore_event_handler_add
4173             (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, obj);
4174         sd->x.property_handler = ecore_event_handler_add
4175             (ECORE_X_EVENT_WINDOW_PROPERTY, _elm_win_property_change, obj);
4176      }
4177 #endif
4178 #ifdef HAVE_ELEMENTARY_WAYLAND
4179    else if ((engine) &&
4180             ((!strcmp(engine, ELM_WAYLAND_SHM)) ||
4181              (!strcmp(engine, ELM_WAYLAND_EGL))))
4182      {
4183         sd->wl.effect_start_handler = ecore_event_handler_add
4184            (ECORE_WL_EVENT_EFFECT_START, _elm_win_wl_effect_start, obj);
4185         sd->wl.effect_end_handler = ecore_event_handler_add
4186            (ECORE_WL_EVENT_EFFECT_END, _elm_win_wl_effect_end, obj);
4187      }
4188 #endif
4189    else if ((engine) && (!strncmp(engine, "shot:", 5)))
4190      _shot_init(sd);
4191
4192    sd->kbdmode = ELM_WIN_KEYBOARD_UNKNOWN;
4193    sd->indmode = ELM_WIN_INDICATOR_UNKNOWN;
4194
4195 #ifdef HAVE_ELEMENTARY_X
4196    _internal_elm_win_xwindow_get(sd);
4197    if (sd->x.xwin)
4198      {
4199         ecore_x_io_error_handler_set(_elm_x_io_err, NULL);
4200      }
4201 #endif
4202
4203 #ifdef HAVE_ELEMENTARY_WAYLAND
4204    _elm_win_wlwindow_get(sd);
4205 #endif
4206
4207    if ((_elm_config->bgpixmap)
4208 #ifdef HAVE_ELEMENTARY_X
4209        &&
4210        (((sd->x.xwin) && (!ecore_x_screen_is_composited(0))) ||
4211            (!sd->x.xwin)))
4212 #else
4213      )
4214 #endif
4215      TRAP(sd, avoid_damage_set, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
4216    // bg pixmap done by x - has other issues like can be redrawn by x before it
4217    // is filled/ready by app
4218    //     TRAP(sd, avoid_damage_set, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
4219
4220    sd->type = type;
4221    sd->parent = parent;
4222    sd->modal_count = 0;
4223    sd->withdrawn = ecore_evas_withdrawn_get(sd->ee);
4224    sd->obscured = ecore_evas_obscured_get(sd->ee);
4225
4226    if (sd->parent)
4227      {
4228 #ifdef HAVE_ELEMENTARY_WAYLAND
4229         if ((sd->type >= ELM_WIN_BASIC) && (sd->type <= ELM_WIN_DND))
4230           ecore_wl_window_parent_set(sd->wl.win, elm_win_wl_window_get(sd->parent));
4231 #endif
4232         evas_object_event_callback_add
4233           (sd->parent, EVAS_CALLBACK_DEL, _elm_win_on_parent_del, obj);
4234      }
4235
4236    sd->evas = ecore_evas_get(sd->ee);
4237
4238    evas_object_color_set(obj, 0, 0, 0, 0);
4239    evas_object_move(obj, 0, 0);
4240    evas_object_resize(obj, 1, 1);
4241    evas_object_pass_events_set(obj, EINA_TRUE);
4242
4243    if (type == ELM_WIN_INLINED_IMAGE)
4244      elm_widget_parent2_set(obj, parent);
4245
4246    /* use own version of ecore_evas_object_associate() that does TRAP() */
4247    ecore_evas_data_set(sd->ee, "elm_win", obj);
4248
4249    if (type != ELM_WIN_FAKE)
4250      {
4251         evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
4252            _elm_win_obj_callback_changed_size_hints, obj);
4253         evas_object_intercept_raise_callback_add
4254           (obj, _elm_win_obj_intercept_raise, obj);
4255         evas_object_intercept_lower_callback_add
4256           (obj, _elm_win_obj_intercept_lower, obj);
4257         evas_object_intercept_stack_above_callback_add
4258           (obj, _elm_win_obj_intercept_stack_above, obj);
4259         evas_object_intercept_stack_below_callback_add
4260           (obj, _elm_win_obj_intercept_stack_below, obj);
4261         evas_object_intercept_layer_set_callback_add
4262           (obj, _elm_win_obj_intercept_layer_set, obj);
4263         evas_object_intercept_show_callback_add
4264           (obj, _elm_win_obj_intercept_show, obj);
4265      }
4266
4267    TRAP(sd, name_class_set, name, _elm_appname);
4268    TRAP(sd, title_set, sd->title);
4269    ecore_evas_callback_delete_request_set(sd->ee, _elm_win_delete_request);
4270    ecore_evas_callback_state_change_set(sd->ee, _elm_win_state_change);
4271    ecore_evas_callback_focus_in_set(sd->ee, _elm_win_focus_in);
4272    ecore_evas_callback_focus_out_set(sd->ee, _elm_win_focus_out);
4273    ecore_evas_callback_resize_set(sd->ee, _elm_win_resize);
4274    ecore_evas_callback_move_set(sd->ee, _elm_win_move);
4275    if (type != ELM_WIN_FAKE)
4276      ecore_evas_callback_mouse_in_set(sd->ee, _elm_win_mouse_in);
4277    evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _elm_win_cb_hide, NULL);
4278    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _elm_win_cb_show, NULL);
4279
4280    evas_image_cache_set(sd->evas, (_elm_config->image_cache * 1024));
4281    evas_font_cache_set(sd->evas, (_elm_config->font_cache * 1024));
4282
4283    EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
4284      evas_font_path_append(sd->evas, fontpath);
4285
4286    if (!_elm_config->font_hinting)
4287      evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_NONE);
4288    else if (_elm_config->font_hinting == 1)
4289      evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_AUTO);
4290    else if (_elm_config->font_hinting == 2)
4291      evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_BYTECODE);
4292
4293    sd->wm_rot.wm_supported = ecore_evas_wm_rotation_supported_get(sd->ee);
4294    sd->wm_rot.preferred_rot = -1; // it means that elm_win doesn't use preferred rotation.
4295
4296 #ifdef HAVE_ELEMENTARY_X
4297    _elm_win_xwin_update(sd);
4298 #endif
4299 #ifdef HAVE_ELEMENTARY_WAYLAND
4300    _elm_win_wlwin_update(sd);
4301 #endif
4302
4303    /* do not append to list; all windows render as black rects */
4304
4305    sd->frame_style = eina_stringshare_add("default");
4306    if (type != ELM_WIN_FAKE)
4307      {
4308         _elm_win_list = eina_list_append(_elm_win_list, obj);
4309         _elm_win_count++;
4310
4311         if ((engine) && ((!strcmp(engine, ELM_SOFTWARE_FB)) || (!strcmp(engine, ELM_DRM))))
4312           {
4313              TRAP(sd, fullscreen_set, 1);
4314           }
4315         else if ((type != ELM_WIN_INLINED_IMAGE) &&
4316                  ((engine) &&
4317                   ((!strcmp(engine, ELM_WAYLAND_SHM) ||
4318                    (!strcmp(engine, ELM_WAYLAND_EGL))))))
4319           _elm_win_frame_add(sd, sd->frame_style);
4320
4321         if (_elm_config->focus_highlight_enable)
4322           elm_win_focus_highlight_enabled_set(obj, EINA_TRUE);
4323         if (_elm_config->focus_highlight_animate)
4324           elm_win_focus_highlight_animate_set(obj, EINA_TRUE);
4325
4326         //Prohibiting auto-rendering, until elm_win is shown.
4327         if (_elm_config->auto_norender_withdrawn)
4328           {
4329              if (elm_win_withdrawn_get(obj))
4330                {
4331                   if (!evas_object_data_get(obj, "__win_auto_norender"))
4332                     {
4333                        elm_win_norender_push(obj);
4334                        evas_object_data_set(obj, "__win_auto_norender", obj);
4335                     }
4336                }
4337           }
4338      }
4339
4340 #ifdef ELM_DEBUG
4341    Evas_Modifier_Mask mask = evas_key_modifier_mask_get(sd->evas, "Control");
4342    evas_object_event_callback_add
4343      (obj, EVAS_CALLBACK_KEY_DOWN, _debug_key_down, NULL);
4344
4345    if (evas_object_key_grab(obj, "F12", mask, 0, EINA_TRUE))
4346      INF("Ctrl+F12 key combination exclusive for dot tree generation\n");
4347    else
4348      ERR("failed to grab F12 key to elm widgets (dot) tree generation");
4349 #endif
4350
4351    if (type != ELM_WIN_FAKE)
4352      {
4353         if ((_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_ON) ||
4354             ((_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_AUTO) &&
4355              ((engine) &&
4356               ((!strcmp(engine, ELM_SOFTWARE_FB)) || (!strcmp(engine, ELM_DRM))))))
4357           {
4358              Evas_Object *o;
4359              Evas_Coord mw = 1, mh = 1, hx = 0, hy = 0;
4360
4361              sd->pointer.obj = o = edje_object_add(ecore_evas_get(tmp_sd.ee));
4362              _elm_theme_object_set(obj, o, "pointer", "base", "default");
4363              edje_object_size_min_calc(o, &mw, &mh);
4364              evas_object_resize(o, mw, mh);
4365              edje_object_part_geometry_get(o, "elm.swallow.hotspot",
4366                                            &hx, &hy, NULL, NULL);
4367              sd->pointer.hot_x = hx;
4368              sd->pointer.hot_y = hy;
4369              evas_object_show(o);
4370              ecore_evas_object_cursor_set(tmp_sd.ee, o, EVAS_LAYER_MAX, hx, hy);
4371           }
4372         else if (_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_OFF)
4373           {
4374              // do nothing
4375           }
4376      }
4377
4378    sd->edje = edje_object_add(sd->evas);
4379    _elm_win_theme_internal(obj, sd);
4380
4381    sd->box = evas_object_box_add(sd->evas);
4382    evas_object_box_layout_set(sd->box, _window_layout_stack, obj, NULL);
4383    edje_object_part_swallow(sd->edje, "elm.swallow.contents", sd->box);
4384    evas_object_move(sd->edje, 0, 0);
4385    evas_object_resize(sd->edje, 1, 1);
4386    if (type != ELM_WIN_FAKE)
4387      {
4388         edje_object_update_hints_set(sd->edje, EINA_TRUE);
4389         evas_object_event_callback_add(sd->edje, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
4390                                        _elm_win_on_resize_obj_changed_size_hints, obj);
4391      }
4392
4393    eo_do(obj, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_WINDOW));
4394    if (_elm_config->atspi_mode)
4395      elm_interface_atspi_window_created_signal_emit(obj);
4396
4397    if(_elm_config->win_no_border)
4398      _elm_win_borderless_set(obj, sd, EINA_TRUE);
4399
4400    evas_object_show(sd->edje);
4401
4402    eo_do(obj, eo_event_callback_add(EO_EV_CALLBACK_ADD, _cb_added, sd),
4403          eo_event_callback_add(EO_EV_CALLBACK_DEL, _cb_deled, sd));
4404    if (type == ELM_WIN_FAKE)
4405      {
4406         _elm_win_resize_job(obj);
4407         _elm_win_move(sd->ee);
4408      }
4409    return obj;
4410 }
4411
4412 EOLIAN static Eo *
4413 _elm_win_eo_base_finalize(Eo *obj, Elm_Win_Data *_pd)
4414 {
4415    obj = _elm_win_finalize_internal(obj, _pd, _pd->name, _pd->type);
4416    if (obj)
4417      {
4418         eo_do_super(obj, MY_CLASS, obj = eo_finalize());
4419      }
4420    return obj;
4421 }
4422
4423 EOLIAN static Eo *
4424 _elm_win_eo_base_constructor(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED)
4425 {
4426    /* Do nothing. */
4427    /* XXX: We are calling the constructor chain from the finalizer. It's
4428     * really bad and hacky. Needs fixing. */
4429
4430    return obj;
4431 }
4432
4433 EOLIAN static void
4434 _elm_win_fake_canvas_set(Eo *obj EINA_UNUSED, Elm_Win_Data *pd, Ecore_Evas *oee)
4435 {
4436    pd->ee = oee;
4437 }
4438
4439 EOLIAN static void
4440 _elm_win_type_set(Eo *obj, Elm_Win_Data *sd, Elm_Win_Type type)
4441 {
4442    Eina_Bool finalized;
4443    if (eo_do_ret(obj, finalized, eo_finalized_get()))
4444      {
4445         ERR("This function is only allowed during construction.");
4446         return;
4447      }
4448    sd->type = type;
4449 }
4450
4451 EOLIAN static Elm_Win_Type
4452 _elm_win_type_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4453 {
4454    return sd->type;
4455 }
4456
4457 EOLIAN static void
4458 _elm_win_name_set(Eo *obj, Elm_Win_Data *sd, const char *name)
4459 {
4460    Eina_Bool finalized;
4461    if (eo_do_ret(obj, finalized, eo_finalized_get()))
4462      {
4463         ERR("This function is only allowed during construction.");
4464         return;
4465      }
4466    sd->name = eina_stringshare_add(name);
4467 }
4468
4469 EOLIAN static void
4470 _elm_win_noblank_set(Eo *obj EINA_UNUSED, Elm_Win_Data *pd, Eina_Bool noblank)
4471 {
4472    noblank = !!noblank;
4473    if (pd->noblank == noblank) return;
4474    pd->noblank = noblank;
4475    _win_noblank_eval();
4476 }
4477
4478 EOLIAN static Eina_Bool
4479 _elm_win_noblank_get(Eo *obj EINA_UNUSED, Elm_Win_Data *pd)
4480 {
4481    return pd->noblank;
4482 }
4483
4484 EOLIAN static void *
4485 _elm_win_trap_data_get(Eo *obj EINA_UNUSED, Elm_Win_Data *pd)
4486 {
4487    return pd->trap_data;
4488 }
4489
4490
4491 EAPI Evas_Object *
4492 elm_win_util_standard_add(const char *name, const char *title)
4493 {
4494    Evas_Object *win, *bg;
4495
4496    win = elm_win_add(NULL, name, ELM_WIN_BASIC);
4497    if (!win) return NULL;
4498
4499    elm_win_title_set(win, title);
4500    bg = elm_bg_add(win);
4501    if (!bg)
4502      {
4503         evas_object_del(win);
4504         return NULL;
4505      }
4506    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
4507    elm_win_resize_object_add(win, bg);
4508    evas_object_show(bg);
4509
4510    return win;
4511 }
4512
4513 EAPI Evas_Object *
4514 elm_win_util_dialog_add(Evas_Object *parent, const char *name, const char *title)
4515 {
4516    Evas_Object *win, *bg;
4517
4518    win = elm_win_add(parent, name, ELM_WIN_DIALOG_BASIC);
4519    if (!win) return NULL;
4520
4521    elm_win_title_set(win, title);
4522    bg = elm_bg_add(win);
4523    if (!bg)
4524      {
4525         evas_object_del(win);
4526         return NULL;
4527      }
4528    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
4529    elm_win_resize_object_add(win, bg);
4530    evas_object_show(bg);
4531
4532    return win;
4533 }
4534
4535 EOLIAN static void
4536 _elm_win_resize_object_add(Eo *obj, Elm_Win_Data *sd, Evas_Object *subobj)
4537 {
4538    elm_widget_sub_object_add(obj, subobj);
4539
4540    if (!evas_object_box_append(sd->box, subobj))
4541      ERR("could not append %p to box", subobj);
4542 }
4543
4544 EOLIAN static void
4545 _elm_win_resize_object_del(Eo *obj, Elm_Win_Data *sd, Evas_Object *subobj)
4546 {
4547    if (!elm_widget_sub_object_del(obj, subobj))
4548      ERR("could not remove sub object %p from %p", subobj, obj);
4549
4550    evas_object_box_remove(sd->box, subobj);
4551 }
4552
4553 EOLIAN static void
4554 _elm_win_title_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *title)
4555 {
4556    if (!title) return;
4557    eina_stringshare_replace(&(sd->title), title);
4558    if (sd->ee)
4559      TRAP(sd, title_set, sd->title);
4560    if (sd->frame_obj)
4561      edje_object_part_text_escaped_set
4562        (sd->frame_obj, "elm.text.title", sd->title);
4563 }
4564
4565 EOLIAN static const char*
4566 _elm_win_title_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4567 {
4568    return sd->title;
4569 }
4570
4571 EOLIAN static void
4572 _elm_win_icon_name_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *icon_name)
4573 {
4574    if (!icon_name) return;
4575    eina_stringshare_replace(&(sd->icon_name), icon_name);
4576 #ifdef HAVE_ELEMENTARY_X
4577    _elm_win_xwin_update(sd);
4578 #endif
4579 }
4580
4581 EOLIAN static const char*
4582 _elm_win_icon_name_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4583 {
4584    return sd->icon_name;
4585 }
4586
4587 EOLIAN static void
4588 _elm_win_role_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *role)
4589 {
4590    if (!role) return;
4591    eina_stringshare_replace(&(sd->role), role);
4592 #ifdef HAVE_ELEMENTARY_X
4593    _elm_win_xwin_update(sd);
4594 #endif
4595 #ifdef HAVE_ELEMENTARY_WAYLAND
4596    ecore_wl_window_role_set(sd->wl.win, role);
4597 #endif
4598 }
4599
4600 EOLIAN static const char*
4601 _elm_win_role_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4602 {
4603    return sd->role;
4604 }
4605
4606 EOLIAN static void
4607 _elm_win_icon_object_set(Eo *obj, Elm_Win_Data *sd, Evas_Object *icon)
4608 {
4609    if (sd->icon)
4610      evas_object_event_callback_del_full
4611        (sd->icon, EVAS_CALLBACK_DEL, _elm_win_on_icon_del, obj);
4612    sd->icon = icon;
4613    if (sd->icon)
4614      evas_object_event_callback_add
4615        (sd->icon, EVAS_CALLBACK_DEL, _elm_win_on_icon_del, obj);
4616 #ifdef HAVE_ELEMENTARY_X
4617    _elm_win_xwin_update(sd);
4618 #endif
4619 }
4620
4621 EOLIAN static const Evas_Object*
4622 _elm_win_icon_object_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4623 {
4624    return sd->icon;
4625 }
4626
4627 EOLIAN static void
4628 _elm_win_autodel_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool autodel)
4629 {
4630    sd->autodel = autodel;
4631 }
4632
4633 EOLIAN static Eina_Bool
4634 _elm_win_autodel_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4635 {
4636    return sd->autodel;
4637 }
4638
4639 EOLIAN static void
4640 _elm_win_autohide_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool autohide)
4641 {
4642    sd->autohide = autohide;
4643 }
4644
4645 EOLIAN static Eina_Bool
4646 _elm_win_autohide_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4647 {
4648    return sd->autohide;
4649 }
4650
4651 EOLIAN static void
4652 _elm_win_activate(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4653 {
4654    TRAP(sd, activate);
4655 }
4656
4657 EOLIAN static void
4658 _elm_win_lower(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4659 {
4660    TRAP(sd, lower);
4661 }
4662
4663 EOLIAN static void
4664 _elm_win_raise(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4665 {
4666    TRAP(sd, raise);
4667 }
4668
4669 EOLIAN static void
4670 _elm_win_center(Eo *obj, Elm_Win_Data *sd, Eina_Bool h, Eina_Bool v)
4671 {
4672    int win_w, win_h, screen_w, screen_h, nx, ny;
4673
4674    if ((trap) && (trap->center) && (!trap->center(sd->trap_data, obj, h, v)))
4675      return;
4676
4677    ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &screen_w, &screen_h);
4678    if ((!screen_w) || (!screen_h)) return;
4679
4680    evas_object_geometry_get(obj, &nx, &ny, &win_w, &win_h);
4681    if ((!win_w) || (!win_h)) return;
4682
4683    if (h) nx = win_w >= screen_w ? 0 : (screen_w / 2) - (win_w / 2);
4684    if (v) ny = win_h >= screen_h ? 0 : (screen_h / 2) - (win_h / 2);
4685    if (nx < sd->screen.x) nx = sd->screen.x;
4686    if (ny < sd->screen.y) ny = sd->screen.y;
4687
4688    evas_object_move(obj, nx, ny);
4689 }
4690
4691 EOLIAN static void
4692 _elm_win_borderless_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool borderless)
4693 {
4694    const char *engine_name = ecore_evas_engine_name_get(sd->ee);
4695    Eina_Bool need_frame = engine_name &&
4696                           ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
4697                            (!strcmp(engine_name, ELM_WAYLAND_EGL)));
4698
4699    if (need_frame)
4700      need_frame = !sd->fullscreen;
4701
4702    if (borderless)
4703      {
4704         if (need_frame)
4705           _elm_win_frame_del(sd);
4706      }
4707    else
4708      {
4709         if (need_frame)
4710           _elm_win_frame_add(sd, sd->frame_style);
4711
4712         if (sd->frame_obj)
4713           evas_object_show(sd->frame_obj);
4714      }
4715
4716    sd->borderless = borderless;
4717
4718    TRAP(sd, borderless_set, borderless);
4719 #ifdef HAVE_ELEMENTARY_X
4720    _elm_win_xwin_update(sd);
4721 #endif
4722 }
4723
4724 EOLIAN static Eina_Bool
4725 _elm_win_borderless_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4726 {
4727    return ecore_evas_borderless_get(sd->ee);
4728 }
4729
4730 EOLIAN static void
4731 _elm_win_border_style_set(Eo *obj, Elm_Win_Data *sd, const char *style)
4732 {
4733    Elm_Theme *theme;
4734    char buf[1024];
4735
4736    if (!style) return;
4737    if (!strcmp(sd->frame_style, style))
4738      return;
4739
4740    theme = elm_widget_theme_get(obj);
4741    if (!theme) theme = elm_theme_default_get();
4742    if (theme)
4743      {
4744         snprintf(buf, sizeof(buf), "elm/border/base/%s", style);
4745         if (!elm_theme_group_path_find(theme, buf))
4746           return;
4747      }
4748
4749    eina_stringshare_replace(&(sd->frame_style), style);
4750
4751    if (sd->frame_obj)
4752      {
4753         _elm_win_frame_del(sd);
4754         _elm_win_frame_add(sd, sd->frame_style);
4755
4756         if (sd->frame_obj)
4757           evas_object_show(sd->frame_obj);
4758      }
4759 }
4760
4761 EOLIAN static const char*
4762 _elm_win_border_style_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4763 {
4764    return sd->frame_style;
4765 }
4766
4767 EOLIAN static void
4768 _elm_win_shaped_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool shaped)
4769 {
4770    TRAP(sd, shaped_set, shaped);
4771 #ifdef HAVE_ELEMENTARY_X
4772    _elm_win_xwin_update(sd);
4773 #endif
4774 }
4775
4776 EOLIAN static Eina_Bool
4777 _elm_win_shaped_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4778 {
4779    return ecore_evas_shaped_get(sd->ee);
4780 }
4781
4782 EOLIAN static void
4783 _elm_win_alpha_set(Eo *obj, Elm_Win_Data *sd, Eina_Bool enabled)
4784 {
4785    sd->application_alpha = enabled;
4786    _elm_win_apply_alpha(obj, sd);
4787 }
4788
4789 EOLIAN static Eina_Bool
4790 _elm_win_alpha_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4791 {
4792    if (sd->img_obj)
4793      {
4794         return evas_object_image_alpha_get(sd->img_obj);
4795      }
4796    else
4797      {
4798         return ecore_evas_alpha_get(sd->ee);
4799      }
4800
4801    return EINA_FALSE;
4802 }
4803
4804 EOLIAN static void
4805 _elm_win_override_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool override)
4806 {
4807    TRAP(sd, override_set, override);
4808 #ifdef HAVE_ELEMENTARY_X
4809    _elm_win_xwin_update(sd);
4810 #endif
4811 }
4812
4813 EOLIAN static Eina_Bool
4814 _elm_win_override_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4815 {
4816    return ecore_evas_override_get(sd->ee);
4817 }
4818
4819 EOLIAN static void
4820 _elm_win_fullscreen_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool fullscreen)
4821 {
4822    const char *engine_name = ecore_evas_engine_name_get(sd->ee);
4823    // YYY: handle if sd->img_obj
4824    if (engine_name &&
4825        ((!strcmp(engine_name, ELM_SOFTWARE_FB)) ||
4826         (!strcmp(engine_name, ELM_DRM))))
4827      {
4828         // these engines... can ONLY be fullscreen
4829         return;
4830      }
4831    else if (sd->type == ELM_WIN_FAKE)
4832      sd->fullscreen = !!fullscreen;
4833    else
4834      {
4835 //        sd->fullscreen = fullscreen;
4836         Eina_Bool need_frame = engine_name &&
4837                                ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
4838                                 (!strcmp(engine_name, ELM_WAYLAND_EGL)));
4839
4840         if (need_frame)
4841           need_frame = !ecore_evas_borderless_get(sd->ee);
4842
4843         TRAP(sd, fullscreen_set, fullscreen);
4844
4845         if (fullscreen)
4846           {
4847              if (need_frame)
4848                _elm_win_frame_del(sd);
4849           }
4850         else
4851           {
4852              if (need_frame)
4853                _elm_win_frame_add(sd, sd->frame_style);
4854
4855              if (sd->frame_obj)
4856                evas_object_show(sd->frame_obj);
4857           }
4858 #ifdef HAVE_ELEMENTARY_X
4859         _elm_win_xwin_update(sd);
4860 #endif
4861      }
4862 }
4863
4864 EOLIAN static Eina_Bool
4865 _elm_win_fullscreen_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4866 {
4867    const char *engine_name = ecore_evas_engine_name_get(sd->ee);
4868
4869    if (engine_name &&
4870        ((!strcmp(engine_name, ELM_SOFTWARE_FB)) ||
4871         (!strcmp(engine_name, ELM_DRM))))
4872      {
4873         // these engines... can ONLY be fullscreen
4874         return EINA_TRUE;
4875      }
4876    return sd->fullscreen;
4877 }
4878
4879 static void
4880 _dbus_menu_set(Eina_Bool dbus_connect, void *data)
4881 {
4882    ELM_WIN_DATA_GET_OR_RETURN(data, sd);
4883
4884    if (dbus_connect)
4885      {
4886         DBG("Setting menu to D-Bus");
4887         edje_object_part_unswallow(sd->edje, sd->main_menu);
4888         edje_object_signal_emit(sd->edje, "elm,action,hide_menu", "elm");
4889         _elm_menu_menu_bar_hide(sd->main_menu);
4890      }
4891    else
4892      {
4893         DBG("Setting menu to local mode");
4894         edje_object_part_swallow(sd->edje, "elm.swallow.menu", sd->main_menu);
4895         edje_object_signal_emit(sd->edje, "elm,action,show_menu", "elm");
4896         evas_object_show(sd->main_menu);
4897      }
4898 }
4899
4900 EOLIAN static Evas_Object *
4901 _elm_win_main_menu_get(Eo *obj, Elm_Win_Data *sd)
4902 {
4903    Eina_Bool use_dbus = EINA_FALSE;
4904
4905    if (sd->main_menu) goto end;
4906
4907    sd->main_menu = elm_menu_add(obj);
4908    _elm_menu_menu_bar_set(sd->main_menu, EINA_TRUE);
4909
4910 #ifdef HAVE_ELEMENTARY_X
4911    if (!_elm_config->disable_external_menu && sd->x.xwin) use_dbus = EINA_TRUE;
4912 #endif
4913
4914 #ifdef HAVE_ELEMENTARY_X
4915    if (use_dbus && _elm_dbus_menu_register(sd->main_menu))
4916      {
4917         _elm_dbus_menu_app_menu_register(sd->x.xwin, sd->main_menu,
4918                                          _dbus_menu_set, obj);
4919      }
4920    else
4921 #endif
4922      _dbus_menu_set(EINA_FALSE, obj);
4923
4924 end:
4925    return sd->main_menu;
4926 }
4927
4928 EOLIAN static void
4929 _elm_win_maximized_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool maximized)
4930 {
4931    _elm_win_frame_maximized_state_update(sd, maximized);
4932    // YYY: handle if sd->img_obj
4933    TRAP(sd, maximized_set, maximized);
4934 #ifdef HAVE_ELEMENTARY_X
4935    _elm_win_xwin_update(sd);
4936 #endif
4937 }
4938
4939 EOLIAN static Eina_Bool
4940 _elm_win_maximized_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4941 {
4942    return sd->maximized;
4943 }
4944
4945 EOLIAN static void
4946 _elm_win_iconified_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool iconified)
4947 {
4948 //   sd->iconified = iconified;
4949    TRAP(sd, iconified_set, iconified);
4950 #ifdef HAVE_ELEMENTARY_X
4951    _elm_win_xwin_update(sd);
4952 #endif
4953 }
4954
4955 EOLIAN static Eina_Bool
4956 _elm_win_iconified_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4957 {
4958    return sd->iconified;
4959 }
4960
4961 EOLIAN static void
4962 _elm_win_withdrawn_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool withdrawn)
4963 {
4964 //   sd->withdrawn = withdrawn;
4965    TRAP(sd, withdrawn_set, withdrawn);
4966 #ifdef HAVE_ELEMENTARY_X
4967    _elm_win_xwin_update(sd);
4968 #endif
4969 }
4970
4971 EOLIAN static Eina_Bool
4972 _elm_win_withdrawn_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4973 {
4974    return sd->withdrawn;
4975 }
4976
4977 EOLIAN static void
4978 _elm_win_available_profiles_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char **profiles, unsigned int count)
4979 {
4980    Eina_Bool found = EINA_FALSE;
4981
4982    _elm_win_available_profiles_del(sd);
4983    if ((profiles) && (count >= 1))
4984      {
4985         sd->profile.available_list = calloc(count, sizeof(char *));
4986         if (sd->profile.available_list)
4987           {
4988              if (!sd->profile.name) found = EINA_TRUE;
4989
4990              unsigned int i;
4991              for (i = 0; i < count; i++)
4992                {
4993                   sd->profile.available_list[i] = eina_stringshare_add(profiles[i]);
4994
4995                   /* check to see if a given array has a current profile of elm_win */
4996                   if ((sd->profile.name) &&
4997                       (!strcmp(sd->profile.name, profiles[i])))
4998                     {
4999                        found = EINA_TRUE;
5000                     }
5001                }
5002              sd->profile.count = count;
5003           }
5004      }
5005
5006    if (ecore_evas_window_profile_supported_get(sd->ee))
5007      {
5008         ecore_evas_window_available_profiles_set(sd->ee,
5009                                                  sd->profile.available_list,
5010                                                  sd->profile.count);
5011
5012         /* current profile of elm_win is wrong, change profile */
5013         if ((sd->profile.available_list) && (!found))
5014           {
5015              eina_stringshare_replace(&(sd->profile.name),
5016                                       sd->profile.available_list[0]);
5017              ecore_evas_window_profile_set(sd->ee, sd->profile.name);
5018           }
5019
5020      }
5021    else
5022      {
5023         if (sd->profile.available_list)
5024           _elm_win_profile_update(sd);
5025      }
5026 }
5027
5028 EOLIAN static Eina_Bool
5029 _elm_win_available_profiles_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, char ***profiles, unsigned int *count)
5030 {
5031    if (ecore_evas_window_profile_supported_get(sd->ee))
5032      {
5033         return ecore_evas_window_available_profiles_get(sd->ee,
5034                                                        profiles,
5035                                                        count);
5036      }
5037    else
5038      {
5039         if (profiles) *profiles = (char **)sd->profile.available_list;
5040         if (count) *count = sd->profile.count;
5041         return EINA_TRUE;
5042      }
5043 }
5044
5045 EOLIAN static void
5046 _elm_win_profile_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *profile)
5047 {
5048    /* check to see if a given profile is present in an available profiles */
5049    if ((profile) && (sd->profile.available_list))
5050      {
5051         Eina_Bool found = EINA_FALSE;
5052         unsigned int i;
5053         for (i = 0; i < sd->profile.count; i++)
5054           {
5055              if (!strcmp(profile,
5056                          sd->profile.available_list[i]))
5057                {
5058                   found = EINA_TRUE;
5059                   break;
5060                }
5061           }
5062         if (!found) return;
5063      }
5064
5065    if (ecore_evas_window_profile_supported_get(sd->ee))
5066      {
5067         if (!profile) _elm_win_profile_del(sd);
5068         ecore_evas_window_profile_set(sd->ee, profile);
5069      }
5070    else
5071      {
5072         if (_internal_elm_win_profile_set(sd, profile))
5073           _elm_win_profile_update(sd);
5074      }
5075 }
5076
5077 EOLIAN static const char*
5078 _elm_win_profile_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5079 {
5080    return sd->profile.name;
5081 }
5082
5083 EOLIAN static void
5084 _elm_win_urgent_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool urgent)
5085 {
5086    if (sd->urgent == urgent)
5087      return;
5088    sd->urgent = urgent;
5089    TRAP(sd, urgent_set, urgent);
5090 #ifdef HAVE_ELEMENTARY_X
5091    _elm_win_xwin_update(sd);
5092 #endif
5093 }
5094
5095 EOLIAN static Eina_Bool
5096 _elm_win_urgent_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5097 {
5098    return sd->urgent;
5099 }
5100
5101 EOLIAN static void
5102 _elm_win_demand_attention_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool demand_attention)
5103 {
5104    sd->demand_attention = demand_attention;
5105    TRAP(sd, demand_attention_set, demand_attention);
5106 #ifdef HAVE_ELEMENTARY_X
5107    _elm_win_xwin_update(sd);
5108 #endif
5109 }
5110
5111 EOLIAN static Eina_Bool
5112 _elm_win_demand_attention_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5113 {
5114    return sd->demand_attention;
5115 }
5116
5117 EOLIAN static void
5118 _elm_win_modal_set(Eo *obj, Elm_Win_Data *sd, Eina_Bool modal)
5119 {
5120    if (sd->modal_count) return;
5121
5122    const Eina_List *l;
5123    Evas_Object *current;
5124
5125    if ((modal) && (!sd->modal) && (evas_object_visible_get(obj)))
5126      {
5127        INCREMENT_MODALITY()
5128      }
5129    else if ((!modal) && (sd->modal) && (evas_object_visible_get(obj)))
5130      {
5131        DECREMENT_MODALITY()
5132      }
5133
5134    sd->modal = modal;
5135    TRAP(sd, modal_set, modal);
5136 #ifdef HAVE_ELEMENTARY_X
5137    _elm_win_xwin_update(sd);
5138 #endif
5139 }
5140
5141 EOLIAN static Eina_Bool
5142 _elm_win_modal_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5143 {
5144    return sd->modal;
5145 }
5146
5147 EOLIAN static void
5148 _elm_win_aspect_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, double aspect)
5149 {
5150    sd->aspect = aspect;
5151    TRAP(sd, aspect_set, aspect);
5152 #ifdef HAVE_ELEMENTARY_X
5153    _elm_win_xwin_update(sd);
5154 #endif
5155 }
5156
5157 EOLIAN static double
5158 _elm_win_aspect_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5159 {
5160    return sd->aspect;
5161 }
5162
5163 EOLIAN static void
5164 _elm_win_size_base_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int w, int h)
5165 {
5166    sd->size_base_w = w;
5167    sd->size_base_h = h;
5168    TRAP(sd, size_base_set, w, h);
5169 #ifdef HAVE_ELEMENTARY_X
5170    _elm_win_xwin_update(sd);
5171 #endif
5172 }
5173
5174 EOLIAN static void
5175 _elm_win_size_base_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *w, int *h)
5176 {
5177    if (w) *w = sd->size_base_w;
5178    if (h) *h = sd->size_base_h;
5179 }
5180
5181 EOLIAN static void
5182 _elm_win_size_step_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int w, int h)
5183 {
5184    sd->size_step_w = w;
5185    sd->size_step_h = h;
5186    TRAP(sd, size_step_set, w, h);
5187 #ifdef HAVE_ELEMENTARY_X
5188    _elm_win_xwin_update(sd);
5189 #endif
5190 }
5191
5192 EOLIAN static void
5193 _elm_win_size_step_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *w, int *h)
5194 {
5195    if (w) *w = sd->size_step_w;
5196    if (h) *h = sd->size_step_h;
5197 }
5198
5199 EOLIAN static void
5200 _elm_win_layer_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int layer)
5201 {
5202    TRAP(sd, layer_set, layer);
5203 #ifdef HAVE_ELEMENTARY_X
5204    _elm_win_xwin_update(sd);
5205 #endif
5206 }
5207
5208 EOLIAN static int
5209 _elm_win_layer_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5210 {
5211    return ecore_evas_layer_get(sd->ee);
5212 }
5213
5214 EAPI void
5215 elm_win_norender_push(Evas_Object *obj)
5216 {
5217    ELM_WIN_CHECK(obj);
5218    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
5219
5220    sd->norender++;
5221    if (sd->norender == 1) ecore_evas_manual_render_set(sd->ee, EINA_TRUE);
5222 }
5223
5224 EAPI void
5225 elm_win_norender_pop(Evas_Object *obj)
5226 {
5227    ELM_WIN_CHECK(obj);
5228    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
5229
5230    if (sd->norender <= 0) return;
5231    sd->norender--;
5232    if (sd->norender == 0) ecore_evas_manual_render_set(sd->ee, EINA_FALSE);
5233 }
5234
5235 EAPI int
5236 elm_win_norender_get(const Evas_Object *obj)
5237 {
5238    ELM_WIN_CHECK(obj) - 1;
5239    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, -1);
5240    return sd->norender;
5241 }
5242
5243 EAPI void
5244 elm_win_render(Evas_Object *obj)
5245 {
5246    ELM_WIN_CHECK(obj);
5247    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
5248    ecore_evas_manual_render(sd->ee);
5249 }
5250
5251 static int
5252 _win_rotation_degree_check(int rotation)
5253 {
5254    if ((rotation > 360) || (rotation < 0))
5255      {
5256         WRN("Rotation degree should be 0 ~ 360 (passed degree: %d)", rotation);
5257         rotation %= 360;
5258         if (rotation < 0) rotation += 360;
5259      }
5260    return rotation;
5261 }
5262
5263 /*
5264  * This API resizes the internal window(ex: X window) and evas_output.
5265  * But this does not resize the elm window object and its contents.
5266  */
5267 static void
5268 _win_rotate(Evas_Object *obj, Elm_Win_Data *sd, int rotation, Eina_Bool resize)
5269 {
5270    rotation = _win_rotation_degree_check(rotation);
5271    if (sd->rot == rotation) return;
5272    sd->rot = rotation;
5273    if (resize) TRAP(sd, rotation_with_resize_set, rotation);
5274    else TRAP(sd, rotation_set, rotation);
5275    evas_object_size_hint_min_set(obj, -1, -1);
5276    evas_object_size_hint_max_set(obj, -1, -1);
5277    _elm_win_resize_objects_eval(obj);
5278 #ifdef HAVE_ELEMENTARY_X
5279    _elm_win_xwin_update(sd);
5280 #endif
5281    _elm_win_frame_obj_update(sd);
5282    elm_widget_orientation_set(obj, rotation);
5283    eo_do(obj, eo_event_callback_call
5284      (ELM_WIN_EVENT_ROTATION_CHANGED, NULL));
5285 }
5286
5287 EOLIAN static void
5288 _elm_win_rotation_set(Eo *obj, Elm_Win_Data *sd, int rotation)
5289 {
5290    _win_rotate(obj, sd, rotation, EINA_FALSE);
5291 }
5292
5293 /*
5294  * This API does not resize the internal window (ex: X window).
5295  * But this resizes evas_output, elm window, and its contents.
5296  */
5297 EOLIAN static void
5298 _elm_win_rotation_with_resize_set(Eo *obj, Elm_Win_Data *sd, int rotation)
5299 {
5300    _win_rotate(obj, sd, rotation, EINA_TRUE);
5301 }
5302
5303 EOLIAN static int
5304 _elm_win_rotation_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5305 {
5306    return sd->rot;
5307 }
5308
5309 EOLIAN static Eina_Bool
5310 _elm_win_wm_rotation_supported_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5311 {
5312    return sd->wm_rot.wm_supported;
5313 }
5314
5315 /* This will unset a preferred rotation, if given preferred rotation is '-1'.
5316  */
5317 EAPI void
5318 elm_win_wm_rotation_preferred_rotation_set(const Evas_Object *obj,
5319                                            int rotation)
5320 {
5321    ELM_WIN_CHECK(obj);
5322    eo_do((Eo *) obj, elm_obj_win_wm_preferred_rotation_set(rotation));
5323 }
5324
5325 EOLIAN static void
5326 _elm_win_wm_preferred_rotation_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int rotation)
5327 {
5328    int rot;
5329
5330    if (!sd->wm_rot.use)
5331      sd->wm_rot.use = EINA_TRUE;
5332
5333    // '-1' means that elm_win doesn't use preferred rotation.
5334    if (rotation == -1)
5335      rot = -1;
5336    else
5337      rot = _win_rotation_degree_check(rotation);
5338
5339    if (sd->wm_rot.preferred_rot == rot) return;
5340    sd->wm_rot.preferred_rot = rot;
5341
5342    ecore_evas_wm_rotation_preferred_rotation_set(sd->ee, rot);
5343 }
5344
5345 EOLIAN static int
5346 _elm_win_wm_preferred_rotation_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5347 {
5348    return sd->wm_rot.preferred_rot;
5349 }
5350
5351 EOLIAN static void
5352 _elm_win_wm_available_rotations_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const int *rotations, unsigned int count)
5353 {
5354    unsigned int i;
5355    int r;
5356
5357    if (!sd->wm_rot.use)
5358      sd->wm_rot.use = EINA_TRUE;
5359
5360    ELM_SAFE_FREE(sd->wm_rot.rots, free);
5361    sd->wm_rot.count = 0;
5362
5363    if (count > 0)
5364      {
5365         sd->wm_rot.rots = calloc(count, sizeof(int));
5366         if (!sd->wm_rot.rots) return;
5367         for (i = 0; i < count; i++)
5368           {
5369              r = _win_rotation_degree_check(rotations[i]);
5370              sd->wm_rot.rots[i] = r;
5371           }
5372      }
5373
5374    sd->wm_rot.count = count;
5375
5376    ecore_evas_wm_rotation_available_rotations_set(sd->ee,
5377                                                   sd->wm_rot.rots,
5378                                                   sd->wm_rot.count);
5379 }
5380
5381 EOLIAN static Eina_Bool
5382 _elm_win_wm_available_rotations_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int **rotations, unsigned int *count)
5383 {
5384    if (!sd->wm_rot.use) return EINA_FALSE;
5385
5386    if (sd->wm_rot.count > 0)
5387      {
5388         if (rotations)
5389           {
5390              *rotations = calloc(sd->wm_rot.count, sizeof(int));
5391              if (*rotations)
5392                {
5393                   memcpy(*rotations,
5394                          sd->wm_rot.rots,
5395                          sizeof(int) * sd->wm_rot.count);
5396                }
5397           }
5398      }
5399
5400    if (count) *count = sd->wm_rot.count;
5401    return EINA_TRUE;
5402 }
5403
5404 EOLIAN static void
5405 _elm_win_wm_manual_rotation_done_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool set)
5406 {
5407    if (!sd->wm_rot.use) return;
5408    ecore_evas_wm_rotation_manual_rotation_done_set(sd->ee, set);
5409 }
5410
5411 EOLIAN static Eina_Bool
5412 _elm_win_wm_manual_rotation_done_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5413 {
5414    if (!sd->wm_rot.use) return EINA_FALSE;
5415    return ecore_evas_wm_rotation_manual_rotation_done_get(sd->ee);
5416 }
5417
5418 EOLIAN static void
5419 _elm_win_wm_manual_rotation_done_manual(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5420 {
5421    if (!sd->wm_rot.use) return;
5422    ecore_evas_wm_rotation_manual_rotation_done(sd->ee);
5423 }
5424
5425 EOLIAN static void
5426 _elm_win_sticky_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool sticky)
5427 {
5428 //   sd->sticky = sticky;
5429    TRAP(sd, sticky_set, sticky);
5430 #ifdef HAVE_ELEMENTARY_X
5431    _elm_win_xwin_update(sd);
5432 #endif
5433 }
5434
5435 EOLIAN static Eina_Bool
5436 _elm_win_sticky_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5437 {
5438    return sd->sticky;
5439 }
5440
5441 EOLIAN static void
5442 _elm_win_keyboard_mode_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Win_Keyboard_Mode mode)
5443 {
5444    if (mode == sd->kbdmode) return;
5445 #ifdef HAVE_ELEMENTARY_X
5446    _internal_elm_win_xwindow_get(sd);
5447 #endif
5448    sd->kbdmode = mode;
5449 #ifdef HAVE_ELEMENTARY_X
5450    if (sd->x.xwin)
5451      ecore_x_e_virtual_keyboard_state_set
5452        (sd->x.xwin, (Ecore_X_Virtual_Keyboard_State)sd->kbdmode);
5453 #endif
5454 }
5455
5456 EOLIAN static Elm_Win_Keyboard_Mode
5457 _elm_win_keyboard_mode_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5458 {
5459    return sd->kbdmode;
5460 }
5461
5462 EOLIAN static void
5463 _elm_win_keyboard_win_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool is_keyboard)
5464 {
5465 #ifdef HAVE_ELEMENTARY_X
5466    _internal_elm_win_xwindow_get(sd);
5467    if (sd->x.xwin)
5468      ecore_x_e_virtual_keyboard_set(sd->x.xwin, is_keyboard);
5469 #else
5470    (void)is_keyboard;
5471 #endif
5472 }
5473
5474 EOLIAN static Eina_Bool
5475 _elm_win_keyboard_win_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5476 {
5477 #ifdef HAVE_ELEMENTARY_X
5478    _internal_elm_win_xwindow_get(sd);
5479    if (sd->x.xwin) return ecore_x_e_virtual_keyboard_get(sd->x.xwin);
5480 #endif
5481    return EINA_FALSE;
5482 }
5483
5484 EOLIAN static void
5485 _elm_win_indicator_mode_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Win_Indicator_Mode mode)
5486 {
5487    if (mode == sd->indmode) return;
5488 #ifdef HAVE_ELEMENTARY_X
5489    _internal_elm_win_xwindow_get(sd);
5490 #endif
5491    sd->indmode = mode;
5492 #ifdef HAVE_ELEMENTARY_X
5493    if (sd->x.xwin)
5494      {
5495         if (sd->indmode == ELM_WIN_INDICATOR_SHOW)
5496           ecore_x_e_illume_indicator_state_set
5497             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON);
5498         else if (sd->indmode == ELM_WIN_INDICATOR_HIDE)
5499           ecore_x_e_illume_indicator_state_set
5500             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
5501      }
5502 #endif
5503 #ifdef HAVE_ELEMENTARY_WAYLAND
5504    _elm_win_wlwindow_get(sd);
5505    if (sd->wl.win)
5506      {
5507         if (sd->indmode == ELM_WIN_INDICATOR_SHOW)
5508           ecore_wl_window_indicator_state_set
5509             (sd->wl.win, ECORE_WL_INDICATOR_STATE_ON);
5510         else if (sd->indmode == ELM_WIN_INDICATOR_HIDE)
5511           ecore_wl_window_indicator_state_set
5512             (sd->wl.win, ECORE_WL_INDICATOR_STATE_OFF);
5513      }
5514 #endif
5515    eo_do(obj, eo_event_callback_call
5516      (ELM_WIN_EVENT_INDICATOR_PROP_CHANGED, NULL));
5517 }
5518
5519 EOLIAN static Elm_Win_Indicator_Mode
5520 _elm_win_indicator_mode_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5521 {
5522    return sd->indmode;
5523 }
5524
5525 EOLIAN static void
5526 _elm_win_indicator_opacity_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Win_Indicator_Opacity_Mode mode)
5527 {
5528    if (mode == sd->ind_o_mode) return;
5529    sd->ind_o_mode = mode;
5530 #ifdef HAVE_ELEMENTARY_X
5531    _internal_elm_win_xwindow_get(sd);
5532    if (sd->x.xwin)
5533      {
5534         if (sd->ind_o_mode == ELM_WIN_INDICATOR_OPAQUE)
5535           ecore_x_e_illume_indicator_opacity_set
5536             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_OPAQUE);
5537         else if (sd->ind_o_mode == ELM_WIN_INDICATOR_TRANSLUCENT)
5538           ecore_x_e_illume_indicator_opacity_set
5539             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT);
5540         else if (sd->ind_o_mode == ELM_WIN_INDICATOR_TRANSPARENT)
5541           ecore_x_e_illume_indicator_opacity_set
5542             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_TRANSPARENT);
5543      }
5544 #endif
5545 #ifdef HAVE_ELEMENTARY_WAYLAND
5546    _elm_win_wlwindow_get(sd);
5547    if (sd->wl.win)
5548      {
5549         if (sd->ind_o_mode == ELM_WIN_INDICATOR_OPAQUE)
5550           ecore_wl_window_indicator_opacity_set
5551             (sd->wl.win, ECORE_WL_INDICATOR_OPAQUE);
5552         else if (sd->ind_o_mode == ELM_WIN_INDICATOR_TRANSLUCENT)
5553           ecore_wl_window_indicator_opacity_set
5554             (sd->wl.win, ECORE_WL_INDICATOR_TRANSLUCENT);
5555         else if (sd->ind_o_mode == ELM_WIN_INDICATOR_TRANSPARENT)
5556           ecore_wl_window_indicator_opacity_set
5557             (sd->wl.win, ECORE_WL_INDICATOR_TRANSPARENT);
5558      }
5559 #endif
5560    eo_do(obj, eo_event_callback_call
5561      (ELM_WIN_EVENT_INDICATOR_PROP_CHANGED, NULL));
5562 }
5563
5564 EOLIAN static Elm_Win_Indicator_Opacity_Mode
5565 _elm_win_indicator_opacity_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5566 {
5567    return sd->ind_o_mode;
5568 }
5569
5570 EOLIAN static void
5571 _elm_win_screen_position_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *x, int *y)
5572 {
5573    if (x) *x = sd->screen.x;
5574    if (y) *y = sd->screen.y;
5575 }
5576
5577 EOLIAN static Eina_Bool
5578 _elm_win_focus_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5579 {
5580    return ecore_evas_focus_get(sd->ee);
5581 }
5582
5583 EOLIAN static void
5584 _elm_win_screen_constrain_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool constrain)
5585 {
5586    sd->constrain = !!constrain;
5587 }
5588
5589 EOLIAN static Eina_Bool
5590 _elm_win_screen_constrain_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5591 {
5592    return sd->constrain;
5593 }
5594
5595 EOLIAN static void
5596 _elm_win_screen_size_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *x, int *y, int *w, int *h)
5597 {
5598    ecore_evas_screen_geometry_get(sd->ee, x, y, w, h);
5599 }
5600
5601 EOLIAN static void
5602 _elm_win_screen_dpi_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *xdpi, int *ydpi)
5603 {
5604    ecore_evas_screen_dpi_get(sd->ee, xdpi, ydpi);
5605 }
5606
5607 EOLIAN static void
5608 _elm_win_conformant_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool conformant)
5609 {
5610 #ifdef HAVE_ELEMENTARY_X
5611    _internal_elm_win_xwindow_get(sd);
5612    if (sd->x.xwin)
5613      ecore_x_e_illume_conformant_set(sd->x.xwin, conformant);
5614 #elif HAVE_ELEMENTARY_WAYLAND
5615    _elm_win_wlwindow_get(sd);
5616    if (sd->wl.win)
5617      ecore_wl_window_conformant_set(sd->wl.win, conformant);
5618 #else
5619    (void)conformant;
5620 #endif
5621 }
5622
5623 EOLIAN static Eina_Bool
5624 _elm_win_conformant_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5625 {
5626 #ifdef HAVE_ELEMENTARY_X
5627    _internal_elm_win_xwindow_get(sd);
5628    if (sd->x.xwin)
5629      return ecore_x_e_illume_conformant_get(sd->x.xwin);
5630 #endif
5631 #if HAVE_ELEMENTARY_WAYLAND
5632    _elm_win_wlwindow_get(sd);
5633    if (sd->wl.win)
5634      return ecore_wl_window_conformant_get(sd->wl.win);
5635 #endif
5636
5637    return EINA_FALSE;
5638 }
5639
5640 EOLIAN static void
5641 _elm_win_quickpanel_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool quickpanel)
5642 {
5643 #ifdef HAVE_ELEMENTARY_X
5644    _internal_elm_win_xwindow_get(sd);
5645    if (sd->x.xwin)
5646      {
5647         ecore_x_e_illume_quickpanel_set(sd->x.xwin, quickpanel);
5648         if (quickpanel)
5649           {
5650              Ecore_X_Window_State states[2];
5651
5652              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
5653              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
5654              ecore_x_netwm_window_state_set(sd->x.xwin, states, 2);
5655              ecore_x_icccm_hints_set(sd->x.xwin, 0, 0, 0, 0, 0, 0, 0);
5656           }
5657      }
5658 #endif
5659 #ifdef HAVE_ELEMENTARY_WAYLAND
5660    _elm_win_focus_skip_set(sd, EINA_TRUE);
5661 #endif
5662 }
5663
5664 EOLIAN static Eina_Bool
5665 _elm_win_quickpanel_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5666 {
5667 #ifdef HAVE_ELEMENTARY_X
5668    _internal_elm_win_xwindow_get(sd);
5669    if (sd->x.xwin)
5670      return ecore_x_e_illume_quickpanel_get(sd->x.xwin);
5671 #endif
5672
5673    return EINA_FALSE;
5674 }
5675
5676 EOLIAN static void
5677 _elm_win_quickpanel_priority_major_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int priority)
5678 {
5679 #ifdef HAVE_ELEMENTARY_X
5680    _internal_elm_win_xwindow_get(sd);
5681    if (sd->x.xwin)
5682      ecore_x_e_illume_quickpanel_priority_major_set(sd->x.xwin, priority);
5683 #else
5684    (void)priority;
5685 #endif
5686 }
5687
5688 EOLIAN static int
5689 _elm_win_quickpanel_priority_major_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5690 {
5691 #ifdef HAVE_ELEMENTARY_X
5692    _internal_elm_win_xwindow_get(sd);
5693    if (sd->x.xwin)
5694      return ecore_x_e_illume_quickpanel_priority_major_get(sd->x.xwin);
5695 #endif
5696
5697    return -1;
5698 }
5699
5700 EOLIAN static void
5701 _elm_win_quickpanel_priority_minor_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int priority)
5702 {
5703 #ifdef HAVE_ELEMENTARY_X
5704    _internal_elm_win_xwindow_get(sd);
5705    if (sd->x.xwin)
5706      ecore_x_e_illume_quickpanel_priority_minor_set(sd->x.xwin, priority);
5707 #else
5708    (void)priority;
5709 #endif
5710 }
5711
5712 EOLIAN static int
5713 _elm_win_quickpanel_priority_minor_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5714 {
5715 #ifdef HAVE_ELEMENTARY_X
5716    _internal_elm_win_xwindow_get(sd);
5717    if (sd->x.xwin)
5718      return ecore_x_e_illume_quickpanel_priority_minor_get(sd->x.xwin);
5719 #endif
5720
5721    return -1;
5722 }
5723
5724 EOLIAN static void
5725 _elm_win_quickpanel_zone_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int zone)
5726 {
5727 #ifdef HAVE_ELEMENTARY_X
5728    _internal_elm_win_xwindow_get(sd);
5729    if (sd->x.xwin)
5730      ecore_x_e_illume_quickpanel_zone_set(sd->x.xwin, zone);
5731 #else
5732    (void)zone;
5733 #endif
5734 }
5735
5736 EOLIAN static int
5737 _elm_win_quickpanel_zone_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5738 {
5739 #ifdef HAVE_ELEMENTARY_X
5740    _internal_elm_win_xwindow_get(sd);
5741    if (sd->x.xwin)
5742      return ecore_x_e_illume_quickpanel_zone_get(sd->x.xwin);
5743 #endif
5744
5745    return 0;
5746 }
5747
5748 EOLIAN static void
5749 _elm_win_prop_focus_skip_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool skip)
5750 {
5751    _elm_win_focus_skip_set(sd, skip);
5752 }
5753
5754 EOLIAN static void
5755 _elm_win_illume_command_send(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Illume_Command command, void *params)
5756 {
5757    (void) params;
5758
5759 #ifdef HAVE_ELEMENTARY_X
5760    _internal_elm_win_xwindow_get(sd);
5761    if (sd->x.xwin)
5762      {
5763         switch (command)
5764           {
5765            case ELM_ILLUME_COMMAND_FOCUS_BACK:
5766              ecore_x_e_illume_focus_back_send(sd->x.xwin);
5767              break;
5768
5769            case ELM_ILLUME_COMMAND_FOCUS_FORWARD:
5770              ecore_x_e_illume_focus_forward_send(sd->x.xwin);
5771              break;
5772
5773            case ELM_ILLUME_COMMAND_FOCUS_HOME:
5774              ecore_x_e_illume_focus_home_send(sd->x.xwin);
5775              break;
5776
5777            case ELM_ILLUME_COMMAND_CLOSE:
5778              ecore_x_e_illume_close_send(sd->x.xwin);
5779              break;
5780
5781            default:
5782              break;
5783           }
5784      }
5785 #else
5786    (void)command;
5787 #endif
5788 }
5789
5790 EOLIAN static Eina_Bool
5791 _elm_win_keygrab_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *key, Evas_Modifier_Mask modifiers EINA_UNUSED, Evas_Modifier_Mask not_modifiers EINA_UNUSED, int priority EINA_UNUSED, Elm_Win_Keygrab_Mode grab_mode)
5792 {
5793    Eina_Bool ret = EINA_FALSE;
5794 #ifdef HAVE_ELEMENTARY_X
5795    _internal_elm_win_xwindow_get(sd);
5796    if (sd->x.xwin)
5797      {
5798         Ecore_X_Win_Keygrab_Mode x_grab_mode;
5799         switch (grab_mode)
5800           {
5801            case ELM_WIN_KEYGRAB_SHARED:
5802              x_grab_mode = ECORE_X_WIN_KEYGRAB_SHARED;
5803              break;
5804            case ELM_WIN_KEYGRAB_TOPMOST:
5805              x_grab_mode = ECORE_X_WIN_KEYGRAB_TOPMOST;
5806              break;
5807            case ELM_WIN_KEYGRAB_EXCLUSIVE:
5808              x_grab_mode = ECORE_X_WIN_KEYGRAB_EXCLUSIVE;
5809              break;
5810            case ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE:
5811              x_grab_mode = ECORE_X_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE;
5812              break;
5813            default:
5814              return ret;
5815           }
5816          ret = ecore_x_window_keygrab_set(sd->x.xwin, key, 0, 0, 0, x_grab_mode);
5817      }
5818 #endif
5819 // TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
5820 #ifdef HAVE_ELEMENTARY_WAYLAND
5821    _elm_win_wlwindow_get(sd);
5822    if (sd->wl.win)
5823      {
5824         Ecore_Wl_Window_Keygrab_Mode wl_grab_mode;
5825         switch (grab_mode)
5826           {
5827            case ELM_WIN_KEYGRAB_SHARED:
5828              wl_grab_mode = ECORE_WL_WINDOW_KEYGRAB_SHARED;
5829              break;
5830            case ELM_WIN_KEYGRAB_TOPMOST:
5831              wl_grab_mode = ECORE_WL_WINDOW_KEYGRAB_TOPMOST;
5832              break;
5833            case ELM_WIN_KEYGRAB_EXCLUSIVE:
5834              wl_grab_mode = ECORE_WL_WINDOW_KEYGRAB_EXCLUSIVE;
5835              break;
5836            case ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE:
5837              wl_grab_mode = ECORE_WL_WINDOW_KEYGRAB_OVERRIDE_EXCLUSIVE;
5838              break;
5839            default:
5840              return ret;
5841           }
5842         ret = ecore_wl_window_keygrab_set(sd->wl.win, key, 0, 0, 0, wl_grab_mode);
5843      }
5844 #endif
5845 //
5846    return ret;
5847 }
5848
5849 EOLIAN static Eina_Bool
5850 _elm_win_keygrab_unset(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *key, Evas_Modifier_Mask modifiers EINA_UNUSED, Evas_Modifier_Mask not_modifiers EINA_UNUSED)
5851 {
5852    Eina_Bool ret = EINA_FALSE;
5853 #ifdef HAVE_ELEMENTARY_X
5854    _internal_elm_win_xwindow_get(sd);
5855    if (sd->x.xwin)
5856      ret = ecore_x_window_keygrab_unset(sd->x.xwin, key, 0, 0);
5857 #endif
5858 // TIZEN_ONLY(20150722): Add ecore_wl_window_keygrab_* APIs
5859 #ifdef HAVE_ELEMENTARY_WAYLAND
5860    _elm_win_wlwindow_get(sd);
5861    if (sd->wl.win)
5862      ret = ecore_wl_window_keygrab_unset(sd->wl.win, key, 0, 0);
5863 #endif
5864 //
5865    return ret;
5866 }
5867
5868 EOLIAN static Evas_Object*
5869 _elm_win_inlined_image_object_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5870 {
5871    return sd->img_obj;
5872 }
5873
5874 EOLIAN static void
5875 _elm_win_focus_highlight_enabled_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool enabled)
5876 {
5877    enabled = !!enabled;
5878    if (sd->focus_highlight.enabled == enabled)
5879      return;
5880
5881    sd->focus_highlight.enabled = enabled;
5882
5883    if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
5884      _elm_win_focus_highlight_init(sd);
5885    else
5886      _elm_win_focus_highlight_shutdown(sd);
5887 }
5888
5889 EOLIAN static Eina_Bool
5890 _elm_win_focus_highlight_enabled_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5891 {
5892    return sd->focus_highlight.enabled;
5893 }
5894
5895 static Eina_Bool
5896 _elm_win_theme_internal(Eo *obj, Elm_Win_Data *sd)
5897 {
5898    Eina_Bool ret = EINA_FALSE;
5899    const char *s;
5900
5901    if (!_elm_theme_object_set(obj, sd->edje, "win", "base",
5902                                elm_widget_style_get(obj)))
5903      return EINA_FALSE;
5904
5905    edje_object_mirrored_set(sd->edje, elm_widget_mirrored_get(obj));
5906    edje_object_scale_set(sd->edje,
5907                          elm_widget_scale_get(obj) * elm_config_scale_get());
5908
5909    eo_do(obj, eo_event_callback_call(ELM_WIN_EVENT_THEME_CHANGED, NULL));
5910    eo_do(obj, ret = elm_obj_widget_disable());
5911
5912    if (!sd->theme_alpha && !sd->application_alpha)
5913      {
5914         s = edje_object_data_get(sd->edje, "alpha");
5915         if (s)
5916           {
5917              if (!strcmp(s, "1") ||
5918                  !strcmp(s, "true"))
5919                {
5920                   sd->application_alpha = 1;
5921                   _elm_win_apply_alpha(obj, sd);
5922                }
5923           }
5924      }
5925
5926    return ret;
5927 }
5928
5929 EOLIAN static Eina_Bool
5930 _elm_win_elm_widget_theme_apply(Eo *obj, Elm_Win_Data *sd)
5931 {
5932    Eina_Bool int_ret = EINA_FALSE;
5933    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
5934    if (!int_ret) return EINA_FALSE;
5935
5936    sd->focus_highlight.theme_changed = EINA_TRUE;
5937    if (!_elm_win_theme_internal(obj, sd))
5938      return EINA_FALSE;
5939    _elm_win_focus_highlight_reconfigure_job_start(sd);
5940
5941    return EINA_TRUE;
5942 }
5943
5944 EOLIAN static void
5945 _elm_win_focus_highlight_style_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *style)
5946 {
5947    eina_stringshare_replace(&sd->focus_highlight.style, style);
5948    sd->focus_highlight.theme_changed = EINA_TRUE;
5949    _elm_win_focus_highlight_reconfigure_job_start(sd);
5950 }
5951
5952 EOLIAN static const char*
5953 _elm_win_focus_highlight_style_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5954 {
5955    return sd->focus_highlight.style;
5956 }
5957
5958 EOLIAN static void
5959 _elm_win_focus_highlight_animate_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool animate)
5960 {
5961    animate = !!animate;
5962    if (sd->focus_highlight.animate == animate)
5963      return;
5964
5965    sd->focus_highlight.animate = animate;
5966    sd->focus_highlight.theme_changed = EINA_TRUE;
5967    _elm_win_focus_highlight_reconfigure_job_start(sd);
5968 }
5969
5970 EOLIAN static Eina_Bool
5971 _elm_win_focus_highlight_animate_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5972 {
5973    return sd->focus_highlight.animate;
5974 }
5975
5976 EOLIAN static Eina_Bool
5977 _elm_win_socket_listen(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *svcname, int svcnum, Eina_Bool svcsys)
5978 {
5979    if (!sd->ee) return EINA_FALSE;
5980
5981    if (!ecore_evas_extn_socket_listen(sd->ee, svcname, svcnum, svcsys))
5982      return EINA_FALSE;
5983
5984    if (_elm_config->atspi_mode)
5985      {
5986         if (sd->socket_proxy)
5987           eo_unref(sd->socket_proxy);
5988         sd->socket_proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, svcnum, ELM_ATSPI_PROXY_TYPE_SOCKET);
5989         elm_atspi_bridge_utils_proxy_listen(sd->socket_proxy);
5990      }
5991
5992    return EINA_TRUE;
5993 }
5994
5995 /* windowing specific calls - shall we do this differently? */
5996
5997 EOLIAN static Ecore_X_Window
5998 _elm_win_xwindow_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
5999 {
6000 #ifdef HAVE_ELEMENTARY_X
6001    if (sd->x.xwin) return sd->x.xwin;
6002    if (sd->parent) return elm_win_xwindow_get(sd->parent);
6003 #endif
6004    return 0;
6005 }
6006
6007 EAPI Ecore_Wl_Window *
6008 elm_win_wl_window_get(const Evas_Object *obj)
6009 {
6010    ELM_WIN_CHECK(obj) NULL;
6011    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
6012    const char *engine_name = ecore_evas_engine_name_get(sd->ee);
6013
6014    if (!(engine_name &&
6015          ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
6016           (!strcmp(engine_name, ELM_WAYLAND_EGL)))))
6017      return NULL;
6018
6019    if (!evas_object_smart_type_check_ptr(obj, MY_CLASS_NAME_LEGACY))
6020      {
6021         Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
6022         return _elm_ee_wlwin_get(ee);
6023      }
6024
6025    Ecore_Wl_Window *ret = NULL;
6026    eo_do((Eo *) obj, ret = elm_obj_win_wl_window_get());
6027    return ret;
6028 }
6029
6030 EOLIAN static Ecore_Wl_Window*
6031 _elm_win_wl_window_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
6032 {
6033 #if HAVE_ELEMENTARY_WAYLAND
6034    if (sd->wl.win) return sd->wl.win;
6035    if (sd->parent) return elm_win_wl_window_get(sd->parent);
6036 #else
6037    (void)sd;
6038 #endif
6039    return NULL;
6040 }
6041
6042 EAPI Eina_Bool
6043 elm_win_trap_set(const Elm_Win_Trap *t)
6044 {
6045    DBG("old %p, new %p", trap, t);
6046
6047    if ((t) && (t->version != ELM_WIN_TRAP_VERSION))
6048      {
6049         CRI("trying to set a trap version %lu while %lu was expected!",
6050                  t->version, ELM_WIN_TRAP_VERSION);
6051         return EINA_FALSE;
6052      }
6053
6054    trap = t;
6055    return EINA_TRUE;
6056 }
6057
6058 EAPI void
6059 elm_win_floating_mode_set(Evas_Object *obj, Eina_Bool floating)
6060 {
6061    ELM_WIN_CHECK(obj);
6062    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
6063
6064    floating = !!floating;
6065    if (floating == sd->floating) return;
6066    sd->floating = floating;
6067 #if HAVE_ELEMENTARY_WAYLAND
6068    _elm_win_wlwindow_get(sd);
6069    if (sd->wl.win)
6070      {
6071         if (floating)
6072           {
6073              const char *engine_name = ecore_evas_engine_name_get(sd->ee);
6074              Eina_Bool need_frame = engine_name &&
6075                 ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
6076                  (!strcmp(engine_name, ELM_WAYLAND_EGL)));
6077
6078              if (need_frame)
6079                need_frame = !sd->fullscreen;
6080
6081              if (need_frame)
6082                {
6083                   _elm_win_frame_del(sd);
6084                   _elm_win_frame_add(sd, "floating");
6085                }
6086
6087              if (sd->frame_obj)
6088                evas_object_show(sd->frame_obj);
6089           }
6090         else
6091           {
6092              elm_win_borderless_set(obj, sd->borderless);
6093           }
6094         ecore_wl_window_floating_mode_set(sd->wl.win, floating);
6095      }
6096 #endif
6097 #ifdef HAVE_ELEMENTARY_X
6098    _internal_elm_win_xwindow_get(sd);
6099    if (sd->x.xwin)
6100      {
6101         if (sd->floating)
6102           ecore_x_e_illume_window_state_set
6103              (sd->x.xwin, ECORE_X_ILLUME_WINDOW_STATE_FLOATING);
6104         else
6105           ecore_x_e_illume_window_state_set
6106              (sd->x.xwin, ECORE_X_ILLUME_WINDOW_STATE_NORMAL);
6107      }
6108 #endif
6109 }
6110
6111 EAPI Eina_Bool
6112 elm_win_floating_mode_get(const Evas_Object *obj)
6113 {
6114    ELM_WIN_CHECK(obj) EINA_FALSE;
6115    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
6116
6117    return sd->floating;
6118 }
6119
6120 EOLIAN static Ecore_Window
6121 _elm_win_window_id_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
6122 {
6123    const char *engine_name = ecore_evas_engine_name_get(sd->ee);
6124
6125    if ((engine_name &&
6126         ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
6127          (!strcmp(engine_name, ELM_WAYLAND_EGL)))))
6128      {
6129 #if HAVE_ELEMENTARY_WAYLAND
6130         if (sd->wl.win) return (Ecore_Window)ecore_wl_window_surface_id_get(sd->wl.win);
6131         if (sd->parent)
6132           {
6133              Ecore_Wl_Window *parent;
6134
6135              parent = elm_win_wl_window_get(sd->parent);
6136              if (parent) return (Ecore_Window)ecore_wl_window_surface_id_get(parent);
6137              return 0;
6138           }
6139 #endif
6140      }
6141    else if ((engine_name &&
6142              ((!strcmp(engine_name, ELM_SOFTWARE_X11)) ||
6143               (!strcmp(engine_name, ELM_OPENGL_X11)))))
6144      {
6145 #ifdef HAVE_ELEMENTARY_X
6146         _internal_elm_win_xwindow_get(sd);
6147         if (sd->x.xwin) return (Ecore_Window)sd->x.xwin;
6148         if (sd->parent) return (Ecore_Window)elm_win_xwindow_get(sd->parent);
6149 #endif
6150      }
6151
6152    return 0;
6153 }
6154
6155 void
6156 _elm_win_focus_highlight_in_theme_update(Evas_Object *obj, Eina_Bool in_theme)
6157 {
6158    ELM_WIN_DATA_GET(obj, sd);
6159    sd->focus_highlight.cur.in_theme = !!in_theme;
6160 }
6161
6162 void
6163 _elm_win_focus_highlight_start(Evas_Object *obj)
6164 {
6165    ELM_WIN_DATA_GET(obj, sd);
6166
6167    if (!(sd->focus_highlight.enabled) && !(sd->focus_highlight.auto_enabled)) return;
6168    sd->focus_highlight.cur.visible = EINA_TRUE;
6169    sd->focus_highlight.geometry_changed = EINA_TRUE;
6170    _elm_win_focus_highlight_reconfigure_job(obj);
6171 }
6172
6173 void
6174 _elm_win_focus_auto_show(Evas_Object *obj)
6175 {
6176    ELM_WIN_DATA_GET(obj, sd);
6177    Eina_Bool pfocus = (sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled);
6178    sd->focus_highlight.auto_enabled = _elm_config->win_auto_focus_enable;
6179    sd->focus_highlight.auto_animate = _elm_config->win_auto_focus_animate;
6180    if (pfocus != ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
6181      {
6182         if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))
6183           _elm_win_focus_highlight_init(sd);
6184      }
6185 }
6186
6187 void
6188 _elm_win_focus_auto_hide(Evas_Object *obj)
6189 {
6190    ELM_WIN_DATA_GET(obj, sd);
6191    Eina_Bool pfocus = (sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled);
6192    sd->focus_highlight.auto_enabled = EINA_FALSE;
6193    sd->focus_highlight.auto_animate = EINA_FALSE;
6194    if (pfocus != ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
6195      {
6196         if (!((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)))
6197           _elm_win_focus_highlight_shutdown(sd);
6198      }
6199 }
6200
6201 void
6202 _elm_win_object_set_accessibility_highlight(Evas_Object *win, Evas_Object *obj)
6203 {
6204    if (!win) return;
6205    ELM_WIN_DATA_GET(win, sd);
6206    _elm_win_accessibility_highlight_hide(win);
6207    _elm_win_accessibility_highlight_callbacks_del(sd);
6208    if (obj)
6209      {
6210          _elm_win_accessibility_highlight_init(sd, obj);
6211          _elm_win_accessibility_highlight_show(win);
6212      }
6213    else
6214      {
6215          _elm_win_accessibility_highlight_hide(win);
6216      }
6217 }
6218
6219 EAPI Ecore_Window
6220 elm_win_window_id_get(const Evas_Object *obj)
6221 {
6222    if (!obj) return 0;
6223
6224    if (!evas_object_smart_type_check_ptr(obj, MY_CLASS_NAME_LEGACY))
6225      {
6226         Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
6227         return ecore_evas_window_get(ee);
6228      }
6229
6230    ELM_WIN_CHECK(obj) 0;
6231    Ecore_Window ret = 0;
6232    eo_do((Eo *) obj, ret = elm_obj_win_window_id_get());
6233    return ret;
6234 }
6235
6236 static Eina_Bool
6237 _on_atspi_bus_connected(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6238 {
6239    Evas_Object *win;
6240    Eina_List *l;
6241
6242    EINA_LIST_FOREACH(_elm_win_list, l, win)
6243      {
6244         /**
6245          * Reemit accessibility events when AT-SPI2 connection is begin
6246          * established. This assures that Assistive Technology clients will
6247          * receive all org.a11y.window events and could keep track of active
6248          * windows whithin system.
6249          */
6250         elm_interface_atspi_window_created_signal_emit(win);
6251         if (elm_win_focus_get(win))
6252           {
6253              elm_interface_atspi_window_activated_signal_emit(win);
6254              /** Reemit focused event to inform atspi clients about currently
6255               * focused object **/
6256              unsigned int order = 0;
6257              Evas_Object *target;
6258              eo_do(win, target = elm_obj_widget_newest_focus_order_get(&order, EINA_TRUE));
6259              if (target)
6260                elm_interface_atspi_accessible_state_changed_signal_emit(target, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
6261           }
6262         else
6263           elm_interface_atspi_window_deactivated_signal_emit(win);
6264      }
6265    return EINA_TRUE;
6266 }
6267
6268 EOLIAN static void
6269 _elm_win_class_constructor(Eo_Class *klass)
6270 {
6271    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
6272
6273    if (_elm_config->atspi_mode)
6274      {
6275         Eo *bridge = _elm_atspi_bridge_get();
6276         if (bridge)
6277            eo_do(bridge, eo_event_callback_add(ELM_ATSPI_BRIDGE_EVENT_CONNECTED, _on_atspi_bus_connected, NULL));
6278      }
6279 }
6280
6281 EOLIAN static Eo*
6282 _elm_win_elm_interface_atspi_accessible_parent_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd EINA_UNUSED)
6283 {
6284    // attach all kinds of windows directly to ATSPI application root object
6285    Eo *bridge = _elm_atspi_bridge_get();
6286    return elm_atspi_bridge_root_get(bridge);
6287 }
6288
6289 EOLIAN static const Elm_Atspi_Action*
6290 _elm_win_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd EINA_UNUSED)
6291 {
6292    static Elm_Atspi_Action atspi_actions[] = {
6293           { "move,previous", "move", "previous", _key_action_move},
6294           { "move,next", "move", "next", _key_action_move},
6295           { "move,left", "move", "left", _key_action_move},
6296           { "move,right", "move", "right", _key_action_move},
6297           { "move,up", "move", "up", _key_action_move},
6298           { "move,down", "move", "down", _key_action_move},
6299           { NULL, NULL, NULL, NULL }
6300    };
6301    return &atspi_actions[0];
6302 }
6303
6304 EOLIAN static Elm_Atspi_State_Set
6305 _elm_win_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Win_Data *sd EINA_UNUSED)
6306 {
6307    Elm_Atspi_State_Set ret;
6308    eo_do_super(obj, MY_CLASS, ret = elm_interface_atspi_accessible_state_set_get());
6309
6310    if (elm_win_focus_get(obj))
6311      STATE_TYPE_SET(ret, ELM_ATSPI_STATE_ACTIVE);
6312
6313    return ret;
6314 }
6315
6316 EOLIAN static char*
6317 _elm_win_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Win_Data *sd EINA_UNUSED)
6318 {
6319    const char *ret = elm_win_title_get(obj);
6320    return ret ? strdup(ret) : strdup("");
6321 }
6322
6323 #include "elm_win.eo.c"
6324
6325 //////////////////////////////////////////////////////////////////
6326
6327 EAPI const Eina_List *
6328 elm_win_aux_hints_supported_get(const Evas_Object *obj)
6329 {
6330    ELM_WIN_CHECK(obj) NULL;
6331    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
6332    return ecore_evas_aux_hints_supported_get(sd->ee);
6333 }
6334
6335 EAPI int
6336 elm_win_aux_hint_add(Evas_Object *obj, const char *hint, const char *val)
6337 {
6338    ELM_WIN_CHECK(obj) -1;
6339    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, -1);
6340    return ecore_evas_aux_hint_add(sd->ee, hint, val);
6341 }
6342
6343 EAPI Eina_Bool
6344 elm_win_aux_hint_del(Evas_Object *obj,
6345                      const int    id)
6346 {
6347    ELM_WIN_CHECK(obj) EINA_FALSE;
6348    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
6349    return ecore_evas_aux_hint_del(sd->ee, id);
6350 }
6351
6352 EAPI Eina_Bool
6353 elm_win_aux_hint_val_set(Evas_Object *obj, const int id, const char *val)
6354 {
6355    ELM_WIN_CHECK(obj) EINA_FALSE;
6356    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
6357    return ecore_evas_aux_hint_val_set(sd->ee, id, val);
6358 }
6359
6360 EAPI const char *
6361 elm_win_aux_hint_val_get(Evas_Object *obj, int id)
6362 {
6363    ELM_WIN_CHECK(obj) EINA_FALSE;
6364    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
6365    return ecore_evas_aux_hint_val_get(sd->ee, id);
6366 }
6367
6368 EAPI int
6369 elm_win_aux_hint_id_get(Evas_Object *obj, const char *hint)
6370 {
6371    ELM_WIN_CHECK(obj) EINA_FALSE;
6372    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
6373    return ecore_evas_aux_hint_id_get(sd->ee, hint);
6374 }
6375
6376 EINA_DEPRECATED EAPI void
6377 elm_win_profiles_set(Evas_Object *obj, const char **profiles, unsigned int num_profiles)
6378 {
6379    ELM_WIN_CHECK(obj);
6380    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
6381
6382    _elm_win_available_profiles_set(obj, sd, profiles, num_profiles);
6383 }
6384
6385 EAPI void
6386 elm_win_input_rect_set(Evas_Object *obj, Eina_Rectangle *input_rect)
6387 {
6388    ELM_WIN_CHECK(obj);
6389    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
6390    TRAP(sd, input_rect_set, input_rect);
6391 }
6392
6393 EAPI void
6394 elm_win_input_rect_add(Evas_Object *obj, Eina_Rectangle *input_rect)
6395 {
6396    ELM_WIN_CHECK(obj);
6397    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
6398    TRAP(sd, input_rect_add, input_rect);
6399 }
6400
6401 EAPI void
6402 elm_win_input_rect_subtract(Evas_Object *obj, Eina_Rectangle *input_rect)
6403 {
6404    ELM_WIN_CHECK(obj);
6405    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
6406    TRAP(sd, input_rect_subtract, input_rect);
6407 }
6408
6409 //////////////////////////////////////////////////////////////////