focus: Avoid un-necessary focus animation call
[platform/upstream/elementary.git] / src / lib / elm_win.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <Elementary.h>
6 #include <Elementary_Cursor.h>
7
8 #include "elm_priv.h"
9 #include "elm_widget_menu.h"
10
11 #define MY_CLASS ELM_OBJ_WIN_CLASS
12
13 #define MY_CLASS_NAME "Elm_Win"
14 #define MY_CLASS_NAME_LEGACY "elm_win"
15
16 static const Elm_Win_Trap *trap = NULL;
17
18 #define TRAP(sd, name, ...)                                             \
19   do                                                                    \
20     {                                                                   \
21        if ((!trap) || (!trap->name) ||                                  \
22            ((trap->name) &&                                             \
23             (trap->name(sd->trap_data, sd->obj, ## __VA_ARGS__)))) \
24          ecore_evas_##name(sd->ee, ##__VA_ARGS__);                      \
25     }                                                                   \
26   while (0)
27
28 #define ELM_WIN_DATA_GET(o, sd) \
29   Elm_Win_Data * sd = eo_data_scope_get(o, MY_CLASS)
30
31 #define ELM_WIN_DATA_GET_OR_RETURN(o, ptr)           \
32   ELM_WIN_DATA_GET(o, ptr);                          \
33   if (!ptr)                                          \
34     {                                                \
35        CRI("No widget data for object %p (%s)", \
36                 o, evas_object_type_get(o));         \
37        return;                                       \
38     }
39
40 #define ELM_WIN_DATA_GET_OR_RETURN_VAL(o, ptr, val)  \
41   ELM_WIN_DATA_GET(o, ptr);                          \
42   if (!ptr)                                          \
43     {                                                \
44        CRI("No widget data for object %p (%s)", \
45                 o, evas_object_type_get(o));         \
46        return val;                                   \
47     }
48
49 #define ELM_WIN_CHECK(obj)                                             \
50   if (!obj || !eo_isa(obj, MY_CLASS)) \
51     return
52
53 #define ENGINE_GET() (_elm_preferred_engine ? _elm_preferred_engine : (_elm_config->engine ? _elm_config->engine : ""))
54 #define ENGINE_COMPARE(name) (!strcmp(ENGINE_GET(), name))
55
56 typedef struct _Elm_Win_Data Elm_Win_Data;
57
58 struct _Elm_Win_Data
59 {
60    Ecore_Evas           *ee;
61    Evas                 *evas;
62    Evas_Object          *parent; /* parent *window* object*/
63    Evas_Object          *img_obj, *frame_obj;
64    Evas_Object          *client_obj; /* rect representing the client */
65    Evas_Object          *spacer_obj;
66    Eo                   *layout;
67    Eo                   *box;
68    Evas_Object          *obj; /* The object itself */
69 #ifdef HAVE_ELEMENTARY_X
70    struct
71    {
72       Ecore_X_Window       xwin;
73       Ecore_Event_Handler *client_message_handler;
74       Ecore_Event_Handler *property_handler;
75    } x;
76 #endif
77 #ifdef HAVE_ELEMENTARY_WAYLAND
78    struct
79    {
80       Ecore_Wl_Window *win;
81    } wl;
82 #endif
83
84    Ecore_Job                     *deferred_resize_job;
85    Ecore_Job                     *deferred_child_eval_job;
86
87    Elm_Win_Type                   type;
88    Elm_Win_Keyboard_Mode          kbdmode;
89    Elm_Win_Indicator_Mode         indmode;
90    Elm_Win_Indicator_Opacity_Mode ind_o_mode;
91    struct
92    {
93       const char  *info;
94       Ecore_Timer *timer;
95       int          repeat_count;
96       int          shot_counter;
97    } shot;
98    int                            resize_location;
99    int                           *autodel_clear, rot;
100    struct
101    {
102       int x, y;
103    } screen;
104    struct
105    {
106       Ecore_Evas  *ee;
107       Evas        *evas;
108       Evas_Object *obj, *hot_obj;
109       int          hot_x, hot_y;
110    } pointer;
111    struct
112    {
113       Evas_Object *fobj; /* focus highlight edje object */
114
115       struct
116       {
117          Evas_Object *target;
118          Eina_Bool    visible : 1;
119          Eina_Bool    in_theme: 1; /**< focus highlight is handled by theme.
120                                      this is set true if edc data item "focus_highlight" is set to "on" during focus in callback. */
121       } cur, prev;
122
123       const char  *style;
124       Ecore_Job   *reconf_job;
125
126       Eina_Bool    enabled : 1;
127       Eina_Bool    theme_changed : 1; /* set true when the focus theme is changed */
128       Eina_Bool    animate : 1; /* set true when the focus highlight animate is enabled */
129       Eina_Bool    animate_supported : 1; /* set true when the focus highlight animate is supported by theme */
130       Eina_Bool    geometry_changed : 1;
131    } focus_highlight;
132
133    Evas_Object *icon;
134    const char  *title;
135    const char  *icon_name;
136    const char  *role;
137
138    Evas_Object *main_menu;
139
140    struct
141    {
142       const char  *name;
143       const char **available_list;
144       unsigned int count;
145    } profile;
146    struct
147    {
148       int          preferred_rot; /* indicates preferred rotation value, -1 means invalid. */
149       int         *rots; /* indicates available rotations */
150       unsigned int count; /* number of elements in available rotations */
151       Eina_Bool    wm_supported : 1; /* set true when the window manager support window rotation */
152       Eina_Bool    use : 1; /* set ture when application use window manager rotation. */
153    } wm_rot;
154
155    void *trap_data;
156
157    double       aspect;
158    int          size_base_w, size_base_h;
159    int          size_step_w, size_step_h;
160    int          norender;
161    Eina_Bool    urgent : 1;
162    Eina_Bool    modal : 1;
163    Eina_Bool    demand_attention : 1;
164    Eina_Bool    autodel : 1;
165    Eina_Bool    constrain : 1;
166    Eina_Bool    resizing : 1;
167    Eina_Bool    iconified : 1;
168    Eina_Bool    withdrawn : 1;
169    Eina_Bool    sticky : 1;
170    Eina_Bool    fullscreen : 1;
171    Eina_Bool    maximized : 1;
172    Eina_Bool    skip_focus : 1;
173    Eina_Bool    floating : 1;
174 };
175
176 static const char SIG_DELETE_REQUEST[] = "delete,request";
177 static const char SIG_FOCUS_OUT[] = "focus,out"; // deprecated. use "focused" instead.
178 static const char SIG_FOCUS_IN[] = "focus,in"; // deprecated. use "unfocused" instead.
179 static const char SIG_MOVED[] = "moved";
180 static const char SIG_WITHDRAWN[] = "withdrawn";
181 static const char SIG_ICONIFIED[] = "iconified";
182 static const char SIG_NORMAL[] = "normal";
183 static const char SIG_STICK[] = "stick";
184 static const char SIG_UNSTICK[] = "unstick";
185 static const char SIG_FULLSCREEN[] = "fullscreen";
186 static const char SIG_UNFULLSCREEN[] = "unfullscreen";
187 static const char SIG_MAXIMIZED[] = "maximized";
188 static const char SIG_UNMAXIMIZED[] = "unmaximized";
189 static const char SIG_IOERR[] = "ioerr";
190 static const char SIG_INDICATOR_PROP_CHANGED[] = "indicator,prop,changed";
191 static const char SIG_ROTATION_CHANGED[] = "rotation,changed";
192 static const char SIG_PROFILE_CHANGED[] = "profile,changed";
193 static const char SIG_FOCUSED[] = "focused";
194 static const char SIG_UNFOCUSED[] = "unfocused";
195 static const char SIG_WM_ROTATION_CHANGED[] = "wm,rotation,changed";
196
197 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
198    {SIG_DELETE_REQUEST, ""},
199    {SIG_FOCUS_OUT, ""},
200    {SIG_FOCUS_IN, ""},
201    {SIG_MOVED, ""},
202    {SIG_WITHDRAWN, ""},
203    {SIG_ICONIFIED, ""},
204    {SIG_NORMAL, ""},
205    {SIG_STICK, ""},
206    {SIG_UNSTICK, ""},
207    {SIG_FULLSCREEN, ""},
208    {SIG_UNFULLSCREEN, ""},
209    {SIG_MAXIMIZED, ""},
210    {SIG_UNMAXIMIZED, ""},
211    {SIG_IOERR, ""},
212    {SIG_INDICATOR_PROP_CHANGED, ""},
213    {SIG_ROTATION_CHANGED, ""},
214    {SIG_PROFILE_CHANGED, ""},
215    {SIG_FOCUSED, ""},
216    {SIG_UNFOCUSED, ""},
217    {SIG_WM_ROTATION_CHANGED, ""},
218    {NULL, NULL}
219 };
220
221 Eina_List *_elm_win_list = NULL;
222 int _elm_win_deferred_free = 0;
223
224 static int _elm_win_count = 0;
225
226 static Eina_Bool _elm_win_auto_throttled = EINA_FALSE;
227
228 static Ecore_Job *_elm_win_state_eval_job = NULL;
229
230 static void
231 _elm_win_on_resize_obj_changed_size_hints(void *data,
232                                           Evas *e,
233                                           Evas_Object *obj,
234                                           void *event_info);
235 static void
236 _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj);
237
238 #ifdef HAVE_ELEMENTARY_X
239 static void _elm_win_xwin_update(Elm_Win_Data *sd);
240 #endif
241
242 EAPI double _elm_startup_time = 0;
243
244 static void
245 _elm_win_first_frame_do(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
246 {
247    double end = ecore_time_unix_get();
248    char *first = data;
249
250    switch (*first)
251      {
252       case 'A': abort();
253       case 'E':
254       case 'D': exit(-1);
255       case 'T': fprintf(stderr, "Startup time: '%f' - '%f' = '%f' sec\n", end, _elm_startup_time, end - _elm_startup_time);
256                 break;
257      }
258
259    evas_event_callback_del_full(e, EVAS_CALLBACK_RENDER_POST, _elm_win_first_frame_do, data);
260 }
261
262 static void
263 _elm_win_state_eval(void *data EINA_UNUSED)
264 {
265    Eina_List *l;
266    Evas_Object *obj;
267    int _elm_win_count_shown = 0;
268    int _elm_win_count_iconified = 0;
269    int _elm_win_count_withdrawn = 0;
270
271    _elm_win_state_eval_job = NULL;
272
273    if (_elm_config->auto_norender_withdrawn)
274      {
275         EINA_LIST_FOREACH(_elm_win_list, l, obj)
276           {
277              if ((elm_win_withdrawn_get(obj)) ||
278                  ((elm_win_iconified_get(obj) &&
279                    (_elm_config->auto_norender_iconified_same_as_withdrawn))))
280                {
281                   if (!evas_object_data_get(obj, "__win_auto_norender"))
282                     {
283                        Evas *evas = evas_object_evas_get(obj);
284
285                        elm_win_norender_push(obj);
286                        evas_object_data_set(obj, "__win_auto_norender", obj);
287
288                        if (_elm_config->auto_flush_withdrawn)
289                          {
290                             edje_file_cache_flush();
291                             edje_collection_cache_flush();
292                             evas_image_cache_flush(evas);
293                             evas_font_cache_flush(evas);
294                          }
295                        if (_elm_config->auto_dump_withdrawn)
296                          {
297                             evas_render_dump(evas);
298                          }
299                     }
300                }
301              else
302                {
303                   if (evas_object_data_get(obj, "__win_auto_norender"))
304                     {
305                        elm_win_norender_pop(obj);
306                        evas_object_data_del(obj, "__win_auto_norender");
307                     }
308                }
309           }
310      }
311    if (((_elm_config->auto_throttle) &&
312         (elm_policy_get(ELM_POLICY_THROTTLE) != ELM_POLICY_THROTTLE_NEVER)) ||
313         (elm_policy_get(ELM_POLICY_THROTTLE) == ELM_POLICY_THROTTLE_HIDDEN_ALWAYS))
314      {
315         if (_elm_win_count == 0)
316           {
317              if (_elm_win_auto_throttled)
318                {
319                   ecore_throttle_adjust(-_elm_config->auto_throttle_amount);
320                   _elm_win_auto_throttled = EINA_FALSE;
321                }
322           }
323         else
324           {
325              EINA_LIST_FOREACH(_elm_win_list, l, obj)
326                {
327                   if (elm_win_withdrawn_get(obj))
328                     _elm_win_count_withdrawn++;
329                   else if (elm_win_iconified_get(obj))
330                     _elm_win_count_iconified++;
331                   else if (evas_object_visible_get(obj))
332                     _elm_win_count_shown++;
333                }
334              if (_elm_win_count_shown <= 0)
335                {
336                   if (!_elm_win_auto_throttled)
337                     {
338                        ecore_throttle_adjust(_elm_config->auto_throttle_amount);
339                        _elm_win_auto_throttled = EINA_TRUE;
340                     }
341                }
342              else
343                {
344                   if (_elm_win_auto_throttled)
345                     {
346                        ecore_throttle_adjust(-_elm_config->auto_throttle_amount);
347                        _elm_win_auto_throttled = EINA_FALSE;
348                     }
349                }
350           }
351      }
352 }
353
354 static void
355 _elm_win_state_eval_queue(void)
356 {
357    ecore_job_del(_elm_win_state_eval_job);
358    _elm_win_state_eval_job = ecore_job_add(_elm_win_state_eval, NULL);
359 }
360
361 // example shot spec (wait 0.1 sec then save as my-window.png):
362 // ELM_ENGINE="shot:delay=0.1:file=my-window.png"
363
364 static double
365 _shot_delay_get(Elm_Win_Data *sd)
366 {
367    char *p, *pd;
368    char *d = strdup(sd->shot.info);
369
370    if (!d) return 0.5;
371    for (p = (char *)sd->shot.info; *p; p++)
372      {
373         if (!strncmp(p, "delay=", 6))
374           {
375              double v;
376
377              for (pd = d, p += 6; (*p) && (*p != ':'); p++, pd++)
378                {
379                   *pd = *p;
380                }
381              *pd = 0;
382              v = _elm_atof(d);
383              free(d);
384              return v;
385           }
386      }
387    free(d);
388
389    return 0.5;
390 }
391
392 static char *
393 _shot_file_get(Elm_Win_Data *sd)
394 {
395    char *p;
396    char *tmp = strdup(sd->shot.info);
397    char *repname = NULL;
398
399    if (!tmp) return NULL;
400
401    for (p = (char *)sd->shot.info; *p; p++)
402      {
403         if (!strncmp(p, "file=", 5))
404           {
405              strcpy(tmp, p + 5);
406              if (!sd->shot.repeat_count) return tmp;
407              else
408                {
409                   char *dotptr = strrchr(tmp, '.');
410                   if (dotptr)
411                     {
412                        size_t size = sizeof(char) * (strlen(tmp) + 16);
413                        repname = malloc(size);
414                        strncpy(repname, tmp, dotptr - tmp);
415                        snprintf(repname + (dotptr - tmp), size -
416                                 (dotptr - tmp), "%03i",
417                                 sd->shot.shot_counter + 1);
418                        strcat(repname, dotptr);
419                        free(tmp);
420                        return repname;
421                     }
422                }
423           }
424      }
425    free(tmp);
426    if (!sd->shot.repeat_count) return strdup("out.png");
427
428    repname = malloc(sizeof(char) * 24);
429    snprintf(repname, sizeof(char) * 24, "out%03i.png",
430             sd->shot.shot_counter + 1);
431
432    return repname;
433 }
434
435 static int
436 _shot_repeat_count_get(Elm_Win_Data *sd)
437 {
438    char *p, *pd;
439    char *d = strdup(sd->shot.info);
440
441    if (!d) return 0;
442    for (p = (char *)sd->shot.info; *p; p++)
443      {
444         if (!strncmp(p, "repeat=", 7))
445           {
446              int v;
447
448              for (pd = d, p += 7; (*p) && (*p != ':'); p++, pd++)
449                {
450                   *pd = *p;
451                }
452              *pd = 0;
453              v = atoi(d);
454              if (v < 0) v = 0;
455              if (v > 1000) v = 999;
456              free(d);
457              return v;
458           }
459      }
460    free(d);
461
462    return 0;
463 }
464
465 static char *
466 _shot_key_get(Elm_Win_Data *sd EINA_UNUSED)
467 {
468    return NULL;
469 }
470
471 static char *
472 _shot_flags_get(Elm_Win_Data *sd EINA_UNUSED)
473 {
474    return NULL;
475 }
476
477 static void
478 _shot_do(Elm_Win_Data *sd)
479 {
480    Ecore_Evas *ee;
481    Evas_Object *o;
482    unsigned int *pixels;
483    int w, h;
484    char *file, *key, *flags;
485
486    ecore_evas_manual_render(sd->ee);
487    pixels = (void *)ecore_evas_buffer_pixels_get(sd->ee);
488    if (!pixels) return;
489
490    ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
491    if ((w < 1) || (h < 1)) return;
492
493    file = _shot_file_get(sd);
494    if (!file) return;
495
496    key = _shot_key_get(sd);
497    flags = _shot_flags_get(sd);
498    ee = ecore_evas_buffer_new(1, 1);
499    o = evas_object_image_add(ecore_evas_get(ee));
500    evas_object_image_alpha_set(o, ecore_evas_alpha_get(sd->ee));
501    evas_object_image_size_set(o, w, h);
502    evas_object_image_data_set(o, pixels);
503    if (!evas_object_image_save(o, file, key, flags))
504      {
505         ERR("Cannot save window to '%s' (key '%s', flags '%s')",
506             file, key, flags);
507      }
508    free(file);
509    free(key);
510    free(flags);
511    ecore_evas_free(ee);
512    if (sd->shot.repeat_count) sd->shot.shot_counter++;
513 }
514
515 static Eina_Bool
516 _shot_delay(void *data)
517 {
518    ELM_WIN_DATA_GET(data, sd);
519
520    _shot_do(sd);
521    if (sd->shot.repeat_count)
522      {
523         int remainshot = (sd->shot.repeat_count - sd->shot.shot_counter);
524         if (remainshot > 0) return EINA_TRUE;
525      }
526    sd->shot.timer = NULL;
527    elm_exit();
528
529    return EINA_FALSE;
530 }
531
532 static void
533 _shot_init(Elm_Win_Data *sd)
534 {
535    if (!sd->shot.info) return;
536
537    sd->shot.repeat_count = _shot_repeat_count_get(sd);
538    sd->shot.shot_counter = 0;
539 }
540
541 static void
542 _shot_handle(Elm_Win_Data *sd)
543 {
544    if (!sd->shot.info) return;
545
546    if (!sd->shot.timer)
547      sd->shot.timer = ecore_timer_add(_shot_delay_get(sd), _shot_delay,
548                                       sd->obj);
549 }
550
551 /* elm-win specific associate, does the trap while ecore_evas_object_associate()
552  * does not.
553  */
554 static Elm_Win_Data *
555 _elm_win_associate_get(const Ecore_Evas *ee)
556 {
557    Evas_Object *obj = ecore_evas_data_get(ee, "elm_win");
558    if (!obj) return NULL;
559    ELM_WIN_DATA_GET(obj, sd);
560    return sd;
561 }
562
563 /* Interceptors Callbacks */
564 static void
565 _elm_win_obj_intercept_raise(void *data, Evas_Object *obj EINA_UNUSED)
566 {
567    ELM_WIN_DATA_GET(data, sd);
568    TRAP(sd, raise);
569 }
570
571 static void
572 _elm_win_obj_intercept_lower(void *data, Evas_Object *obj EINA_UNUSED)
573 {
574    ELM_WIN_DATA_GET(data, sd);
575    TRAP(sd, lower);
576 }
577
578 static void
579 _elm_win_obj_intercept_stack_above(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *above EINA_UNUSED)
580 {
581    INF("TODO: %s", __FUNCTION__);
582 }
583
584 static void
585 _elm_win_obj_intercept_stack_below(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Evas_Object *below EINA_UNUSED)
586 {
587    INF("TODO: %s", __FUNCTION__);
588 }
589
590 static void
591 _elm_win_obj_intercept_layer_set(void *data, Evas_Object *obj EINA_UNUSED, int l)
592 {
593    ELM_WIN_DATA_GET(data, sd);
594    TRAP(sd, layer_set, l);
595 }
596
597 /* Event Callbacks */
598
599 static void
600 _elm_win_obj_callback_changed_size_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
601 {
602    ELM_WIN_DATA_GET(data, sd);
603    Evas_Coord w, h;
604
605    evas_object_size_hint_min_get(obj, &w, &h);
606    TRAP(sd, size_min_set, w, h);
607
608    evas_object_size_hint_max_get(obj, &w, &h);
609    if (w < 1) w = -1;
610    if (h < 1) h = -1;
611    TRAP(sd, size_max_set, w, h);
612 }
613 /* end of elm-win specific associate */
614
615 static void
616 _elm_win_move(Ecore_Evas *ee)
617 {
618    Elm_Win_Data *sd = _elm_win_associate_get(ee);
619    int x, y;
620
621    if (!sd) return;
622
623    ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
624    sd->screen.x = x;
625    sd->screen.y = y;
626    evas_object_smart_callback_call(sd->obj, SIG_MOVED, NULL);
627    evas_nochange_push(evas_object_evas_get(sd->obj));
628    evas_object_move(sd->obj, x, y);
629    evas_nochange_pop(evas_object_evas_get(sd->obj));
630 }
631
632 static void
633 _elm_win_resize_job(void *data)
634 {
635    ELM_WIN_DATA_GET(data, sd);
636    int w, h;
637
638    sd->deferred_resize_job = NULL;
639    ecore_evas_request_geometry_get(sd->ee, NULL, NULL, &w, &h);
640    if (sd->constrain)
641      {
642         int sw, sh;
643         ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sw, &sh);
644         w = MIN(w, sw);
645         h = MIN(h, sh);
646      }
647
648    if (sd->frame_obj)
649      {
650         int fx, fy, fw, fh;
651
652         evas_output_framespace_get(sd->evas, &fx, &fy, &fw, &fh);
653         evas_object_move(sd->frame_obj, -fx, -fy);
654         evas_object_resize(sd->frame_obj, w + fw, h + fh);
655      }
656
657    evas_object_resize(sd->obj, w, h);
658    evas_object_resize(sd->layout, w, h);
659 }
660
661 static void
662 _elm_win_resize(Ecore_Evas *ee)
663 {
664    Elm_Win_Data *sd = _elm_win_associate_get(ee);
665    if (!sd) return;
666
667    ecore_job_del(sd->deferred_resize_job);
668    sd->deferred_resize_job = ecore_job_add(_elm_win_resize_job, sd->obj);
669 }
670
671 static void
672 _elm_win_mouse_in(Ecore_Evas *ee)
673 {
674    Elm_Win_Data *sd = _elm_win_associate_get(ee);
675    if (!sd) return;
676
677    if (sd->resizing) sd->resizing = EINA_FALSE;
678 }
679
680 static void
681 _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win_Data *sd)
682 {
683    ELM_SAFE_FREE(sd->focus_highlight.reconf_job, ecore_job_del);
684 }
685
686 static void
687 _elm_win_focus_highlight_visible_set(Elm_Win_Data *sd,
688                                      Eina_Bool visible)
689 {
690    Evas_Object *fobj = sd->focus_highlight.fobj;
691    if (!fobj) return;
692
693    if (visible)
694      {
695         evas_object_show(fobj);
696         edje_object_signal_emit(fobj, "elm,action,focus,show", "elm");
697      }
698    else
699      {
700         edje_object_signal_emit(fobj, "elm,action,focus,hide", "elm");
701      }
702 }
703
704 static void
705 _elm_win_focus_highlight_anim_setup(Elm_Win_Data *sd,
706                                     Evas_Object *obj)
707 {
708    Evas_Coord tx, ty, tw, th;
709    Evas_Coord px, py, pw, ph;
710    Edje_Message_Int_Set *m;
711    Evas_Object *target = sd->focus_highlight.cur.target;
712
713    evas_object_geometry_get(obj, &px, &py, &pw, &ph);
714    elm_widget_focus_highlight_geometry_get(target, &tx, &ty, &tw, &th, EINA_TRUE);
715    evas_object_move(obj, tx, ty);
716    evas_object_resize(obj, tw, th);
717
718    if ((px == tx) && (py == ty) && (pw == tw) && (ph == th)) return;
719
720    if (!_elm_config->focus_highlight_clip_disable)
721      evas_object_clip_unset(obj);
722
723    m = alloca(sizeof(*m) + (sizeof(int) * 8));
724    m->count = 8;
725    m->val[0] = px - tx;
726    m->val[1] = py - ty;
727    m->val[2] = pw;
728    m->val[3] = ph;
729    m->val[4] = 0;
730    m->val[5] = 0;
731    m->val[6] = tw;
732    m->val[7] = th;
733    edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m);
734 }
735
736 static void
737 _elm_win_focus_highlight_simple_setup(Elm_Win_Data *sd,
738                                       Evas_Object *obj)
739 {
740    Evas_Object *clip, *target = sd->focus_highlight.cur.target;
741    Evas_Coord x, y, w, h;
742
743    elm_widget_focus_highlight_geometry_get(target, &x, &y, &w, &h, EINA_TRUE);
744
745    evas_object_move(obj, x, y);
746    evas_object_resize(obj, w, h);
747
748    if (!_elm_config->focus_highlight_clip_disable)
749      {
750         clip = evas_object_clip_get(target);
751         if (clip) evas_object_clip_set(obj, clip);
752      }
753
754    edje_object_signal_emit(obj, "elm,state,anim,stop", "elm");
755 }
756
757 static void
758 _elm_win_focus_highlight_reconfigure_job(void *data)
759 {
760    ELM_WIN_DATA_GET(data, sd);
761    Evas_Object *target = sd->focus_highlight.cur.target;
762    Evas_Object *previous = sd->focus_highlight.prev.target;
763    Evas_Object *fobj = sd->focus_highlight.fobj;
764    Eina_Bool visible_changed;
765    Eina_Bool common_visible;
766    const char *sig = NULL;
767    const char *focus_style_target = NULL;
768    const char *focus_style_previous = NULL;
769
770    _elm_win_focus_highlight_reconfigure_job_stop(sd);
771
772    visible_changed = (sd->focus_highlight.cur.visible !=
773                       sd->focus_highlight.prev.visible);
774
775    if ((target == previous) && (!visible_changed) &&
776        (!sd->focus_highlight.geometry_changed) &&
777        (!sd->focus_highlight.theme_changed))
778      return;
779
780    if ((previous) && (sd->focus_highlight.prev.in_theme))
781      elm_widget_signal_emit
782        (previous, "elm,action,focus_highlight,hide", "elm");
783
784    if (!target)
785      common_visible = EINA_FALSE;
786    else if (sd->focus_highlight.cur.in_theme)
787      {
788         common_visible = EINA_FALSE;
789         if (sd->focus_highlight.cur.visible)
790           sig = "elm,action,focus_highlight,show";
791         else
792           sig = "elm,action,focus_highlight,hide";
793      }
794    else
795      common_visible = sd->focus_highlight.cur.visible;
796
797    if (sig)
798      elm_widget_signal_emit(target, sig, "elm");
799
800    if ((!target) || (!common_visible) || (sd->focus_highlight.cur.in_theme))
801      goto the_end;
802
803    if (previous)
804      focus_style_previous = elm_widget_focus_highlight_style_get(previous);
805    focus_style_target = elm_widget_focus_highlight_style_get(target);
806
807    if (sd->focus_highlight.theme_changed ||
808        (focus_style_target != focus_style_previous))
809      {
810         const char *str;
811
812         if (focus_style_target)
813           str = focus_style_target;
814         else if (sd->focus_highlight.style)
815           str = sd->focus_highlight.style;
816         else
817           str = "default";
818
819         elm_widget_theme_object_set
820           (sd->obj, fobj, "focus_highlight", "top", str);
821         sd->focus_highlight.theme_changed = EINA_FALSE;
822
823         if (sd->focus_highlight.animate)
824           {
825              str = edje_object_data_get(sd->focus_highlight.fobj, "animate");
826              sd->focus_highlight.animate_supported = ((str) && (!strcmp(str, "on")));
827           }
828         else
829           sd->focus_highlight.animate_supported = EINA_FALSE;
830      }
831
832    if ((sd->focus_highlight.animate_supported) && (previous) &&
833        (!sd->focus_highlight.prev.in_theme))
834      _elm_win_focus_highlight_anim_setup(sd, fobj);
835    else
836      _elm_win_focus_highlight_simple_setup(sd, fobj);
837    evas_object_raise(fobj);
838
839 the_end:
840    _elm_win_focus_highlight_visible_set(sd, common_visible);
841    sd->focus_highlight.geometry_changed = EINA_FALSE;
842    sd->focus_highlight.prev = sd->focus_highlight.cur;
843 }
844
845 static void
846 _elm_win_focus_highlight_reconfigure_job_start(Elm_Win_Data *sd)
847 {
848    ecore_job_del(sd->focus_highlight.reconf_job);
849
850    sd->focus_highlight.reconf_job = ecore_job_add(
851        _elm_win_focus_highlight_reconfigure_job, sd->obj);
852 }
853
854 static void
855 _elm_win_focus_in(Ecore_Evas *ee)
856 {
857    Elm_Win_Data *sd = _elm_win_associate_get(ee);
858    Evas_Object *obj;
859    unsigned int order = 0;
860
861    if (!sd) return;
862
863    obj = sd->obj;
864
865    _elm_widget_top_win_focused_set(obj, EINA_TRUE);
866    if (!elm_widget_focus_order_get(obj)
867        || (obj == elm_widget_newest_focus_order_get(obj, &order, EINA_TRUE)))
868      {
869         elm_widget_focus_steal(obj);
870      }
871    else
872      elm_widget_focus_restore(obj);
873    evas_object_smart_callback_call(obj, SIG_FOCUS_IN, NULL);
874    evas_object_smart_callback_call(obj, SIG_FOCUSED, NULL);
875    sd->focus_highlight.cur.visible = EINA_TRUE;
876    _elm_win_focus_highlight_reconfigure_job_start(sd);
877    if (sd->frame_obj)
878      {
879         edje_object_signal_emit(sd->frame_obj, "elm,action,focus", "elm");
880      }
881
882    /* do nothing */
883    /* else if (sd->img_obj) */
884    /*   { */
885    /*   } */
886 }
887
888 static void
889 _elm_win_focus_out(Ecore_Evas *ee)
890 {
891    Elm_Win_Data *sd = _elm_win_associate_get(ee);
892    Evas_Object *obj;
893
894    if (!sd) return;
895
896    obj = sd->obj;
897
898    elm_object_focus_set(obj, EINA_FALSE);
899    _elm_widget_top_win_focused_set(obj, EINA_FALSE);
900    evas_object_smart_callback_call(obj, SIG_FOCUS_OUT, NULL);
901    evas_object_smart_callback_call(obj, SIG_UNFOCUSED, NULL);
902    sd->focus_highlight.cur.visible = EINA_FALSE;
903    _elm_win_focus_highlight_reconfigure_job_start(sd);
904    if (sd->frame_obj)
905      {
906         edje_object_signal_emit(sd->frame_obj, "elm,action,unfocus", "elm");
907      }
908
909    /* access */
910    _elm_access_object_highlight_disable(evas_object_evas_get(obj));
911
912    /* do nothing */
913    /* if (sd->img_obj) */
914    /*   { */
915    /*   } */
916 }
917
918 static void
919 _elm_win_available_profiles_del(Elm_Win_Data *sd)
920 {
921    if (!sd->profile.available_list) return;
922
923    unsigned int i;
924    for (i = 0; i < sd->profile.count; i++)
925      ELM_SAFE_FREE(sd->profile.available_list[i], eina_stringshare_del);
926    sd->profile.count = 0;
927    ELM_SAFE_FREE(sd->profile.available_list, free);
928 }
929
930 static void
931 _elm_win_profile_del(Elm_Win_Data *sd)
932 {
933    ELM_SAFE_FREE(sd->profile.name, eina_stringshare_del);
934 }
935
936 static Eina_Bool
937 _internal_elm_win_profile_set(Elm_Win_Data *sd, const char *profile)
938 {
939    Eina_Bool changed = EINA_FALSE;
940    if (profile)
941      {
942         if (sd->profile.name)
943           {
944              if (strcmp(sd->profile.name, profile) != 0)
945                {
946                   eina_stringshare_replace(&(sd->profile.name), profile);
947                   changed = EINA_TRUE;
948                }
949           }
950         else
951           {
952              sd->profile.name = eina_stringshare_add(profile);
953              changed = EINA_TRUE;
954           }
955      }
956    else
957      _elm_win_profile_del(sd);
958
959    return changed;
960 }
961
962 static void
963 _elm_win_profile_update(Elm_Win_Data *sd)
964 {
965    if (sd->profile.available_list)
966      {
967         Eina_Bool found = EINA_FALSE;
968         if (sd->profile.name)
969           {
970              unsigned int i;
971              for (i = 0; i < sd->profile.count; i++)
972                {
973                   if (!strcmp(sd->profile.name,
974                               sd->profile.available_list[i]))
975                     {
976                        found = EINA_TRUE;
977                        break;
978                     }
979                }
980           }
981
982         /* If current profile is not present in an available profiles,
983          * change current profile to the 1st element of an array.
984          */
985         if (!found)
986           _internal_elm_win_profile_set(sd, sd->profile.available_list[0]);
987      }
988
989    _elm_config_profile_set(sd->profile.name);
990
991    /* update sub ee */
992    Ecore_Evas *ee2;
993    Eina_List *sub, *l = NULL;
994
995    sub = ecore_evas_sub_ecore_evas_list_get(sd->ee);
996    EINA_LIST_FOREACH(sub, l, ee2)
997      ecore_evas_window_profile_set(ee2, sd->profile.name);
998
999    evas_object_smart_callback_call(sd->obj, SIG_PROFILE_CHANGED, NULL);
1000 }
1001
1002 static void
1003 _elm_win_state_change(Ecore_Evas *ee)
1004 {
1005    Elm_Win_Data *sd = _elm_win_associate_get(ee);
1006    Evas_Object *obj;
1007    Eina_Bool ch_withdrawn = EINA_FALSE;
1008    Eina_Bool ch_sticky = EINA_FALSE;
1009    Eina_Bool ch_iconified = EINA_FALSE;
1010    Eina_Bool ch_fullscreen = EINA_FALSE;
1011    Eina_Bool ch_maximized = EINA_FALSE;
1012    Eina_Bool ch_profile = EINA_FALSE;
1013    Eina_Bool ch_wm_rotation = EINA_FALSE;
1014    const char *profile;
1015
1016    if (!sd) return;
1017
1018    obj = sd->obj;
1019
1020    if (sd->withdrawn != ecore_evas_withdrawn_get(sd->ee))
1021      {
1022         sd->withdrawn = ecore_evas_withdrawn_get(sd->ee);
1023         ch_withdrawn = EINA_TRUE;
1024      }
1025    if (sd->sticky != ecore_evas_sticky_get(sd->ee))
1026      {
1027         sd->sticky = ecore_evas_sticky_get(sd->ee);
1028         ch_sticky = EINA_TRUE;
1029      }
1030    if (sd->iconified != ecore_evas_iconified_get(sd->ee))
1031      {
1032         sd->iconified = ecore_evas_iconified_get(sd->ee);
1033         ch_iconified = EINA_TRUE;
1034      }
1035    if (sd->fullscreen != ecore_evas_fullscreen_get(sd->ee))
1036      {
1037         sd->fullscreen = ecore_evas_fullscreen_get(sd->ee);
1038         ch_fullscreen = EINA_TRUE;
1039      }
1040    if (sd->maximized != ecore_evas_maximized_get(sd->ee))
1041      {
1042         sd->maximized = ecore_evas_maximized_get(sd->ee);
1043         ch_maximized = EINA_TRUE;
1044      }
1045
1046    profile = ecore_evas_window_profile_get(sd->ee);
1047    ch_profile = _internal_elm_win_profile_set(sd, profile);
1048
1049    if (sd->wm_rot.use)
1050      {
1051         if (sd->rot != ecore_evas_rotation_get(sd->ee))
1052           {
1053              sd->rot = ecore_evas_rotation_get(sd->ee);
1054              ch_wm_rotation = EINA_TRUE;
1055           }
1056      }
1057
1058    _elm_win_state_eval_queue();
1059
1060    if ((ch_withdrawn) || (ch_iconified))
1061      {
1062         if (sd->withdrawn)
1063           evas_object_smart_callback_call(obj, SIG_WITHDRAWN, NULL);
1064         else if (sd->iconified)
1065           evas_object_smart_callback_call(obj, SIG_ICONIFIED, NULL);
1066         else
1067           evas_object_smart_callback_call(obj, SIG_NORMAL, NULL);
1068      }
1069    if (ch_sticky)
1070      {
1071         if (sd->sticky)
1072           evas_object_smart_callback_call(obj, SIG_STICK, NULL);
1073         else
1074           evas_object_smart_callback_call(obj, SIG_UNSTICK, NULL);
1075      }
1076    if (ch_fullscreen)
1077      {
1078         if (sd->fullscreen)
1079           evas_object_smart_callback_call(obj, SIG_FULLSCREEN, NULL);
1080         else
1081           evas_object_smart_callback_call(obj, SIG_UNFULLSCREEN, NULL);
1082      }
1083    if (ch_maximized)
1084      {
1085         if (sd->maximized)
1086           evas_object_smart_callback_call(obj, SIG_MAXIMIZED, NULL);
1087         else
1088           evas_object_smart_callback_call(obj, SIG_UNMAXIMIZED, NULL);
1089      }
1090    if (ch_profile)
1091      {
1092         _elm_win_profile_update(sd);
1093      }
1094    if (ch_wm_rotation)
1095      {
1096         evas_object_size_hint_min_set(obj, -1, -1);
1097         evas_object_size_hint_max_set(obj, -1, -1);
1098 #ifdef HAVE_ELEMENTARY_X
1099         _elm_win_xwin_update(sd);
1100 #endif
1101         elm_widget_orientation_set(obj, sd->rot);
1102         evas_object_smart_callback_call(obj, SIG_ROTATION_CHANGED, NULL);
1103         evas_object_smart_callback_call(obj, SIG_WM_ROTATION_CHANGED, NULL);
1104      }
1105 }
1106
1107 EOLIAN static Eina_Bool
1108 _elm_win_elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Win_Data *_pd EINA_UNUSED)
1109 {
1110    return EINA_TRUE;
1111 }
1112
1113 EOLIAN static Eina_Bool
1114 _elm_win_elm_widget_focus_next(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED, Elm_Focus_Direction dir, Evas_Object **next)
1115 {
1116    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1117
1118    const Eina_List *items;
1119    void *(*list_data_get)(const Eina_List *list);
1120
1121    /* Focus chain */
1122    if (wd->subobjs)
1123      {
1124         if (!(items = elm_widget_focus_custom_chain_get(obj)))
1125           {
1126              items = wd->subobjs;
1127              if (!items)
1128                return EINA_FALSE;
1129           }
1130         list_data_get = eina_list_data_get;
1131
1132         elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
1133
1134         if (*next) return EINA_TRUE;
1135      }
1136    *next = (Evas_Object *)obj;
1137    return EINA_FALSE;
1138 }
1139
1140 EOLIAN static Eina_Bool
1141 _elm_win_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Win_Data *_pd EINA_UNUSED)
1142 {
1143    return EINA_TRUE;
1144 }
1145
1146 EOLIAN static Eina_Bool
1147 _elm_win_elm_widget_focus_direction(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED, const Evas_Object *base, double degree, Evas_Object **direction, double *weight)
1148 {
1149    const Eina_List *items;
1150    void *(*list_data_get)(const Eina_List *list);
1151
1152    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1153
1154    /* Focus chain */
1155    if (wd->subobjs)
1156      {
1157         if (!(items = elm_widget_focus_custom_chain_get(obj)))
1158           items = wd->subobjs;
1159
1160         list_data_get = eina_list_data_get;
1161
1162         return elm_widget_focus_list_direction_get
1163                  (obj, base, items, list_data_get, degree, direction, weight);
1164      }
1165
1166    return EINA_FALSE;
1167 }
1168
1169 EOLIAN static Eina_Bool
1170 _elm_win_elm_widget_on_focus(Eo *obj, Elm_Win_Data *sd)
1171 {
1172    Eina_Bool int_ret = EINA_FALSE;
1173    eo_do_super(obj, MY_CLASS, elm_obj_widget_on_focus(&int_ret));
1174    if (!int_ret) return EINA_TRUE;
1175
1176    if (sd->img_obj)
1177      evas_object_focus_set(sd->img_obj, elm_widget_focus_get(obj));
1178    else
1179      evas_object_focus_set(obj, elm_widget_focus_get(obj));
1180
1181    return EINA_TRUE;
1182 }
1183
1184 EOLIAN static Eina_Bool
1185 _elm_win_elm_widget_event(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED, Evas_Object *src, Evas_Callback_Type type, void *event_info)
1186 {
1187    (void) src;
1188    Evas_Event_Key_Down *ev = event_info;
1189
1190    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
1191    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
1192
1193    if ((!strcmp(ev->key, "Tab")) ||
1194        (!strcmp(ev->key, "ISO_Left_Tab")))
1195      {
1196         if (evas_key_modifier_is_set(ev->modifiers, "Control") ||
1197             evas_key_modifier_is_set(ev->modifiers, "Alt"))
1198           return EINA_FALSE;
1199         if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
1200           elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS);
1201         else
1202           elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
1203
1204         goto success;
1205      }
1206    else if ((!strcmp(ev->key, "Left")) ||
1207             ((!strcmp(ev->key, "KP_Left")) && (!ev->string)))
1208      {
1209         elm_widget_focus_cycle(obj, ELM_FOCUS_LEFT);
1210
1211         goto success;
1212      }
1213    else if ((!strcmp(ev->key, "Right")) ||
1214             ((!strcmp(ev->key, "KP_Right")) && (!ev->string)))
1215      {
1216         elm_widget_focus_cycle(obj, ELM_FOCUS_RIGHT);
1217
1218         goto success;
1219      }
1220    else if ((!strcmp(ev->key, "Up")) ||
1221             ((!strcmp(ev->key, "KP_Up")) && (!ev->string)))
1222      {
1223         elm_widget_focus_cycle(obj, ELM_FOCUS_UP);
1224
1225         goto success;
1226      }
1227    else if ((!strcmp(ev->key, "Down")) ||
1228             ((!strcmp(ev->key, "KP_Down")) && (!ev->string)))
1229      {
1230         elm_widget_focus_cycle(obj, ELM_FOCUS_DOWN);
1231
1232         goto success;
1233      }
1234
1235    return EINA_FALSE;
1236
1237 success:
1238    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1239    return EINA_TRUE;
1240 }
1241
1242 static void
1243 _deferred_ecore_evas_free(void *data)
1244 {
1245    ecore_evas_free(data);
1246    _elm_win_deferred_free--;
1247 }
1248
1249 EOLIAN static void
1250 _elm_win_evas_smart_show(Eo *obj, Elm_Win_Data *sd)
1251 {
1252    if (!evas_object_visible_get(obj))
1253      _elm_win_state_eval_queue();
1254    eo_do_super(obj, MY_CLASS, evas_obj_smart_show());
1255
1256    TRAP(sd, show);
1257
1258    if (sd->shot.info) _shot_handle(sd);
1259 }
1260
1261 EOLIAN static void
1262 _elm_win_evas_smart_hide(Eo *obj, Elm_Win_Data *sd)
1263 {
1264    if (evas_object_visible_get(obj))
1265      _elm_win_state_eval_queue();
1266    eo_do_super(obj, MY_CLASS, evas_obj_smart_hide());
1267
1268    TRAP(sd, hide);
1269
1270    if (sd->frame_obj)
1271      {
1272         evas_object_hide(sd->frame_obj);
1273      }
1274    if (sd->img_obj)
1275      {
1276         evas_object_hide(sd->img_obj);
1277      }
1278    if (sd->pointer.obj)
1279      {
1280         evas_object_hide(sd->pointer.obj);
1281         ecore_evas_hide(sd->pointer.ee);
1282      }
1283 }
1284
1285 static void
1286 _elm_win_on_parent_del(void *data,
1287                        Evas *e EINA_UNUSED,
1288                        Evas_Object *obj,
1289                        void *event_info EINA_UNUSED)
1290 {
1291    ELM_WIN_DATA_GET(data, sd);
1292
1293    if (obj == sd->parent) sd->parent = NULL;
1294 }
1295
1296 static void
1297 _elm_win_focus_target_move(void *data,
1298                            Evas *e EINA_UNUSED,
1299                            Evas_Object *obj EINA_UNUSED,
1300                            void *event_info EINA_UNUSED)
1301 {
1302    ELM_WIN_DATA_GET(data, sd);
1303
1304    sd->focus_highlight.geometry_changed = EINA_TRUE;
1305    _elm_win_focus_highlight_reconfigure_job_start(sd);
1306 }
1307
1308 static void
1309 _elm_win_focus_target_resize(void *data,
1310                              Evas *e EINA_UNUSED,
1311                              Evas_Object *obj EINA_UNUSED,
1312                              void *event_info EINA_UNUSED)
1313 {
1314    ELM_WIN_DATA_GET(data, sd);
1315
1316    sd->focus_highlight.geometry_changed = EINA_TRUE;
1317    _elm_win_focus_highlight_reconfigure_job_start(sd);
1318 }
1319
1320 static void
1321 _elm_win_focus_target_del(void *data,
1322                           Evas *e EINA_UNUSED,
1323                           Evas_Object *obj EINA_UNUSED,
1324                           void *event_info EINA_UNUSED)
1325 {
1326    ELM_WIN_DATA_GET(data, sd);
1327
1328    sd->focus_highlight.cur.target = NULL;
1329
1330    _elm_win_focus_highlight_reconfigure_job_start(sd);
1331 }
1332
1333 static Evas_Object *
1334 _elm_win_focus_target_get(Evas_Object *obj)
1335 {
1336    Evas_Object *o = obj;
1337
1338    do
1339      {
1340         if (elm_widget_is(o))
1341           {
1342              if (!elm_widget_highlight_ignore_get(o))
1343                break;
1344              o = elm_widget_parent_get(o);
1345              if (!o)
1346                o = evas_object_smart_parent_get(o);
1347           }
1348         else
1349           {
1350              o = elm_widget_parent_widget_get(o);
1351              if (!o)
1352                o = evas_object_smart_parent_get(o);
1353           }
1354      }
1355    while (o);
1356
1357    return o;
1358 }
1359
1360 static void
1361 _elm_win_focus_target_callbacks_add(Elm_Win_Data *sd)
1362 {
1363    Evas_Object *obj = sd->focus_highlight.cur.target;
1364    if (!obj) return;
1365
1366    evas_object_event_callback_add
1367      (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd->obj);
1368    evas_object_event_callback_add
1369      (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd->obj);
1370    evas_object_event_callback_add
1371      (obj, EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
1372 }
1373
1374 static void
1375 _elm_win_focus_target_callbacks_del(Elm_Win_Data *sd)
1376 {
1377    Evas_Object *obj = sd->focus_highlight.cur.target;
1378
1379    evas_object_event_callback_del_full
1380      (obj, EVAS_CALLBACK_MOVE, _elm_win_focus_target_move, sd->obj);
1381    evas_object_event_callback_del_full
1382      (obj, EVAS_CALLBACK_RESIZE, _elm_win_focus_target_resize, sd->obj);
1383    evas_object_event_callback_del_full
1384      (obj, EVAS_CALLBACK_DEL, _elm_win_focus_target_del, sd->obj);
1385 }
1386
1387 static void
1388 _elm_win_object_focus_in(void *data,
1389                          Evas *e EINA_UNUSED,
1390                          void *event_info)
1391 {
1392    Evas_Object *obj = event_info, *target;
1393    ELM_WIN_DATA_GET(data, sd);
1394
1395    if (sd->focus_highlight.cur.target == obj)
1396      return;
1397
1398    target = _elm_win_focus_target_get(obj);
1399    sd->focus_highlight.cur.target = target;
1400    if (target && elm_widget_highlight_in_theme_get(target))
1401      sd->focus_highlight.cur.in_theme = EINA_TRUE;
1402    else
1403      _elm_win_focus_target_callbacks_add(sd);
1404
1405    _elm_win_focus_highlight_reconfigure_job_start(sd);
1406 }
1407
1408 static void
1409 _elm_win_object_focus_out(void *data,
1410                           Evas *e EINA_UNUSED,
1411                           void *event_info EINA_UNUSED)
1412 {
1413    ELM_WIN_DATA_GET(data, sd);
1414
1415    if (!sd->focus_highlight.cur.target)
1416      return;
1417
1418    if (!sd->focus_highlight.cur.in_theme)
1419      _elm_win_focus_target_callbacks_del(sd);
1420
1421    sd->focus_highlight.cur.target = NULL;
1422    sd->focus_highlight.cur.in_theme = EINA_FALSE;
1423
1424    _elm_win_focus_highlight_reconfigure_job_start(sd);
1425 }
1426
1427 static void
1428 _elm_win_focus_highlight_shutdown(Elm_Win_Data *sd)
1429 {
1430    _elm_win_focus_highlight_reconfigure_job_stop(sd);
1431    if (sd->focus_highlight.cur.target)
1432      {
1433         elm_widget_signal_emit(sd->focus_highlight.cur.target,
1434                                "elm,action,focus_highlight,hide", "elm");
1435         _elm_win_focus_target_callbacks_del(sd);
1436         sd->focus_highlight.cur.target = NULL;
1437      }
1438    ELM_SAFE_FREE(sd->focus_highlight.fobj, evas_object_del);
1439
1440    evas_event_callback_del_full
1441      (sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
1442      _elm_win_object_focus_in, sd->obj);
1443    evas_event_callback_del_full
1444      (sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
1445      _elm_win_object_focus_out, sd->obj);
1446 }
1447
1448 static void
1449 _win_img_hide(void *data,
1450               Evas *e EINA_UNUSED,
1451               Evas_Object *obj EINA_UNUSED,
1452               void *event_info EINA_UNUSED)
1453 {
1454    elm_widget_focus_hide_handle(data);
1455 }
1456
1457 static void
1458 _win_img_mouse_up(void *data,
1459                   Evas *e EINA_UNUSED,
1460                   Evas_Object *obj EINA_UNUSED,
1461                   void *event_info)
1462 {
1463    Evas_Event_Mouse_Up *ev = event_info;
1464    if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
1465      elm_widget_focus_mouse_up_handle(data);
1466 }
1467
1468 static void
1469 _win_img_focus_in(void *data,
1470                   Evas *e EINA_UNUSED,
1471                   Evas_Object *obj EINA_UNUSED,
1472                   void *event_info EINA_UNUSED)
1473 {
1474    elm_widget_focus_steal(data);
1475 }
1476
1477 static void
1478 _win_img_focus_out(void *data,
1479                    Evas *e EINA_UNUSED,
1480                    Evas_Object *obj EINA_UNUSED,
1481                    void *event_info EINA_UNUSED)
1482 {
1483    elm_widget_focused_object_clear(data);
1484 }
1485
1486 static void
1487 _elm_win_on_img_obj_del(void *data,
1488                         Evas *e EINA_UNUSED,
1489                         Evas_Object *obj EINA_UNUSED,
1490                         void *event_info EINA_UNUSED)
1491 {
1492    ELM_WIN_DATA_GET(data, sd);
1493    _elm_win_img_callbacks_del(sd->obj, sd->img_obj);
1494    sd->img_obj = NULL;
1495 }
1496
1497 static void
1498 _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj)
1499 {
1500    evas_object_event_callback_del_full
1501      (imgobj, EVAS_CALLBACK_DEL, _elm_win_on_img_obj_del, obj);
1502    evas_object_event_callback_del_full
1503      (imgobj, EVAS_CALLBACK_HIDE, _win_img_hide, obj);
1504    evas_object_event_callback_del_full
1505      (imgobj, EVAS_CALLBACK_MOUSE_UP, _win_img_mouse_up, obj);
1506    evas_object_event_callback_del_full
1507      (imgobj, EVAS_CALLBACK_FOCUS_IN, _win_img_focus_in, obj);
1508    evas_object_event_callback_del_full
1509      (imgobj, EVAS_CALLBACK_FOCUS_OUT, _win_img_focus_out, obj);
1510 }
1511
1512 EOLIAN static void
1513 _elm_win_evas_smart_del(Eo *obj, Elm_Win_Data *sd)
1514 {
1515    evas_object_event_callback_del_full(sd->layout,
1516                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1517                                        _elm_win_on_resize_obj_changed_size_hints,
1518                                        obj);
1519    evas_object_del(sd->box);
1520    evas_object_del(sd->layout);
1521
1522    /* NB: child deletion handled by parent's smart del */
1523
1524    if ((trap) && (trap->del))
1525      trap->del(sd->trap_data, obj);
1526
1527    if (sd->parent)
1528      {
1529         evas_object_event_callback_del_full
1530           (sd->parent, EVAS_CALLBACK_DEL, _elm_win_on_parent_del, obj);
1531         sd->parent = NULL;
1532      }
1533
1534    if (sd->autodel_clear) *(sd->autodel_clear) = -1;
1535
1536    _elm_win_list = eina_list_remove(_elm_win_list, obj);
1537    _elm_win_count--;
1538    _elm_win_state_eval_queue();
1539
1540    if (sd->ee)
1541      {
1542         ecore_evas_callback_delete_request_set(sd->ee, NULL);
1543         ecore_evas_callback_resize_set(sd->ee, NULL);
1544      }
1545
1546    ecore_job_del(sd->deferred_resize_job);
1547    ecore_job_del(sd->deferred_child_eval_job);
1548    eina_stringshare_del(sd->shot.info);
1549    ecore_timer_del(sd->shot.timer);
1550
1551 #ifdef HAVE_ELEMENTARY_X
1552    ecore_event_handler_del(sd->x.client_message_handler);
1553    ecore_event_handler_del(sd->x.property_handler);
1554 #endif
1555
1556    if (sd->img_obj)
1557      {
1558         _elm_win_img_callbacks_del(obj, sd->img_obj);
1559         sd->img_obj = NULL;
1560      }
1561    else
1562      {
1563         if (sd->ee)
1564           {
1565              ecore_job_add(_deferred_ecore_evas_free, sd->ee);
1566              _elm_win_deferred_free++;
1567           }
1568      }
1569
1570    _elm_win_focus_highlight_shutdown(sd);
1571    eina_stringshare_del(sd->focus_highlight.style);
1572
1573    eina_stringshare_del(sd->title);
1574    eina_stringshare_del(sd->icon_name);
1575    eina_stringshare_del(sd->role);
1576    evas_object_del(sd->icon);
1577    evas_object_del(sd->main_menu);
1578
1579    _elm_win_profile_del(sd);
1580    _elm_win_available_profiles_del(sd);
1581
1582    /* Don't let callback in the air that point to sd */
1583    ecore_evas_callback_delete_request_set(sd->ee, NULL);
1584    ecore_evas_callback_resize_set(sd->ee, NULL);
1585    ecore_evas_callback_mouse_in_set(sd->ee, NULL);
1586    ecore_evas_callback_focus_in_set(sd->ee, NULL);
1587    ecore_evas_callback_focus_out_set(sd->ee, NULL);
1588    ecore_evas_callback_move_set(sd->ee, NULL);
1589    ecore_evas_callback_state_change_set(sd->ee, NULL);
1590
1591    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
1592
1593    if ((!_elm_win_list) &&
1594        (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
1595      {
1596         edje_file_cache_flush();
1597         edje_collection_cache_flush();
1598         evas_image_cache_flush(evas_object_evas_get(obj));
1599         evas_font_cache_flush(evas_object_evas_get(obj));
1600         elm_exit();
1601      }
1602 }
1603
1604 static void
1605 _elm_win_obj_intercept_show(void *data,
1606                             Evas_Object *obj)
1607 {
1608    ELM_WIN_DATA_GET(data, sd);
1609
1610    // this is called to make sure all smart containers have calculated their
1611    // sizes BEFORE we show the window to make sure it initially appears at
1612    // our desired size (ie min size is known first)
1613    evas_smart_objects_calculate(evas_object_evas_get(obj));
1614    if (sd->frame_obj)
1615      {
1616         evas_object_show(sd->frame_obj);
1617      }
1618    if (sd->img_obj)
1619      {
1620         evas_object_show(sd->img_obj);
1621      }
1622    if (sd->pointer.obj)
1623      {
1624         ecore_evas_show(sd->pointer.ee);
1625         evas_object_show(sd->pointer.obj);
1626      }
1627    evas_object_show(obj);
1628 }
1629
1630 EOLIAN static void
1631 _elm_win_evas_smart_move(Eo *obj, Elm_Win_Data *sd, Evas_Coord x, Evas_Coord y)
1632 {
1633    if (sd->img_obj)
1634      {
1635         if ((x != sd->screen.x) || (y != sd->screen.y))
1636           {
1637              sd->screen.x = x;
1638              sd->screen.y = y;
1639              evas_object_smart_callback_call(obj, SIG_MOVED, NULL);
1640           }
1641         return;
1642      }
1643    else
1644      {
1645         TRAP(sd, move, x, y);
1646         if (!ecore_evas_override_get(sd->ee))  return;
1647      }
1648
1649    eo_do_super(obj, MY_CLASS, evas_obj_smart_move(x, y));
1650
1651    if (ecore_evas_override_get(sd->ee))
1652      {
1653         sd->screen.x = x;
1654         sd->screen.y = y;
1655         evas_object_smart_callback_call(obj, SIG_MOVED, NULL);
1656      }
1657    if (sd->frame_obj)
1658      {
1659         /* FIXME: We should update ecore_wl_window_location here !! */
1660         sd->screen.x = x;
1661         sd->screen.y = y;
1662      }
1663    if (sd->img_obj)
1664      {
1665         sd->screen.x = x;
1666         sd->screen.y = y;
1667      }
1668 }
1669
1670 EOLIAN static void
1671 _elm_win_evas_smart_resize(Eo *obj, Elm_Win_Data *sd, Evas_Coord w, Evas_Coord h)
1672 {
1673    eo_do_super(obj, MY_CLASS, evas_obj_smart_resize(w, h));
1674
1675    if (sd->img_obj)
1676      {
1677         if (sd->constrain)
1678           {
1679              int sw, sh;
1680
1681              ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &sw, &sh);
1682              w = MIN(w, sw);
1683              h = MIN(h, sh);
1684           }
1685         if (w < 1) w = 1;
1686         if (h < 1) h = 1;
1687
1688         evas_object_image_size_set(sd->img_obj, w, h);
1689      }
1690
1691    TRAP(sd, resize, w, h);
1692 }
1693
1694 static void
1695 _elm_win_delete_request(Ecore_Evas *ee)
1696 {
1697    Elm_Win_Data *sd = _elm_win_associate_get(ee);
1698    Evas_Object *obj;
1699
1700    if (!sd) return;
1701
1702    obj = sd->obj;
1703
1704    int autodel = sd->autodel;
1705    sd->autodel_clear = &autodel;
1706    evas_object_ref(obj);
1707    evas_object_smart_callback_call(obj, SIG_DELETE_REQUEST, NULL);
1708    // FIXME: if above callback deletes - then the below will be invalid
1709    if (autodel) evas_object_del(obj);
1710    else sd->autodel_clear = NULL;
1711    evas_object_unref(obj);
1712 }
1713
1714 Ecore_X_Window
1715 _elm_ee_xwin_get(const Ecore_Evas *ee)
1716 {
1717 #ifdef HAVE_ELEMENTARY_X
1718    const char *engine_name;
1719    if (!ee) return 0;
1720
1721    engine_name = ecore_evas_engine_name_get(ee);
1722    if (EINA_UNLIKELY(!engine_name)) return 0;
1723
1724    if (!strcmp(engine_name, ELM_SOFTWARE_X11))
1725      {
1726         return ecore_evas_software_x11_window_get(ee);
1727      }
1728    else if (!strcmp(engine_name, ELM_OPENGL_X11))
1729      {
1730         return ecore_evas_gl_x11_window_get(ee);
1731      }
1732 #else
1733    (void)ee;
1734 #endif
1735    return 0;
1736 }
1737
1738 #ifdef HAVE_ELEMENTARY_X
1739 static void
1740 _internal_elm_win_xwindow_get(Elm_Win_Data *sd)
1741 {
1742    sd->x.xwin = _elm_ee_xwin_get(sd->ee);
1743 }
1744 #endif
1745
1746 Ecore_Wl_Window *
1747 _elm_ee_wlwin_get(const Ecore_Evas *ee)
1748 {
1749 #ifdef HAVE_ELEMENTARY_WAYLAND
1750    const char *engine_name;
1751
1752    if (!ee) return NULL;
1753
1754    engine_name = ecore_evas_engine_name_get(ee);
1755    if (EINA_UNLIKELY(!engine_name)) return NULL;
1756
1757    if ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
1758        (!strcmp(engine_name, ELM_WAYLAND_EGL)))
1759      {
1760         return ecore_evas_wayland_window_get(ee);
1761      }
1762 #else
1763    (void)ee;
1764 #endif
1765    return NULL;
1766 }
1767
1768 #ifdef HAVE_ELEMENTARY_WAYLAND
1769 static void
1770 _elm_win_wlwindow_get(Elm_Win_Data *sd)
1771 {
1772    sd->wl.win = _elm_ee_wlwin_get(sd->ee);
1773 }
1774 #endif
1775
1776 #ifdef HAVE_ELEMENTARY_X
1777 static void
1778 _elm_win_xwin_update(Elm_Win_Data *sd)
1779 {
1780    const char *s;
1781
1782    _internal_elm_win_xwindow_get(sd);
1783    if (sd->parent)
1784      {
1785         ELM_WIN_DATA_GET(sd->parent, sdp);
1786         if (sdp)
1787           {
1788              if (sd->x.xwin)
1789                ecore_x_icccm_transient_for_set(sd->x.xwin, sdp->x.xwin);
1790           }
1791      }
1792
1793    if (!sd->x.xwin) return;  /* nothing more to do */
1794
1795    s = sd->title;
1796    if (!s) s = _elm_appname;
1797    if (!s) s = "";
1798    if (sd->icon_name) s = sd->icon_name;
1799    ecore_x_icccm_icon_name_set(sd->x.xwin, s);
1800    ecore_x_netwm_icon_name_set(sd->x.xwin, s);
1801
1802    s = sd->role;
1803    if (s) ecore_x_icccm_window_role_set(sd->x.xwin, s);
1804
1805    // set window icon
1806    if (sd->icon)
1807      {
1808         void *data;
1809
1810         data = evas_object_image_data_get(sd->icon, EINA_FALSE);
1811         if (data)
1812           {
1813              Ecore_X_Icon ic;
1814              int w = 0, h = 0, stride, x, y;
1815              unsigned char *p;
1816              unsigned int *p2;
1817
1818              evas_object_image_size_get(sd->icon, &w, &h);
1819              stride = evas_object_image_stride_get(sd->icon);
1820              if ((w > 0) && (h > 0) &&
1821                  (stride >= (int)(w * sizeof(unsigned int))))
1822                {
1823                   ic.width = w;
1824                   ic.height = h;
1825                   ic.data = malloc(w * h * sizeof(unsigned int));
1826
1827                   if (ic.data)
1828                     {
1829                        p = (unsigned char *)data;
1830                        p2 = (unsigned int *)ic.data;
1831                        for (y = 0; y < h; y++)
1832                          {
1833                             for (x = 0; x < w; x++)
1834                               {
1835                                  *p2 = *((unsigned int *)p);
1836                                  p += sizeof(unsigned int);
1837                                  p2++;
1838                               }
1839                             p += (stride - (w * sizeof(unsigned int)));
1840                          }
1841                        ecore_x_netwm_icons_set(sd->x.xwin, &ic, 1);
1842                        free(ic.data);
1843                     }
1844                }
1845              evas_object_image_data_set(sd->icon, data);
1846           }
1847      }
1848
1849    switch (sd->type)
1850      {
1851       case ELM_WIN_BASIC:
1852         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_NORMAL);
1853         break;
1854
1855       case ELM_WIN_DIALOG_BASIC:
1856         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DIALOG);
1857         break;
1858
1859       case ELM_WIN_DESKTOP:
1860         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DESKTOP);
1861         break;
1862
1863       case ELM_WIN_DOCK:
1864         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DOCK);
1865         break;
1866
1867       case ELM_WIN_TOOLBAR:
1868         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_TOOLBAR);
1869         break;
1870
1871       case ELM_WIN_MENU:
1872         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_MENU);
1873         break;
1874
1875       case ELM_WIN_UTILITY:
1876         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_UTILITY);
1877         break;
1878
1879       case ELM_WIN_SPLASH:
1880         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_SPLASH);
1881         break;
1882
1883       case ELM_WIN_DROPDOWN_MENU:
1884         ecore_x_netwm_window_type_set
1885           (sd->x.xwin, ECORE_X_WINDOW_TYPE_DROPDOWN_MENU);
1886         break;
1887
1888       case ELM_WIN_POPUP_MENU:
1889         ecore_x_netwm_window_type_set
1890           (sd->x.xwin, ECORE_X_WINDOW_TYPE_POPUP_MENU);
1891         break;
1892
1893       case ELM_WIN_TOOLTIP:
1894         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_TOOLTIP);
1895         break;
1896
1897       case ELM_WIN_NOTIFICATION:
1898         ecore_x_netwm_window_type_set
1899           (sd->x.xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
1900         break;
1901
1902       case ELM_WIN_COMBO:
1903         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_COMBO);
1904         break;
1905
1906       case ELM_WIN_DND:
1907         ecore_x_netwm_window_type_set(sd->x.xwin, ECORE_X_WINDOW_TYPE_DND);
1908         break;
1909
1910       default:
1911         break;
1912      }
1913    ecore_x_e_virtual_keyboard_state_set
1914      (sd->x.xwin, (Ecore_X_Virtual_Keyboard_State)sd->kbdmode);
1915    if (sd->indmode == ELM_WIN_INDICATOR_SHOW)
1916      ecore_x_e_illume_indicator_state_set
1917        (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON);
1918    else if (sd->indmode == ELM_WIN_INDICATOR_HIDE)
1919      ecore_x_e_illume_indicator_state_set
1920        (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
1921 }
1922
1923 #endif
1924
1925 /**
1926   * @internal
1927   *
1928   * Resize the window according to window layout's min and weight.
1929   * If the window layout's weight is 0.0, the window max is limited to layout's
1930   * min size.
1931   *
1932   * This is called when the window layout's weight hint is changed or when the
1933   * window is rotated.
1934   *
1935   * @param obj window object
1936   */
1937 static void
1938 _elm_win_resize_objects_eval(Evas_Object *obj)
1939 {
1940    ELM_WIN_DATA_GET(obj, sd);
1941    Evas_Coord w, h, minw, minh, maxw, maxh;
1942    double wx, wy;
1943
1944    evas_object_size_hint_min_get(sd->layout, &minw, &minh);
1945    if (minw < 1) minw = 1;
1946    if (minh < 1) minh = 1;
1947
1948    evas_object_size_hint_weight_get(sd->layout, &wx, &wy);
1949    if (!wx) maxw = minw;
1950    else maxw = 32767;
1951    if (!wy) maxh = minh;
1952    else maxh = 32767;
1953
1954    evas_object_size_hint_min_set(obj, minw, minh);
1955    evas_object_size_hint_max_set(obj, maxw, maxh);
1956    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1957    if (w < minw) w = minw;
1958    if (h < minh) h = minh;
1959    if (w > maxw) w = maxw;
1960    if (h > maxh) h = maxh;
1961    evas_object_resize(obj, w, h);
1962 }
1963
1964 static void
1965 _elm_win_on_resize_obj_changed_size_hints(void *data,
1966                                           Evas *e EINA_UNUSED,
1967                                           Evas_Object *obj EINA_UNUSED,
1968                                           void *event_info EINA_UNUSED)
1969 {
1970    _elm_win_resize_objects_eval(data);
1971 }
1972
1973 void
1974 _elm_win_shutdown(void)
1975 {
1976    while (_elm_win_list) evas_object_del(_elm_win_list->data);
1977    ELM_SAFE_FREE(_elm_win_state_eval_job, ecore_job_del);
1978 }
1979
1980 void
1981 _elm_win_rescale(Elm_Theme *th,
1982                  Eina_Bool use_theme)
1983 {
1984    const Eina_List *l;
1985    Evas_Object *obj;
1986
1987    if (!use_theme)
1988      {
1989         EINA_LIST_FOREACH(_elm_win_list, l, obj)
1990           elm_widget_theme(obj);
1991      }
1992    else
1993      {
1994         EINA_LIST_FOREACH(_elm_win_list, l, obj)
1995           elm_widget_theme_specific(obj, th, EINA_FALSE);
1996      }
1997 }
1998
1999 void
2000 _elm_win_access(Eina_Bool is_access)
2001 {
2002    Evas *evas;
2003    const Eina_List *l;
2004    Evas_Object *obj;
2005    Evas_Object *fobj;
2006
2007    EINA_LIST_FOREACH(_elm_win_list, l, obj)
2008      {
2009         elm_widget_access(obj, is_access);
2010
2011          /* floating orphan object. if there are A, B, C objects and user does
2012             as below, then there would be floating orphan objects.
2013
2014               1. elm_object_content_set(layout, A);
2015               2. elm_object_content_set(layout, B);
2016               3. elm_object_content_set(layout, C);
2017
2018             now, the object A and B are floating orphan objects */
2019
2020         fobj = obj;
2021         for (;;)
2022           {
2023              fobj = evas_object_below_get(fobj);
2024              if (!fobj) break;
2025
2026              if (elm_widget_is(fobj) && !elm_widget_parent_get(fobj))
2027                {
2028                   elm_widget_access(fobj, is_access);
2029                }
2030           }
2031
2032         if (!is_access)
2033           {
2034              evas = evas_object_evas_get(obj);
2035             if (evas) _elm_access_object_highlight_disable(evas);
2036           }
2037      }
2038 }
2039
2040 void
2041 _elm_win_translate(void)
2042 {
2043    const Eina_List *l;
2044    Evas_Object *obj;
2045
2046    EINA_LIST_FOREACH(_elm_win_list, l, obj)
2047      elm_widget_translate(obj);
2048 }
2049
2050 #ifdef HAVE_ELEMENTARY_X
2051 static Eina_Bool
2052 _elm_win_client_message(void *data,
2053                         int type EINA_UNUSED,
2054                         void *event)
2055 {
2056    ELM_WIN_DATA_GET(data, sd);
2057    Ecore_X_Event_Client_Message *e = event;
2058
2059    if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
2060    if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH)
2061      {
2062         if ((unsigned int)e->data.l[0] == sd->x.xwin)
2063           {
2064              Evas *evas = evas_object_evas_get(sd->obj);
2065              if (evas)
2066                {
2067                   edje_file_cache_flush();
2068                   edje_collection_cache_flush();
2069                   evas_image_cache_flush(evas);
2070                   evas_font_cache_flush(evas);
2071                }
2072           }
2073      }
2074    else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP)
2075      {
2076         if ((unsigned int)e->data.l[0] == sd->x.xwin)
2077           {
2078              Evas *evas = evas_object_evas_get(sd->obj);
2079              if (evas)
2080                {
2081                   edje_file_cache_flush();
2082                   edje_collection_cache_flush();
2083                   evas_image_cache_flush(evas);
2084                   evas_font_cache_flush(evas);
2085                   evas_render_dump(evas);
2086                }
2087           }
2088      }
2089    else if (e->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL)
2090      {
2091         if ((unsigned int)e->data.l[0] == sd->x.xwin)
2092           {
2093              if ((unsigned int)e->data.l[1] ==
2094                  ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT)
2095                {
2096                   // XXX: call right access func
2097                }
2098              else if ((unsigned int)e->data.l[1] ==
2099                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV)
2100                {
2101                   // XXX: call right access func
2102                }
2103              else if ((unsigned int)e->data.l[1] ==
2104                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE)
2105                {
2106                   _elm_access_highlight_object_activate
2107                     (sd->obj, ELM_ACTIVATE_DEFAULT);
2108                }
2109              else if ((unsigned int)e->data.l[1] ==
2110                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ)
2111                {
2112                   /* there would be better way to read highlight object */
2113                   Evas *evas;
2114                   evas = evas_object_evas_get(sd->obj);
2115                   if (!evas) return ECORE_CALLBACK_PASS_ON;
2116
2117                   _elm_access_mouse_event_enabled_set(EINA_TRUE);
2118
2119                   evas_event_feed_mouse_in(evas, 0, NULL);
2120                   evas_event_feed_mouse_move
2121                     (evas, e->data.l[2], e->data.l[3], 0, NULL);
2122
2123                   _elm_access_mouse_event_enabled_set(EINA_FALSE);
2124                }
2125              else if ((unsigned int)e->data.l[1] ==
2126                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT)
2127                {
2128                   _elm_access_highlight_cycle(sd->obj, ELM_FOCUS_NEXT);
2129                }
2130              else if ((unsigned int)e->data.l[1] ==
2131                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV)
2132                {
2133                   _elm_access_highlight_cycle(sd->obj, ELM_FOCUS_PREVIOUS);
2134                }
2135              else if ((unsigned int)e->data.l[1] ==
2136                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP)
2137                {
2138                   _elm_access_highlight_object_activate
2139                     (sd->obj, ELM_ACTIVATE_UP);
2140                }
2141              else if ((unsigned int)e->data.l[1] ==
2142                       ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN)
2143                {
2144                   _elm_access_highlight_object_activate
2145                     (sd->obj, ELM_ACTIVATE_DOWN);
2146                }
2147           }
2148      }
2149    return ECORE_CALLBACK_PASS_ON;
2150 }
2151
2152 static Eina_Bool
2153 _elm_win_property_change(void *data,
2154                          int type EINA_UNUSED,
2155                          void *event)
2156 {
2157    ELM_WIN_DATA_GET(data, sd);
2158    Ecore_X_Event_Window_Property *e = event;
2159
2160    if (e->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE)
2161      {
2162         if (e->win == sd->x.xwin)
2163           {
2164              sd->indmode = (Elm_Win_Indicator_Mode)ecore_x_e_illume_indicator_state_get(e->win);
2165              evas_object_smart_callback_call(sd->obj, SIG_INDICATOR_PROP_CHANGED, NULL);
2166           }
2167      }
2168    return ECORE_CALLBACK_PASS_ON;
2169 }
2170 #endif
2171
2172 static void
2173 _elm_win_focus_highlight_hide(void *data EINA_UNUSED,
2174                               Evas_Object *obj,
2175                               const char *emission EINA_UNUSED,
2176                               const char *source EINA_UNUSED)
2177 {
2178    evas_object_hide(obj);
2179 }
2180
2181 static void
2182 _elm_win_focus_highlight_anim_end(void *data,
2183                                   Evas_Object *obj,
2184                                   const char *emission EINA_UNUSED,
2185                                   const char *source EINA_UNUSED)
2186 {
2187    ELM_WIN_DATA_GET(data, sd);
2188
2189    _elm_win_focus_highlight_simple_setup(sd, obj);
2190 }
2191
2192 static void
2193 _elm_win_focus_highlight_init(Elm_Win_Data *sd)
2194 {
2195    evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
2196                            _elm_win_object_focus_in, sd->obj);
2197    evas_event_callback_add(sd->evas,
2198                            EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
2199                            _elm_win_object_focus_out, sd->obj);
2200
2201    sd->focus_highlight.cur.target = NULL;
2202    sd->focus_highlight.fobj = edje_object_add(sd->evas);
2203    sd->focus_highlight.theme_changed = EINA_TRUE;
2204
2205    edje_object_signal_callback_add(sd->focus_highlight.fobj,
2206                                    "elm,action,focus,hide,end", "*",
2207                                    _elm_win_focus_highlight_hide, NULL);
2208    edje_object_signal_callback_add(sd->focus_highlight.fobj,
2209                                    "elm,action,focus,anim,end", "*",
2210                                    _elm_win_focus_highlight_anim_end, sd->obj);
2211    _elm_win_focus_highlight_reconfigure_job_start(sd);
2212 }
2213
2214 static void
2215 _elm_win_frame_cb_move_start(void *data,
2216                              Evas_Object *obj EINA_UNUSED,
2217                              const char *sig EINA_UNUSED,
2218                              const char *source)
2219 {
2220    ELM_WIN_DATA_GET(data, sd);
2221
2222    if (!sd) return;
2223
2224 #ifdef HAVE_ELEMENTARY_WAYLAND
2225    if (!strcmp(source, "elm"))
2226      ecore_wl_window_cursor_from_name_set(sd->wl.win, ELM_CURSOR_HAND1);
2227    else
2228      ecore_wl_window_cursor_default_restore(sd->wl.win);
2229 #else
2230    (void)source;
2231 #endif
2232
2233    /* NB: Wayland handles moving surfaces by itself so we cannot
2234     * specify a specific x/y we want. Instead, we will pass in the
2235     * existing x/y values so they can be recorded as 'previous'
2236     * position. The new position will get updated automatically when
2237     * the move is finished */
2238
2239    ecore_evas_wayland_move(sd->ee, sd->screen.x, sd->screen.y);
2240 }
2241
2242 static void
2243 _elm_win_frame_cb_move_stop(void *data,
2244                             Evas_Object *obj EINA_UNUSED,
2245                             const char *sig EINA_UNUSED,
2246                             const char *source EINA_UNUSED)
2247 {
2248    ELM_WIN_DATA_GET(data, sd);
2249
2250    if (!sd) return;
2251
2252 #ifdef HAVE_ELEMENTARY_WAYLAND
2253    ecore_wl_window_cursor_default_restore(sd->wl.win);
2254 #endif
2255 }
2256
2257 #ifdef HAVE_ELEMENTARY_WAYLAND
2258 struct _resize_info
2259 {
2260    const char *name;
2261    int location;
2262 };
2263
2264 static struct _resize_info _border_side[4] =
2265 {
2266      { ELM_CURSOR_TOP_SIDE, 1 },
2267      { ELM_CURSOR_LEFT_SIDE, 4 },
2268      { ELM_CURSOR_BOTTOM_SIDE, 2 },
2269      { ELM_CURSOR_RIGHT_SIDE, 8 },
2270 };
2271
2272 static struct _resize_info _border_corner[4] =
2273 {
2274      { ELM_CURSOR_TOP_LEFT_CORNER, 5 },
2275      { ELM_CURSOR_BOTTOM_LEFT_CORNER, 6 },
2276      { ELM_CURSOR_BOTTOM_RIGHT_CORNER, 10 },
2277      { ELM_CURSOR_TOP_RIGHT_CORNER, 9 },
2278 };
2279 #endif
2280
2281 static void
2282 _elm_win_frame_obj_update(Elm_Win_Data *sd)
2283 {
2284    int fx, fy, fw, fh;
2285    int ox, oy, ow, oh;
2286    int sx, sy, sw, sh;
2287    int x, y, w, h;
2288    evas_object_geometry_get(sd->frame_obj, &fx, &fy, &fw, &fh);
2289    evas_object_geometry_get(sd->client_obj, &ox, &oy, &ow, &oh);
2290    evas_object_geometry_get(sd->spacer_obj, &sx, &sy, &sw, &sh);
2291
2292    evas_output_framespace_get(sd->evas, &x, &y, &w, &h);
2293
2294    if ((x != (ox - fx)) || (y != (oy - fy)) ||
2295        (w != (fw - ow)) || (h != (fh - oh)))
2296      {
2297         evas_output_framespace_set(sd->evas, (ox - fx), (oy - fy),
2298                                    (fw - ow), (fh - oh));
2299      }
2300
2301 #ifdef HAVE_ELEMENTARY_WAYLAND
2302    ecore_wl_window_opaque_region_set(sd->wl.win, -fx, -(fy - sy), sw, sh);
2303 #endif
2304 }
2305
2306 static void
2307 _elm_win_frame_obj_move(void *data,
2308                         Evas *e EINA_UNUSED,
2309                         Evas_Object *obj EINA_UNUSED,
2310                         void *event_info EINA_UNUSED)
2311 {
2312    Elm_Win_Data *sd;
2313
2314    if (!(sd = data)) return;
2315    if (!sd->client_obj) return;
2316
2317    _elm_win_frame_obj_update(sd);
2318 }
2319
2320 static void
2321 _elm_win_frame_obj_resize(void *data,
2322                           Evas *e EINA_UNUSED,
2323                           Evas_Object *obj EINA_UNUSED,
2324                           void *event_info EINA_UNUSED)
2325 {
2326    Elm_Win_Data *sd;
2327
2328    if (!(sd = data)) return;
2329    if (!sd->client_obj) return;
2330
2331    _elm_win_frame_obj_update(sd);
2332 }
2333
2334 static void
2335 _elm_win_frame_cb_resize_show(void *data,
2336                               Evas_Object *obj EINA_UNUSED,
2337                               const char *sig EINA_UNUSED,
2338                               const char *source)
2339 {
2340    ELM_WIN_DATA_GET(data, sd);
2341
2342    if (!sd) return;
2343    if (sd->resizing) return;
2344
2345 #ifdef HAVE_ELEMENTARY_WAYLAND
2346    int i;
2347    i = sd->rot / 90;
2348    if (!strcmp(source, "elm.event.resize.t"))
2349      ecore_wl_window_cursor_from_name_set(sd->wl.win,
2350                                           _border_side[(0 + i) % 4].name);
2351    else if (!strcmp(source, "elm.event.resize.b"))
2352      ecore_wl_window_cursor_from_name_set(sd->wl.win,
2353                                           _border_side[(2 + i) % 4].name);
2354    else if (!strcmp(source, "elm.event.resize.l"))
2355      ecore_wl_window_cursor_from_name_set(sd->wl.win,
2356                                           _border_side[(1 + i) % 4].name);
2357    else if (!strcmp(source, "elm.event.resize.r"))
2358      ecore_wl_window_cursor_from_name_set(sd->wl.win,
2359                                           _border_side[(3 + i) % 4].name);
2360    else if (!strcmp(source, "elm.event.resize.tl"))
2361      ecore_wl_window_cursor_from_name_set(sd->wl.win,
2362                                           _border_corner[(0 + i) % 4].name);
2363    else if (!strcmp(source, "elm.event.resize.tr"))
2364      ecore_wl_window_cursor_from_name_set(sd->wl.win,
2365                                           _border_corner[(3 + i) % 4].name);
2366    else if (!strcmp(source, "elm.event.resize.bl"))
2367      ecore_wl_window_cursor_from_name_set(sd->wl.win,
2368                                           _border_corner[(1 + i) % 4].name);
2369    else if (!strcmp(source, "elm.event.resize.br"))
2370      ecore_wl_window_cursor_from_name_set(sd->wl.win,
2371                                           _border_corner[(2 + i) % 4].name);
2372    else
2373      ecore_wl_window_cursor_default_restore(sd->wl.win);
2374 #else
2375    (void)source;
2376 #endif
2377 }
2378
2379 static void
2380 _elm_win_frame_cb_resize_hide(void *data,
2381                               Evas_Object *obj EINA_UNUSED,
2382                               const char *sig EINA_UNUSED,
2383                               const char *source EINA_UNUSED)
2384 {
2385    ELM_WIN_DATA_GET(data, sd);
2386
2387    if (!sd) return;
2388    if (sd->resizing) return;
2389
2390 #ifdef HAVE_ELEMENTARY_WAYLAND
2391    ecore_wl_window_cursor_default_restore(sd->wl.win);
2392 #endif
2393 }
2394
2395 static void
2396 _elm_win_frame_cb_resize_start(void *data,
2397                                Evas_Object *obj EINA_UNUSED,
2398                                const char *sig EINA_UNUSED,
2399                                const char *source)
2400 {
2401 #ifdef HAVE_ELEMENTARY_WAYLAND
2402    ELM_WIN_DATA_GET(data, sd);
2403    int i;
2404
2405    if (!sd) return;
2406    if (sd->resizing) return;
2407
2408    sd->resizing = EINA_TRUE;
2409    i = sd->rot / 90;
2410    if (!strcmp(source, "elm.event.resize.t"))
2411      sd->resize_location = _border_side[(0 + i) % 4].location;
2412    else if (!strcmp(source, "elm.event.resize.b"))
2413      sd->resize_location = _border_side[(2 + i) % 4].location;
2414    else if (!strcmp(source, "elm.event.resize.l"))
2415      sd->resize_location = _border_side[(1 + i) % 4].location;
2416    else if (!strcmp(source, "elm.event.resize.r"))
2417      sd->resize_location = _border_side[(3 + i) % 4].location;
2418    else if (!strcmp(source, "elm.event.resize.tl"))
2419      sd->resize_location = _border_corner[(0 + i) % 4].location;
2420    else if (!strcmp(source, "elm.event.resize.tr"))
2421      sd->resize_location = _border_corner[(3 + i) % 4].location;
2422    else if (!strcmp(source, "elm.event.resize.bl"))
2423      sd->resize_location = _border_corner[(1 + i) % 4].location;
2424    else if (!strcmp(source, "elm.event.resize.br"))
2425      sd->resize_location = _border_corner[(2 + i) % 4].location;
2426    else
2427      sd->resize_location = 0;
2428
2429    if (sd->resize_location > 0)
2430      ecore_evas_wayland_resize(sd->ee, sd->resize_location);
2431 #else
2432    (void)data;
2433    (void)source;
2434 #endif
2435 }
2436
2437 static void
2438 _elm_win_frame_cb_minimize(void *data,
2439                            Evas_Object *obj EINA_UNUSED,
2440                            const char *sig EINA_UNUSED,
2441                            const char *source EINA_UNUSED)
2442 {
2443    ELM_WIN_DATA_GET(data, sd);
2444
2445    if (!sd) return;
2446 //   sd->iconified = EINA_TRUE;
2447    TRAP(sd, iconified_set, EINA_TRUE);
2448 }
2449
2450 static void
2451 _elm_win_frame_maximized_state_update(Elm_Win_Data *sd, Eina_Bool maximized)
2452 {
2453    const char *emission;
2454
2455    if (maximized)
2456      emission = "elm,state,maximized";
2457    else
2458      emission = "elm,state,unmaximized";
2459
2460    edje_object_signal_emit(sd->frame_obj, emission, "elm");
2461    edje_object_message_signal_process(sd->frame_obj);
2462    evas_object_smart_calculate(sd->frame_obj);
2463
2464    _elm_win_frame_obj_update(sd);
2465 }
2466
2467 static void
2468 _elm_win_frame_cb_maximize(void *data,
2469                            Evas_Object *obj EINA_UNUSED,
2470                            const char *sig EINA_UNUSED,
2471                            const char *source EINA_UNUSED)
2472 {
2473    Eina_Bool value;
2474    ELM_WIN_DATA_GET(data, sd);
2475
2476    if (!sd) return;
2477    if (sd->maximized) value = EINA_FALSE;
2478    else value = EINA_TRUE;
2479
2480    _elm_win_frame_maximized_state_update(sd, value);
2481
2482    TRAP(sd, maximized_set, value);
2483 }
2484
2485 static void
2486 _elm_win_frame_cb_close(void *data,
2487                         Evas_Object *obj EINA_UNUSED,
2488                         const char *sig EINA_UNUSED,
2489                         const char *source EINA_UNUSED)
2490 {
2491    ELM_WIN_DATA_GET(data, sd);
2492    Evas_Object *win;
2493
2494    /* FIXME: After the current freeze, this should be handled differently.
2495     *
2496     * Ideally, we would want to mimic the X11 backend and use something
2497     * like ECORE_WL_EVENT_WINDOW_DELETE and handle the delete_request
2498     * inside of ecore_evas. That would be the 'proper' way, but since we are
2499     * in a freeze right now, I cannot add a new event value, or a new
2500     * event structure to ecore_wayland.
2501     *
2502     * So yes, this is a temporary 'stop-gap' solution which will be fixed
2503     * when the freeze is over, but it does fix a trac bug for now, and in a
2504     * way which does not break API or the freeze. - dh
2505     */
2506
2507    if (!sd) return;
2508
2509    win = sd->obj;
2510
2511    int autodel = sd->autodel;
2512    sd->autodel_clear = &autodel;
2513    evas_object_ref(win);
2514    evas_object_smart_callback_call(win, SIG_DELETE_REQUEST, NULL);
2515    // FIXME: if above callback deletes - then the below will be invalid
2516    if (autodel) evas_object_del(win);
2517    else sd->autodel_clear = NULL;
2518    evas_object_unref(win);
2519 }
2520
2521 static void
2522 _elm_win_frame_add(Elm_Win_Data *sd,
2523                    const char *style)
2524 {
2525    Evas_Object *obj = sd->obj;
2526    int w, h, mw, mh;
2527    short layer;
2528
2529    sd->frame_obj = edje_object_add(sd->evas);
2530    layer = evas_object_layer_get(obj);
2531    evas_object_layer_set(sd->frame_obj, layer + 1);
2532    if (!elm_widget_theme_object_set
2533        (sd->obj, sd->frame_obj, "border", "base", style))
2534      {
2535         ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
2536         return;
2537      }
2538
2539    sd->spacer_obj = evas_object_rectangle_add(sd->evas);
2540    evas_object_color_set(sd->spacer_obj, 0, 0, 0, 0);
2541    evas_object_repeat_events_set(sd->spacer_obj, EINA_TRUE);
2542    edje_object_part_swallow(sd->frame_obj, "elm.swallow.frame_spacer",
2543                             sd->spacer_obj);
2544
2545    sd->client_obj = evas_object_rectangle_add(sd->evas);
2546    evas_object_color_set(sd->client_obj, 0, 0, 0, 0);
2547    /* NB: Tried pass_events here, but that fails to send events */
2548    evas_object_repeat_events_set(sd->client_obj, EINA_TRUE);
2549    edje_object_part_swallow(sd->frame_obj, "elm.swallow.client",
2550                             sd->client_obj);
2551
2552    evas_object_is_frame_object_set(sd->frame_obj, EINA_TRUE);
2553
2554    evas_object_event_callback_add
2555      (sd->frame_obj, EVAS_CALLBACK_MOVE, _elm_win_frame_obj_move, sd);
2556    evas_object_event_callback_add
2557      (sd->frame_obj, EVAS_CALLBACK_RESIZE, _elm_win_frame_obj_resize, sd);
2558
2559    /* NB: Do NOT remove these calls !! Needed to calculate proper
2560     * framespace on inital show of the window */
2561    edje_object_size_min_calc(sd->frame_obj, &mw, &mh);
2562    evas_object_move(sd->frame_obj, 0, 0);
2563    evas_object_resize(sd->frame_obj, mw, mh);
2564    evas_object_smart_calculate(sd->frame_obj);
2565
2566    edje_object_signal_callback_add
2567      (sd->frame_obj, "elm,action,move,start", "elm",
2568      _elm_win_frame_cb_move_start, obj);
2569    edje_object_signal_callback_add
2570      (sd->frame_obj, "elm,action,move,stop", "elm",
2571      _elm_win_frame_cb_move_stop, obj);
2572    edje_object_signal_callback_add
2573      (sd->frame_obj, "elm,action,resize,show", "*",
2574      _elm_win_frame_cb_resize_show, obj);
2575    edje_object_signal_callback_add
2576      (sd->frame_obj, "elm,action,resize,hide", "*",
2577      _elm_win_frame_cb_resize_hide, obj);
2578    edje_object_signal_callback_add
2579      (sd->frame_obj, "elm,action,resize,start", "*",
2580      _elm_win_frame_cb_resize_start, obj);
2581    edje_object_signal_callback_add
2582      (sd->frame_obj, "elm,action,minimize", "elm",
2583      _elm_win_frame_cb_minimize, obj);
2584    edje_object_signal_callback_add
2585      (sd->frame_obj, "elm,action,maximize", "elm",
2586      _elm_win_frame_cb_maximize, obj);
2587    edje_object_signal_callback_add
2588      (sd->frame_obj, "elm,action,close", "elm", _elm_win_frame_cb_close, obj);
2589
2590    if (sd->title)
2591      {
2592         edje_object_part_text_escaped_set
2593           (sd->frame_obj, "elm.text.title", sd->title);
2594      }
2595
2596    ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
2597    ecore_evas_resize(sd->ee, w, h);
2598 }
2599
2600 static void
2601 _elm_win_frame_del(Elm_Win_Data *sd)
2602 {
2603    int w, h;
2604
2605    ELM_SAFE_FREE(sd->client_obj, evas_object_del);
2606
2607    if (sd->frame_obj)
2608      {
2609         evas_object_event_callback_del_full
2610           (sd->frame_obj, EVAS_CALLBACK_MOVE, _elm_win_frame_obj_move, sd);
2611         evas_object_event_callback_del_full
2612           (sd->frame_obj, EVAS_CALLBACK_RESIZE, _elm_win_frame_obj_resize, sd);
2613
2614         edje_object_signal_callback_del
2615           (sd->frame_obj, "elm,action,move,start", "elm",
2616               _elm_win_frame_cb_move_start);
2617         edje_object_signal_callback_del
2618           (sd->frame_obj, "elm,action,move,stop", "elm",
2619               _elm_win_frame_cb_move_stop);
2620         edje_object_signal_callback_del
2621           (sd->frame_obj, "elm,action,resize,show", "*",
2622               _elm_win_frame_cb_resize_show);
2623         edje_object_signal_callback_del
2624           (sd->frame_obj, "elm,action,resize,hide", "*",
2625               _elm_win_frame_cb_resize_hide);
2626         edje_object_signal_callback_del
2627           (sd->frame_obj, "elm,action,resize,start", "*",
2628               _elm_win_frame_cb_resize_start);
2629         edje_object_signal_callback_del
2630           (sd->frame_obj, "elm,action,minimize", "elm",
2631               _elm_win_frame_cb_minimize);
2632         edje_object_signal_callback_del
2633           (sd->frame_obj, "elm,action,maximize", "elm",
2634               _elm_win_frame_cb_maximize);
2635         edje_object_signal_callback_del
2636           (sd->frame_obj, "elm,action,close", "elm",
2637               _elm_win_frame_cb_close);
2638
2639         ELM_SAFE_FREE(sd->frame_obj, evas_object_del);
2640      }
2641
2642    evas_output_framespace_set(sd->evas, 0, 0, 0, 0);
2643    ecore_evas_geometry_get(sd->ee, NULL, NULL, &w, &h);
2644    ecore_evas_resize(sd->ee, w, h);
2645 }
2646
2647 #ifdef ELM_DEBUG
2648 static void
2649 _debug_key_down(void *data EINA_UNUSED,
2650                 Evas *e EINA_UNUSED,
2651                 Evas_Object *obj,
2652                 void *event_info)
2653 {
2654    Evas_Event_Key_Down *ev = event_info;
2655
2656    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
2657      return;
2658
2659    if ((strcmp(ev->key, "F12")) ||
2660        (!evas_key_modifier_is_set(ev->modifiers, "Control")))
2661      return;
2662
2663    INF("Tree graph generated.");
2664    elm_object_tree_dot_dump(obj, "./dump.dot");
2665 }
2666
2667 #endif
2668
2669 static void
2670 _win_inlined_image_set(Elm_Win_Data *sd)
2671 {
2672    evas_object_image_alpha_set(sd->img_obj, EINA_FALSE);
2673    evas_object_image_filled_set(sd->img_obj, EINA_TRUE);
2674
2675    evas_object_event_callback_add
2676      (sd->img_obj, EVAS_CALLBACK_DEL, _elm_win_on_img_obj_del, sd->obj);
2677    evas_object_event_callback_add
2678      (sd->img_obj, EVAS_CALLBACK_HIDE, _win_img_hide, sd->obj);
2679    evas_object_event_callback_add
2680      (sd->img_obj, EVAS_CALLBACK_MOUSE_UP, _win_img_mouse_up, sd->obj);
2681    evas_object_event_callback_add
2682      (sd->img_obj, EVAS_CALLBACK_FOCUS_IN, _win_img_focus_in, sd->obj);
2683    evas_object_event_callback_add
2684      (sd->img_obj, EVAS_CALLBACK_FOCUS_OUT, _win_img_focus_out, sd->obj);
2685 }
2686
2687 static void
2688 _elm_win_on_icon_del(void *data,
2689                      Evas *e EINA_UNUSED,
2690                      Evas_Object *obj,
2691                      void *event_info EINA_UNUSED)
2692 {
2693    ELM_WIN_DATA_GET(data, sd);
2694
2695    if (sd->icon == obj) sd->icon = NULL;
2696 }
2697
2698 EOLIAN static void
2699 _elm_win_evas_smart_add(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED)
2700 {
2701    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
2702
2703    elm_widget_can_focus_set(obj, EINA_TRUE);
2704
2705    elm_widget_highlight_ignore_set(obj, EINA_TRUE);
2706 }
2707
2708 #ifdef HAVE_ELEMENTARY_X
2709 static void
2710 _elm_x_io_err(void *data EINA_UNUSED)
2711 {
2712    Eina_List *l;
2713    Evas_Object *obj;
2714
2715    EINA_LIST_FOREACH(_elm_win_list, l, obj)
2716      evas_object_smart_callback_call(obj, SIG_IOERR, NULL);
2717    elm_exit();
2718 }
2719 #endif
2720
2721 EAPI Evas_Object *
2722 elm_win_add(Evas_Object *parent,
2723             const char *name,
2724             Elm_Win_Type type)
2725 {
2726    Evas_Object *obj = eo_add_custom(MY_CLASS, parent, elm_obj_win_constructor(name, type));
2727    eo_unref(obj);
2728    return obj;
2729 }
2730
2731 static void
2732 _elm_win_cb_hide(void *data EINA_UNUSED,
2733                  Evas *e EINA_UNUSED,
2734                  Evas_Object *obj EINA_UNUSED,
2735                  void *event_info EINA_UNUSED)
2736 {
2737    _elm_win_state_eval_queue();
2738 }
2739
2740 static void
2741 _elm_win_cb_show(void *data EINA_UNUSED,
2742                  Evas *e EINA_UNUSED,
2743                  Evas_Object *obj EINA_UNUSED,
2744                  void *event_info EINA_UNUSED)
2745 {
2746    _elm_win_state_eval_queue();
2747 }
2748
2749 /**
2750   * @internal
2751   *
2752   * Recalculate the size of window considering its resize objects' weight and
2753   * min size. If any of its resize objects' weight equals to 0.0, window
2754   * layout's weight will be set to 0.0.
2755   *
2756   * @param o box object
2757   * @param p box's private data
2758   * @param data window object
2759   */
2760 static void
2761 _window_layout_stack(Evas_Object *o, Evas_Object_Box_Data *p, void *data)
2762 {
2763    const Eina_List *l;
2764    Evas_Object *child;
2765    Evas_Object_Box_Option *opt;
2766    Evas_Coord x, y, w, h;
2767    double wx, wy;
2768    Evas_Coord minw = -1, minh = -1;
2769    double weight_x = EVAS_HINT_EXPAND;
2770    double weight_y = EVAS_HINT_EXPAND;
2771
2772    EINA_LIST_FOREACH(p->children, l, opt)
2773      {
2774         child = opt->obj;
2775         evas_object_size_hint_weight_get(child, &wx, &wy);
2776         if (wx == 0.0) weight_x = 0;
2777         if (wy == 0.0) weight_y = 0;
2778
2779         evas_object_size_hint_min_get(child, &w, &h);
2780         if (w > minw) minw = w;
2781         if (h > minh) minh = h;
2782      }
2783
2784    evas_object_size_hint_min_set(o, minw, minh);
2785    evas_object_geometry_get(o, &x, &y, &w, &h);
2786    if (w < minw) w = minw;
2787    if (h < minh) h = minh;
2788    evas_object_resize(o, w, h);
2789
2790    EINA_LIST_FOREACH(p->children, l, opt)
2791      {
2792         child = opt->obj;
2793         evas_object_move(child, x, y);
2794         evas_object_resize(child, w, h);
2795      }
2796
2797    ELM_WIN_DATA_GET(data, sd);
2798    evas_object_size_hint_weight_set(sd->layout, weight_x, weight_y);
2799    evas_object_smart_changed(sd->layout);
2800 }
2801
2802 static Eina_Bool
2803 _accel_is_gl(void)
2804 {
2805    if ((_elm_accel_preference) &&
2806        ((!strcasecmp(_elm_accel_preference, "gl")) ||
2807         (!strcasecmp(_elm_accel_preference, "opengl")) ||
2808         (!strcasecmp(_elm_accel_preference, "3d")) ||
2809         (!strcasecmp(_elm_accel_preference, "hw")) ||
2810         (!strcasecmp(_elm_accel_preference, "accel")) ||
2811         (!strcasecmp(_elm_accel_preference, "hardware"))
2812        ))
2813      return EINA_TRUE;
2814    return EINA_FALSE;
2815 }
2816
2817 EOLIAN static void
2818 _elm_win_constructor(Eo *obj, Elm_Win_Data *sd, const char *name, Elm_Win_Type type)
2819 {
2820    sd->obj = obj; // in ctor
2821
2822    Evas_Object *parent;
2823    Evas *e;
2824    const Eina_List *l;
2825    const char *fontpath, *engine = NULL, *enginelist[32], *disp;
2826    int i;
2827
2828    Elm_Win_Data tmp_sd;
2829
2830    eo_do(obj, eo_parent_get(&parent));
2831
2832    /* just to store some data while trying out to create a canvas */
2833    memset(&tmp_sd, 0, sizeof(Elm_Win_Data));
2834
2835    switch (type)
2836      {
2837       case ELM_WIN_INLINED_IMAGE:
2838         if (!parent) break;
2839           {
2840              e = evas_object_evas_get(parent);
2841              Ecore_Evas *ee;
2842
2843              if (!e) break;
2844
2845              ee = ecore_evas_ecore_evas_get(e);
2846              if (!ee) break;
2847
2848              tmp_sd.img_obj = ecore_evas_object_image_new(ee);
2849              if (!tmp_sd.img_obj) break;
2850
2851              tmp_sd.ee = ecore_evas_object_ecore_evas_get(tmp_sd.img_obj);
2852              if (!tmp_sd.ee)
2853                {
2854                   ELM_SAFE_FREE(tmp_sd.img_obj, evas_object_del);
2855                }
2856           }
2857         break;
2858
2859       case ELM_WIN_SOCKET_IMAGE:
2860         tmp_sd.ee = ecore_evas_extn_socket_new(1, 1);
2861         break;
2862
2863       default:
2864         disp = getenv("ELM_DISPLAY");
2865         if ((disp) && (!strcmp(disp, "x11")))
2866           {
2867              if (_accel_is_gl())
2868                {
2869                   enginelist[0] = ELM_OPENGL_X11;
2870                   enginelist[1] = ELM_SOFTWARE_X11;
2871                   enginelist[2] = NULL;
2872                }
2873              else
2874                {
2875                   enginelist[0] = ENGINE_GET();
2876                   enginelist[1] = ELM_SOFTWARE_X11;
2877                   enginelist[2] = ELM_OPENGL_X11;
2878                   enginelist[3] = NULL;
2879                }
2880           }
2881         else if ((disp) && (!strcmp(disp, "wl")))
2882           {
2883              if (_accel_is_gl())
2884                {
2885                   enginelist[0] = ELM_WAYLAND_EGL;
2886                   enginelist[1] = ELM_WAYLAND_SHM;
2887                   enginelist[2] = NULL;
2888                }
2889              else
2890                {
2891                   enginelist[0] = ENGINE_GET();
2892                   enginelist[1] = ELM_WAYLAND_SHM;
2893                   enginelist[2] = ELM_WAYLAND_EGL;
2894                   enginelist[3] = NULL;
2895                }
2896           }
2897         else if ((disp) && (!strcmp(disp, "win")))
2898           {
2899              enginelist[0] = ENGINE_GET();
2900              enginelist[1] = ELM_SOFTWARE_WIN32;
2901              enginelist[2] = NULL;
2902           }
2903         else if ((disp) && (!strcmp(disp, "sdl")))
2904           {
2905              if (_accel_is_gl())
2906                {
2907                   enginelist[0] = ELM_OPENGL_SDL;
2908                   enginelist[1] = ELM_SOFTWARE_SDL;
2909                   enginelist[2] = NULL;
2910                }
2911              else
2912                {
2913                   enginelist[0] = ENGINE_GET();
2914                   enginelist[1] = ELM_SOFTWARE_SDL;
2915                   enginelist[2] = ELM_OPENGL_SDL;
2916                   enginelist[3] = NULL;
2917                }
2918           }
2919         else if ((disp) && (!strcmp(disp, "mac")))
2920           {
2921              enginelist[0] = ENGINE_GET();
2922              enginelist[1] = ELM_OPENGL_COCOA;
2923              enginelist[2] = NULL;
2924           }
2925         else if ((disp) && (!strcmp(disp, "ews")))
2926           {
2927              enginelist[0] = ENGINE_GET();
2928              enginelist[1] = ELM_EWS;
2929              enginelist[2] = NULL;
2930           }
2931         else if ((disp) && (!strcmp(disp, "fb")))
2932           {
2933              enginelist[0] = ENGINE_GET();
2934              enginelist[1] = ELM_DRM;
2935              enginelist[2] = ELM_SOFTWARE_FB;
2936              enginelist[3] = NULL;
2937           }
2938         else if ((disp) && (!strcmp(disp, "buffer")))
2939           {
2940              enginelist[0] = ENGINE_GET();
2941              enginelist[1] = ELM_BUFFER;
2942              enginelist[2] = NULL;
2943           }
2944         else if ((disp) && (!strcmp(disp, "ps3")))
2945           {
2946              enginelist[0] = ENGINE_GET();
2947              enginelist[1] = ELM_SOFTWARE_PSL1GHT;
2948              enginelist[2] = NULL;
2949           }
2950         else if ((disp) && (!strcmp(disp, "shot")))
2951           {
2952              enginelist[0] = ENGINE_GET();
2953              enginelist[1] = NULL;
2954           }
2955         else
2956           {
2957              if (_accel_is_gl())
2958                {
2959                   enginelist[0] = ELM_OPENGL_X11;
2960                   enginelist[1] = ELM_WAYLAND_EGL;
2961                   enginelist[2] = ELM_DRM;
2962                   enginelist[3] = ELM_SOFTWARE_FB;
2963                   enginelist[4] = ELM_OPENGL_COCOA;
2964                   enginelist[5] = ELM_OPENGL_SDL;
2965                   enginelist[6] = NULL;
2966                }
2967              else
2968                {
2969                   enginelist[0] = ENGINE_GET();
2970                   enginelist[1] = ELM_SOFTWARE_X11;
2971                   enginelist[2] = ELM_WAYLAND_SHM;
2972                   enginelist[3] = ELM_DRM;
2973                   enginelist[4] = ELM_SOFTWARE_FB;
2974                   enginelist[5] = ELM_OPENGL_COCOA;
2975                   enginelist[6] = ELM_SOFTWARE_SDL;
2976                   enginelist[7] = NULL;
2977                }
2978           }
2979         for (i = 0; i < 30; i++)
2980           {
2981              if ((i > 0) && (!enginelist[i])) break;
2982              if (!strcmp(enginelist[i], ELM_SOFTWARE_X11))
2983                tmp_sd.ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
2984              else if (!strcmp(enginelist[i], ELM_OPENGL_X11))
2985                {
2986                   int opt[10], opt_i = 0;
2987
2988                   if (_elm_config->vsync)
2989                     {
2990                        opt[opt_i++] = ECORE_EVAS_GL_X11_OPT_VSYNC;
2991                        opt[opt_i++] = 1;
2992                        opt[opt_i++] = 0;
2993                     }
2994                   if (opt_i > 0)
2995                     tmp_sd.ee = ecore_evas_gl_x11_options_new(NULL, 0, 0, 0, 1, 1, opt);
2996                   else
2997                     tmp_sd.ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1);
2998                }
2999              else if (!strcmp(enginelist[i], ELM_WAYLAND_SHM))
3000                tmp_sd.ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 0, 1, 1, 0);
3001              else if (!strcmp(enginelist[i], ELM_WAYLAND_EGL))
3002                tmp_sd.ee = ecore_evas_wayland_egl_new(NULL, 0, 0, 0, 1, 1, 0);
3003              else if (!strcmp(enginelist[i], ELM_SOFTWARE_WIN32))
3004                tmp_sd.ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1);
3005              else if (!strcmp(enginelist[i], ELM_SOFTWARE_SDL))
3006                tmp_sd.ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1);
3007              else if (!strcmp(enginelist[i], ELM_OPENGL_SDL))
3008                tmp_sd.ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0);
3009              else if (!strcmp(enginelist[i], ELM_OPENGL_COCOA))
3010                tmp_sd.ee = ecore_evas_cocoa_new(NULL, 1, 1, 0, 0);
3011              else if (!strcmp(enginelist[i], ELM_EWS))
3012                tmp_sd.ee = ecore_evas_ews_new(0, 0, 1, 1);
3013              else if (!strcmp(enginelist[i], ELM_SOFTWARE_FB))
3014                tmp_sd.ee = ecore_evas_fb_new(NULL, 0, 1, 1);
3015              else if (!strcmp(enginelist[i], ELM_BUFFER))
3016                tmp_sd.ee = ecore_evas_buffer_new(1, 1);
3017              else if (!strcmp(enginelist[i], ELM_SOFTWARE_PSL1GHT))
3018                tmp_sd.ee = ecore_evas_psl1ght_new(NULL, 1, 1);
3019              else if (!strcmp(enginelist[i], ELM_DRM))
3020                tmp_sd.ee = ecore_evas_drm_new(NULL, 0, 0, 0, 1, 1);
3021              else if (!strncmp(enginelist[i], "shot:", 5))
3022                {
3023                   tmp_sd.ee = ecore_evas_buffer_new(1, 1);
3024                   ecore_evas_manual_render_set(tmp_sd.ee, EINA_TRUE);
3025                   tmp_sd.shot.info = eina_stringshare_add(ENGINE_GET() + 5);
3026                }
3027              engine = enginelist[i];
3028              if (tmp_sd.ee) break;
3029           }
3030         break;
3031      }
3032
3033    if (!tmp_sd.ee)
3034      {
3035         ERR("Cannot create window.");
3036         eo_error_set(obj);
3037         return;
3038      }
3039
3040    eo_do(obj, eo_parent_set(ecore_evas_get(tmp_sd.ee)));
3041    eo_do_super(obj, MY_CLASS, eo_constructor());
3042    eo_do(obj,
3043          evas_obj_type_set(MY_CLASS_NAME_LEGACY),
3044          evas_obj_smart_callbacks_descriptions_set(_smart_callbacks, NULL));
3045
3046    if (getenv("ELM_FIRST_FRAME"))
3047      evas_event_callback_add(ecore_evas_get(tmp_sd.ee), EVAS_CALLBACK_RENDER_POST,
3048                              _elm_win_first_frame_do, getenv("ELM_FIRST_FRAME"));
3049
3050    /* copying possibly altered fields back */
3051 #define SD_CPY(_field)             \
3052   do                               \
3053     {                              \
3054        sd->_field = tmp_sd._field; \
3055     } while (0)
3056
3057    SD_CPY(ee);
3058    SD_CPY(img_obj);
3059    SD_CPY(shot.info);
3060 #undef SD_CPY
3061
3062    if ((trap) && (trap->add))
3063      sd->trap_data = trap->add(obj);
3064
3065    /* complementary actions, which depend on final smart data
3066     * pointer */
3067    if (type == ELM_WIN_INLINED_IMAGE)
3068      _win_inlined_image_set(sd);
3069 #ifdef HAVE_ELEMENTARY_X
3070    else if ((engine) &&
3071             ((!strcmp(engine, ELM_SOFTWARE_X11)) ||
3072              (!strcmp(engine, ELM_OPENGL_X11))))
3073      {
3074         sd->x.client_message_handler = ecore_event_handler_add
3075             (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, obj);
3076         sd->x.property_handler = ecore_event_handler_add
3077             (ECORE_X_EVENT_WINDOW_PROPERTY, _elm_win_property_change, obj);
3078      }
3079 #endif
3080    else if ((engine) && (!strncmp(engine, "shot:", 5)))
3081      _shot_init(sd);
3082
3083    sd->kbdmode = ELM_WIN_KEYBOARD_UNKNOWN;
3084    sd->indmode = ELM_WIN_INDICATOR_UNKNOWN;
3085
3086 #ifdef HAVE_ELEMENTARY_X
3087    _internal_elm_win_xwindow_get(sd);
3088    if (sd->x.xwin)
3089      {
3090         ecore_x_io_error_handler_set(_elm_x_io_err, NULL);
3091      }
3092 #endif
3093
3094 #ifdef HAVE_ELEMENTARY_WAYLAND
3095    if ((ENGINE_COMPARE(ELM_WAYLAND_SHM)) || (ENGINE_COMPARE(ELM_WAYLAND_EGL)))
3096      _elm_win_wlwindow_get(sd);
3097 #endif
3098
3099    if ((_elm_config->bgpixmap)
3100 #ifdef HAVE_ELEMENTARY_X
3101        &&
3102        (((sd->x.xwin) && (!ecore_x_screen_is_composited(0))) ||
3103            (!sd->x.xwin)))
3104 #else
3105      )
3106 #endif
3107      TRAP(sd, avoid_damage_set, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
3108    // bg pixmap done by x - has other issues like can be redrawn by x before it
3109    // is filled/ready by app
3110    //     TRAP(sd, avoid_damage_set, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
3111
3112    sd->type = type;
3113    sd->parent = parent;
3114
3115    if (sd->parent)
3116      evas_object_event_callback_add
3117        (sd->parent, EVAS_CALLBACK_DEL, _elm_win_on_parent_del, obj);
3118
3119    sd->evas = ecore_evas_get(sd->ee);
3120
3121    evas_object_color_set(obj, 0, 0, 0, 0);
3122    evas_object_move(obj, 0, 0);
3123    evas_object_resize(obj, 1, 1);
3124    evas_object_layer_set(obj, 50);
3125    evas_object_pass_events_set(obj, EINA_TRUE);
3126
3127    if (type == ELM_WIN_INLINED_IMAGE)
3128      elm_widget_parent2_set(obj, parent);
3129
3130    /* use own version of ecore_evas_object_associate() that does TRAP() */
3131    ecore_evas_data_set(sd->ee, "elm_win", obj);
3132
3133    evas_object_event_callback_add
3134      (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
3135       _elm_win_obj_callback_changed_size_hints, obj);
3136
3137    evas_object_intercept_raise_callback_add
3138      (obj, _elm_win_obj_intercept_raise, obj);
3139    evas_object_intercept_lower_callback_add
3140      (obj, _elm_win_obj_intercept_lower, obj);
3141    evas_object_intercept_stack_above_callback_add
3142      (obj, _elm_win_obj_intercept_stack_above, obj);
3143    evas_object_intercept_stack_below_callback_add
3144      (obj, _elm_win_obj_intercept_stack_below, obj);
3145    evas_object_intercept_layer_set_callback_add
3146      (obj, _elm_win_obj_intercept_layer_set, obj);
3147    evas_object_intercept_show_callback_add
3148      (obj, _elm_win_obj_intercept_show, obj);
3149
3150    TRAP(sd, name_class_set, name, _elm_appname);
3151    ecore_evas_callback_delete_request_set(sd->ee, _elm_win_delete_request);
3152    ecore_evas_callback_resize_set(sd->ee, _elm_win_resize);
3153    ecore_evas_callback_mouse_in_set(sd->ee, _elm_win_mouse_in);
3154    ecore_evas_callback_focus_in_set(sd->ee, _elm_win_focus_in);
3155    ecore_evas_callback_focus_out_set(sd->ee, _elm_win_focus_out);
3156    ecore_evas_callback_move_set(sd->ee, _elm_win_move);
3157    ecore_evas_callback_state_change_set(sd->ee, _elm_win_state_change);
3158    evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _elm_win_cb_hide, NULL);
3159    evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _elm_win_cb_show, NULL);
3160
3161    evas_image_cache_set(sd->evas, (_elm_config->image_cache * 1024));
3162    evas_font_cache_set(sd->evas, (_elm_config->font_cache * 1024));
3163
3164    EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
3165      evas_font_path_append(sd->evas, fontpath);
3166
3167    if (!_elm_config->font_hinting)
3168      evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_NONE);
3169    else if (_elm_config->font_hinting == 1)
3170      evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_AUTO);
3171    else if (_elm_config->font_hinting == 2)
3172      evas_font_hinting_set(sd->evas, EVAS_FONT_HINTING_BYTECODE);
3173
3174 #ifdef HAVE_ELEMENTARY_X
3175    _elm_win_xwin_update(sd);
3176 #endif
3177
3178    _elm_win_list = eina_list_append(_elm_win_list, obj);
3179    _elm_win_count++;
3180
3181    if ((engine) && ((!strcmp(engine, ELM_SOFTWARE_FB)) || (!strcmp(engine, ELM_DRM))))
3182      {
3183         TRAP(sd, fullscreen_set, 1);
3184      }
3185    else if ((type != ELM_WIN_INLINED_IMAGE) &&
3186             ((engine) &&
3187              ((!strcmp(engine, ELM_WAYLAND_SHM) ||
3188               (!strcmp(engine, ELM_WAYLAND_EGL))))))
3189      _elm_win_frame_add(sd, "default");
3190
3191    if (_elm_config->focus_highlight_enable)
3192      elm_win_focus_highlight_enabled_set(obj, EINA_TRUE);
3193    if (_elm_config->focus_highlight_animate)
3194      elm_win_focus_highlight_animate_set(obj, EINA_TRUE);
3195
3196 #ifdef ELM_DEBUG
3197    Evas_Modifier_Mask mask = evas_key_modifier_mask_get(sd->evas, "Control");
3198    evas_object_event_callback_add
3199      (obj, EVAS_CALLBACK_KEY_DOWN, _debug_key_down, NULL);
3200
3201    if (evas_object_key_grab(obj, "F12", mask, 0, EINA_TRUE))
3202      INF("Ctrl+F12 key combination exclusive for dot tree generation\n");
3203    else
3204      ERR("failed to grab F12 key to elm widgets (dot) tree generation");
3205 #endif
3206
3207    if ((_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_ON) ||
3208        ((_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_AUTO) &&
3209         ((engine) && 
3210          ((!strcmp(engine, ELM_SOFTWARE_FB)) || (!strcmp(engine, ELM_DRM))))))
3211      {
3212         Evas_Object *o;
3213         Evas_Coord mw = 1, mh = 1, hx = 0, hy = 0;
3214
3215         sd->pointer.obj = o = edje_object_add(ecore_evas_get(tmp_sd.ee));
3216         _elm_theme_object_set(obj, o, "pointer", "base", "default");
3217         edje_object_size_min_calc(o, &mw, &mh);
3218         evas_object_resize(o, mw, mh);
3219         edje_object_part_geometry_get(o, "elm.swallow.hotspot",
3220                                       &hx, &hy, NULL, NULL);
3221         sd->pointer.hot_x = hx;
3222         sd->pointer.hot_y = hy;
3223         evas_object_show(o);
3224         ecore_evas_object_cursor_set(tmp_sd.ee, o, EVAS_LAYER_MAX, hx, hy);
3225      }
3226    else if (_elm_config->softcursor_mode == ELM_SOFTCURSOR_MODE_OFF)
3227      {
3228         // do nothing
3229      }
3230
3231    sd->wm_rot.wm_supported = ecore_evas_wm_rotation_supported_get(sd->ee);
3232    sd->wm_rot.preferred_rot = -1; // it means that elm_win doesn't use preferred rotation.
3233
3234    sd->layout = edje_object_add(sd->evas);
3235    _elm_theme_object_set(obj, sd->layout, "win", "base", "default");
3236    sd->box = evas_object_box_add(sd->evas);
3237    evas_object_box_layout_set(sd->box, _window_layout_stack, obj, NULL);
3238    edje_object_part_swallow(sd->layout, "elm.swallow.contents", sd->box);
3239    evas_object_move(sd->layout, 0, 0);
3240    evas_object_resize(sd->layout, 1, 1);
3241    edje_object_update_hints_set(sd->layout, EINA_TRUE);
3242    evas_object_event_callback_add(sd->layout, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
3243                                   _elm_win_on_resize_obj_changed_size_hints, obj);
3244    evas_object_show(sd->layout);
3245 }
3246
3247 EOLIAN static void
3248 _elm_win_eo_base_constructor(Eo *obj, Elm_Win_Data *_pd EINA_UNUSED)
3249 {
3250    eo_error_set(obj);
3251    ERR("only custom constructor can be used with '%s' class", MY_CLASS_NAME);
3252 }
3253
3254 EOLIAN static Elm_Win_Type
3255 _elm_win_type_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3256 {
3257    return sd->type;
3258 }
3259
3260 EAPI Evas_Object *
3261 elm_win_util_standard_add(const char *name,
3262                           const char *title)
3263 {
3264    Evas_Object *win, *bg;
3265
3266    win = elm_win_add(NULL, name, ELM_WIN_BASIC);
3267    if (!win) return NULL;
3268
3269    elm_win_title_set(win, title);
3270    bg = elm_bg_add(win);
3271    if (!bg)
3272      {
3273         evas_object_del(win);
3274         return NULL;
3275      }
3276    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
3277    elm_win_resize_object_add(win, bg);
3278    evas_object_show(bg);
3279
3280    return win;
3281 }
3282
3283 EOLIAN static void
3284 _elm_win_resize_object_add(Eo *obj, Elm_Win_Data *sd, Evas_Object *subobj)
3285 {
3286    elm_widget_sub_object_add(obj, subobj);
3287
3288    if (!evas_object_box_append(sd->box, subobj))
3289      ERR("could not append %p to box", subobj);
3290 }
3291
3292 EOLIAN static void
3293 _elm_win_resize_object_del(Eo *obj, Elm_Win_Data *sd, Evas_Object *subobj)
3294 {
3295    if (!elm_widget_sub_object_del(obj, subobj))
3296      ERR("could not remove sub object %p from %p", subobj, obj);
3297
3298    evas_object_box_remove(sd->box, subobj);
3299 }
3300
3301 EOLIAN static void
3302 _elm_win_title_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *title)
3303 {
3304    if (!title) return;
3305    eina_stringshare_replace(&(sd->title), title);
3306    TRAP(sd, title_set, sd->title);
3307    if (sd->frame_obj)
3308      edje_object_part_text_escaped_set
3309        (sd->frame_obj, "elm.text.title", sd->title);
3310 }
3311
3312 EOLIAN static const char*
3313 _elm_win_title_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3314 {
3315    return sd->title;
3316 }
3317
3318 EOLIAN static void
3319 _elm_win_icon_name_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *icon_name)
3320 {
3321    if (!icon_name) return;
3322    eina_stringshare_replace(&(sd->icon_name), icon_name);
3323 #ifdef HAVE_ELEMENTARY_X
3324    _elm_win_xwin_update(sd);
3325 #endif
3326 }
3327
3328 EOLIAN static const char*
3329 _elm_win_icon_name_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3330 {
3331    return sd->icon_name;
3332 }
3333
3334 EOLIAN static void
3335 _elm_win_role_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *role)
3336 {
3337    if (!role) return;
3338    eina_stringshare_replace(&(sd->role), role);
3339 #ifdef HAVE_ELEMENTARY_X
3340    _elm_win_xwin_update(sd);
3341 #endif
3342 }
3343
3344 EOLIAN static const char*
3345 _elm_win_role_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3346 {
3347    return sd->role;
3348 }
3349
3350 EOLIAN static void
3351 _elm_win_icon_object_set(Eo *obj, Elm_Win_Data *sd, Evas_Object *icon)
3352 {
3353    if (sd->icon)
3354      evas_object_event_callback_del_full
3355        (sd->icon, EVAS_CALLBACK_DEL, _elm_win_on_icon_del, obj);
3356    sd->icon = icon;
3357    if (sd->icon)
3358      evas_object_event_callback_add
3359        (sd->icon, EVAS_CALLBACK_DEL, _elm_win_on_icon_del, obj);
3360 #ifdef HAVE_ELEMENTARY_X
3361    _elm_win_xwin_update(sd);
3362 #endif
3363 }
3364
3365 EOLIAN static const Evas_Object*
3366 _elm_win_icon_object_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3367 {
3368    return sd->icon;
3369 }
3370
3371 EOLIAN static void
3372 _elm_win_autodel_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool autodel)
3373 {
3374    sd->autodel = autodel;
3375 }
3376
3377 EOLIAN static Eina_Bool
3378 _elm_win_autodel_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3379 {
3380    return sd->autodel;
3381 }
3382
3383 EOLIAN static void
3384 _elm_win_activate(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3385 {
3386    TRAP(sd, activate);
3387 }
3388
3389 EOLIAN static void
3390 _elm_win_lower(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3391 {
3392    TRAP(sd, lower);
3393 }
3394
3395 EOLIAN static void
3396 _elm_win_raise(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3397 {
3398    TRAP(sd, raise);
3399 }
3400
3401 EOLIAN static void
3402 _elm_win_center(Eo *obj, Elm_Win_Data *sd, Eina_Bool h, Eina_Bool v)
3403 {
3404    int win_w, win_h, screen_w, screen_h, nx, ny;
3405
3406    if ((trap) && (trap->center) && (!trap->center(sd->trap_data, obj)))
3407      return;
3408
3409    ecore_evas_screen_geometry_get(sd->ee, NULL, NULL, &screen_w, &screen_h);
3410    if ((!screen_w) || (!screen_h)) return;
3411
3412    evas_object_geometry_get(obj, NULL, NULL, &win_w, &win_h);
3413    if ((!win_w) || (!win_h)) return;
3414
3415    if (h) nx = win_w >= screen_w ? 0 : (screen_w / 2) - (win_w / 2);
3416    else nx = sd->screen.x;
3417    if (v) ny = win_h >= screen_h ? 0 : (screen_h / 2) - (win_h / 2);
3418    else ny = sd->screen.y;
3419    if (nx < 0) nx = 0;
3420    if (ny < 0) ny = 0;
3421
3422    evas_object_move(obj, nx, ny);
3423 }
3424
3425 EOLIAN static void
3426 _elm_win_borderless_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool borderless)
3427 {
3428    Eina_Bool need_frame = EINA_FALSE;
3429
3430    const char *engine_name = ecore_evas_engine_name_get(sd->ee);
3431    need_frame = engine_name &&
3432                 ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
3433                  (!strcmp(engine_name, ELM_WAYLAND_EGL)));
3434
3435    if (borderless)
3436      {
3437         if (need_frame)
3438           _elm_win_frame_del(sd);
3439      }
3440    else
3441      {
3442         if (need_frame)
3443           _elm_win_frame_add(sd, "default");
3444
3445         if (sd->frame_obj)
3446           evas_object_show(sd->frame_obj);
3447      }
3448
3449    TRAP(sd, borderless_set, borderless);
3450 #ifdef HAVE_ELEMENTARY_X
3451    _elm_win_xwin_update(sd);
3452 #endif
3453 }
3454
3455 EOLIAN static Eina_Bool
3456 _elm_win_borderless_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3457 {
3458    return ecore_evas_borderless_get(sd->ee);
3459 }
3460
3461 EOLIAN static void
3462 _elm_win_shaped_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool shaped)
3463 {
3464    TRAP(sd, shaped_set, shaped);
3465 #ifdef HAVE_ELEMENTARY_X
3466    _elm_win_xwin_update(sd);
3467 #endif
3468 }
3469
3470 EOLIAN static Eina_Bool
3471 _elm_win_shaped_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3472 {
3473    return ecore_evas_shaped_get(sd->ee);
3474 }
3475
3476 EOLIAN static void
3477 _elm_win_alpha_set(Eo *obj, Elm_Win_Data *sd, Eina_Bool enabled)
3478 {
3479    if (sd->img_obj)
3480      {
3481         evas_object_image_alpha_set(sd->img_obj, enabled);
3482         ecore_evas_alpha_set(sd->ee, enabled);
3483      }
3484    else
3485      {
3486 #ifdef HAVE_ELEMENTARY_X
3487         if (sd->x.xwin)
3488           {
3489              if (enabled)
3490                {
3491                   if (!ecore_x_screen_is_composited(0))
3492                     elm_win_shaped_set(obj, enabled);
3493                   else
3494                     TRAP(sd, alpha_set, enabled);
3495                }
3496              else
3497                TRAP(sd, alpha_set, enabled);
3498              _elm_win_xwin_update(sd);
3499           }
3500         else
3501 #endif
3502           TRAP(sd, alpha_set, enabled);
3503      }
3504 }
3505
3506 EOLIAN static Eina_Bool
3507 _elm_win_alpha_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3508 {
3509    if (sd->img_obj)
3510      {
3511         return evas_object_image_alpha_get(sd->img_obj);
3512      }
3513    else
3514      {
3515         return ecore_evas_alpha_get(sd->ee);
3516      }
3517
3518    return EINA_FALSE;
3519 }
3520
3521 EOLIAN static void
3522 _elm_win_override_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool override)
3523 {
3524    TRAP(sd, override_set, override);
3525 #ifdef HAVE_ELEMENTARY_X
3526    _elm_win_xwin_update(sd);
3527 #endif
3528 }
3529
3530 EOLIAN static Eina_Bool
3531 _elm_win_override_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3532 {
3533    return ecore_evas_override_get(sd->ee);
3534 }
3535
3536 EOLIAN static void
3537 _elm_win_fullscreen_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool fullscreen)
3538 {
3539    // YYY: handle if sd->img_obj
3540    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
3541        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE) || 
3542        ENGINE_COMPARE(ELM_DRM))
3543      {
3544         // these engines... can ONLY be fullscreen
3545         return;
3546      }
3547    else
3548      {
3549 //        sd->fullscreen = fullscreen;
3550
3551         Eina_Bool need_frame = EINA_FALSE;
3552
3553         const char *engine_name = ecore_evas_engine_name_get(sd->ee);
3554         need_frame = engine_name &&
3555                      ((!strcmp(engine_name, ELM_WAYLAND_SHM)) ||
3556                       (!strcmp(engine_name, ELM_WAYLAND_EGL)));
3557
3558         TRAP(sd, fullscreen_set, fullscreen);
3559
3560         if (fullscreen)
3561           {
3562              if (need_frame)
3563                _elm_win_frame_del(sd);
3564           }
3565         else
3566           {
3567              if (need_frame)
3568                _elm_win_frame_add(sd, "default");
3569
3570              if (sd->frame_obj)
3571                evas_object_show(sd->frame_obj);
3572           }
3573 #ifdef HAVE_ELEMENTARY_X
3574         _elm_win_xwin_update(sd);
3575 #endif
3576      }
3577 }
3578
3579 EOLIAN static Eina_Bool
3580 _elm_win_fullscreen_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3581 {
3582    const char* engine_name = ecore_evas_engine_name_get(sd->ee);
3583
3584    if (engine_name &&
3585        ((!strcmp(engine_name, ELM_SOFTWARE_FB)) ||
3586         (!strcmp(engine_name, ELM_SOFTWARE_16_WINCE)) || 
3587         (!strcmp(engine_name, ELM_DRM))))
3588      {
3589         // these engines... can ONLY be fullscreen
3590         return EINA_TRUE;
3591      }
3592    else
3593      {
3594         return sd->fullscreen;
3595      }
3596
3597    return EINA_FALSE;
3598 }
3599
3600 static void
3601 _dbus_menu_set(Eina_Bool dbus_connect, void *data)
3602 {
3603    ELM_WIN_DATA_GET_OR_RETURN(data, sd);
3604
3605    if (dbus_connect)
3606      {
3607         DBG("Setting menu to D-Bus");
3608         edje_object_part_unswallow(sd->layout, sd->main_menu);
3609         edje_object_signal_emit(sd->layout, "elm,action,hide_menu", "elm");
3610         _elm_menu_menu_bar_hide(sd->main_menu);
3611      }
3612    else
3613      {
3614         DBG("Setting menu to local mode");
3615         edje_object_part_swallow(sd->layout, "elm.swallow.menu", sd->main_menu);
3616         edje_object_signal_emit(sd->layout, "elm,action,show_menu", "elm");
3617         evas_object_show(sd->main_menu);
3618      }
3619 }
3620
3621 EOLIAN static Evas_Object *
3622 _elm_win_main_menu_get(Eo *obj, Elm_Win_Data *sd)
3623 {
3624    Eina_Bool use_dbus = EINA_FALSE;
3625
3626    if (sd->main_menu) goto end;
3627
3628    sd->main_menu = elm_menu_add(obj);
3629    _elm_menu_menu_bar_set(sd->main_menu, EINA_TRUE);
3630
3631 #ifdef HAVE_ELEMENTARY_X
3632    if (!_elm_config->disable_external_menu && sd->x.xwin) use_dbus = EINA_TRUE;
3633 #endif
3634
3635 #ifdef HAVE_ELEMENTARY_X
3636    if (use_dbus && _elm_dbus_menu_register(sd->main_menu))
3637      {
3638         _elm_dbus_menu_app_menu_register(sd->x.xwin, sd->main_menu,
3639                                          _dbus_menu_set, obj);
3640      }
3641    else
3642 #endif
3643      _dbus_menu_set(EINA_FALSE, obj);
3644
3645 end:
3646    return sd->main_menu;
3647 }
3648
3649 EOLIAN static void
3650 _elm_win_maximized_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool maximized)
3651 {
3652    _elm_win_frame_maximized_state_update(sd, maximized);
3653    // YYY: handle if sd->img_obj
3654    TRAP(sd, maximized_set, maximized);
3655 #ifdef HAVE_ELEMENTARY_X
3656    _elm_win_xwin_update(sd);
3657 #endif
3658 }
3659
3660 EOLIAN static Eina_Bool
3661 _elm_win_maximized_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3662 {
3663    return sd->maximized;
3664 }
3665
3666 EOLIAN static void
3667 _elm_win_iconified_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool iconified)
3668 {
3669 //   sd->iconified = iconified;
3670    TRAP(sd, iconified_set, iconified);
3671 #ifdef HAVE_ELEMENTARY_X
3672    _elm_win_xwin_update(sd);
3673 #endif
3674 }
3675
3676 EOLIAN static Eina_Bool
3677 _elm_win_iconified_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3678 {
3679    return sd->iconified;
3680 }
3681
3682 EOLIAN static void
3683 _elm_win_withdrawn_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool withdrawn)
3684 {
3685 //   sd->withdrawn = withdrawn;
3686    TRAP(sd, withdrawn_set, withdrawn);
3687 #ifdef HAVE_ELEMENTARY_X
3688    _elm_win_xwin_update(sd);
3689 #endif
3690 }
3691
3692 EOLIAN static Eina_Bool
3693 _elm_win_withdrawn_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3694 {
3695    return sd->withdrawn;
3696 }
3697
3698 EOLIAN static void
3699 _elm_win_available_profiles_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char **profiles, unsigned int count)
3700 {
3701    Eina_Bool found = EINA_FALSE;
3702
3703    _elm_win_available_profiles_del(sd);
3704    if ((profiles) && (count >= 1))
3705      {
3706         sd->profile.available_list = calloc(count, sizeof(char *));
3707         if (sd->profile.available_list)
3708           {
3709              if (!sd->profile.name) found = EINA_TRUE;
3710
3711              unsigned int i;
3712              for (i = 0; i < count; i++)
3713                {
3714                   sd->profile.available_list[i] = eina_stringshare_add(profiles[i]);
3715
3716                   /* check to see if a given array has a current profile of elm_win */
3717                   if ((sd->profile.name) &&
3718                       (!strcmp(sd->profile.name, profiles[i])))
3719                     {
3720                        found = EINA_TRUE;
3721                     }
3722                }
3723              sd->profile.count = count;
3724           }
3725      }
3726
3727    if (ecore_evas_window_profile_supported_get(sd->ee))
3728      {
3729         ecore_evas_window_available_profiles_set(sd->ee,
3730                                                  sd->profile.available_list,
3731                                                  sd->profile.count);
3732
3733         /* current profile of elm_win is wrong, change profile */
3734         if ((sd->profile.available_list) && (!found))
3735           {
3736              eina_stringshare_replace(&(sd->profile.name),
3737                                       sd->profile.available_list[0]);
3738              ecore_evas_window_profile_set(sd->ee, sd->profile.name);
3739           }
3740
3741      }
3742    else
3743      {
3744         if (sd->profile.available_list)
3745           _elm_win_profile_update(sd);
3746      }
3747 }
3748
3749 EOLIAN static Eina_Bool
3750 _elm_win_available_profiles_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, char ***profiles, unsigned int *count)
3751 {
3752    if (ecore_evas_window_profile_supported_get(sd->ee))
3753      {
3754         return ecore_evas_window_available_profiles_get(sd->ee,
3755                                                        profiles,
3756                                                        count);
3757      }
3758    else
3759      {
3760         if (profiles) *profiles = (char **)sd->profile.available_list;
3761         if (count) *count = sd->profile.count;
3762         return EINA_TRUE;
3763      }
3764 }
3765
3766 EOLIAN static void
3767 _elm_win_profile_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *profile)
3768 {
3769    /* check to see if a given profile is present in an available profiles */
3770    if ((profile) && (sd->profile.available_list))
3771      {
3772         Eina_Bool found = EINA_FALSE;
3773         unsigned int i;
3774         for (i = 0; i < sd->profile.count; i++)
3775           {
3776              if (!strcmp(profile,
3777                          sd->profile.available_list[i]))
3778                {
3779                   found = EINA_TRUE;
3780                   break;
3781                }
3782           }
3783         if (!found) return;
3784      }
3785
3786    if (ecore_evas_window_profile_supported_get(sd->ee))
3787      {
3788         if (!profile) _elm_win_profile_del(sd);
3789         ecore_evas_window_profile_set(sd->ee, profile);
3790      }
3791    else
3792      {
3793         if (_internal_elm_win_profile_set(sd, profile))
3794           _elm_win_profile_update(sd);
3795      }
3796 }
3797
3798 EOLIAN static const char*
3799 _elm_win_profile_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3800 {
3801    return sd->profile.name;
3802 }
3803
3804 EOLIAN static void
3805 _elm_win_urgent_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool urgent)
3806 {
3807    sd->urgent = urgent;
3808    TRAP(sd, urgent_set, urgent);
3809 #ifdef HAVE_ELEMENTARY_X
3810    _elm_win_xwin_update(sd);
3811 #endif
3812 }
3813
3814 EOLIAN static Eina_Bool
3815 _elm_win_urgent_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3816 {
3817    return sd->urgent;
3818 }
3819
3820 EOLIAN static void
3821 _elm_win_demand_attention_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool demand_attention)
3822 {
3823    sd->demand_attention = demand_attention;
3824    TRAP(sd, demand_attention_set, demand_attention);
3825 #ifdef HAVE_ELEMENTARY_X
3826    _elm_win_xwin_update(sd);
3827 #endif
3828 }
3829
3830 EOLIAN static Eina_Bool
3831 _elm_win_demand_attention_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3832 {
3833    return sd->demand_attention;
3834 }
3835
3836 EOLIAN static void
3837 _elm_win_modal_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool modal)
3838 {
3839    sd->modal = modal;
3840    TRAP(sd, modal_set, modal);
3841 #ifdef HAVE_ELEMENTARY_X
3842    _elm_win_xwin_update(sd);
3843 #endif
3844 }
3845
3846 EOLIAN static Eina_Bool
3847 _elm_win_modal_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3848 {
3849    return sd->modal;
3850 }
3851
3852 EOLIAN static void
3853 _elm_win_aspect_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, double aspect)
3854 {
3855    sd->aspect = aspect;
3856    TRAP(sd, aspect_set, aspect);
3857 #ifdef HAVE_ELEMENTARY_X
3858    _elm_win_xwin_update(sd);
3859 #endif
3860 }
3861
3862 EOLIAN static double
3863 _elm_win_aspect_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3864 {
3865    return sd->aspect;
3866 }
3867
3868 EOLIAN static void
3869 _elm_win_size_base_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int w, int h)
3870 {
3871    sd->size_base_w = w;
3872    sd->size_base_h = h;
3873    TRAP(sd, size_base_set, w, h);
3874 #ifdef HAVE_ELEMENTARY_X
3875    _elm_win_xwin_update(sd);
3876 #endif
3877 }
3878
3879 EOLIAN static void
3880 _elm_win_size_base_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *w, int *h)
3881 {
3882    if (w) *w = sd->size_base_w;
3883    if (w) *h = sd->size_base_h;
3884 }
3885
3886 EOLIAN static void
3887 _elm_win_size_step_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int w, int h)
3888 {
3889    sd->size_step_w = w;
3890    sd->size_step_h = h;
3891    TRAP(sd, size_step_set, w, h);
3892 #ifdef HAVE_ELEMENTARY_X
3893    _elm_win_xwin_update(sd);
3894 #endif
3895 }
3896
3897 EOLIAN static void
3898 _elm_win_size_step_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *w, int *h)
3899 {
3900    if (w) *w = sd->size_step_w;
3901    if (w) *h = sd->size_step_h;
3902 }
3903
3904 EOLIAN static void
3905 _elm_win_layer_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int layer)
3906 {
3907    TRAP(sd, layer_set, layer);
3908 #ifdef HAVE_ELEMENTARY_X
3909    _elm_win_xwin_update(sd);
3910 #endif
3911 }
3912
3913 EOLIAN static int
3914 _elm_win_layer_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
3915 {
3916    return ecore_evas_layer_get(sd->ee);
3917 }
3918
3919 EAPI void
3920 elm_win_norender_push(Evas_Object *obj)
3921 {
3922    ELM_WIN_CHECK(obj);
3923    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
3924
3925    sd->norender++;
3926    if (sd->norender == 1) ecore_evas_manual_render_set(sd->ee, EINA_TRUE);
3927 }
3928
3929 EAPI void
3930 elm_win_norender_pop(Evas_Object *obj)
3931 {
3932    ELM_WIN_CHECK(obj);
3933    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
3934
3935    if (sd->norender <= 0) return;
3936    sd->norender--;
3937    if (sd->norender == 0) ecore_evas_manual_render_set(sd->ee, EINA_FALSE);
3938 }
3939
3940 EAPI int
3941 elm_win_norender_get(Evas_Object *obj)
3942 {
3943    ELM_WIN_CHECK(obj) - 1;
3944    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, -1);
3945    return sd->norender;
3946 }
3947
3948 EAPI void
3949 elm_win_render(Evas_Object *obj)
3950 {
3951    ELM_WIN_CHECK(obj);
3952    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
3953    ecore_evas_manual_render(sd->ee);
3954 }
3955
3956 static int
3957 _win_rotation_degree_check(int rotation)
3958 {
3959    if ((rotation > 360) || (rotation < 0))
3960      {
3961         WRN("Rotation degree should be 0 ~ 360 (passed degree: %d)", rotation);
3962         rotation %= 360;
3963         if (rotation < 0) rotation += 360;
3964      }
3965    return rotation;
3966 }
3967
3968 /*
3969  * This API resizes the internal window(ex: X window) and evas_output.
3970  * But this does not resize the elm window object and its contents.
3971  */
3972 static void
3973 _win_rotate(Evas_Object *obj, Elm_Win_Data *sd, int rotation, Eina_Bool resize)
3974 {
3975    rotation = _win_rotation_degree_check(rotation);
3976    if (sd->rot == rotation) return;
3977    sd->rot = rotation;
3978    if (resize) TRAP(sd, rotation_with_resize_set, rotation);
3979    else TRAP(sd, rotation_set, rotation);
3980    evas_object_size_hint_min_set(obj, -1, -1);
3981    evas_object_size_hint_max_set(obj, -1, -1);
3982    _elm_win_resize_objects_eval(obj);
3983 #ifdef HAVE_ELEMENTARY_X
3984    _elm_win_xwin_update(sd);
3985 #endif
3986    _elm_win_frame_obj_update(sd);
3987    elm_widget_orientation_set(obj, rotation);
3988    evas_object_smart_callback_call(obj, SIG_ROTATION_CHANGED, NULL);
3989 }
3990
3991 EOLIAN static void
3992 _elm_win_rotation_set(Eo *obj, Elm_Win_Data *sd, int rotation)
3993 {
3994    _win_rotate(obj, sd, rotation, EINA_FALSE);
3995 }
3996
3997 /*
3998  * This API does not resize the internal window (ex: X window).
3999  * But this resizes evas_output, elm window, and its contents.
4000  */
4001 EOLIAN static void
4002 _elm_win_rotation_with_resize_set(Eo *obj, Elm_Win_Data *sd, int rotation)
4003 {
4004    _win_rotate(obj, sd, rotation, EINA_TRUE);
4005 }
4006
4007 EOLIAN static int
4008 _elm_win_rotation_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4009 {
4010    return sd->rot;
4011 }
4012
4013 EOLIAN static Eina_Bool
4014 _elm_win_wm_rotation_supported_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4015 {
4016    return sd->wm_rot.wm_supported;
4017 }
4018
4019 /* This will unset a preferred rotation, if given preferred rotation is '-1'.
4020  */
4021 EAPI void
4022 elm_win_wm_rotation_preferred_rotation_set(const Evas_Object *obj,
4023                                            int rotation)
4024 {
4025    ELM_WIN_CHECK(obj);
4026    eo_do((Eo *) obj, elm_obj_win_wm_preferred_rotation_set(rotation));
4027 }
4028
4029 EOLIAN static void
4030 _elm_win_wm_preferred_rotation_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int rotation)
4031 {
4032    int rot;
4033
4034    if (!sd->wm_rot.use)
4035      sd->wm_rot.use = EINA_TRUE;
4036
4037    // '-1' means that elm_win doesn't use preferred rotation.
4038    if (rotation == -1)
4039      rot = -1;
4040    else
4041      rot = _win_rotation_degree_check(rotation);
4042
4043    if (sd->wm_rot.preferred_rot == rot) return;
4044    sd->wm_rot.preferred_rot = rot;
4045
4046    ecore_evas_wm_rotation_preferred_rotation_set(sd->ee, rot);
4047 }
4048
4049 EOLIAN static int
4050 _elm_win_wm_preferred_rotation_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4051 {
4052    return sd->wm_rot.preferred_rot;
4053 }
4054
4055 EOLIAN static void
4056 _elm_win_wm_available_rotations_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const int *rotations, unsigned int count)
4057 {
4058    unsigned int i;
4059    int r;
4060
4061    if (!sd->wm_rot.use)
4062      sd->wm_rot.use = EINA_TRUE;
4063
4064    ELM_SAFE_FREE(sd->wm_rot.rots, free);
4065    sd->wm_rot.count = 0;
4066
4067    if (count > 0)
4068      {
4069         sd->wm_rot.rots = calloc(count, sizeof(int));
4070         if (!sd->wm_rot.rots) return;
4071         for (i = 0; i < count; i++)
4072           {
4073              r = _win_rotation_degree_check(rotations[i]);
4074              sd->wm_rot.rots[i] = r;
4075           }
4076      }
4077
4078    sd->wm_rot.count = count;
4079
4080    ecore_evas_wm_rotation_available_rotations_set(sd->ee,
4081                                                   sd->wm_rot.rots,
4082                                                   sd->wm_rot.count);
4083 }
4084
4085 EOLIAN static Eina_Bool
4086 _elm_win_wm_available_rotations_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int **rotations, unsigned int *count)
4087 {
4088    if (!sd->wm_rot.use) return EINA_FALSE;
4089
4090    if (sd->wm_rot.count > 0)
4091      {
4092         if (rotations)
4093           {
4094              *rotations = calloc(sd->wm_rot.count, sizeof(int));
4095              if (*rotations)
4096                {
4097                   memcpy(*rotations,
4098                          sd->wm_rot.rots,
4099                          sizeof(int) * sd->wm_rot.count);
4100                }
4101           }
4102      }
4103
4104    if (count) *count = sd->wm_rot.count;
4105    return EINA_TRUE;
4106 }
4107
4108 EOLIAN static void
4109 _elm_win_wm_manual_rotation_done_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool set)
4110 {
4111    if (!sd->wm_rot.use) return;
4112    ecore_evas_wm_rotation_manual_rotation_done_set(sd->ee, set);
4113 }
4114
4115 EOLIAN static Eina_Bool
4116 _elm_win_wm_manual_rotation_done_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4117 {
4118    if (!sd->wm_rot.use) return EINA_FALSE;
4119    return ecore_evas_wm_rotation_manual_rotation_done_get(sd->ee);
4120 }
4121
4122 EOLIAN static void
4123 _elm_win_wm_manual_rotation_done(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4124 {
4125    if (!sd->wm_rot.use) return;
4126    ecore_evas_wm_rotation_manual_rotation_done(sd->ee);
4127 }
4128
4129 EOLIAN static void
4130 _elm_win_sticky_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool sticky)
4131 {
4132 //   sd->sticky = sticky;
4133    TRAP(sd, sticky_set, sticky);
4134 #ifdef HAVE_ELEMENTARY_X
4135    _elm_win_xwin_update(sd);
4136 #endif
4137 }
4138
4139 EOLIAN static Eina_Bool
4140 _elm_win_sticky_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4141 {
4142    return sd->sticky;
4143 }
4144
4145 EOLIAN static void
4146 _elm_win_keyboard_mode_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Win_Keyboard_Mode mode)
4147 {
4148    if (mode == sd->kbdmode) return;
4149 #ifdef HAVE_ELEMENTARY_X
4150    _internal_elm_win_xwindow_get(sd);
4151 #endif
4152    sd->kbdmode = mode;
4153 #ifdef HAVE_ELEMENTARY_X
4154    if (sd->x.xwin)
4155      ecore_x_e_virtual_keyboard_state_set
4156        (sd->x.xwin, (Ecore_X_Virtual_Keyboard_State)sd->kbdmode);
4157 #endif
4158 }
4159
4160 EOLIAN static Elm_Win_Keyboard_Mode
4161 _elm_win_keyboard_mode_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4162 {
4163    return sd->kbdmode;
4164 }
4165
4166 EOLIAN static void
4167 _elm_win_keyboard_win_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool is_keyboard)
4168 {
4169 #ifdef HAVE_ELEMENTARY_X
4170    _internal_elm_win_xwindow_get(sd);
4171    if (sd->x.xwin)
4172      ecore_x_e_virtual_keyboard_set(sd->x.xwin, is_keyboard);
4173 #else
4174    (void)is_keyboard;
4175 #endif
4176 }
4177
4178 EOLIAN static Eina_Bool
4179 _elm_win_keyboard_win_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4180 {
4181 #ifdef HAVE_ELEMENTARY_X
4182    _internal_elm_win_xwindow_get(sd);
4183    if (sd->x.xwin) return ecore_x_e_virtual_keyboard_get(sd->x.xwin);
4184 #endif
4185    return EINA_FALSE;
4186 }
4187
4188 EOLIAN static void
4189 _elm_win_indicator_mode_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Win_Indicator_Mode mode)
4190 {
4191    if (mode == sd->indmode) return;
4192 #ifdef HAVE_ELEMENTARY_X
4193    _internal_elm_win_xwindow_get(sd);
4194 #endif
4195    sd->indmode = mode;
4196 #ifdef HAVE_ELEMENTARY_X
4197    if (sd->x.xwin)
4198      {
4199         if (sd->indmode == ELM_WIN_INDICATOR_SHOW)
4200           ecore_x_e_illume_indicator_state_set
4201             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON);
4202         else if (sd->indmode == ELM_WIN_INDICATOR_HIDE)
4203           ecore_x_e_illume_indicator_state_set
4204             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
4205      }
4206 #endif
4207    evas_object_smart_callback_call(obj, SIG_INDICATOR_PROP_CHANGED, NULL);
4208 }
4209
4210 EOLIAN static Elm_Win_Indicator_Mode
4211 _elm_win_indicator_mode_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4212 {
4213    return sd->indmode;
4214 }
4215
4216 EOLIAN static void
4217 _elm_win_indicator_opacity_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Win_Indicator_Opacity_Mode mode)
4218 {
4219    if (mode == sd->ind_o_mode) return;
4220    sd->ind_o_mode = mode;
4221 #ifdef HAVE_ELEMENTARY_X
4222    _internal_elm_win_xwindow_get(sd);
4223    if (sd->x.xwin)
4224      {
4225         if (sd->ind_o_mode == ELM_WIN_INDICATOR_OPAQUE)
4226           ecore_x_e_illume_indicator_opacity_set
4227             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_OPAQUE);
4228         else if (sd->ind_o_mode == ELM_WIN_INDICATOR_TRANSLUCENT)
4229           ecore_x_e_illume_indicator_opacity_set
4230             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT);
4231         else if (sd->ind_o_mode == ELM_WIN_INDICATOR_TRANSPARENT)
4232           ecore_x_e_illume_indicator_opacity_set
4233             (sd->x.xwin, ECORE_X_ILLUME_INDICATOR_TRANSPARENT);
4234      }
4235 #endif
4236    evas_object_smart_callback_call(obj, SIG_INDICATOR_PROP_CHANGED, NULL);
4237 }
4238
4239 EOLIAN static Elm_Win_Indicator_Opacity_Mode
4240 _elm_win_indicator_opacity_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4241 {
4242    return sd->ind_o_mode;
4243 }
4244
4245 EOLIAN static void
4246 _elm_win_screen_position_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *x, int *y)
4247 {
4248    if (x) *x = sd->screen.x;
4249    if (y) *y = sd->screen.y;
4250 }
4251
4252 EOLIAN static Eina_Bool
4253 _elm_win_focus_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4254 {
4255    return ecore_evas_focus_get(sd->ee);
4256 }
4257
4258 EOLIAN static void
4259 _elm_win_screen_constrain_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool constrain)
4260 {
4261    sd->constrain = !!constrain;
4262 }
4263
4264 EOLIAN static Eina_Bool
4265 _elm_win_screen_constrain_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4266 {
4267    return sd->constrain;
4268 }
4269
4270 EOLIAN static void
4271 _elm_win_screen_size_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *x, int *y, int *w, int *h)
4272 {
4273    ecore_evas_screen_geometry_get(sd->ee, x, y, w, h);
4274 }
4275
4276 EOLIAN static void
4277 _elm_win_screen_dpi_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int *xdpi, int *ydpi)
4278 {
4279    ecore_evas_screen_dpi_get(sd->ee, xdpi, ydpi);
4280 }
4281
4282 EOLIAN static void
4283 _elm_win_conformant_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool conformant)
4284 {
4285 #ifdef HAVE_ELEMENTARY_X
4286    _internal_elm_win_xwindow_get(sd);
4287    if (sd->x.xwin)
4288      ecore_x_e_illume_conformant_set(sd->x.xwin, conformant);
4289 #else
4290    (void)conformant;
4291 #endif
4292 }
4293
4294 EOLIAN static Eina_Bool
4295 _elm_win_conformant_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4296 {
4297 #ifdef HAVE_ELEMENTARY_X
4298    _internal_elm_win_xwindow_get(sd);
4299    if (sd->x.xwin)
4300      return ecore_x_e_illume_conformant_get(sd->x.xwin);
4301 #endif
4302
4303    return EINA_FALSE;
4304 }
4305
4306 EOLIAN static void
4307 _elm_win_quickpanel_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool quickpanel)
4308 {
4309 #ifdef HAVE_ELEMENTARY_X
4310    _internal_elm_win_xwindow_get(sd);
4311    if (sd->x.xwin)
4312      {
4313         ecore_x_e_illume_quickpanel_set(sd->x.xwin, quickpanel);
4314         if (quickpanel)
4315           {
4316              Ecore_X_Window_State states[2];
4317
4318              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
4319              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
4320              ecore_x_netwm_window_state_set(sd->x.xwin, states, 2);
4321              ecore_x_icccm_hints_set(sd->x.xwin, 0, 0, 0, 0, 0, 0, 0);
4322           }
4323      }
4324 #else
4325    (void)quickpanel;
4326 #endif
4327 }
4328
4329 EOLIAN static Eina_Bool
4330 _elm_win_quickpanel_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4331 {
4332 #ifdef HAVE_ELEMENTARY_X
4333    _internal_elm_win_xwindow_get(sd);
4334    if (sd->x.xwin)
4335      return ecore_x_e_illume_quickpanel_get(sd->x.xwin);
4336 #endif
4337
4338    return EINA_FALSE;
4339 }
4340
4341 EOLIAN static void
4342 _elm_win_quickpanel_priority_major_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int priority)
4343 {
4344 #ifdef HAVE_ELEMENTARY_X
4345    _internal_elm_win_xwindow_get(sd);
4346    if (sd->x.xwin)
4347      ecore_x_e_illume_quickpanel_priority_major_set(sd->x.xwin, priority);
4348 #else
4349    (void)priority;
4350 #endif
4351 }
4352
4353 EOLIAN static int
4354 _elm_win_quickpanel_priority_major_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4355 {
4356 #ifdef HAVE_ELEMENTARY_X
4357    _internal_elm_win_xwindow_get(sd);
4358    if (sd->x.xwin)
4359      return ecore_x_e_illume_quickpanel_priority_major_get(sd->x.xwin);
4360 #endif
4361
4362    return -1;
4363 }
4364
4365 EOLIAN static void
4366 _elm_win_quickpanel_priority_minor_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int priority)
4367 {
4368 #ifdef HAVE_ELEMENTARY_X
4369    _internal_elm_win_xwindow_get(sd);
4370    if (sd->x.xwin)
4371      ecore_x_e_illume_quickpanel_priority_minor_set(sd->x.xwin, priority);
4372 #else
4373    (void)priority;
4374 #endif
4375 }
4376
4377 EOLIAN static int
4378 _elm_win_quickpanel_priority_minor_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4379 {
4380 #ifdef HAVE_ELEMENTARY_X
4381    _internal_elm_win_xwindow_get(sd);
4382    if (sd->x.xwin)
4383      return ecore_x_e_illume_quickpanel_priority_minor_get(sd->x.xwin);
4384 #endif
4385
4386    return -1;
4387 }
4388
4389 EOLIAN static void
4390 _elm_win_quickpanel_zone_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, int zone)
4391 {
4392 #ifdef HAVE_ELEMENTARY_X
4393    _internal_elm_win_xwindow_get(sd);
4394    if (sd->x.xwin)
4395      ecore_x_e_illume_quickpanel_zone_set(sd->x.xwin, zone);
4396 #else
4397    (void)zone;
4398 #endif
4399 }
4400
4401 EOLIAN static int
4402 _elm_win_quickpanel_zone_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4403 {
4404 #ifdef HAVE_ELEMENTARY_X
4405    _internal_elm_win_xwindow_get(sd);
4406    if (sd->x.xwin)
4407      return ecore_x_e_illume_quickpanel_zone_get(sd->x.xwin);
4408 #endif
4409
4410    return 0;
4411 }
4412
4413 EOLIAN static void
4414 _elm_win_prop_focus_skip_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool skip)
4415 {
4416    sd->skip_focus = skip;
4417    TRAP(sd, focus_skip_set, skip);
4418 }
4419
4420 EOLIAN static void
4421 _elm_win_illume_command_send(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Illume_Command command, void *params)
4422 {
4423    (void) params;
4424
4425 #ifdef HAVE_ELEMENTARY_X
4426    _internal_elm_win_xwindow_get(sd);
4427    if (sd->x.xwin)
4428      {
4429         switch (command)
4430           {
4431            case ELM_ILLUME_COMMAND_FOCUS_BACK:
4432              ecore_x_e_illume_focus_back_send(sd->x.xwin);
4433              break;
4434
4435            case ELM_ILLUME_COMMAND_FOCUS_FORWARD:
4436              ecore_x_e_illume_focus_forward_send(sd->x.xwin);
4437              break;
4438
4439            case ELM_ILLUME_COMMAND_FOCUS_HOME:
4440              ecore_x_e_illume_focus_home_send(sd->x.xwin);
4441              break;
4442
4443            case ELM_ILLUME_COMMAND_CLOSE:
4444              ecore_x_e_illume_close_send(sd->x.xwin);
4445              break;
4446
4447            default:
4448              break;
4449           }
4450      }
4451 #else
4452    (void)command;
4453 #endif
4454 }
4455
4456 EOLIAN static Evas_Object*
4457 _elm_win_inlined_image_object_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4458 {
4459    return sd->img_obj;
4460 }
4461
4462 EOLIAN static void
4463 _elm_win_focus_highlight_enabled_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool enabled)
4464 {
4465    enabled = !!enabled;
4466    if (sd->focus_highlight.enabled == enabled)
4467      return;
4468
4469    sd->focus_highlight.enabled = enabled;
4470
4471    if (sd->focus_highlight.enabled)
4472      _elm_win_focus_highlight_init(sd);
4473    else
4474      _elm_win_focus_highlight_shutdown(sd);
4475 }
4476
4477 EOLIAN static Eina_Bool
4478 _elm_win_focus_highlight_enabled_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4479 {
4480    return sd->focus_highlight.enabled;
4481 }
4482
4483 EOLIAN static Eina_Bool
4484 _elm_win_elm_widget_theme_apply(Eo *obj, Elm_Win_Data *sd)
4485 {
4486    Eina_Bool int_ret = EINA_FALSE;
4487    eo_do_super(obj, MY_CLASS, elm_obj_widget_theme_apply(&int_ret));
4488    if (!int_ret) return EINA_TRUE;
4489
4490    sd->focus_highlight.theme_changed = EINA_TRUE;
4491    _elm_win_focus_highlight_reconfigure_job_start(sd);
4492
4493    return EINA_TRUE;
4494 }
4495
4496 EOLIAN static void
4497 _elm_win_focus_highlight_style_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *style)
4498 {
4499    eina_stringshare_replace(&sd->focus_highlight.style, style);
4500    sd->focus_highlight.theme_changed = EINA_TRUE;
4501    _elm_win_focus_highlight_reconfigure_job_start(sd);
4502 }
4503
4504 EOLIAN static const char*
4505 _elm_win_focus_highlight_style_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4506 {
4507    return sd->focus_highlight.style;
4508 }
4509
4510 EOLIAN static void
4511 _elm_win_focus_highlight_animate_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool animate)
4512 {
4513    animate = !!animate;
4514    if (sd->focus_highlight.animate == animate)
4515      return;
4516
4517    sd->focus_highlight.animate = animate;
4518    sd->focus_highlight.theme_changed = EINA_TRUE;
4519    _elm_win_focus_highlight_reconfigure_job_start(sd);
4520 }
4521
4522 EOLIAN static Eina_Bool
4523 _elm_win_focus_highlight_animate_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4524 {
4525    return sd->focus_highlight.animate;
4526 }
4527
4528 EOLIAN static Eina_Bool
4529 _elm_win_socket_listen(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *svcname, int svcnum, Eina_Bool svcsys)
4530 {
4531    if (!sd->ee) return EINA_FALSE;
4532
4533    if (!ecore_evas_extn_socket_listen(sd->ee, svcname, svcnum, svcsys))
4534      return EINA_FALSE;
4535
4536    return EINA_TRUE;
4537 }
4538
4539 /* windowing specific calls - shall we do this differently? */
4540
4541 EOLIAN static Ecore_X_Window
4542 _elm_win_xwindow_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4543 {
4544 #ifdef HAVE_ELEMENTARY_X
4545    if (sd->x.xwin) return sd->x.xwin;
4546    if (sd->parent) return elm_win_xwindow_get(sd->parent);
4547 #endif
4548    return 0;
4549 }
4550
4551 EAPI Ecore_Wl_Window *
4552 elm_win_wl_window_get(const Evas_Object *obj)
4553 {
4554    if (!obj) return NULL;
4555
4556    if ((!ENGINE_COMPARE(ELM_WAYLAND_SHM)) &&
4557        (!ENGINE_COMPARE(ELM_WAYLAND_EGL)))
4558      return NULL;
4559
4560    if (!evas_object_smart_type_check_ptr(obj, MY_CLASS_NAME_LEGACY))
4561      {
4562         Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
4563         return _elm_ee_wlwin_get(ee);
4564      }
4565
4566    ELM_WIN_CHECK(obj) NULL;
4567    Ecore_Wl_Window *ret = NULL;
4568    eo_do((Eo *) obj, elm_obj_win_wl_window_get(&ret));
4569    return ret;
4570 }
4571
4572 EOLIAN static Ecore_Wl_Window*
4573 _elm_win_wl_window_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4574 {
4575 #if HAVE_ELEMENTARY_WAYLAND
4576    if (sd->wl.win) return sd->wl.win;
4577    if (sd->parent) return elm_win_wl_window_get(sd->parent);
4578 #else
4579    (void)sd;
4580 #endif
4581    return NULL;
4582 }
4583
4584 EAPI Eina_Bool
4585 elm_win_trap_set(const Elm_Win_Trap *t)
4586 {
4587    DBG("old %p, new %p", trap, t);
4588
4589    if ((t) && (t->version != ELM_WIN_TRAP_VERSION))
4590      {
4591         CRI("trying to set a trap version %lu while %lu was expected!",
4592                  t->version, ELM_WIN_TRAP_VERSION);
4593         return EINA_FALSE;
4594      }
4595
4596    trap = t;
4597    return EINA_TRUE;
4598 }
4599
4600 EAPI void
4601 elm_win_floating_mode_set(Evas_Object *obj, Eina_Bool floating)
4602 {
4603    ELM_WIN_CHECK(obj);
4604    ELM_WIN_DATA_GET_OR_RETURN(obj, sd);
4605
4606    floating = !!floating;
4607    if (floating == sd->floating) return;
4608    sd->floating = floating;
4609 #ifdef HAVE_ELEMENTARY_X
4610    _internal_elm_win_xwindow_get(sd);
4611    if (sd->x.xwin)
4612      {
4613         if (sd->floating)
4614           ecore_x_e_illume_window_state_set
4615              (sd->x.xwin, ECORE_X_ILLUME_WINDOW_STATE_FLOATING);
4616         else
4617           ecore_x_e_illume_window_state_set
4618              (sd->x.xwin, ECORE_X_ILLUME_WINDOW_STATE_NORMAL);
4619      }
4620 #endif
4621 }
4622
4623 EAPI Eina_Bool
4624 elm_win_floating_mode_get(const Evas_Object *obj)
4625 {
4626    ELM_WIN_CHECK(obj) EINA_FALSE;
4627    ELM_WIN_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
4628
4629    return sd->floating;
4630 }
4631
4632 EOLIAN static Ecore_Window
4633 _elm_win_window_id_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
4634 {
4635    if ((ENGINE_COMPARE(ELM_WAYLAND_SHM)) || (ENGINE_COMPARE(ELM_WAYLAND_EGL)))
4636      {
4637 #if HAVE_ELEMENTARY_WAYLAND
4638         if (sd->wl.win) return (Ecore_Window)ecore_wl_window_surface_id_get(sd->wl.win);
4639         if (sd->parent)
4640           {
4641              Ecore_Wl_Window *parent;
4642
4643              parent = elm_win_wl_window_get(sd->parent);
4644              if (parent) return (Ecore_Window)ecore_wl_window_surface_id_get(parent);
4645              return 0;
4646           }
4647 #endif
4648      }
4649    else
4650      {
4651 #ifdef HAVE_ELEMENTARY_X
4652         _internal_elm_win_xwindow_get(sd);
4653         if (sd->x.xwin) return (Ecore_Window)sd->x.xwin;
4654         if (sd->parent) return (Ecore_Window)elm_win_xwindow_get(sd->parent);
4655 #endif
4656      }
4657
4658    return 0;
4659 }
4660
4661 void
4662 _elm_win_focus_highlight_start(Evas_Object *obj)
4663 {
4664    ELM_WIN_DATA_GET(obj, sd);
4665
4666    if (!elm_win_focus_highlight_enabled_get(obj)) return;
4667    sd->focus_highlight.cur.visible = EINA_TRUE;
4668    sd->focus_highlight.geometry_changed = EINA_TRUE;
4669    _elm_win_focus_highlight_reconfigure_job(obj);
4670 }
4671
4672 EAPI Ecore_Window
4673 elm_win_window_id_get(const Evas_Object *obj)
4674 {
4675    if (!obj) return 0;
4676
4677    if (!evas_object_smart_type_check_ptr(obj, MY_CLASS_NAME_LEGACY))
4678      {
4679         Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
4680         return ecore_evas_window_get(ee);
4681      }
4682
4683    ELM_WIN_CHECK(obj) 0;
4684    Ecore_Window ret = 0;
4685    eo_do((Eo *) obj, elm_obj_win_window_id_get(&ret));
4686    return ret;
4687 }
4688
4689 EOLIAN static void
4690 _elm_win_class_constructor(Eo_Class *klass)
4691 {
4692    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
4693 }
4694
4695 #include "elm_win.eo.c"