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