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