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