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