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