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