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