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