we really should focus when we release mouse AND on_hold is... NOT
[framework/uifw/elementary.git] / src / lib / elm_win.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 typedef struct _Elm_Win Elm_Win;
5
6 struct _Elm_Win
7 {
8    Ecore_Evas *ee;
9    Evas *evas;
10    Evas_Object *parent, *win_obj, *img_obj, *frame_obj;
11    Eina_List *subobjs;
12 #ifdef HAVE_ELEMENTARY_X
13    Ecore_X_Window xwin;
14    Ecore_Event_Handler *client_message_handler;
15 #endif
16    Ecore_Job *deferred_resize_job;
17    Ecore_Job *deferred_child_eval_job;
18
19    Elm_Win_Type type;
20    Elm_Win_Keyboard_Mode kbdmode;
21    struct {
22       const char *info;
23       Ecore_Timer *timer;
24       int repeat_count;
25       int shot_counter;
26    } shot;
27    Eina_Bool autodel : 1;
28    int *autodel_clear, rot;
29    struct {
30       int x, y;
31    } screen;
32
33    struct {
34       Evas_Object *top;
35
36       struct {
37          Evas_Object *target;
38          Eina_Bool visible : 1;
39          Eina_Bool handled : 1;
40       } cur, prev;
41
42       const char *style;
43       Ecore_Job *reconf_job;
44
45       Eina_Bool enabled : 1;
46       Eina_Bool changed_theme : 1;
47       Eina_Bool top_animate : 1;
48       Eina_Bool geometry_changed : 1;
49    } focus_highlight;
50 };
51
52 static const char *widtype = NULL;
53 static void _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
54 static void _elm_win_obj_callback_img_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
55 static void _elm_win_obj_callback_parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
56 static void _elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y);
57 static void _elm_win_obj_intercept_show(void *data, Evas_Object *obj);
58 static void _elm_win_move(Ecore_Evas *ee);
59 static void _elm_win_resize(Ecore_Evas *ee);
60 static void _elm_win_delete_request(Ecore_Evas *ee);
61 static void _elm_win_resize_job(void *data);
62 #ifdef HAVE_ELEMENTARY_X
63 static void _elm_win_xwin_update(Elm_Win *win);
64 #endif
65 static void _elm_win_eval_subobjs(Evas_Object *obj);
66 static void _elm_win_subobj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
67 static void _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
68 static void _elm_win_focus_highlight_init(Elm_Win *win);
69 static void _elm_win_focus_highlight_shutdown(Elm_Win *win);
70 static void _elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible);
71 static void _elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win);
72 static void _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win);
73 static void _elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission, const char *source);
74 static void _elm_win_focus_highlight_reconfigure(Elm_Win *win);
75
76 static const char SIG_DELETE_REQUEST[] = "delete,request";
77 static const char SIG_FOCUS_OUT[] = "focus,out";
78 static const char SIG_FOCUS_IN[] = "focus,in";
79 static const char SIG_MOVED[] = "moved";
80
81 static const Evas_Smart_Cb_Description _signals[] = {
82    {SIG_DELETE_REQUEST, ""},
83    {SIG_FOCUS_OUT, ""},
84    {SIG_FOCUS_IN, ""},
85    {SIG_MOVED, ""},
86    {NULL, NULL}
87 };
88
89
90
91 Eina_List *_elm_win_list = NULL;
92 int _elm_win_deferred_free = 0;
93
94 // exmaple shot spec (wait 0.1 sec then save as my-window.png):
95 // ELM_ENGINE="shot:delay=0.1:file=my-window.png"
96
97 static double
98 _shot_delay_get(Elm_Win *win)
99 {
100    char *p, *pd;
101    char *d = strdup(win->shot.info);
102
103    if (!d) return 0.5;
104    for (p = (char *)win->shot.info; *p; p++)
105      {
106         if (!strncmp(p, "delay=", 6))
107           {
108              double v;
109
110              for (pd = d, p += 6; (*p) && (*p != ':'); p++, pd++)
111                {
112                   *pd = *p;
113                }
114              *pd = 0;
115              v = atof(d);
116              free(d);
117              return v;
118           }
119      }
120    free(d);
121    return 0.5;
122 }
123
124 static char *
125 _shot_file_get(Elm_Win *win)
126 {
127    char *p;
128    char *tmp = strdup(win->shot.info);
129    char *repname = NULL;
130
131    if (!tmp) return NULL;
132
133    for (p = (char *)win->shot.info; *p; p++)
134      {
135         if (!strncmp(p, "file=", 5))
136           {
137              strcpy(tmp, p + 5);
138              if (!win->shot.repeat_count) return tmp;
139              else
140                {
141                   char *dotptr = strrchr(tmp, '.');
142                   if (dotptr)
143                     {
144                        repname = malloc(sizeof(char)*(strlen(tmp) + 16));
145                        strncpy(repname, tmp, dotptr - tmp);
146                        sprintf(repname + (dotptr - tmp), "%03i",
147                                win->shot.shot_counter + 1);
148                        strcat(repname, dotptr);
149                        return repname;
150                     }
151                }
152           }
153      }
154    free(tmp);
155    if (!win->shot.repeat_count) return strdup("out.png");
156    else
157      {
158         repname = malloc(sizeof(char) * 24);
159         sprintf(repname, "out%03i.png", win->shot.shot_counter + 1);
160         return repname;
161      }
162 }
163
164 static int
165 _shot_repeat_count_get(Elm_Win *win)
166 {
167
168    char *p, *pd;
169    char *d = strdup(win->shot.info);
170
171    if (!d) return 0;
172    for (p = (char *)win->shot.info; *p; p++)
173      {
174         if (!strncmp(p, "repeat=", 7))
175           {
176              int v;
177
178              for (pd = d, p += 7; (*p) && (*p != ':'); p++, pd++)
179                {
180                   *pd = *p;
181                }
182              *pd = 0;
183              v = atoi(d);
184              if (v < 0) v = 0;
185              if (v > 1000) v = 999;
186              free(d);
187              return v;
188           }
189      }
190    free(d);
191    return 0;
192 }
193
194 static char *
195 _shot_key_get(Elm_Win *win __UNUSED__)
196 {
197    return NULL;
198 }
199
200 static char *
201 _shot_flags_get(Elm_Win *win __UNUSED__)
202 {
203    return NULL;
204 }
205
206 static void
207 _shot_do(Elm_Win *win)
208 {
209    Ecore_Evas *ee;
210    Evas_Object *o;
211    unsigned int *pixels;
212    int w, h;
213    char *file, *key, *flags;
214
215    ecore_evas_manual_render(win->ee);
216    pixels = (void *)ecore_evas_buffer_pixels_get(win->ee);
217    if (!pixels) return;
218    ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
219    if ((w < 1) || (h < 1)) return;
220    file = _shot_file_get(win);
221    if (!file) return;
222    key = _shot_key_get(win);
223    flags = _shot_flags_get(win);
224    ee = ecore_evas_buffer_new(1, 1);
225    o = evas_object_image_add(ecore_evas_get(ee));
226    evas_object_image_alpha_set(o, ecore_evas_alpha_get(win->ee));
227    evas_object_image_size_set(o, w, h);
228    evas_object_image_data_set(o, pixels);
229    if (!evas_object_image_save(o, file, key, flags))
230      {
231         ERR("Cannot save window to '%s' (key '%s', flags '%s')",
232             file, key, flags);
233      }
234    free(file);
235    if (key) free(key);
236    if (flags) free(flags);
237    ecore_evas_free(ee);
238    if (win->shot.repeat_count) win->shot.shot_counter++;
239 }
240
241 static Eina_Bool
242 _shot_delay(void *data)
243 {
244    Elm_Win *win = data;
245    _shot_do(win);
246    if (win->shot.repeat_count)
247      {
248         int remainshot = (win->shot.repeat_count - win->shot.shot_counter);
249         if (remainshot > 0) return EINA_TRUE;
250      }
251    win->shot.timer = NULL;
252    elm_exit();
253    return EINA_FALSE;
254 }
255
256 static void
257 _shot_init(Elm_Win *win)
258 {
259    if (!win->shot.info) return;
260    win->shot.repeat_count = _shot_repeat_count_get(win);
261    win->shot.shot_counter = 0;
262 }
263
264 static void
265 _shot_handle(Elm_Win *win)
266 {
267    if (!win->shot.info) return;
268    win->shot.timer = ecore_timer_add(_shot_delay_get(win), _shot_delay, win);
269 }
270
271 static void
272 _elm_win_move(Ecore_Evas *ee)
273 {
274    Evas_Object *obj = ecore_evas_object_associate_get(ee);
275    Elm_Win *win;
276    int x, y;
277
278    if (!obj) return;
279    win = elm_widget_data_get(obj);
280    if (!win) return;
281    ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
282    win->screen.x = x;
283    win->screen.y = y;
284    evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
285 }
286
287 static void
288 _elm_win_resize(Ecore_Evas *ee)
289 {
290    Evas_Object *obj = ecore_evas_object_associate_get(ee);
291    Elm_Win *win;
292
293    if (!obj) return;
294    win = elm_widget_data_get(obj);
295    if (!win) return;
296    if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job);
297    win->deferred_resize_job = ecore_job_add(_elm_win_resize_job, win);
298 }
299
300 static void
301 _elm_win_focus_in(Ecore_Evas *ee)
302 {
303    Evas_Object *obj = ecore_evas_object_associate_get(ee);
304    Elm_Win *win;
305
306    if (!obj) return;
307    win = elm_widget_data_get(obj);
308    if (!win) return;
309    evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_IN, NULL);
310    win->focus_highlight.cur.visible = EINA_TRUE;
311    _elm_win_focus_highlight_reconfigure_job_start(win);
312    if (win->frame_obj)
313      {
314      }
315    else if (win->img_obj)
316      {
317         /* do nothing */
318      }
319 }
320
321 static void
322 _elm_win_focus_out(Ecore_Evas *ee)
323 {
324    Evas_Object *obj = ecore_evas_object_associate_get(ee);
325    Elm_Win *win;
326
327    if (!obj) return;
328    win = elm_widget_data_get(obj);
329    if (!win) return;
330    evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_OUT, NULL);
331    win->focus_highlight.cur.visible = EINA_FALSE;
332    _elm_win_focus_highlight_reconfigure_job_start(win);
333    if (win->frame_obj)
334      {
335      }
336    else if (win->img_obj)
337      {
338         /* do nothing */
339      }
340 }
341
342 static Eina_Bool
343 _elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
344 {
345    Elm_Win *wd = elm_widget_data_get(obj);
346    const Eina_List *items;
347    void *(*list_data_get) (const Eina_List *list);
348
349    if (!wd)
350      return EINA_FALSE;
351
352    /* Focus chain */
353    if (wd->subobjs)
354      {
355         if (!(items = elm_widget_focus_custom_chain_get(obj)))
356           {
357              items = wd->subobjs;
358              if (!items)
359                return EINA_FALSE;
360           }
361         list_data_get = eina_list_data_get;
362
363         elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
364
365         if (*next)
366           return EINA_TRUE;
367      }
368
369    *next = (Evas_Object *)obj;
370    return EINA_FALSE;
371 }
372
373 static void
374 _elm_win_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
375 {
376    Elm_Win *win = elm_widget_data_get(obj);
377    if (!win) return;
378
379    if (win->img_obj)
380       evas_object_focus_set(win->img_obj, elm_widget_focus_get(obj));
381    else
382       evas_object_focus_set(obj, elm_widget_focus_get(obj));
383 }
384
385 static Eina_Bool
386 _elm_win_event_cb(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
387 {
388    if (type == EVAS_CALLBACK_KEY_DOWN)
389      {
390         Evas_Event_Key_Down *ev = event_info;
391         if (!strcmp(ev->keyname, "Tab"))
392           {
393              if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
394                elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS);
395              else
396                elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
397              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
398              return EINA_TRUE;
399           }
400         else if ((!strcmp(ev->keyname, "Left")) ||
401                  (!strcmp(ev->keyname, "KP_Left")))
402           {
403              //TODO : woohyun jung
404           }
405         else if ((!strcmp(ev->keyname, "Right")) ||
406                  (!strcmp(ev->keyname, "KP_Right")))
407           {
408              //TODO : woohyun jung
409           }
410         else if ((!strcmp(ev->keyname, "Up")) ||
411                  (!strcmp(ev->keyname, "KP_Up")))
412           {
413              //TODO : woohyun jung
414           }
415         else if ((!strcmp(ev->keyname, "Down")) ||
416                  (!strcmp(ev->keyname, "KP_Down")))
417           {
418              //TODO : woohyun jung
419           }
420      }
421
422    return EINA_FALSE;
423 }
424
425 static void
426 _deferred_ecore_evas_free(void *data)
427 {
428    ecore_evas_free(data);
429    _elm_win_deferred_free--;
430 }
431
432 static void
433 _elm_win_obj_callback_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
434 {
435    Elm_Win *win = data;
436
437    elm_object_focus_set(obj, EINA_TRUE);
438    if (win->shot.info) _shot_handle(win);
439 }
440
441 static void
442 _elm_win_obj_callback_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
443 {
444    Elm_Win *win = data;
445
446    if (win->frame_obj)
447      {
448      }
449    else if (win->img_obj)
450      {
451         evas_object_hide(win->img_obj);
452      }
453 }
454
455 static void
456 _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info __UNUSED__)
457 {
458    Elm_Win *win = data;
459    Evas_Object *child;
460
461    if (win->parent)
462      {
463         evas_object_event_callback_del_full(win->parent, EVAS_CALLBACK_DEL,
464                                             _elm_win_obj_callback_parent_del, win);
465         win->parent = NULL;
466      }
467    if (win->autodel_clear) *(win->autodel_clear) = -1;
468    _elm_win_list = eina_list_remove(_elm_win_list, win->win_obj);
469    while (win->subobjs) elm_win_resize_object_del(obj, win->subobjs->data);
470    if (win->ee)
471      {
472         ecore_evas_callback_delete_request_set(win->ee, NULL);
473         ecore_evas_callback_resize_set(win->ee, NULL);
474      }
475    if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job);
476    if (win->deferred_child_eval_job) ecore_job_del(win->deferred_child_eval_job);
477    if (win->shot.info) eina_stringshare_del(win->shot.info);
478    if (win->shot.timer) ecore_timer_del(win->shot.timer);
479    while (((child = evas_object_bottom_get(win->evas))) &&
480           (child != obj))
481      {
482         evas_object_del(child);
483      }
484    while (((child = evas_object_top_get(win->evas))) &&
485           (child != obj))
486      {
487         evas_object_del(child);
488      }
489 #ifdef HAVE_ELEMENTARY_X
490    if (win->client_message_handler)
491      ecore_event_handler_del(win->client_message_handler);
492 #endif
493    // FIXME: Why are we flushing edje on every window destroy ??
494    //   edje_file_cache_flush();
495    //   edje_collection_cache_flush();
496    //   evas_image_cache_flush(win->evas);
497    //   evas_font_cache_flush(win->evas);
498    // FIXME: we are in the del handler for the object and delete the canvas
499    // that lives under it from the handler... nasty. deferring doesn't help either
500
501    if (win->img_obj)
502      {
503         win->img_obj = NULL;
504      }
505    else
506      {
507         if (win->ee)
508           {
509              ecore_job_add(_deferred_ecore_evas_free, win->ee);
510              _elm_win_deferred_free++;
511           }
512      }
513
514    _elm_win_focus_highlight_shutdown(win);
515    eina_stringshare_del(win->focus_highlight.style);
516
517    free(win);
518
519    if ((!_elm_win_list) &&
520        (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
521      {
522         edje_file_cache_flush();
523         edje_collection_cache_flush();
524         evas_image_cache_flush(e);
525         evas_font_cache_flush(e);
526         elm_exit();
527      }
528 }
529
530 static void
531 _elm_win_obj_callback_img_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
532 {
533    Elm_Win *win = data;
534    if (!win->img_obj) return;
535    evas_object_event_callback_del_full
536       (win->img_obj, EVAS_CALLBACK_DEL, _elm_win_obj_callback_img_obj_del, win);
537    evas_object_del(win->img_obj);
538 }
539
540 static void
541 _elm_win_obj_callback_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
542 {
543    Elm_Win *win = data;
544    if (obj == win->parent) win->parent = NULL;
545 }
546
547 static void
548 _elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y)
549 {
550    Elm_Win *win = data;
551
552    if (win->img_obj)
553      {
554         if ((x != win->screen.x) || (y != win->screen.y))
555           {
556              win->screen.x = x;
557              win->screen.y = y;
558              evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
559           }
560      }
561    else
562      {
563         evas_object_move(obj, x, y);
564      }
565 }
566
567 static void
568 _elm_win_obj_intercept_show(void *data, Evas_Object *obj)
569 {
570    Elm_Win *win = data;
571    // this is called to make sure all smart containers have calculated their
572    // sizes BEFORE we show the window to make sure it initially appears at
573    // our desired size (ie min size is known first)
574    evas_smart_objects_calculate(evas_object_evas_get(obj));
575    evas_object_show(obj);
576    if (win->frame_obj)
577      {
578      }
579    else if (win->img_obj)
580      {
581         evas_object_show(win->img_obj);
582      }
583 }
584
585 static void
586 _elm_win_obj_callback_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
587 {
588    Elm_Win *win = data;
589
590    if (ecore_evas_override_get(win->ee))
591      {
592         Evas_Coord x, y;
593
594         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
595         win->screen.x = x;
596         win->screen.y = y;
597         evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
598      }
599    if (win->frame_obj)
600      {
601      }
602    else if (win->img_obj)
603      {
604         Evas_Coord x, y;
605
606         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
607         win->screen.x = x;
608         win->screen.y = y;
609 //        evas_object_move(win->img_obj, x, y);
610      }
611 }
612
613 static void
614 _elm_win_obj_callback_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
615 {
616    Elm_Win *win = data;
617
618    if (win->frame_obj)
619      {
620      }
621    else if (win->img_obj)
622      {
623         Evas_Coord w = 1, h = 1;
624
625         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
626         if (w < 1) w = 1;
627         if (h < 1) h = 1;
628         evas_object_image_size_set(win->img_obj, w, h);
629      }
630 }
631
632 static void
633 _elm_win_delete_request(Ecore_Evas *ee)
634 {
635    Evas_Object *obj = ecore_evas_object_associate_get(ee);
636    Elm_Win *win;
637    if (strcmp(elm_widget_type_get(obj), "win")) return;
638
639    win = elm_widget_data_get(obj);
640    if (!win) return;
641    int autodel = win->autodel;
642    win->autodel_clear = &autodel;
643    evas_object_ref(win->win_obj);
644    evas_object_smart_callback_call(win->win_obj, SIG_DELETE_REQUEST, NULL);
645    // FIXME: if above callback deletes - then the below will be invalid
646    if (autodel) evas_object_del(win->win_obj);
647    else win->autodel_clear = NULL;
648    evas_object_unref(win->win_obj);
649 }
650
651 static void
652 _elm_win_resize_job(void *data)
653 {
654    Elm_Win *win = data;
655    const Eina_List *l;
656    Evas_Object *obj;
657    int w, h;
658
659    win->deferred_resize_job = NULL;
660    ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
661    evas_object_resize(win->win_obj, w, h);
662    if (win->frame_obj)
663      {
664      }
665    else if (win->img_obj)
666      {
667      }
668    EINA_LIST_FOREACH(win->subobjs, l, obj)
669      {
670         evas_object_move(obj, 0, 0);
671         evas_object_resize(obj, w, h);
672      }
673 }
674
675 #ifdef HAVE_ELEMENTARY_X
676 static void
677 _elm_win_xwindow_get(Elm_Win *win)
678 {
679    win->xwin = 0;
680
681 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
682    if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
683      {
684        if (win->ee) win->xwin = ecore_evas_software_x11_window_get(win->ee);
685      }
686    else if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
687             ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
688             ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE) ||
689             ENGINE_COMPARE(ELM_SOFTWARE_SDL) ||
690             ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) ||
691             ENGINE_COMPARE(ELM_OPENGL_SDL))
692      {
693      }
694    else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
695      {
696         if (win->ee) win->xwin = ecore_evas_software_x11_16_window_get(win->ee);
697      }
698    else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
699      {
700         if (win->ee) win->xwin = ecore_evas_software_x11_8_window_get(win->ee);
701      }
702 /* killed
703    else if (ENGINE_COMPARE(ELM_XRENDER_X11))
704      {
705         if (win->ee) win->xwin = ecore_evas_xrender_x11_window_get(win->ee);
706      }
707  */
708    else if (ENGINE_COMPARE(ELM_OPENGL_X11))
709      {
710         if (win->ee) win->xwin = ecore_evas_gl_x11_window_get(win->ee);
711      }
712    else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
713      {
714         if (win->ee) win->xwin = (long)ecore_evas_win32_window_get(win->ee);
715      }
716 #undef ENGINE_COMPARE
717 }
718 #endif
719
720 #ifdef HAVE_ELEMENTARY_X
721 static void
722 _elm_win_xwin_update(Elm_Win *win)
723 {
724    _elm_win_xwindow_get(win);
725    if (win->parent)
726      {
727         Elm_Win *win2;
728
729         win2 = elm_widget_data_get(win->parent);
730         if (win2)
731           {
732              if (win->xwin)
733                ecore_x_icccm_transient_for_set(win->xwin, win2->xwin);
734           }
735      }
736
737    if (!win->xwin) return; /* nothing more to do */
738
739    switch (win->type)
740      {
741       case ELM_WIN_BASIC:
742          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NORMAL);
743          break;
744       case ELM_WIN_DIALOG_BASIC:
745          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DIALOG);
746          break;
747       case ELM_WIN_DESKTOP:
748          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DESKTOP);
749          break;
750       case ELM_WIN_DOCK:
751          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DOCK);
752          break;
753       case ELM_WIN_TOOLBAR:
754          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLBAR);
755          break;
756       case ELM_WIN_MENU:
757          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_MENU);
758          break;
759       case ELM_WIN_UTILITY:
760          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_UTILITY);
761          break;
762       case ELM_WIN_SPLASH:
763          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_SPLASH);
764          break;
765       case ELM_WIN_DROPDOWN_MENU:
766          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DROPDOWN_MENU);
767          break;
768       case ELM_WIN_POPUP_MENU:
769          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_POPUP_MENU);
770          break;
771       case ELM_WIN_TOOLTIP:
772          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLTIP);
773          break;
774       case ELM_WIN_NOTIFICATION:
775          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
776          break;
777       case ELM_WIN_COMBO:
778          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_COMBO);
779          break;
780       case ELM_WIN_DND:
781          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DND);
782          break;
783       default:
784          break;
785      }
786    ecore_x_e_virtual_keyboard_state_set
787       (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
788 }
789 #endif
790
791 static void
792 _elm_win_eval_subobjs(Evas_Object *obj)
793 {
794    const Eina_List *l;
795    const Evas_Object *child;
796
797    Elm_Win *win = elm_widget_data_get(obj);
798    Evas_Coord w, h, minw = -1, minh = -1, maxw = -1, maxh = -1;
799    int xx = 1, xy = 1;
800    double wx, wy;
801
802    EINA_LIST_FOREACH(win->subobjs, l, child)
803      {
804         evas_object_size_hint_weight_get(child, &wx, &wy);
805         if (wx == 0.0) xx = 0;
806         if (wy == 0.0) xy = 0;
807
808         evas_object_size_hint_min_get(child, &w, &h);
809         if (w < 1) w = 1;
810         if (h < 1) h = 1;
811         if (w > minw) minw = w;
812         if (h > minh) minh = h;
813
814         evas_object_size_hint_max_get(child, &w, &h);
815         if (w < 1) w = -1;
816         if (h < 1) h = -1;
817         if (maxw == -1) maxw = w;
818         else if ((w > 0) && (w < maxw)) maxw = w;
819         if (maxh == -1) maxh = h;
820         else if ((h > 0) && (h < maxh)) maxh = h;
821      }
822    if (!xx) maxw = minw;
823    else maxw = 32767;
824    if (!xy) maxh = minh;
825    else maxh = 32767;
826    evas_object_size_hint_min_set(obj, minw, minh);
827    evas_object_size_hint_max_set(obj, maxw, maxh);
828    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
829    if (w < minw) w = minw;
830    if (h < minh) h = minh;
831    if ((maxw >= 0) && (w > maxw)) w = maxw;
832    if ((maxh >= 0) && (h > maxh)) h = maxh;
833    evas_object_resize(obj, w, h);
834 }
835
836 static void
837 _elm_win_subobj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
838 {
839    Elm_Win *win = elm_widget_data_get(data);
840    win->subobjs = eina_list_remove(win->subobjs, obj);
841    _elm_win_eval_subobjs(win->win_obj);
842 }
843
844 static void
845 _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
846 {
847    _elm_win_eval_subobjs(data);
848 }
849
850 void
851 _elm_win_shutdown(void)
852 {
853    while (_elm_win_list)
854      evas_object_del(_elm_win_list->data);
855 }
856
857 void
858 _elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme)
859 {
860    const Eina_List *l;
861    Evas_Object *obj;
862
863    if (!use_theme)
864      {
865         EINA_LIST_FOREACH(_elm_win_list, l, obj)
866           elm_widget_theme(obj);
867      }
868    else
869      {
870         EINA_LIST_FOREACH(_elm_win_list, l, obj)
871           elm_widget_theme_specific(obj, th, EINA_FALSE);
872      }
873 }
874
875 #ifdef HAVE_ELEMENTARY_X
876 static Eina_Bool
877 _elm_win_client_message(void *data, int type __UNUSED__, void *event)
878 {
879    Elm_Win *win = data;
880    Ecore_X_Event_Client_Message *e = event;
881
882    if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
883    if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH)
884      {
885         if ((unsigned)e->data.l[0] == win->xwin)
886           {
887              Evas *evas = evas_object_evas_get(win->win_obj);
888              if (evas)
889                {
890                   edje_file_cache_flush();
891                   edje_collection_cache_flush();
892                   evas_image_cache_flush(evas);
893                   evas_font_cache_flush(evas);
894                }
895           }
896      }
897    else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP)
898      {
899         if ((unsigned)e->data.l[0] == win->xwin)
900           {
901              Evas *evas = evas_object_evas_get(win->win_obj);
902              if (evas)
903                {
904                   edje_file_cache_flush();
905                   edje_collection_cache_flush();
906                   evas_image_cache_flush(evas);
907                   evas_font_cache_flush(evas);
908                   evas_render_dump(evas);
909                }
910           }
911      }
912    return ECORE_CALLBACK_PASS_ON;
913 }
914 #endif
915
916 static void
917 _elm_win_focus_target_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
918 {
919    Elm_Win *win = data;
920
921    win->focus_highlight.geometry_changed = EINA_TRUE;
922    _elm_win_focus_highlight_reconfigure_job_start(win);
923 }
924
925 static void
926 _elm_win_focus_target_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
927 {
928    Elm_Win *win = data;
929
930    win->focus_highlight.geometry_changed = EINA_TRUE;
931    _elm_win_focus_highlight_reconfigure_job_start(win);
932 }
933
934 static void
935 _elm_win_focus_target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
936 {
937    Elm_Win *win = data;
938
939    win->focus_highlight.cur.target = NULL;
940
941    _elm_win_focus_highlight_reconfigure_job_start(win);
942 }
943
944 static void
945 _elm_win_focus_target_callbacks_add(Elm_Win *win)
946 {
947    Evas_Object *obj = win->focus_highlight.cur.target;
948
949    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
950                                   _elm_win_focus_target_move, win);
951    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
952                                   _elm_win_focus_target_resize, win);
953    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
954                                   _elm_win_focus_target_del, win);
955 }
956
957 static void
958 _elm_win_focus_target_callbacks_del(Elm_Win *win)
959 {
960    Evas_Object *obj = win->focus_highlight.cur.target;
961
962    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
963                                        _elm_win_focus_target_move, win);
964    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
965                                        _elm_win_focus_target_resize, win);
966    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
967                                        _elm_win_focus_target_del, win);
968 }
969
970 static Evas_Object *
971 _elm_win_focus_target_get(Evas_Object *obj)
972 {
973    Evas_Object *o = obj;
974
975    do
976      {
977         if (elm_widget_is(o))
978           {
979              if (!elm_widget_highlight_ignore_get(o))
980                break;
981              o = elm_widget_parent_get(o);
982              if (!o)
983                o = evas_object_smart_parent_get(o);
984           }
985         else
986           {
987              o = elm_widget_parent_widget_get(o);
988              if (!o)
989                o = evas_object_smart_parent_get(o);
990           }
991      }
992    while (o);
993
994    return o;
995 }
996
997 static void
998 _elm_win_object_focus_in(void *data, Evas *e __UNUSED__, void *event_info)
999 {
1000    Evas_Object *obj = event_info, *target;
1001    Elm_Win *win = data;
1002
1003    if (win->focus_highlight.cur.target == obj)
1004      return;
1005
1006    target = _elm_win_focus_target_get(obj);
1007    win->focus_highlight.cur.target = target;
1008    if (elm_widget_highlight_in_theme_get(target))
1009      win->focus_highlight.cur.handled = EINA_TRUE;
1010    else
1011      _elm_win_focus_target_callbacks_add(win);
1012
1013    _elm_win_focus_highlight_reconfigure_job_start(win);
1014 }
1015
1016 static void
1017 _elm_win_object_focus_out(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
1018 {
1019    Elm_Win *win = data;
1020
1021    if (!win->focus_highlight.cur.target)
1022      return;
1023
1024    if (!win->focus_highlight.cur.handled)
1025      _elm_win_focus_target_callbacks_del(win);
1026    win->focus_highlight.cur.target = NULL;
1027    win->focus_highlight.cur.handled = EINA_FALSE;
1028
1029    _elm_win_focus_highlight_reconfigure_job_start(win);
1030 }
1031
1032 static void
1033 _elm_win_focus_highlight_hide(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
1034 {
1035    evas_object_hide(obj);
1036 }
1037
1038 static void
1039 _elm_win_focus_highlight_init(Elm_Win *win)
1040 {
1041    evas_event_callback_add(win->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
1042                            _elm_win_object_focus_in, win);
1043    evas_event_callback_add(win->evas,
1044                            EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
1045                            _elm_win_object_focus_out, win);
1046
1047    win->focus_highlight.cur.target = evas_focus_get(win->evas);
1048
1049    win->focus_highlight.top = edje_object_add(win->evas);
1050    win->focus_highlight.changed_theme = EINA_TRUE;
1051    edje_object_signal_callback_add(win->focus_highlight.top,
1052                                    "elm,action,focus,hide,end", "",
1053                                    _elm_win_focus_highlight_hide, NULL);
1054    edje_object_signal_callback_add(win->focus_highlight.top,
1055                                    "elm,action,focus,anim,end", "",
1056                                    _elm_win_focus_highlight_anim_end, win);
1057    _elm_win_focus_highlight_reconfigure_job_start(win);
1058 }
1059
1060 static void
1061 _elm_win_focus_highlight_shutdown(Elm_Win *win)
1062 {
1063    _elm_win_focus_highlight_reconfigure_job_stop(win);
1064    if (win->focus_highlight.cur.target)
1065      {
1066         _elm_win_focus_target_callbacks_del(win);
1067         win->focus_highlight.cur.target = NULL;
1068      }
1069    if (win->focus_highlight.top)
1070      {
1071         evas_object_del(win->focus_highlight.top);
1072         win->focus_highlight.top = NULL;
1073      }
1074
1075    evas_event_callback_del_full(win->evas,
1076                                 EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
1077                                 _elm_win_object_focus_in, win);
1078    evas_event_callback_del_full(win->evas,
1079                                 EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
1080                                 _elm_win_object_focus_out, win);
1081 }
1082
1083 static void
1084 _elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible)
1085 {
1086    Evas_Object *top;
1087
1088    top = win->focus_highlight.top;
1089    if (visible)
1090      {
1091         if (top)
1092           {
1093              evas_object_show(top);
1094              edje_object_signal_emit(top, "elm,action,focus,show", "elm");
1095           }
1096      }
1097    else
1098      {
1099         if (top)
1100           edje_object_signal_emit(top, "elm,action,focus,hide", "elm");
1101      }
1102 }
1103
1104 static void
1105 _elm_win_focus_highlight_reconfigure_job(void *data)
1106 {
1107    _elm_win_focus_highlight_reconfigure((Elm_Win *)data);
1108 }
1109
1110 static void
1111 _elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win)
1112 {
1113    if (win->focus_highlight.reconf_job)
1114      ecore_job_del(win->focus_highlight.reconf_job);
1115    win->focus_highlight.reconf_job = ecore_job_add(
1116       _elm_win_focus_highlight_reconfigure_job, win);
1117 }
1118
1119 static void
1120 _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win)
1121 {
1122    if (win->focus_highlight.reconf_job)
1123      ecore_job_del(win->focus_highlight.reconf_job);
1124    win->focus_highlight.reconf_job = NULL;
1125 }
1126
1127 static void
1128 _elm_win_focus_highlight_simple_setup(Elm_Win *win, Evas_Object *obj)
1129 {
1130    Evas_Object *clip, *target = win->focus_highlight.cur.target;
1131    Evas_Coord x, y, w, h;
1132
1133    clip = evas_object_clip_get(target);
1134    evas_object_geometry_get(target, &x, &y, &w, &h);
1135
1136    evas_object_move(obj, x, y);
1137    evas_object_resize(obj, w, h);
1138    evas_object_clip_set(obj, clip);
1139 }
1140
1141 static void
1142 _elm_win_focus_highlight_anim_setup(Elm_Win *win, Evas_Object *obj)
1143 {
1144    Evas_Coord tx, ty, tw, th;
1145    Evas_Coord w, h, px, py, pw, ph;
1146    Edje_Message_Int_Set *m;
1147    Evas_Object *previous = win->focus_highlight.prev.target;
1148    Evas_Object *target = win->focus_highlight.cur.target;
1149
1150    evas_object_geometry_get(win->win_obj, NULL, NULL, &w, &h);
1151    evas_object_geometry_get(target, &tx, &ty, &tw, &th);
1152    evas_object_geometry_get(previous, &px, &py, &pw, &ph);
1153    evas_object_move(obj, 0, 0);
1154    evas_object_resize(obj, tw, th);
1155    evas_object_clip_unset(obj);
1156
1157    m = alloca(sizeof(*m) + (sizeof(int) * 8));
1158    m->count = 8;
1159    m->val[0] = px;
1160    m->val[1] = py;
1161    m->val[2] = pw;
1162    m->val[3] = ph;
1163    m->val[4] = tx;
1164    m->val[5] = ty;
1165    m->val[6] = tw;
1166    m->val[7] = th;
1167    edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m);
1168 }
1169
1170 static void
1171 _elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
1172 {
1173    Elm_Win *win = data;
1174    _elm_win_focus_highlight_simple_setup(win, obj);
1175 }
1176
1177 static void
1178 _elm_win_focus_highlight_reconfigure(Elm_Win *win)
1179 {
1180    Evas_Object *target = win->focus_highlight.cur.target;
1181    Evas_Object *previous = win->focus_highlight.prev.target;
1182    Evas_Object *top = win->focus_highlight.top;
1183    Eina_Bool visible_changed;
1184    Eina_Bool common_visible;
1185    const char *sig = NULL;
1186
1187    _elm_win_focus_highlight_reconfigure_job_stop(win);
1188
1189    visible_changed = (win->focus_highlight.cur.visible !=
1190                       win->focus_highlight.prev.visible);
1191
1192    if ((target == previous) && (!visible_changed) &&
1193        (!win->focus_highlight.geometry_changed))
1194      return;
1195
1196    if ((previous) && (win->focus_highlight.prev.handled))
1197      elm_widget_signal_emit(previous, "elm,action,focus_highlight,hide", "elm");
1198
1199    if (!target)
1200      common_visible = EINA_FALSE;
1201    else if (win->focus_highlight.cur.handled)
1202      {
1203         common_visible = EINA_FALSE;
1204         if (win->focus_highlight.cur.visible)
1205           sig = "elm,action,focus_highlight,show";
1206         else
1207           sig = "elm,action,focus_highlight,hide";
1208      }
1209    else
1210      common_visible = win->focus_highlight.cur.visible;
1211
1212    _elm_win_focus_highlight_visible_set(win, common_visible);
1213    if (sig)
1214      elm_widget_signal_emit(target, sig, "elm");
1215
1216    if ((!target) || (!common_visible) || (win->focus_highlight.cur.handled))
1217      goto the_end;
1218
1219    if (win->focus_highlight.changed_theme)
1220      {
1221         const char *str;
1222         if (win->focus_highlight.style)
1223           str = win->focus_highlight.style;
1224         else
1225           str = "default";
1226         _elm_theme_object_set(win->win_obj, top, "focus_highlight", "top",
1227                               str);
1228         win->focus_highlight.changed_theme = EINA_FALSE;
1229
1230         if (_elm_config->focus_highlight_animate)
1231           {
1232              str = edje_object_data_get(win->focus_highlight.top, "animate");
1233              win->focus_highlight.top_animate = ((str) && (!strcmp(str, "on")));
1234           }
1235      }
1236
1237    if ((win->focus_highlight.top_animate) && (previous) &&
1238        (!win->focus_highlight.prev.handled))
1239      _elm_win_focus_highlight_anim_setup(win, top);
1240    else
1241      _elm_win_focus_highlight_simple_setup(win, top);
1242    evas_object_raise(top);
1243
1244 the_end:
1245    win->focus_highlight.geometry_changed = EINA_FALSE;
1246    win->focus_highlight.prev = win->focus_highlight.cur;
1247 }
1248
1249 #ifdef ELM_DEBUG
1250 static void
1251 _debug_key_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
1252 {
1253    Evas_Event_Key_Down *ev = event_info;
1254
1255    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1256      return;
1257
1258
1259    if ((strcmp(ev->keyname, "F12")) ||
1260        (!evas_key_modifier_is_set(ev->modifiers, "Control")))
1261      return;
1262
1263    printf("Tree graph generated.\n");
1264    elm_object_tree_dot_dump(obj, "./dump.dot");
1265 }
1266 #endif
1267
1268 static void
1269 _win_img_hide(void        *data,
1270               Evas        *e __UNUSED__,
1271               Evas_Object *obj __UNUSED__,
1272               void        *event_info __UNUSED__)
1273 {
1274    Elm_Win *win = data;
1275
1276    elm_widget_focus_hide_handle(win->win_obj);
1277 }
1278
1279 static void
1280 _win_img_mouse_up(void        *data,
1281                   Evas        *e __UNUSED__,
1282                   Evas_Object *obj __UNUSED__,
1283                   void        *event_info)
1284 {
1285    Elm_Win *win = data;
1286    Evas_Event_Mouse_Up *ev = event_info;
1287    if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
1288       elm_widget_focus_mouse_up_handle(win->win_obj);
1289 }
1290
1291 static void
1292 _win_img_focus_in(void        *data,
1293                   Evas        *e __UNUSED__,
1294                   Evas_Object *obj __UNUSED__,
1295                   void        *event_info __UNUSED__)
1296 {
1297    Elm_Win *win = data;
1298    elm_widget_focus_steal(win->win_obj);
1299 }
1300
1301 static void
1302 _win_img_focus_out(void        *data,
1303                    Evas        *e __UNUSED__,
1304                    Evas_Object *obj __UNUSED__,
1305                    void        *event_info __UNUSED__)
1306 {
1307    Elm_Win *win = data;
1308    elm_widget_focused_object_clear(win->win_obj);
1309 }
1310
1311 static void
1312 _win_inlined_image_set(Elm_Win *win)
1313 {
1314    evas_object_image_alpha_set(win->img_obj, EINA_FALSE);
1315    evas_object_image_filled_set(win->img_obj, EINA_TRUE);
1316    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_DEL,
1317                                   _elm_win_obj_callback_img_obj_del, win);
1318
1319    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_HIDE,
1320                                   _win_img_hide, win);
1321    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_MOUSE_UP,
1322                                   _win_img_mouse_up, win);
1323    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_FOCUS_IN,
1324                                   _win_img_focus_in, win);
1325    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_FOCUS_OUT,
1326                                   _win_img_focus_out, win);
1327 }
1328
1329 EAPI Evas_Object *
1330 elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
1331 {
1332    Elm_Win *win;
1333    const Eina_List *l;
1334    const char *fontpath;
1335
1336    win = ELM_NEW(Elm_Win);
1337
1338 #define FALLBACK_TRY(engine)                                              \
1339    if (!win->ee)                                                          \
1340    do {                                                                   \
1341         CRITICAL(engine " engine creation failed. Trying software X11."); \
1342         elm_engine_set(ELM_SOFTWARE_X11);                                 \
1343         win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);       \
1344    } while (0)
1345 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
1346
1347    switch (type)
1348      {
1349       case ELM_WIN_INLINED_IMAGE:
1350         if (!parent) break;
1351         {
1352            Evas *e = evas_object_evas_get(parent);
1353            Ecore_Evas *ee;
1354            if (!e) break;
1355            ee = ecore_evas_ecore_evas_get(e);
1356            if (!ee) break;
1357            win->img_obj = ecore_evas_object_image_new(ee);
1358            if (!win->img_obj) break;
1359            win->ee = ecore_evas_object_ecore_evas_get(win->img_obj);
1360            if (win->ee)
1361              {
1362                 _win_inlined_image_set(win);
1363                 break;
1364              }
1365            evas_object_del(win->img_obj);
1366            win->img_obj = NULL;
1367         }
1368         break;
1369       default:
1370         if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
1371           {
1372              win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
1373 #ifdef HAVE_ELEMENTARY_X
1374              win->client_message_handler = ecore_event_handler_add
1375                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1376 #endif
1377           }
1378         else if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
1379           {
1380              win->ee = ecore_evas_fb_new(NULL, 0, 1, 1);
1381              FALLBACK_TRY("Sofware FB");
1382           }
1383         else if (ENGINE_COMPARE(ELM_SOFTWARE_DIRECTFB))
1384           {
1385              win->ee = ecore_evas_directfb_new(NULL, 1, 0, 0, 1, 1);
1386              FALLBACK_TRY("Sofware DirectFB");
1387           }
1388         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
1389           {
1390              win->ee = ecore_evas_software_x11_16_new(NULL, 0, 0, 0, 1, 1);
1391              FALLBACK_TRY("Sofware-16");
1392 #ifdef HAVE_ELEMENTARY_X
1393              win->client_message_handler = ecore_event_handler_add
1394                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1395 #endif
1396      }
1397         else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
1398           {
1399              win->ee = ecore_evas_software_x11_8_new(NULL, 0, 0, 0, 1, 1);
1400              FALLBACK_TRY("Sofware-8");
1401 #ifdef HAVE_ELEMENTARY_X
1402              win->client_message_handler = ecore_event_handler_add
1403                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1404 #endif
1405           }
1406 /* killed
1407         else if (ENGINE_COMPARE(ELM_XRENDER_X11))
1408           {
1409              win->ee = ecore_evas_xrender_x11_new(NULL, 0, 0, 0, 1, 1);
1410              FALLBACK_TRY("XRender");
1411 #ifdef HAVE_ELEMENTARY_X
1412              win->client_message_handler = ecore_event_handler_add
1413                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1414 #endif
1415           }
1416  */
1417         else if (ENGINE_COMPARE(ELM_OPENGL_X11))
1418           {
1419              int opt[10];
1420              int opt_i = 0;
1421
1422              if (_elm_config->vsync)
1423                {
1424                   opt[opt_i] = ECORE_EVAS_GL_X11_OPT_VSYNC;
1425                   opt_i++;
1426                   opt[opt_i] = 1;
1427                   opt_i++;
1428                }
1429              if (opt_i > 0)
1430                 win->ee = ecore_evas_gl_x11_options_new(NULL, 0, 0, 0, 1, 1, opt);
1431              else
1432                 win->ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1);
1433              FALLBACK_TRY("OpenGL");
1434 #ifdef HAVE_ELEMENTARY_X
1435              win->client_message_handler = ecore_event_handler_add
1436                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1437 #endif
1438           }
1439         else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
1440           {
1441              win->ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1);
1442              FALLBACK_TRY("Sofware Win32");
1443           }
1444         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
1445           {
1446              win->ee = ecore_evas_software_wince_gdi_new(NULL, 0, 0, 1, 1);
1447              FALLBACK_TRY("Sofware-16-WinCE");
1448           }
1449         else if (ENGINE_COMPARE(ELM_SOFTWARE_SDL))
1450           {
1451              win->ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1);
1452              FALLBACK_TRY("Sofware SDL");
1453           }
1454         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_SDL))
1455           {
1456              win->ee = ecore_evas_sdl16_new(NULL, 0, 0, 0, 0, 0, 1);
1457              FALLBACK_TRY("Sofware-16-SDL");
1458           }
1459         else if (ENGINE_COMPARE(ELM_OPENGL_SDL))
1460           {
1461              win->ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0);
1462              FALLBACK_TRY("OpenGL SDL");
1463           }
1464         else if (ENGINE_COMPARE(ELM_BUFFER))
1465           {
1466              win->ee = ecore_evas_buffer_new(1, 1);
1467           }
1468         else if (!strncmp(_elm_config->engine, "shot:", 5))
1469           {
1470              win->ee = ecore_evas_buffer_new(1, 1);
1471              ecore_evas_manual_render_set(win->ee, EINA_TRUE);
1472              win->shot.info = eina_stringshare_add(_elm_config->engine + 5);
1473              _shot_init(win);
1474           }
1475 #undef FALLBACK_TRY
1476         break;
1477      }
1478
1479    if (!win->ee)
1480      {
1481         ERR("Cannot create window.");
1482         free(win);
1483         return NULL;
1484      }
1485 #ifdef HAVE_ELEMENTARY_X
1486    _elm_win_xwindow_get(win);
1487 #endif
1488    if ((_elm_config->bgpixmap) && (!_elm_config->compositing))
1489      ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
1490    // bg pixmap done by x - has other issues like can be redrawn by x before it
1491    // is filled/ready by app
1492    //     ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
1493
1494    win->type = type;
1495    win->parent = parent;
1496    if (win->parent)
1497      evas_object_event_callback_add(win->parent, EVAS_CALLBACK_DEL,
1498                                     _elm_win_obj_callback_parent_del, win);
1499
1500    win->evas = ecore_evas_get(win->ee);
1501    win->win_obj = elm_widget_add(win->evas);
1502    elm_widget_type_set(win->win_obj, "win");
1503    ELM_SET_WIDTYPE(widtype, "win");
1504    elm_widget_data_set(win->win_obj, win);
1505    elm_widget_event_hook_set(win->win_obj, _elm_win_event_cb);
1506    elm_widget_on_focus_hook_set(win->win_obj, _elm_win_on_focus_hook, NULL);
1507    elm_widget_can_focus_set(win->win_obj, EINA_TRUE);
1508    elm_widget_highlight_ignore_set(win->win_obj, EINA_TRUE);
1509    elm_widget_focus_next_hook_set(win->win_obj, _elm_win_focus_next_hook);
1510    evas_object_color_set(win->win_obj, 0, 0, 0, 0);
1511    evas_object_move(win->win_obj, 0, 0);
1512    evas_object_resize(win->win_obj, 1, 1);
1513    evas_object_layer_set(win->win_obj, 50);
1514    evas_object_pass_events_set(win->win_obj, EINA_TRUE);
1515
1516    if (type == ELM_WIN_INLINED_IMAGE)
1517       elm_widget_parent2_set(win->win_obj, parent);
1518    ecore_evas_object_associate(win->ee, win->win_obj,
1519                                ECORE_EVAS_OBJECT_ASSOCIATE_BASE |
1520                                ECORE_EVAS_OBJECT_ASSOCIATE_STACK |
1521                                ECORE_EVAS_OBJECT_ASSOCIATE_LAYER);
1522    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_SHOW,
1523                                   _elm_win_obj_callback_show, win);
1524    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_HIDE,
1525                                   _elm_win_obj_callback_hide, win);
1526    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_DEL,
1527                                   _elm_win_obj_callback_del, win);
1528    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_MOVE,
1529                                   _elm_win_obj_callback_move, win);
1530    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_RESIZE,
1531                                   _elm_win_obj_callback_resize, win);
1532    if (win->img_obj)
1533       evas_object_intercept_move_callback_add(win->win_obj,
1534                                               _elm_win_obj_intercept_move, win);
1535    evas_object_intercept_show_callback_add(win->win_obj,
1536                                            _elm_win_obj_intercept_show, win);
1537
1538    ecore_evas_name_class_set(win->ee, name, _elm_appname);
1539    ecore_evas_callback_delete_request_set(win->ee, _elm_win_delete_request);
1540    ecore_evas_callback_resize_set(win->ee, _elm_win_resize);
1541    ecore_evas_callback_focus_in_set(win->ee, _elm_win_focus_in);
1542    ecore_evas_callback_focus_out_set(win->ee, _elm_win_focus_out);
1543    ecore_evas_callback_move_set(win->ee, _elm_win_move);
1544    evas_image_cache_set(win->evas, (_elm_config->image_cache * 1024));
1545    evas_font_cache_set(win->evas, (_elm_config->font_cache * 1024));
1546    EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
1547       evas_font_path_append(win->evas, fontpath);
1548    if (!_elm_config->font_hinting)
1549      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_NONE);
1550    else if (_elm_config->font_hinting == 1)
1551      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_AUTO);
1552    else if (_elm_config->font_hinting == 2)
1553      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_BYTECODE);
1554
1555 #ifdef HAVE_ELEMENTARY_X
1556    _elm_win_xwin_update(win);
1557 #endif
1558
1559    _elm_win_list = eina_list_append(_elm_win_list, win->win_obj);
1560
1561    if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
1562      {
1563         ecore_evas_fullscreen_set(win->ee, 1);
1564      }
1565 #undef ENGINE_COMPARE
1566
1567    if (_elm_config->focus_highlight_enable)
1568      elm_win_focus_highlight_enabled_set(win->win_obj, EINA_TRUE);
1569
1570 #ifdef ELM_DEBUG
1571    Evas_Modifier_Mask mask = evas_key_modifier_mask_get(win->evas, "Control");
1572    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_KEY_DOWN,
1573                                   _debug_key_down, win);
1574
1575    Eina_Bool ret = evas_object_key_grab(win->win_obj, "F12", mask, 0,
1576                                         EINA_TRUE);
1577    printf("Key F12 exclusive for dot tree generation. (%d)\n", ret);
1578 #endif
1579
1580    evas_object_smart_callbacks_descriptions_set(win->win_obj, _signals);
1581
1582    return win->win_obj;
1583 }
1584
1585 EAPI void
1586 elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj)
1587 {
1588    Evas_Coord w, h;
1589    Elm_Win *win;
1590    ELM_CHECK_WIDTYPE(obj, widtype);
1591    win = elm_widget_data_get(obj);
1592    if (!win) return;
1593    if (eina_list_data_find(win->subobjs, subobj)) return;
1594    win->subobjs = eina_list_append(win->subobjs, subobj);
1595    elm_widget_sub_object_add(obj, subobj);
1596    evas_object_event_callback_add(subobj, EVAS_CALLBACK_DEL,
1597                                   _elm_win_subobj_callback_del, obj);
1598    evas_object_event_callback_add(subobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1599                                   _elm_win_subobj_callback_changed_size_hints,
1600                                   obj);
1601    ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
1602    evas_object_move(subobj, 0, 0);
1603    evas_object_resize(subobj, w, h);
1604    _elm_win_eval_subobjs(obj);
1605 }
1606
1607 EAPI void
1608 elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj)
1609 {
1610    Elm_Win *win;
1611    ELM_CHECK_WIDTYPE(obj, widtype);
1612    win = elm_widget_data_get(obj);
1613    if (!win) return;
1614    evas_object_event_callback_del_full(subobj,
1615                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1616                                        _elm_win_subobj_callback_changed_size_hints,
1617                                        obj);
1618    evas_object_event_callback_del_full(subobj, EVAS_CALLBACK_DEL,
1619                                        _elm_win_subobj_callback_del, obj);
1620    win->subobjs = eina_list_remove(win->subobjs, subobj);
1621    elm_widget_sub_object_del(obj, subobj);
1622    _elm_win_eval_subobjs(obj);
1623 }
1624
1625 EAPI void
1626 elm_win_title_set(Evas_Object *obj, const char *title)
1627 {
1628    Elm_Win *win;
1629    ELM_CHECK_WIDTYPE(obj, widtype);
1630    win = elm_widget_data_get(obj);
1631    if (!win) return;
1632    ecore_evas_title_set(win->ee, title);
1633 }
1634
1635 EAPI const char *
1636 elm_win_title_get(const Evas_Object *obj)
1637 {
1638    Elm_Win *win;
1639    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1640    win = elm_widget_data_get(obj);
1641    if (!win) return NULL;
1642    return ecore_evas_title_get(win->ee);
1643 }
1644
1645 EAPI void
1646 elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel)
1647 {
1648    Elm_Win *win;
1649    ELM_CHECK_WIDTYPE(obj, widtype);
1650    win = elm_widget_data_get(obj);
1651    if (!win) return;
1652    win->autodel = autodel;
1653 }
1654
1655 EAPI Eina_Bool
1656 elm_win_autodel_get(const Evas_Object *obj)
1657 {
1658    Elm_Win *win;
1659    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1660    win = elm_widget_data_get(obj);
1661    if (!win) return EINA_FALSE;
1662    return win->autodel;
1663 }
1664
1665 EAPI void
1666 elm_win_activate(Evas_Object *obj)
1667 {
1668    Elm_Win *win;
1669    ELM_CHECK_WIDTYPE(obj, widtype);
1670    win = elm_widget_data_get(obj);
1671    if (!win) return;
1672    ecore_evas_activate(win->ee);
1673 }
1674
1675 EAPI void
1676 elm_win_lower(Evas_Object *obj)
1677 {
1678    Elm_Win *win;
1679    ELM_CHECK_WIDTYPE(obj, widtype);
1680    win = elm_widget_data_get(obj);
1681    if (!win) return;
1682    ecore_evas_lower(win->ee);
1683 }
1684
1685 EAPI void
1686 elm_win_raise(Evas_Object *obj)
1687 {
1688    Elm_Win *win;
1689    ELM_CHECK_WIDTYPE(obj, widtype);
1690    win = elm_widget_data_get(obj);
1691    if (!win) return;
1692    ecore_evas_raise(win->ee);
1693 }
1694
1695 EAPI void
1696 elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless)
1697 {
1698    Elm_Win *win;
1699    ELM_CHECK_WIDTYPE(obj, widtype);
1700    win = elm_widget_data_get(obj);
1701    if (!win) return;
1702    ecore_evas_borderless_set(win->ee, borderless);
1703 #ifdef HAVE_ELEMENTARY_X
1704    _elm_win_xwin_update(win);
1705 #endif
1706 }
1707
1708 EAPI Eina_Bool
1709 elm_win_borderless_get(const Evas_Object *obj)
1710 {
1711    Elm_Win *win;
1712    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1713    win = elm_widget_data_get(obj);
1714    if (!win) return EINA_FALSE;
1715    return ecore_evas_borderless_get(win->ee);
1716 }
1717
1718 EAPI void
1719 elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped)
1720 {
1721    Elm_Win *win;
1722    ELM_CHECK_WIDTYPE(obj, widtype);
1723    win = elm_widget_data_get(obj);
1724    if (!win) return;
1725    ecore_evas_shaped_set(win->ee, shaped);
1726 #ifdef HAVE_ELEMENTARY_X
1727    _elm_win_xwin_update(win);
1728 #endif
1729 }
1730
1731 EAPI Eina_Bool
1732 elm_win_shaped_get(const Evas_Object *obj)
1733 {
1734    Elm_Win *win;
1735    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1736    win = elm_widget_data_get(obj);
1737    if (!win) return EINA_FALSE;
1738    return ecore_evas_shaped_get(win->ee);
1739 }
1740
1741 EAPI void
1742 elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha)
1743 {
1744    Elm_Win *win;
1745    ELM_CHECK_WIDTYPE(obj, widtype);
1746    win = elm_widget_data_get(obj);
1747    if (!win) return;
1748    if (win->frame_obj)
1749      {
1750      }
1751    else if (win->img_obj)
1752      {
1753         evas_object_image_alpha_set(win->img_obj, alpha);
1754      }
1755    else
1756      {
1757 #ifdef HAVE_ELEMENTARY_X
1758         if (win->xwin)
1759           {
1760              if (alpha)
1761                {
1762                   if (!_elm_config->compositing)
1763                      elm_win_shaped_set(obj, alpha);
1764                   else
1765                      ecore_evas_alpha_set(win->ee, alpha);
1766                }
1767              else
1768                 ecore_evas_alpha_set(win->ee, alpha);
1769              _elm_win_xwin_update(win);
1770           }
1771         else
1772 #endif
1773            ecore_evas_alpha_set(win->ee, alpha);
1774      }
1775 }
1776
1777 EAPI Eina_Bool
1778 elm_win_alpha_get(const Evas_Object *obj)
1779 {
1780    Elm_Win *win;
1781    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1782    win = elm_widget_data_get(obj);
1783    if (!win) return EINA_FALSE;
1784    return ecore_evas_alpha_get(win->ee);
1785 }
1786
1787 EAPI void
1788 elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent)
1789 {
1790    Elm_Win *win;
1791    ELM_CHECK_WIDTYPE(obj, widtype);
1792    win = elm_widget_data_get(obj);
1793    if (!win) return;
1794
1795    if (win->frame_obj)
1796      {
1797      }
1798    else if (win->img_obj)
1799      {
1800         evas_object_image_alpha_set(win->img_obj, transparent);
1801      }
1802    else
1803      {
1804 #ifdef HAVE_ELEMENTARY_X
1805         if (win->xwin)
1806           {
1807              ecore_evas_transparent_set(win->ee, transparent);
1808              _elm_win_xwin_update(win);
1809           }
1810         else
1811 #endif
1812            ecore_evas_transparent_set(win->ee, transparent);
1813      }
1814 }
1815
1816 EAPI Eina_Bool
1817 elm_win_transparent_get(const Evas_Object *obj)
1818 {
1819    Elm_Win *win;
1820    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1821    win = elm_widget_data_get(obj);
1822    if (!win) return EINA_FALSE;
1823
1824    return ecore_evas_transparent_get(win->ee);
1825 }
1826
1827 EAPI void
1828 elm_win_override_set(Evas_Object *obj, Eina_Bool override)
1829 {
1830    Elm_Win *win;
1831    ELM_CHECK_WIDTYPE(obj, widtype);
1832    win = elm_widget_data_get(obj);
1833    if (!win) return;
1834    ecore_evas_override_set(win->ee, override);
1835 #ifdef HAVE_ELEMENTARY_X
1836    _elm_win_xwin_update(win);
1837 #endif
1838 }
1839
1840 EAPI Eina_Bool
1841 elm_win_override_get(const Evas_Object *obj)
1842 {
1843    Elm_Win *win;
1844    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1845    win = elm_widget_data_get(obj);
1846    if (!win) return EINA_FALSE;
1847    return ecore_evas_override_get(win->ee);
1848 }
1849
1850 EAPI void
1851 elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen)
1852 {
1853    Elm_Win *win;
1854    ELM_CHECK_WIDTYPE(obj, widtype);
1855    win = elm_widget_data_get(obj);
1856    if (!win) return;
1857
1858    // YYY: handle if win->img_obj
1859 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
1860    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
1861        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
1862      {
1863         // these engines... can ONLY be fullscreen
1864         return;
1865      }
1866    else
1867      {
1868         ecore_evas_fullscreen_set(win->ee, fullscreen);
1869 #ifdef HAVE_ELEMENTARY_X
1870         _elm_win_xwin_update(win);
1871 #endif
1872      }
1873 #undef ENGINE_COMPARE
1874 }
1875
1876 EAPI Eina_Bool
1877 elm_win_fullscreen_get(const Evas_Object *obj)
1878 {
1879    Elm_Win *win;
1880    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1881    win = elm_widget_data_get(obj);
1882    if (!win) return EINA_FALSE;
1883
1884 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
1885    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
1886        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
1887      {
1888         // these engines... can ONLY be fullscreen
1889         return EINA_TRUE;
1890      }
1891    else
1892      {
1893         return ecore_evas_fullscreen_get(win->ee);
1894      }
1895 #undef ENGINE_COMPARE
1896 }
1897
1898 EAPI void
1899 elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized)
1900 {
1901    Elm_Win *win;
1902    ELM_CHECK_WIDTYPE(obj, widtype);
1903    win = elm_widget_data_get(obj);
1904    if (!win) return;
1905    // YYY: handle if win->img_obj
1906    ecore_evas_maximized_set(win->ee, maximized);
1907 #ifdef HAVE_ELEMENTARY_X
1908    _elm_win_xwin_update(win);
1909 #endif
1910 }
1911
1912 EAPI Eina_Bool
1913 elm_win_maximized_get(const Evas_Object *obj)
1914 {
1915    Elm_Win *win;
1916    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1917    win = elm_widget_data_get(obj);
1918    if (!win) return EINA_FALSE;
1919    return ecore_evas_maximized_get(win->ee);
1920 }
1921
1922 EAPI void
1923 elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified)
1924 {
1925    Elm_Win *win;
1926    ELM_CHECK_WIDTYPE(obj, widtype);
1927    win = elm_widget_data_get(obj);
1928    if (!win) return;
1929    ecore_evas_iconified_set(win->ee, iconified);
1930 #ifdef HAVE_ELEMENTARY_X
1931    _elm_win_xwin_update(win);
1932 #endif
1933 }
1934
1935 EAPI Eina_Bool
1936 elm_win_iconified_get(const Evas_Object *obj)
1937 {
1938    Elm_Win *win;
1939    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1940    win = elm_widget_data_get(obj);
1941    if (!win) return EINA_FALSE;
1942    return ecore_evas_iconified_get(win->ee);
1943 }
1944
1945 EAPI void
1946 elm_win_layer_set(Evas_Object *obj, int layer)
1947 {
1948    Elm_Win *win;
1949    ELM_CHECK_WIDTYPE(obj, widtype);
1950    win = elm_widget_data_get(obj);
1951    if (!win) return;
1952    ecore_evas_layer_set(win->ee, layer);
1953 #ifdef HAVE_ELEMENTARY_X
1954    _elm_win_xwin_update(win);
1955 #endif
1956 }
1957
1958 EAPI int
1959 elm_win_layer_get(const Evas_Object *obj)
1960 {
1961    Elm_Win *win;
1962    ELM_CHECK_WIDTYPE(obj, widtype) -1;
1963    win = elm_widget_data_get(obj);
1964    if (!win) return -1;
1965    return ecore_evas_layer_get(win->ee);
1966 }
1967
1968 EAPI void
1969 elm_win_rotation_set(Evas_Object *obj, int rotation)
1970 {
1971    Elm_Win *win;
1972    ELM_CHECK_WIDTYPE(obj, widtype);
1973    win = elm_widget_data_get(obj);
1974    if (!win) return;
1975    if (win->rot == rotation) return;
1976    win->rot = rotation;
1977    ecore_evas_rotation_set(win->ee, rotation);
1978    evas_object_size_hint_min_set(obj, -1, -1);
1979    evas_object_size_hint_max_set(obj, -1, -1);
1980    _elm_win_eval_subobjs(obj);
1981 #ifdef HAVE_ELEMENTARY_X
1982    _elm_win_xwin_update(win);
1983 #endif
1984 }
1985
1986 EAPI void
1987 elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation)
1988 {
1989    Elm_Win *win;
1990    ELM_CHECK_WIDTYPE(obj, widtype);
1991    win = elm_widget_data_get(obj);
1992    if (!win) return;
1993    if (win->rot == rotation) return;
1994    win->rot = rotation;
1995    ecore_evas_rotation_with_resize_set(win->ee, rotation);
1996    evas_object_size_hint_min_set(obj, -1, -1);
1997    evas_object_size_hint_max_set(obj, -1, -1);
1998    _elm_win_eval_subobjs(obj);
1999 #ifdef HAVE_ELEMENTARY_X
2000    _elm_win_xwin_update(win);
2001 #endif
2002 }
2003
2004 EAPI int
2005 elm_win_rotation_get(const Evas_Object *obj)
2006 {
2007    Elm_Win *win;
2008    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2009    win = elm_widget_data_get(obj);
2010    if (!win) return -1;
2011    return win->rot;
2012 }
2013
2014 EAPI void
2015 elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky)
2016 {
2017    Elm_Win *win;
2018    ELM_CHECK_WIDTYPE(obj, widtype);
2019    win = elm_widget_data_get(obj);
2020    if (!win) return;
2021    ecore_evas_sticky_set(win->ee, sticky);
2022 #ifdef HAVE_ELEMENTARY_X
2023    _elm_win_xwin_update(win);
2024 #endif
2025 }
2026
2027 EAPI Eina_Bool
2028 elm_win_sticky_get(const Evas_Object *obj)
2029 {
2030    Elm_Win *win;
2031    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2032    win = elm_widget_data_get(obj);
2033    if (!win) return EINA_FALSE;
2034    return ecore_evas_sticky_get(win->ee);
2035 }
2036
2037 EAPI void
2038 elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode)
2039 {
2040    Elm_Win *win;
2041    ELM_CHECK_WIDTYPE(obj, widtype);
2042    win = elm_widget_data_get(obj);
2043    if (!win) return;
2044    if (mode == win->kbdmode) return;
2045 #ifdef HAVE_ELEMENTARY_X
2046    _elm_win_xwindow_get(win);
2047 #endif
2048    win->kbdmode = mode;
2049 #ifdef HAVE_ELEMENTARY_X
2050    if (win->xwin)
2051      ecore_x_e_virtual_keyboard_state_set
2052         (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
2053 #endif
2054 }
2055
2056 EAPI Elm_Win_Keyboard_Mode
2057 elm_win_keyboard_mode_get(const Evas_Object *obj)
2058 {
2059    Elm_Win *win;
2060    ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_KEYBOARD_UNKNOWN;
2061    win = elm_widget_data_get(obj);
2062    if (!win) return ELM_WIN_KEYBOARD_UNKNOWN;
2063    return win->kbdmode;
2064 }
2065
2066 EAPI void
2067 elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard)
2068 {
2069    Elm_Win *win;
2070    ELM_CHECK_WIDTYPE(obj, widtype);
2071    win = elm_widget_data_get(obj);
2072    if (!win) return;
2073 #ifdef HAVE_ELEMENTARY_X
2074    _elm_win_xwindow_get(win);
2075    if (win->xwin)
2076      ecore_x_e_virtual_keyboard_set(win->xwin, is_keyboard);
2077 #endif
2078 }
2079
2080 EAPI Eina_Bool
2081 elm_win_keyboard_win_get(const Evas_Object *obj)
2082 {
2083    Elm_Win *win;
2084    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2085    win = elm_widget_data_get(obj);
2086    if (!win) return EINA_FALSE;
2087 #ifdef HAVE_ELEMENTARY_X
2088    _elm_win_xwindow_get(win);
2089    if (win->xwin)
2090      return ecore_x_e_virtual_keyboard_get(win->xwin);
2091 #endif
2092    return EINA_FALSE;
2093 }
2094
2095 EAPI void
2096 elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y)
2097 {
2098    Elm_Win *win;
2099    ELM_CHECK_WIDTYPE(obj, widtype);
2100    win = elm_widget_data_get(obj);
2101    if (!win) return;
2102    if (x) *x = win->screen.x;
2103    if (y) *y = win->screen.y;
2104 }
2105
2106 EAPI void
2107 elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant)
2108 {
2109    Elm_Win *win;
2110    ELM_CHECK_WIDTYPE(obj, widtype);
2111    win = elm_widget_data_get(obj);
2112    if (!win) return;
2113 #ifdef HAVE_ELEMENTARY_X
2114    _elm_win_xwindow_get(win);
2115    if (win->xwin)
2116      ecore_x_e_illume_conformant_set(win->xwin, conformant);
2117 #endif
2118 }
2119
2120 EAPI Eina_Bool
2121 elm_win_conformant_get(const Evas_Object *obj)
2122 {
2123    Elm_Win *win;
2124    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2125    win = elm_widget_data_get(obj);
2126    if (!win) return EINA_FALSE;
2127 #ifdef HAVE_ELEMENTARY_X
2128    _elm_win_xwindow_get(win);
2129    if (win->xwin)
2130      return ecore_x_e_illume_conformant_get(win->xwin);
2131 #endif
2132    return EINA_FALSE;
2133 }
2134
2135 EAPI void
2136 elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel)
2137 {
2138    Elm_Win *win;
2139    ELM_CHECK_WIDTYPE(obj, widtype);
2140    win = elm_widget_data_get(obj);
2141    if (!win) return;
2142 #ifdef HAVE_ELEMENTARY_X
2143    _elm_win_xwindow_get(win);
2144    if (win->xwin)
2145      {
2146         ecore_x_e_illume_quickpanel_set(win->xwin, quickpanel);
2147         if (quickpanel)
2148           {
2149              Ecore_X_Window_State states[2];
2150
2151              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
2152              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
2153              ecore_x_netwm_window_state_set(win->xwin, states, 2);
2154              ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
2155           }
2156      }
2157 #endif
2158 }
2159
2160 EAPI Eina_Bool
2161 elm_win_quickpanel_get(const Evas_Object *obj)
2162 {
2163    Elm_Win *win;
2164    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2165    win = elm_widget_data_get(obj);
2166    if (!win) return EINA_FALSE;
2167 #ifdef HAVE_ELEMENTARY_X
2168    _elm_win_xwindow_get(win);
2169    if (win->xwin)
2170      return ecore_x_e_illume_quickpanel_get(win->xwin);
2171 #endif
2172    return EINA_FALSE;
2173 }
2174
2175 EAPI void
2176 elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority)
2177 {
2178    Elm_Win *win;
2179    ELM_CHECK_WIDTYPE(obj, widtype);
2180    win = elm_widget_data_get(obj);
2181    if (!win) return;
2182 #ifdef HAVE_ELEMENTARY_X
2183    _elm_win_xwindow_get(win);
2184    if (win->xwin)
2185      ecore_x_e_illume_quickpanel_priority_major_set(win->xwin, priority);
2186 #endif
2187 }
2188
2189 EAPI int
2190 elm_win_quickpanel_priority_major_get(const Evas_Object *obj)
2191 {
2192    Elm_Win *win;
2193    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2194    win = elm_widget_data_get(obj);
2195    if (!win) return -1;
2196 #ifdef HAVE_ELEMENTARY_X
2197    _elm_win_xwindow_get(win);
2198    if (win->xwin)
2199      return ecore_x_e_illume_quickpanel_priority_major_get(win->xwin);
2200 #endif
2201    return -1;
2202 }
2203
2204 EAPI void
2205 elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority)
2206 {
2207    Elm_Win *win;
2208    ELM_CHECK_WIDTYPE(obj, widtype);
2209    win = elm_widget_data_get(obj);
2210    if (!win) return;
2211 #ifdef HAVE_ELEMENTARY_X
2212    _elm_win_xwindow_get(win);
2213    if (win->xwin)
2214      ecore_x_e_illume_quickpanel_priority_minor_set(win->xwin, priority);
2215 #endif
2216 }
2217
2218 EAPI int
2219 elm_win_quickpanel_priority_minor_get(const Evas_Object *obj)
2220 {
2221    Elm_Win *win;
2222    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2223    win = elm_widget_data_get(obj);
2224    if (!win) return -1;
2225 #ifdef HAVE_ELEMENTARY_X
2226    _elm_win_xwindow_get(win);
2227    if (win->xwin)
2228      return ecore_x_e_illume_quickpanel_priority_minor_get(win->xwin);
2229 #endif
2230    return -1;
2231 }
2232
2233 EAPI void
2234 elm_win_quickpanel_zone_set(Evas_Object *obj, int zone)
2235 {
2236    Elm_Win *win;
2237    ELM_CHECK_WIDTYPE(obj, widtype);
2238    win = elm_widget_data_get(obj);
2239    if (!win) return;
2240 #ifdef HAVE_ELEMENTARY_X
2241    _elm_win_xwindow_get(win);
2242    if (win->xwin)
2243      ecore_x_e_illume_quickpanel_zone_set(win->xwin, zone);
2244 #endif
2245 }
2246
2247 EAPI int
2248 elm_win_quickpanel_zone_get(const Evas_Object *obj)
2249 {
2250    Elm_Win *win;
2251    ELM_CHECK_WIDTYPE(obj, widtype) 0;
2252    win = elm_widget_data_get(obj);
2253    if (!win) return 0;
2254 #ifdef HAVE_ELEMENTARY_X
2255    _elm_win_xwindow_get(win);
2256    if (win->xwin)
2257      return ecore_x_e_illume_quickpanel_zone_get(win->xwin);
2258 #endif
2259    return 0;
2260 }
2261
2262 EAPI void
2263 elm_win_prop_focus_skip_set(Evas_Object *obj, Eina_Bool skip)
2264 {
2265    Elm_Win *win;
2266    ELM_CHECK_WIDTYPE(obj, widtype);
2267    win = elm_widget_data_get(obj);
2268    if (!win) return;
2269 #ifdef HAVE_ELEMENTARY_X
2270    _elm_win_xwindow_get(win);
2271    if (skip)
2272      {
2273         if (win->xwin)
2274           {
2275              Ecore_X_Window_State states[2];
2276
2277              ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
2278              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
2279              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
2280              ecore_x_netwm_window_state_set(win->xwin, states, 2);
2281           }
2282      }
2283 #endif
2284 }
2285
2286 EAPI void
2287 elm_win_illume_command_send(Evas_Object *obj, Elm_Illume_Command command, void *params __UNUSED__)
2288 {
2289    Elm_Win *win;
2290    ELM_CHECK_WIDTYPE(obj, widtype);
2291    win = elm_widget_data_get(obj);
2292    if (!win) return;
2293 #ifdef HAVE_ELEMENTARY_X
2294    _elm_win_xwindow_get(win);
2295    if (win->xwin)
2296      {
2297         switch (command)
2298           {
2299            case ELM_ILLUME_COMMAND_FOCUS_BACK:
2300               ecore_x_e_illume_focus_back_send(win->xwin);
2301               break;
2302            case ELM_ILLUME_COMMAND_FOCUS_FORWARD:
2303               ecore_x_e_illume_focus_forward_send(win->xwin);
2304               break;
2305            case ELM_ILLUME_COMMAND_FOCUS_HOME:
2306               ecore_x_e_illume_focus_home_send(win->xwin);
2307               break;
2308            case ELM_ILLUME_COMMAND_CLOSE:
2309               ecore_x_e_illume_close_send(win->xwin);
2310               break;
2311            default:
2312               break;
2313           }
2314      }
2315 #endif
2316 }
2317
2318 EAPI Evas_Object *
2319 elm_win_inlined_image_object_get(Evas_Object *obj)
2320 {
2321    Elm_Win *win;
2322    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2323    win = elm_widget_data_get(obj);
2324    if (!win) return NULL;
2325    return win->img_obj;
2326 }
2327
2328 EAPI void
2329 elm_win_focus_highlight_enabled_set(Evas_Object *obj, Eina_Bool enabled)
2330 {
2331    Elm_Win *win;
2332
2333    ELM_CHECK_WIDTYPE(obj, widtype);
2334
2335    win = elm_widget_data_get(obj);
2336    enabled = !!enabled;
2337    if (win->focus_highlight.enabled == enabled)
2338      return;
2339
2340    win->focus_highlight.enabled = enabled;
2341
2342    if (win->focus_highlight.enabled)
2343      _elm_win_focus_highlight_init(win);
2344    else
2345      _elm_win_focus_highlight_shutdown(win);
2346 }
2347
2348 EAPI Eina_Bool
2349 elm_win_focus_highlight_enabled_get(const Evas_Object *obj)
2350 {
2351    Elm_Win *win;
2352
2353    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2354
2355    win = elm_widget_data_get(obj);
2356    return win->focus_highlight.enabled;
2357 }
2358
2359 EAPI void
2360 elm_win_focus_highlight_style_set(Evas_Object *obj, const char *style)
2361 {
2362    Elm_Win *win;
2363
2364    ELM_CHECK_WIDTYPE(obj, widtype);
2365
2366    win = elm_widget_data_get(obj);
2367    eina_stringshare_replace(&win->focus_highlight.style, style);
2368    win->focus_highlight.changed_theme = EINA_TRUE;
2369    _elm_win_focus_highlight_reconfigure_job_start(win);
2370 }
2371
2372 EAPI const char *
2373 elm_win_focus_highlight_style_get(const Evas_Object *obj)
2374 {
2375    Elm_Win *win;
2376
2377    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2378
2379    win = elm_widget_data_get(obj);
2380    return win->focus_highlight.style;
2381 }
2382
2383 typedef struct _Widget_Data Widget_Data;
2384
2385 struct _Widget_Data
2386 {
2387    Evas_Object *frm;
2388    Evas_Object *content;
2389 };
2390
2391 static void _del_hook(Evas_Object *obj);
2392 static void _theme_hook(Evas_Object *obj);
2393 static void _sizing_eval(Evas_Object *obj);
2394 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
2395 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
2396
2397 static const char *widtype2 = NULL;
2398
2399 static void
2400 _del_hook(Evas_Object *obj)
2401 {
2402    Widget_Data *wd = elm_widget_data_get(obj);
2403    if (!wd) return;
2404    free(wd);
2405 }
2406
2407 static void
2408 _theme_hook(Evas_Object *obj)
2409 {
2410    Widget_Data *wd = elm_widget_data_get(obj);
2411    _elm_theme_object_set(obj, wd->frm, "win", "inwin", elm_widget_style_get(obj));
2412    if (wd->content)
2413      edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
2414    _sizing_eval(obj);
2415 }
2416
2417 static Eina_Bool
2418 _elm_inwin_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
2419 {
2420    Widget_Data *wd = elm_widget_data_get(obj);
2421
2422    if (!wd)
2423      return EINA_FALSE;
2424
2425    /* Try Focus cycle in subitem */
2426    if (wd->content)
2427      {
2428         elm_widget_focus_next_get(wd->content, dir, next);
2429         if (*next)
2430           return EINA_TRUE;
2431      }
2432
2433    *next = (Evas_Object *)obj;
2434    return EINA_FALSE;
2435 }
2436
2437 static void
2438 _sizing_eval(Evas_Object *obj)
2439 {
2440    Widget_Data *wd = elm_widget_data_get(obj);
2441    Evas_Coord minw = -1, minh = -1;
2442
2443    evas_object_size_hint_min_get(wd->content, &minw, &minh);
2444    edje_object_size_min_calc(wd->frm, &minw, &minh);
2445    evas_object_size_hint_min_set(obj, minw, minh);
2446    evas_object_size_hint_max_set(obj, -1, -1);
2447 }
2448
2449 static void
2450 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2451 {
2452    _sizing_eval(data);
2453 }
2454
2455 static void
2456 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
2457 {
2458    Widget_Data *wd = elm_widget_data_get(obj);
2459    Evas_Object *sub = event_info;
2460    if (sub == wd->content)
2461      {
2462         evas_object_event_callback_del_full
2463            (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
2464         wd->content = NULL;
2465         _sizing_eval(obj);
2466      }
2467 }
2468
2469 EAPI Evas_Object *
2470 elm_win_inwin_add(Evas_Object *obj)
2471 {
2472    Evas_Object *obj2;
2473    Widget_Data *wd;
2474    Elm_Win *win;
2475
2476    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2477    win = elm_widget_data_get(obj);
2478    if (!win) return NULL;
2479    wd = ELM_NEW(Widget_Data);
2480    obj2 = elm_widget_add(win->evas);
2481    elm_widget_type_set(obj2, "inwin");
2482    ELM_SET_WIDTYPE(widtype2, "inwin");
2483    elm_widget_sub_object_add(obj, obj2);
2484    evas_object_size_hint_weight_set(obj2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2485    evas_object_size_hint_align_set(obj2, EVAS_HINT_FILL, EVAS_HINT_FILL);
2486    elm_win_resize_object_add(obj, obj2);
2487
2488    elm_widget_data_set(obj2, wd);
2489    elm_widget_del_hook_set(obj2, _del_hook);
2490    elm_widget_theme_hook_set(obj2, _theme_hook);
2491    elm_widget_focus_next_hook_set(obj2, _elm_inwin_focus_next_hook);
2492    elm_widget_can_focus_set(obj2, EINA_TRUE);
2493    elm_widget_highlight_ignore_set(obj2, EINA_TRUE);
2494
2495    wd->frm = edje_object_add(win->evas);
2496    _elm_theme_object_set(obj, wd->frm, "win", "inwin", "default");
2497    elm_widget_resize_object_set(obj2, wd->frm);
2498
2499    evas_object_smart_callback_add(obj2, "sub-object-del", _sub_del, obj2);
2500
2501    _sizing_eval(obj2);
2502    return obj2;
2503 }
2504
2505 EAPI void
2506 elm_win_inwin_activate(Evas_Object *obj)
2507 {
2508    ELM_CHECK_WIDTYPE(obj, widtype2);
2509    Widget_Data *wd = elm_widget_data_get(obj);
2510    if (!wd) return;
2511    evas_object_raise(obj);
2512    evas_object_show(obj);
2513    edje_object_signal_emit(wd->frm, "elm,action,show", "elm");
2514    elm_object_focus_set(obj, EINA_TRUE);
2515 }
2516
2517 EAPI void
2518 elm_win_inwin_content_set(Evas_Object *obj, Evas_Object *content)
2519 {
2520    ELM_CHECK_WIDTYPE(obj, widtype2);
2521    Widget_Data *wd = elm_widget_data_get(obj);
2522    if (!wd) return;
2523    if (wd->content == content) return;
2524    if (wd->content) evas_object_del(wd->content);
2525    wd->content = content;
2526    if (content)
2527      {
2528         elm_widget_sub_object_add(obj, content);
2529         evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2530                                        _changed_size_hints, obj);
2531         edje_object_part_swallow(wd->frm, "elm.swallow.content", content);
2532      }
2533    _sizing_eval(obj);
2534 }
2535
2536 EAPI Evas_Object *
2537 elm_win_inwin_content_get(const Evas_Object *obj)
2538 {
2539    ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
2540    Widget_Data *wd = elm_widget_data_get(obj);
2541    if (!wd) return NULL;
2542    return wd->content;
2543 }
2544
2545 EAPI Evas_Object *
2546 elm_win_inwin_content_unset(Evas_Object *obj)
2547 {
2548    ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
2549    Widget_Data *wd = elm_widget_data_get(obj);
2550    if (!wd) return NULL;
2551    if (!wd->content) return NULL;
2552    Evas_Object *content = wd->content;
2553    elm_widget_sub_object_del(obj, wd->content);
2554    edje_object_part_unswallow(wd->frm, wd->content);
2555    wd->content = NULL;
2556    return content;
2557 }
2558
2559 /* windowing spcific calls - shall we do this differently? */
2560
2561 static Ecore_X_Window
2562 _elm_ee_win_get(const Evas_Object *obj)
2563 {
2564    if (!obj) return 0;
2565 #ifdef HAVE_ELEMENTARY_X
2566    Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
2567    if (ee) return (Ecore_X_Window)ecore_evas_window_get(ee);
2568 #endif
2569    return 0;
2570 }
2571
2572 /**
2573  * Get the Ecore_X_Window of an Evas_Object
2574  *
2575  * @param obj The object
2576  *
2577  * @return The Ecore_X_Window of @p obj
2578  *
2579  * @ingroup Win
2580  */
2581 EAPI Ecore_X_Window
2582 elm_win_xwindow_get(const Evas_Object *obj)
2583 {
2584    Elm_Win *win;
2585    const char *type;
2586
2587    if (!obj) return 0;
2588    type = elm_widget_type_get(obj);
2589    if (!type) return 0;
2590    if (type != widtype) return _elm_ee_win_get(obj);
2591 #ifdef HAVE_ELEMENTARY_X
2592    win = elm_widget_data_get(obj);
2593    if (!win) return 0;
2594    if (win->xwin) return win->xwin;
2595    if (win->parent) return elm_win_xwindow_get(win->parent);
2596 #endif
2597    return 0;
2598    win = NULL;
2599 }