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