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