elementary: avoid segv and don't duplicate call.
[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         int hot_x, hot_y;
42      } pointer;
43    struct {
44       Evas_Object *top;
45
46       struct {
47          Evas_Object *target;
48          Eina_Bool visible : 1;
49          Eina_Bool handled : 1;
50       } cur, prev;
51
52       const char *style;
53       Ecore_Job *reconf_job;
54
55       Eina_Bool enabled : 1;
56       Eina_Bool changed_theme : 1;
57       Eina_Bool top_animate : 1;
58       Eina_Bool geometry_changed : 1;
59    } focus_highlight;
60 };
61
62 static const char *widtype = NULL;
63 static void _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
64 static void _elm_win_obj_callback_img_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
65 static void _elm_win_obj_callback_parent_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
66 static void _elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y);
67 static void _elm_win_obj_intercept_show(void *data, Evas_Object *obj);
68 static void _elm_win_move(Ecore_Evas *ee);
69 static void _elm_win_resize(Ecore_Evas *ee);
70 static void _elm_win_delete_request(Ecore_Evas *ee);
71 static void _elm_win_resize_job(void *data);
72 #ifdef HAVE_ELEMENTARY_X
73 static void _elm_win_xwin_update(Elm_Win *win);
74 #endif
75 static void _elm_win_eval_subobjs(Evas_Object *obj);
76 static void _elm_win_subobj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
77 static void _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
78 static void _elm_win_focus_highlight_init(Elm_Win *win);
79 static void _elm_win_focus_highlight_shutdown(Elm_Win *win);
80 static void _elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible);
81 static void _elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win);
82 static void _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win);
83 static void _elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission, const char *source);
84 static void _elm_win_focus_highlight_reconfigure(Elm_Win *win);
85
86 static void _elm_win_frame_add(Elm_Win *win, const char *style);
87 static void _elm_win_frame_cb_move_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__);
88 static void _elm_win_frame_cb_resize_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source);
89 static void _elm_win_frame_cb_minimize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__);
90 static void _elm_win_frame_cb_maximize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__);
91 static void _elm_win_frame_cb_close(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__);
92
93 static void _elm_win_pointer_add(Elm_Win *win, const char *style);
94
95 static const char SIG_DELETE_REQUEST[] = "delete,request";
96 static const char SIG_FOCUS_OUT[] = "focus,out";
97 static const char SIG_FOCUS_IN[] = "focus,in";
98 static const char SIG_MOVED[] = "moved";
99 static const char SIG_THEME_CHANGED[] = "theme,changed";
100
101 static const Evas_Smart_Cb_Description _signals[] = {
102    {SIG_DELETE_REQUEST, ""},
103    {SIG_FOCUS_OUT, ""},
104    {SIG_FOCUS_IN, ""},
105    {SIG_MOVED, ""},
106    {NULL, NULL}
107 };
108
109
110
111 Eina_List *_elm_win_list = NULL;
112 int _elm_win_deferred_free = 0;
113
114 // exmaple shot spec (wait 0.1 sec then save as my-window.png):
115 // ELM_ENGINE="shot:delay=0.1:file=my-window.png"
116
117 static double
118 _shot_delay_get(Elm_Win *win)
119 {
120    char *p, *pd;
121    char *d = strdup(win->shot.info);
122
123    if (!d) return 0.5;
124    for (p = (char *)win->shot.info; *p; p++)
125      {
126         if (!strncmp(p, "delay=", 6))
127           {
128              double v;
129
130              for (pd = d, p += 6; (*p) && (*p != ':'); p++, pd++)
131                {
132                   *pd = *p;
133                }
134              *pd = 0;
135              v = atof(d);
136              free(d);
137              return v;
138           }
139      }
140    free(d);
141    return 0.5;
142 }
143
144 static char *
145 _shot_file_get(Elm_Win *win)
146 {
147    char *p;
148    char *tmp = strdup(win->shot.info);
149    char *repname = NULL;
150
151    if (!tmp) return NULL;
152
153    for (p = (char *)win->shot.info; *p; p++)
154      {
155         if (!strncmp(p, "file=", 5))
156           {
157              strcpy(tmp, p + 5);
158              if (!win->shot.repeat_count) return tmp;
159              else
160                {
161                   char *dotptr = strrchr(tmp, '.');
162                   if (dotptr)
163                     {
164                        size_t size = sizeof(char)*(strlen(tmp) + 16);
165                        repname = malloc(size);
166                        strncpy(repname, tmp, dotptr - tmp);
167                        snprintf(repname + (dotptr - tmp), size - (dotptr - tmp), "%03i",
168                                win->shot.shot_counter + 1);
169                        strcat(repname, dotptr);
170                        free(tmp);
171                        return repname;
172                     }
173                }
174           }
175      }
176    free(tmp);
177    if (!win->shot.repeat_count) return strdup("out.png");
178
179    repname = malloc(sizeof(char) * 24);
180    snprintf(repname, sizeof(char) * 24, "out%03i.png", win->shot.shot_counter + 1);
181    return repname;
182 }
183
184 static int
185 _shot_repeat_count_get(Elm_Win *win)
186 {
187    char *p, *pd;
188    char *d = strdup(win->shot.info);
189
190    if (!d) return 0;
191    for (p = (char *)win->shot.info; *p; p++)
192      {
193         if (!strncmp(p, "repeat=", 7))
194           {
195              int v;
196
197              for (pd = d, p += 7; (*p) && (*p != ':'); p++, pd++)
198                {
199                   *pd = *p;
200                }
201              *pd = 0;
202              v = atoi(d);
203              if (v < 0) v = 0;
204              if (v > 1000) v = 999;
205              free(d);
206              return v;
207           }
208      }
209    free(d);
210    return 0;
211 }
212
213 static char *
214 _shot_key_get(Elm_Win *win __UNUSED__)
215 {
216    return NULL;
217 }
218
219 static char *
220 _shot_flags_get(Elm_Win *win __UNUSED__)
221 {
222    return NULL;
223 }
224
225 static void
226 _shot_do(Elm_Win *win)
227 {
228    Ecore_Evas *ee;
229    Evas_Object *o;
230    unsigned int *pixels;
231    int w, h;
232    char *file, *key, *flags;
233
234    ecore_evas_manual_render(win->ee);
235    pixels = (void *)ecore_evas_buffer_pixels_get(win->ee);
236    if (!pixels) return;
237    ecore_evas_geometry_get(win->ee, NULL, NULL, &w, &h);
238    if ((w < 1) || (h < 1)) return;
239    file = _shot_file_get(win);
240    if (!file) return;
241    key = _shot_key_get(win);
242    flags = _shot_flags_get(win);
243    ee = ecore_evas_buffer_new(1, 1);
244    o = evas_object_image_add(ecore_evas_get(ee));
245    evas_object_image_alpha_set(o, ecore_evas_alpha_get(win->ee));
246    evas_object_image_size_set(o, w, h);
247    evas_object_image_data_set(o, pixels);
248    if (!evas_object_image_save(o, file, key, flags))
249      {
250         ERR("Cannot save window to '%s' (key '%s', flags '%s')",
251             file, key, flags);
252      }
253    free(file);
254    if (key) free(key);
255    if (flags) free(flags);
256    ecore_evas_free(ee);
257    if (win->shot.repeat_count) win->shot.shot_counter++;
258 }
259
260 static Eina_Bool
261 _shot_delay(void *data)
262 {
263    Elm_Win *win = data;
264    _shot_do(win);
265    if (win->shot.repeat_count)
266      {
267         int remainshot = (win->shot.repeat_count - win->shot.shot_counter);
268         if (remainshot > 0) return EINA_TRUE;
269      }
270    win->shot.timer = NULL;
271    elm_exit();
272    return EINA_FALSE;
273 }
274
275 static void
276 _shot_init(Elm_Win *win)
277 {
278    if (!win->shot.info) return;
279    win->shot.repeat_count = _shot_repeat_count_get(win);
280    win->shot.shot_counter = 0;
281 }
282
283 static void
284 _shot_handle(Elm_Win *win)
285 {
286    if (!win->shot.info) return;
287    win->shot.timer = ecore_timer_add(_shot_delay_get(win), _shot_delay, win);
288 }
289
290 static void
291 _elm_win_move(Ecore_Evas *ee)
292 {
293    Evas_Object *obj = ecore_evas_object_associate_get(ee);
294    Elm_Win *win;
295    int x, y;
296
297    if (!obj) return;
298    win = elm_widget_data_get(obj);
299    if (!win) return;
300    ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
301    win->screen.x = x;
302    win->screen.y = y;
303    evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
304 }
305
306 static void
307 _elm_win_resize(Ecore_Evas *ee)
308 {
309    Evas_Object *obj = ecore_evas_object_associate_get(ee);
310    Elm_Win *win;
311
312    if (!obj) return;
313    win = elm_widget_data_get(obj);
314    if (!win) return;
315    if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job);
316    win->deferred_resize_job = ecore_job_add(_elm_win_resize_job, win);
317 }
318
319 static void 
320 _elm_win_mouse_in(Ecore_Evas *ee)
321 {
322    Evas_Object *obj;
323    Elm_Win *win;
324
325    if (!(obj = ecore_evas_object_associate_get(ee))) return;
326    if (!(win = elm_widget_data_get(obj))) return;
327    if (win->resizing) win->resizing = EINA_FALSE;
328 }
329
330 static void
331 _elm_win_focus_in(Ecore_Evas *ee)
332 {
333    Evas_Object *obj = ecore_evas_object_associate_get(ee);
334    Elm_Win *win;
335
336    if (!obj) return;
337    win = elm_widget_data_get(obj);
338    if (!win) return;
339    _elm_widget_top_win_focused_set(win->win_obj, EINA_TRUE);
340    if (!elm_widget_focus_order_get(obj))
341      {
342         elm_widget_focus_steal(win->win_obj);
343         win->show_count++;
344      }
345    else
346      elm_widget_focus_restore(win->win_obj);
347    evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_IN, NULL);
348    win->focus_highlight.cur.visible = EINA_TRUE;
349    _elm_win_focus_highlight_reconfigure_job_start(win);
350    if (win->frame_obj)
351      {
352         edje_object_signal_emit(win->frame_obj, "elm,action,focus", "elm");
353      }
354    else if (win->img_obj)
355      {
356         /* do nothing */
357      }
358 }
359
360 static void
361 _elm_win_focus_out(Ecore_Evas *ee)
362 {
363    Evas_Object *obj = ecore_evas_object_associate_get(ee);
364    Elm_Win *win;
365
366    if (!obj) return;
367    win = elm_widget_data_get(obj);
368    if (!win) return;
369    elm_object_focus_set(win->win_obj, EINA_FALSE);
370    _elm_widget_top_win_focused_set(win->win_obj, EINA_FALSE);
371    evas_object_smart_callback_call(win->win_obj, SIG_FOCUS_OUT, NULL);
372    win->focus_highlight.cur.visible = EINA_FALSE;
373    _elm_win_focus_highlight_reconfigure_job_start(win);
374    if (win->frame_obj)
375      {
376         edje_object_signal_emit(win->frame_obj, "elm,action,unfocus", "elm");
377      }
378    else if (win->img_obj)
379      {
380         /* do nothing */
381      }
382 }
383
384 static Eina_Bool
385 _elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
386 {
387    Elm_Win *wd = elm_widget_data_get(obj);
388    const Eina_List *items;
389    void *(*list_data_get) (const Eina_List *list);
390
391    if (!wd)
392      return EINA_FALSE;
393
394    /* Focus chain */
395    if (wd->subobjs)
396      {
397         if (!(items = elm_widget_focus_custom_chain_get(obj)))
398           {
399              items = wd->subobjs;
400              if (!items)
401                return EINA_FALSE;
402           }
403         list_data_get = eina_list_data_get;
404
405         elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
406
407         if (*next)
408           return EINA_TRUE;
409      }
410
411    *next = (Evas_Object *)obj;
412    return EINA_FALSE;
413 }
414
415 static void
416 _elm_win_on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
417 {
418    Elm_Win *win = elm_widget_data_get(obj);
419    if (!win) return;
420
421    if (win->img_obj)
422       evas_object_focus_set(win->img_obj, elm_widget_focus_get(obj));
423    else
424       evas_object_focus_set(obj, elm_widget_focus_get(obj));
425 }
426
427 static Eina_Bool
428 _elm_win_event_cb(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
429 {
430    if (type == EVAS_CALLBACK_KEY_DOWN)
431      {
432         Evas_Event_Key_Down *ev = event_info;
433         if (!strcmp(ev->keyname, "Tab"))
434           {
435              if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
436                elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS);
437              else
438                elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
439              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
440              return EINA_TRUE;
441           }
442         else if ((!strcmp(ev->keyname, "Left")) ||
443                  (!strcmp(ev->keyname, "KP_Left")))
444           {
445              //TODO : woohyun jung
446           }
447         else if ((!strcmp(ev->keyname, "Right")) ||
448                  (!strcmp(ev->keyname, "KP_Right")))
449           {
450              //TODO : woohyun jung
451           }
452         else if ((!strcmp(ev->keyname, "Up")) ||
453                  (!strcmp(ev->keyname, "KP_Up")))
454           {
455              //TODO : woohyun jung
456           }
457         else if ((!strcmp(ev->keyname, "Down")) ||
458                  (!strcmp(ev->keyname, "KP_Down")))
459           {
460              //TODO : woohyun jung
461           }
462      }
463
464    return EINA_FALSE;
465 }
466
467 static void
468 _deferred_ecore_evas_free(void *data)
469 {
470    ecore_evas_free(data);
471    _elm_win_deferred_free--;
472 }
473
474 static void
475 _elm_win_obj_callback_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
476 {
477    Elm_Win *win = data;
478
479    if (!win->show_count) win->show_count++;
480    if (win->shot.info) _shot_handle(win);
481 }
482
483 static void
484 _elm_win_obj_callback_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
485 {
486    Elm_Win *win = data;
487
488    if (win->frame_obj)
489      {
490         evas_object_hide(win->frame_obj);
491      }
492    else if (win->img_obj)
493      {
494         evas_object_hide(win->img_obj);
495      }
496    if (win->pointer.obj)
497      {
498         evas_object_hide(win->pointer.obj);
499         ecore_evas_hide(win->pointer.ee);
500      }
501 }
502
503 static void
504 _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info __UNUSED__)
505 {
506    Elm_Win *win = data;
507    Evas_Object *child;
508
509    if (win->parent)
510      {
511         evas_object_event_callback_del_full(win->parent, EVAS_CALLBACK_DEL,
512                                             _elm_win_obj_callback_parent_del, win);
513         win->parent = NULL;
514      }
515    if (win->autodel_clear) *(win->autodel_clear) = -1;
516    _elm_win_list = eina_list_remove(_elm_win_list, win->win_obj);
517    while (win->subobjs) elm_win_resize_object_del(obj, win->subobjs->data);
518    if (win->ee)
519      {
520         ecore_evas_callback_delete_request_set(win->ee, NULL);
521         ecore_evas_callback_resize_set(win->ee, NULL);
522      }
523    if (win->deferred_resize_job) ecore_job_del(win->deferred_resize_job);
524    if (win->deferred_child_eval_job) ecore_job_del(win->deferred_child_eval_job);
525    if (win->shot.info) eina_stringshare_del(win->shot.info);
526    if (win->shot.timer) ecore_timer_del(win->shot.timer);
527    evas_object_event_callback_del_full(win->win_obj, EVAS_CALLBACK_DEL,
528                                        _elm_win_obj_callback_del, win);
529    while (((child = evas_object_bottom_get(win->evas))) &&
530           (child != obj))
531      {
532         evas_object_del(child);
533      }
534    while (((child = evas_object_top_get(win->evas))) &&
535           (child != obj))
536      {
537         evas_object_del(child);
538      }
539 #ifdef HAVE_ELEMENTARY_X
540    if (win->client_message_handler)
541      ecore_event_handler_del(win->client_message_handler);
542 #endif
543    // FIXME: Why are we flushing edje on every window destroy ??
544    //   edje_file_cache_flush();
545    //   edje_collection_cache_flush();
546    //   evas_image_cache_flush(win->evas);
547    //   evas_font_cache_flush(win->evas);
548    // FIXME: we are in the del handler for the object and delete the canvas
549    // that lives under it from the handler... nasty. deferring doesn't help either
550
551    if (win->img_obj)
552      {
553         win->img_obj = NULL;
554      }
555    else
556      {
557         if (win->ee)
558           {
559              ecore_job_add(_deferred_ecore_evas_free, win->ee);
560              _elm_win_deferred_free++;
561           }
562      }
563
564    _elm_win_focus_highlight_shutdown(win);
565    eina_stringshare_del(win->focus_highlight.style);
566
567    free(win);
568
569    if ((!_elm_win_list) &&
570        (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
571      {
572         edje_file_cache_flush();
573         edje_collection_cache_flush();
574         evas_image_cache_flush(e);
575         evas_font_cache_flush(e);
576         elm_exit();
577      }
578 }
579
580 static void
581 _elm_win_obj_callback_img_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
582 {
583    Elm_Win *win = data;
584    if (!win->img_obj) return;
585    evas_object_event_callback_del_full
586       (win->img_obj, EVAS_CALLBACK_DEL, _elm_win_obj_callback_img_obj_del, win);
587    evas_object_del(win->img_obj);
588 }
589
590 static void
591 _elm_win_obj_callback_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
592 {
593    Elm_Win *win = data;
594    if (obj == win->parent) win->parent = NULL;
595 }
596
597 static void
598 _elm_win_obj_intercept_move(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y)
599 {
600    Elm_Win *win = data;
601
602    if (win->img_obj)
603      {
604         if ((x != win->screen.x) || (y != win->screen.y))
605           {
606              win->screen.x = x;
607              win->screen.y = y;
608              evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
609           }
610      }
611    else
612      {
613         evas_object_move(obj, x, y);
614      }
615 }
616
617 static void
618 _elm_win_obj_intercept_show(void *data, Evas_Object *obj)
619 {
620    Elm_Win *win = data;
621    // this is called to make sure all smart containers have calculated their
622    // sizes BEFORE we show the window to make sure it initially appears at
623    // our desired size (ie min size is known first)
624    evas_smart_objects_calculate(evas_object_evas_get(obj));
625    if (win->frame_obj)
626      {
627         evas_object_show(win->frame_obj);
628      }
629    else if (win->img_obj)
630      {
631         evas_object_show(win->img_obj);
632      }
633    if (win->pointer.obj)
634      {
635         ecore_evas_show(win->pointer.ee);
636         evas_object_show(win->pointer.obj);
637         ecore_evas_wayland_pointer_set(win->pointer.ee, 10, 10);
638      }
639    evas_object_show(obj);
640 }
641
642 static void
643 _elm_win_obj_callback_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
644 {
645    Elm_Win *win = data;
646
647    if (ecore_evas_override_get(win->ee))
648      {
649         Evas_Coord x, y;
650
651         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
652         win->screen.x = x;
653         win->screen.y = y;
654         evas_object_smart_callback_call(win->win_obj, SIG_MOVED, NULL);
655      }
656    if (win->frame_obj)
657      {
658         Evas_Coord x, y;
659
660         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
661         win->screen.x = x;
662         win->screen.y = y;
663      }
664    else if (win->img_obj)
665      {
666         Evas_Coord x, y;
667
668         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
669         win->screen.x = x;
670         win->screen.y = y;
671 //        evas_object_move(win->img_obj, x, y);
672      }
673 }
674
675 static void
676 _elm_win_obj_callback_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
677 {
678    Elm_Win *win = data;
679
680    if (win->frame_obj)
681      {
682      }
683    else if (win->img_obj)
684      {
685         Evas_Coord w = 1, h = 1;
686
687         evas_object_geometry_get(obj, NULL, NULL, &w, &h);
688         if (win->constrain)
689           {
690              int sw, sh;
691              ecore_evas_screen_geometry_get(win->ee, NULL, NULL, &sw, &sh);
692              w = MIN(w, sw);
693              h = MIN(h, sh);
694           }
695         if (w < 1) w = 1;
696         if (h < 1) h = 1;
697         evas_object_image_size_set(win->img_obj, w, h);
698      }
699 }
700
701 static void
702 _elm_win_delete_request(Ecore_Evas *ee)
703 {
704    Evas_Object *obj = ecore_evas_object_associate_get(ee);
705    Elm_Win *win;
706    if (strcmp(elm_widget_type_get(obj), "win")) return;
707
708    win = elm_widget_data_get(obj);
709    if (!win) return;
710    int autodel = win->autodel;
711    win->autodel_clear = &autodel;
712    evas_object_ref(win->win_obj);
713    evas_object_smart_callback_call(win->win_obj, SIG_DELETE_REQUEST, NULL);
714    // FIXME: if above callback deletes - then the below will be invalid
715    if (autodel) evas_object_del(win->win_obj);
716    else win->autodel_clear = NULL;
717    evas_object_unref(win->win_obj);
718 }
719
720 static void
721 _elm_win_resize_job(void *data)
722 {
723    Elm_Win *win = data;
724    const Eina_List *l;
725    Evas_Object *obj;
726    int w, h;
727
728    win->deferred_resize_job = NULL;
729    ecore_evas_request_geometry_get(win->ee, NULL, NULL, &w, &h);
730    if (win->constrain)
731      {
732         int sw, sh;
733         ecore_evas_screen_geometry_get(win->ee, NULL, NULL, &sw, &sh);
734         w = MIN(w, sw);
735         h = MIN(h, sh);
736      }
737    if (win->frame_obj)
738      {
739         evas_object_resize(win->frame_obj, w, h);
740      }
741    else if (win->img_obj)
742      {
743      }
744    evas_object_resize(win->win_obj, w, h);
745    EINA_LIST_FOREACH(win->subobjs, l, obj)
746      {
747         evas_object_move(obj, 0, 0);
748         evas_object_resize(obj, w, h);
749      }
750 }
751
752 #ifdef HAVE_ELEMENTARY_X
753 static void
754 _elm_win_xwindow_get(Elm_Win *win)
755 {
756    win->xwin = 0;
757
758 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
759    if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
760      {
761        if (win->ee) win->xwin = ecore_evas_software_x11_window_get(win->ee);
762      }
763    else if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
764             ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
765             ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE) ||
766             ENGINE_COMPARE(ELM_SOFTWARE_SDL) ||
767             ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) ||
768             ENGINE_COMPARE(ELM_OPENGL_SDL) ||
769             ENGINE_COMPARE(ELM_OPENGL_COCOA))
770      {
771      }
772    else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
773      {
774         if (win->ee) win->xwin = ecore_evas_software_x11_16_window_get(win->ee);
775      }
776    else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
777      {
778         if (win->ee) win->xwin = ecore_evas_software_x11_8_window_get(win->ee);
779      }
780 /* killed
781    else if (ENGINE_COMPARE(ELM_XRENDER_X11))
782      {
783         if (win->ee) win->xwin = ecore_evas_xrender_x11_window_get(win->ee);
784      }
785  */
786    else if (ENGINE_COMPARE(ELM_OPENGL_X11))
787      {
788         if (win->ee) win->xwin = ecore_evas_gl_x11_window_get(win->ee);
789      }
790    else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
791      {
792         if (win->ee) win->xwin = (long)ecore_evas_win32_window_get(win->ee);
793      }
794 #undef ENGINE_COMPARE
795 }
796 #endif
797
798 #ifdef HAVE_ELEMENTARY_X
799 static void
800 _elm_win_xwin_update(Elm_Win *win)
801 {
802    _elm_win_xwindow_get(win);
803    if (win->parent)
804      {
805         Elm_Win *win2;
806
807         win2 = elm_widget_data_get(win->parent);
808         if (win2)
809           {
810              if (win->xwin)
811                ecore_x_icccm_transient_for_set(win->xwin, win2->xwin);
812           }
813      }
814
815    if (!win->xwin) return; /* nothing more to do */
816
817    switch (win->type)
818      {
819       case ELM_WIN_BASIC:
820          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NORMAL);
821          break;
822       case ELM_WIN_DIALOG_BASIC:
823          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DIALOG);
824          break;
825       case ELM_WIN_DESKTOP:
826          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DESKTOP);
827          break;
828       case ELM_WIN_DOCK:
829          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DOCK);
830          break;
831       case ELM_WIN_TOOLBAR:
832          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLBAR);
833          break;
834       case ELM_WIN_MENU:
835          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_MENU);
836          break;
837       case ELM_WIN_UTILITY:
838          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_UTILITY);
839          break;
840       case ELM_WIN_SPLASH:
841          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_SPLASH);
842          break;
843       case ELM_WIN_DROPDOWN_MENU:
844          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DROPDOWN_MENU);
845          break;
846       case ELM_WIN_POPUP_MENU:
847          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_POPUP_MENU);
848          break;
849       case ELM_WIN_TOOLTIP:
850          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_TOOLTIP);
851          break;
852       case ELM_WIN_NOTIFICATION:
853          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
854          break;
855       case ELM_WIN_COMBO:
856          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_COMBO);
857          break;
858       case ELM_WIN_DND:
859          ecore_x_netwm_window_type_set(win->xwin, ECORE_X_WINDOW_TYPE_DND);
860          break;
861       default:
862          break;
863      }
864    ecore_x_e_virtual_keyboard_state_set
865       (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
866 }
867 #endif
868
869 static void
870 _elm_win_eval_subobjs(Evas_Object *obj)
871 {
872    const Eina_List *l;
873    const Evas_Object *child;
874
875    Elm_Win *win = elm_widget_data_get(obj);
876    Evas_Coord w, h, minw = -1, minh = -1, maxw = -1, maxh = -1;
877    int xx = 1, xy = 1;
878    double wx, wy;
879
880    EINA_LIST_FOREACH(win->subobjs, l, child)
881      {
882         evas_object_size_hint_weight_get(child, &wx, &wy);
883         if (wx == 0.0) xx = 0;
884         if (wy == 0.0) xy = 0;
885
886         evas_object_size_hint_min_get(child, &w, &h);
887         if (w < 1) w = 1;
888         if (h < 1) h = 1;
889         if (w > minw) minw = w;
890         if (h > minh) minh = h;
891
892         evas_object_size_hint_max_get(child, &w, &h);
893         if (w < 1) w = -1;
894         if (h < 1) h = -1;
895         if (maxw == -1) maxw = w;
896         else if ((w > 0) && (w < maxw)) maxw = w;
897         if (maxh == -1) maxh = h;
898         else if ((h > 0) && (h < maxh)) maxh = h;
899      }
900    if (!xx) maxw = minw;
901    else maxw = 32767;
902    if (!xy) maxh = minh;
903    else maxh = 32767;
904    evas_object_size_hint_min_set(obj, minw, minh);
905    evas_object_size_hint_max_set(obj, maxw, maxh);
906    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
907    if (w < minw) w = minw;
908    if (h < minh) h = minh;
909    if ((maxw >= 0) && (w > maxw)) w = maxw;
910    if ((maxh >= 0) && (h > maxh)) h = maxh;
911    evas_object_resize(obj, w, h);
912 }
913
914 static void
915 _elm_win_subobj_callback_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
916 {
917    Elm_Win *win = elm_widget_data_get(data);
918    win->subobjs = eina_list_remove(win->subobjs, obj);
919    _elm_win_eval_subobjs(win->win_obj);
920 }
921
922 static void
923 _elm_win_subobj_callback_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
924 {
925    _elm_win_eval_subobjs(data);
926 }
927
928 void
929 _elm_win_shutdown(void)
930 {
931    while (_elm_win_list)
932      evas_object_del(_elm_win_list->data);
933 }
934
935 void
936 _elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme)
937 {
938    const Eina_List *l;
939    Evas_Object *obj;
940
941    if (!use_theme)
942      {
943         EINA_LIST_FOREACH(_elm_win_list, l, obj)
944           elm_widget_theme(obj);
945      }
946    else
947      {
948         EINA_LIST_FOREACH(_elm_win_list, l, obj)
949           elm_widget_theme_specific(obj, th, EINA_FALSE);
950      }
951 }
952
953 void
954 _elm_win_translate(void)
955 {
956    const Eina_List *l;
957    Evas_Object *obj;
958
959    EINA_LIST_FOREACH(_elm_win_list, l, obj)
960       elm_widget_translate(obj);
961 }
962
963 #ifdef HAVE_ELEMENTARY_X
964 static Eina_Bool
965 _elm_win_client_message(void *data, int type __UNUSED__, void *event)
966 {
967    Elm_Win *win = data;
968    Ecore_X_Event_Client_Message *e = event;
969
970    if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
971    if (e->message_type == ECORE_X_ATOM_E_COMP_FLUSH)
972      {
973         if ((unsigned)e->data.l[0] == win->xwin)
974           {
975              Evas *evas = evas_object_evas_get(win->win_obj);
976              if (evas)
977                {
978                   edje_file_cache_flush();
979                   edje_collection_cache_flush();
980                   evas_image_cache_flush(evas);
981                   evas_font_cache_flush(evas);
982                }
983           }
984      }
985    else if (e->message_type == ECORE_X_ATOM_E_COMP_DUMP)
986      {
987         if ((unsigned)e->data.l[0] == win->xwin)
988           {
989              Evas *evas = evas_object_evas_get(win->win_obj);
990              if (evas)
991                {
992                   edje_file_cache_flush();
993                   edje_collection_cache_flush();
994                   evas_image_cache_flush(evas);
995                   evas_font_cache_flush(evas);
996                   evas_render_dump(evas);
997                }
998           }
999      }
1000    return ECORE_CALLBACK_PASS_ON;
1001 }
1002 #endif
1003
1004 static void
1005 _elm_win_focus_target_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1006 {
1007    Elm_Win *win = data;
1008
1009    win->focus_highlight.geometry_changed = EINA_TRUE;
1010    _elm_win_focus_highlight_reconfigure_job_start(win);
1011 }
1012
1013 static void
1014 _elm_win_focus_target_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1015 {
1016    Elm_Win *win = data;
1017
1018    win->focus_highlight.geometry_changed = EINA_TRUE;
1019    _elm_win_focus_highlight_reconfigure_job_start(win);
1020 }
1021
1022 static void
1023 _elm_win_focus_target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1024 {
1025    Elm_Win *win = data;
1026
1027    win->focus_highlight.cur.target = NULL;
1028
1029    _elm_win_focus_highlight_reconfigure_job_start(win);
1030 }
1031
1032 static void
1033 _elm_win_focus_target_callbacks_add(Elm_Win *win)
1034 {
1035    Evas_Object *obj = win->focus_highlight.cur.target;
1036
1037    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
1038                                   _elm_win_focus_target_move, win);
1039    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
1040                                   _elm_win_focus_target_resize, win);
1041    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
1042                                   _elm_win_focus_target_del, win);
1043 }
1044
1045 static void
1046 _elm_win_focus_target_callbacks_del(Elm_Win *win)
1047 {
1048    Evas_Object *obj = win->focus_highlight.cur.target;
1049
1050    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
1051                                        _elm_win_focus_target_move, win);
1052    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
1053                                        _elm_win_focus_target_resize, win);
1054    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
1055                                        _elm_win_focus_target_del, win);
1056 }
1057
1058 static Evas_Object *
1059 _elm_win_focus_target_get(Evas_Object *obj)
1060 {
1061    Evas_Object *o = obj;
1062
1063    do
1064      {
1065         if (elm_widget_is(o))
1066           {
1067              if (!elm_widget_highlight_ignore_get(o))
1068                break;
1069              o = elm_widget_parent_get(o);
1070              if (!o)
1071                o = evas_object_smart_parent_get(o);
1072           }
1073         else
1074           {
1075              o = elm_widget_parent_widget_get(o);
1076              if (!o)
1077                o = evas_object_smart_parent_get(o);
1078           }
1079      }
1080    while (o);
1081
1082    return o;
1083 }
1084
1085 static void
1086 _elm_win_object_focus_in(void *data, Evas *e __UNUSED__, void *event_info)
1087 {
1088    Evas_Object *obj = event_info, *target;
1089    Elm_Win *win = data;
1090
1091    if (win->focus_highlight.cur.target == obj)
1092      return;
1093
1094    target = _elm_win_focus_target_get(obj);
1095    win->focus_highlight.cur.target = target;
1096    if (elm_widget_highlight_in_theme_get(target))
1097      win->focus_highlight.cur.handled = EINA_TRUE;
1098    else
1099      _elm_win_focus_target_callbacks_add(win);
1100
1101    _elm_win_focus_highlight_reconfigure_job_start(win);
1102 }
1103
1104 static void
1105 _elm_win_object_focus_out(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
1106 {
1107    Elm_Win *win = data;
1108
1109    if (!win->focus_highlight.cur.target)
1110      return;
1111
1112    if (!win->focus_highlight.cur.handled)
1113      _elm_win_focus_target_callbacks_del(win);
1114    win->focus_highlight.cur.target = NULL;
1115    win->focus_highlight.cur.handled = EINA_FALSE;
1116
1117    _elm_win_focus_highlight_reconfigure_job_start(win);
1118 }
1119
1120 static void
1121 _elm_win_focus_highlight_hide(void *data __UNUSED__, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
1122 {
1123    evas_object_hide(obj);
1124 }
1125
1126 static void
1127 _elm_win_focus_highlight_init(Elm_Win *win)
1128 {
1129    evas_event_callback_add(win->evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
1130                            _elm_win_object_focus_in, win);
1131    evas_event_callback_add(win->evas,
1132                            EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
1133                            _elm_win_object_focus_out, win);
1134
1135    win->focus_highlight.cur.target = evas_focus_get(win->evas);
1136
1137    win->focus_highlight.top = edje_object_add(win->evas);
1138    win->focus_highlight.changed_theme = EINA_TRUE;
1139    edje_object_signal_callback_add(win->focus_highlight.top,
1140                                    "elm,action,focus,hide,end", "",
1141                                    _elm_win_focus_highlight_hide, NULL);
1142    edje_object_signal_callback_add(win->focus_highlight.top,
1143                                    "elm,action,focus,anim,end", "",
1144                                    _elm_win_focus_highlight_anim_end, win);
1145    _elm_win_focus_highlight_reconfigure_job_start(win);
1146 }
1147
1148 static void
1149 _elm_win_focus_highlight_shutdown(Elm_Win *win)
1150 {
1151    _elm_win_focus_highlight_reconfigure_job_stop(win);
1152    if (win->focus_highlight.cur.target)
1153      {
1154         _elm_win_focus_target_callbacks_del(win);
1155         win->focus_highlight.cur.target = NULL;
1156      }
1157    if (win->focus_highlight.top)
1158      {
1159         evas_object_del(win->focus_highlight.top);
1160         win->focus_highlight.top = NULL;
1161      }
1162
1163    evas_event_callback_del_full(win->evas,
1164                                 EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
1165                                 _elm_win_object_focus_in, win);
1166    evas_event_callback_del_full(win->evas,
1167                                 EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT,
1168                                 _elm_win_object_focus_out, win);
1169 }
1170
1171 static void
1172 _elm_win_focus_highlight_visible_set(Elm_Win *win, Eina_Bool visible)
1173 {
1174    Evas_Object *top;
1175
1176    top = win->focus_highlight.top;
1177    if (visible)
1178      {
1179         if (top)
1180           {
1181              evas_object_show(top);
1182              edje_object_signal_emit(top, "elm,action,focus,show", "elm");
1183           }
1184      }
1185    else
1186      {
1187         if (top)
1188           edje_object_signal_emit(top, "elm,action,focus,hide", "elm");
1189      }
1190 }
1191
1192 static void
1193 _elm_win_focus_highlight_reconfigure_job(void *data)
1194 {
1195    _elm_win_focus_highlight_reconfigure((Elm_Win *)data);
1196 }
1197
1198 static void
1199 _elm_win_focus_highlight_reconfigure_job_start(Elm_Win *win)
1200 {
1201    if (win->focus_highlight.reconf_job)
1202      ecore_job_del(win->focus_highlight.reconf_job);
1203    win->focus_highlight.reconf_job = ecore_job_add(
1204       _elm_win_focus_highlight_reconfigure_job, win);
1205 }
1206
1207 static void
1208 _elm_win_focus_highlight_reconfigure_job_stop(Elm_Win *win)
1209 {
1210    if (win->focus_highlight.reconf_job)
1211      ecore_job_del(win->focus_highlight.reconf_job);
1212    win->focus_highlight.reconf_job = NULL;
1213 }
1214
1215 static void
1216 _elm_win_focus_highlight_simple_setup(Elm_Win *win, Evas_Object *obj)
1217 {
1218    Evas_Object *clip, *target = win->focus_highlight.cur.target;
1219    Evas_Coord x, y, w, h;
1220
1221    clip = evas_object_clip_get(target);
1222    evas_object_geometry_get(target, &x, &y, &w, &h);
1223
1224    evas_object_move(obj, x, y);
1225    evas_object_resize(obj, w, h);
1226    evas_object_clip_set(obj, clip);
1227 }
1228
1229 static void
1230 _elm_win_focus_highlight_anim_setup(Elm_Win *win, Evas_Object *obj)
1231 {
1232    Evas_Coord tx, ty, tw, th;
1233    Evas_Coord w, h, px, py, pw, ph;
1234    Edje_Message_Int_Set *m;
1235    Evas_Object *previous = win->focus_highlight.prev.target;
1236    Evas_Object *target = win->focus_highlight.cur.target;
1237
1238    evas_object_geometry_get(win->win_obj, NULL, NULL, &w, &h);
1239    evas_object_geometry_get(target, &tx, &ty, &tw, &th);
1240    evas_object_geometry_get(previous, &px, &py, &pw, &ph);
1241    evas_object_move(obj, 0, 0);
1242    evas_object_resize(obj, tw, th);
1243    evas_object_clip_unset(obj);
1244
1245    m = alloca(sizeof(*m) + (sizeof(int) * 8));
1246    m->count = 8;
1247    m->val[0] = px;
1248    m->val[1] = py;
1249    m->val[2] = pw;
1250    m->val[3] = ph;
1251    m->val[4] = tx;
1252    m->val[5] = ty;
1253    m->val[6] = tw;
1254    m->val[7] = th;
1255    edje_object_message_send(obj, EDJE_MESSAGE_INT_SET, 1, m);
1256 }
1257
1258 static void
1259 _elm_win_focus_highlight_anim_end(void *data, Evas_Object *obj, const char *emission __UNUSED__, const char *source __UNUSED__)
1260 {
1261    Elm_Win *win = data;
1262    _elm_win_focus_highlight_simple_setup(win, obj);
1263 }
1264
1265 static void
1266 _elm_win_focus_highlight_reconfigure(Elm_Win *win)
1267 {
1268    Evas_Object *target = win->focus_highlight.cur.target;
1269    Evas_Object *previous = win->focus_highlight.prev.target;
1270    Evas_Object *top = win->focus_highlight.top;
1271    Eina_Bool visible_changed;
1272    Eina_Bool common_visible;
1273    const char *sig = NULL;
1274
1275    _elm_win_focus_highlight_reconfigure_job_stop(win);
1276
1277    visible_changed = (win->focus_highlight.cur.visible !=
1278                       win->focus_highlight.prev.visible);
1279
1280    if ((target == previous) && (!visible_changed) &&
1281        (!win->focus_highlight.geometry_changed))
1282      return;
1283
1284    if ((previous) && (win->focus_highlight.prev.handled))
1285      elm_widget_signal_emit(previous, "elm,action,focus_highlight,hide", "elm");
1286
1287    if (!target)
1288      common_visible = EINA_FALSE;
1289    else if (win->focus_highlight.cur.handled)
1290      {
1291         common_visible = EINA_FALSE;
1292         if (win->focus_highlight.cur.visible)
1293           sig = "elm,action,focus_highlight,show";
1294         else
1295           sig = "elm,action,focus_highlight,hide";
1296      }
1297    else
1298      common_visible = win->focus_highlight.cur.visible;
1299
1300    _elm_win_focus_highlight_visible_set(win, common_visible);
1301    if (sig)
1302      elm_widget_signal_emit(target, sig, "elm");
1303
1304    if ((!target) || (!common_visible) || (win->focus_highlight.cur.handled))
1305      goto the_end;
1306
1307    if (win->focus_highlight.changed_theme)
1308      {
1309         const char *str;
1310         if (win->focus_highlight.style)
1311           str = win->focus_highlight.style;
1312         else
1313           str = "default";
1314         _elm_theme_object_set(win->win_obj, top, "focus_highlight", "top",
1315                               str);
1316         win->focus_highlight.changed_theme = EINA_FALSE;
1317
1318         if (_elm_config->focus_highlight_animate)
1319           {
1320              str = edje_object_data_get(win->focus_highlight.top, "animate");
1321              win->focus_highlight.top_animate = ((str) && (!strcmp(str, "on")));
1322           }
1323      }
1324
1325    if ((win->focus_highlight.top_animate) && (previous) &&
1326        (!win->focus_highlight.prev.handled))
1327      _elm_win_focus_highlight_anim_setup(win, top);
1328    else
1329      _elm_win_focus_highlight_simple_setup(win, top);
1330    evas_object_raise(top);
1331
1332 the_end:
1333    win->focus_highlight.geometry_changed = EINA_FALSE;
1334    win->focus_highlight.prev = win->focus_highlight.cur;
1335 }
1336
1337 static void 
1338 _elm_win_frame_add(Elm_Win *win, const char *style)
1339 {
1340    evas_output_framespace_set(win->evas, 0, 22, 0, 26);
1341
1342    win->frame_obj = edje_object_add(win->evas);
1343    _elm_theme_set(NULL, win->frame_obj, "border", "base", style);
1344    evas_object_is_frame_object_set(win->frame_obj, EINA_TRUE);
1345    evas_object_move(win->frame_obj, 0, 0);
1346    evas_object_resize(win->frame_obj, 1, 1);
1347
1348    edje_object_signal_callback_add(win->frame_obj, "elm,action,move,start", 
1349                                    "elm", _elm_win_frame_cb_move_start, win);
1350    edje_object_signal_callback_add(win->frame_obj, "elm,action,resize,start", 
1351                                    "*", _elm_win_frame_cb_resize_start, win);
1352    edje_object_signal_callback_add(win->frame_obj, "elm,action,minimize", 
1353                                    "elm", _elm_win_frame_cb_minimize, win);
1354    edje_object_signal_callback_add(win->frame_obj, "elm,action,maximize", 
1355                                    "elm", _elm_win_frame_cb_maximize, win);
1356    edje_object_signal_callback_add(win->frame_obj, "elm,action,close", 
1357                                    "elm", _elm_win_frame_cb_close, win);
1358 }
1359
1360 static void 
1361 _elm_win_frame_cb_move_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
1362 {
1363    Elm_Win *win;
1364
1365    if (!(win = data)) return;
1366    /* FIXME: Change mouse pointer */
1367
1368    /* NB: 0,0 are dummy values. Wayland handles the move by itself */
1369    ecore_evas_move(win->ee, 0, 0);
1370 }
1371
1372 static void 
1373 _elm_win_frame_cb_resize_start(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source)
1374 {
1375    Elm_Win *win;
1376
1377    if (!(win = data)) return;
1378    if (win->resizing) return;
1379    win->resizing = EINA_TRUE;
1380
1381    /* FIXME: Change mouse pointer */
1382
1383    if (!strcmp(source, "elm.event.resize.t"))
1384      win->resize_location = 1;
1385    else if (!strcmp(source, "elm.event.resize.b"))
1386      win->resize_location = 2;
1387    else if (!strcmp(source, "elm.event.resize.l"))
1388      win->resize_location = 4;
1389    else if (!strcmp(source, "elm.event.resize.r"))
1390      win->resize_location = 8;
1391    else if (!strcmp(source, "elm.event.resize.tl"))
1392      win->resize_location = 5;
1393    else if (!strcmp(source, "elm.event.resize.tr"))
1394      win->resize_location = 9;
1395    else if (!strcmp(source, "elm.event.resize.bl"))
1396      win->resize_location = 6;
1397    else if (!strcmp(source, "elm.event.resize.br"))
1398      win->resize_location = 10;
1399    else
1400      win->resize_location = 0;
1401
1402    if (win->resize_location > 0)
1403      ecore_evas_wayland_resize(win->ee, win->resize_location);
1404 }
1405
1406 static void 
1407 _elm_win_frame_cb_minimize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
1408 {
1409    Elm_Win *win;
1410
1411    if (!(win = data)) return;
1412    ecore_evas_iconified_set(win->ee, EINA_TRUE);
1413 }
1414
1415 static void 
1416 _elm_win_frame_cb_maximize(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
1417 {
1418    Elm_Win *win;
1419
1420    if (!(win = data)) return;
1421    ecore_evas_maximized_set(win->ee, EINA_TRUE);
1422 }
1423
1424 static void 
1425 _elm_win_frame_cb_close(void *data, Evas_Object *obj __UNUSED__, const char *sig __UNUSED__, const char *source __UNUSED__)
1426 {
1427    Elm_Win *win;
1428
1429    if (!(win = data)) return;
1430    evas_object_del(win->win_obj);
1431 }
1432
1433 static void 
1434 _elm_win_pointer_add(Elm_Win *win, const char *style)
1435 {
1436    int mw, mh;
1437
1438    win->pointer.ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 32, 32, 0);
1439    ecore_evas_resize(win->pointer.ee, 32, 32);
1440
1441    win->pointer.evas = ecore_evas_get(win->ee);
1442
1443    win->pointer.obj = edje_object_add(win->pointer.evas);
1444    _elm_theme_set(NULL, win->pointer.obj, "pointer", "base", style);
1445    edje_object_size_min_calc(win->pointer.obj, &mw, &mh);
1446    printf("ELM Win Pointer Size: %d %d\n", mw, mh);
1447    evas_object_move(win->pointer.obj, 0, 0);
1448    evas_object_resize(win->pointer.obj, 32, 32);
1449    evas_object_show(win->pointer.obj);
1450 }
1451
1452 #ifdef ELM_DEBUG
1453 static void
1454 _debug_key_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
1455 {
1456    Evas_Event_Key_Down *ev = event_info;
1457
1458    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
1459      return;
1460
1461    if ((strcmp(ev->keyname, "F12")) ||
1462        (!evas_key_modifier_is_set(ev->modifiers, "Control")))
1463      return;
1464
1465    printf("Tree graph generated.\n");
1466    elm_object_tree_dot_dump(obj, "./dump.dot");
1467 }
1468 #endif
1469
1470 static void
1471 _win_img_hide(void        *data,
1472               Evas        *e __UNUSED__,
1473               Evas_Object *obj __UNUSED__,
1474               void        *event_info __UNUSED__)
1475 {
1476    Elm_Win *win = data;
1477
1478    elm_widget_focus_hide_handle(win->win_obj);
1479 }
1480
1481 static void
1482 _win_img_mouse_up(void        *data,
1483                   Evas        *e __UNUSED__,
1484                   Evas_Object *obj __UNUSED__,
1485                   void        *event_info)
1486 {
1487    Elm_Win *win = data;
1488    Evas_Event_Mouse_Up *ev = event_info;
1489    if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
1490       elm_widget_focus_mouse_up_handle(win->win_obj);
1491 }
1492
1493 static void
1494 _win_img_focus_in(void        *data,
1495                   Evas        *e __UNUSED__,
1496                   Evas_Object *obj __UNUSED__,
1497                   void        *event_info __UNUSED__)
1498 {
1499    Elm_Win *win = data;
1500    elm_widget_focus_steal(win->win_obj);
1501 }
1502
1503 static void
1504 _win_img_focus_out(void        *data,
1505                    Evas        *e __UNUSED__,
1506                    Evas_Object *obj __UNUSED__,
1507                    void        *event_info __UNUSED__)
1508 {
1509    Elm_Win *win = data;
1510    elm_widget_focused_object_clear(win->win_obj);
1511 }
1512
1513 static void
1514 _win_inlined_image_set(Elm_Win *win)
1515 {
1516    evas_object_image_alpha_set(win->img_obj, EINA_FALSE);
1517    evas_object_image_filled_set(win->img_obj, EINA_TRUE);
1518    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_DEL,
1519                                   _elm_win_obj_callback_img_obj_del, win);
1520
1521    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_HIDE,
1522                                   _win_img_hide, win);
1523    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_MOUSE_UP,
1524                                   _win_img_mouse_up, win);
1525    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_FOCUS_IN,
1526                                   _win_img_focus_in, win);
1527    evas_object_event_callback_add(win->img_obj, EVAS_CALLBACK_FOCUS_OUT,
1528                                   _win_img_focus_out, win);
1529 }
1530
1531 static void
1532 _subobj_del(Elm_Win *win, Evas_Object *obj, Evas_Object *subobj)
1533 {
1534    evas_object_event_callback_del_full(subobj,
1535                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1536                                        _elm_win_subobj_callback_changed_size_hints,
1537                                        obj);
1538    evas_object_event_callback_del_full(subobj, EVAS_CALLBACK_DEL,
1539                                        _elm_win_subobj_callback_del, obj);
1540    win->subobjs = eina_list_remove(win->subobjs, subobj);
1541    _elm_win_eval_subobjs(obj);
1542 }
1543
1544 EAPI Evas_Object *
1545 elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type)
1546 {
1547    Elm_Win *win;
1548    const Eina_List *l;
1549    const char *fontpath;
1550
1551    win = ELM_NEW(Elm_Win);
1552
1553 #define FALLBACK_TRY(engine)                                            \
1554    if (!win->ee)                                                        \
1555       do {                                                              \
1556          CRITICAL(engine " engine creation failed. Trying default.");   \
1557          win->ee = ecore_evas_new(NULL, 0, 0, 1, 1, NULL);              \
1558          if (win->ee)                                                   \
1559             elm_engine_set(ecore_evas_engine_name_get(win->ee));        \
1560    } while (0)
1561 #define ENGINE_COMPARE(name) (_elm_config->engine && !strcmp(_elm_config->engine, name))
1562
1563    switch (type)
1564      {
1565       case ELM_WIN_INLINED_IMAGE:
1566         if (!parent) break;
1567         {
1568            Evas *e = evas_object_evas_get(parent);
1569            Ecore_Evas *ee;
1570            if (!e) break;
1571            ee = ecore_evas_ecore_evas_get(e);
1572            if (!ee) break;
1573            win->img_obj = ecore_evas_object_image_new(ee);
1574            if (!win->img_obj) break;
1575            win->ee = ecore_evas_object_ecore_evas_get(win->img_obj);
1576            if (win->ee)
1577              {
1578                 _win_inlined_image_set(win);
1579                 break;
1580              }
1581            evas_object_del(win->img_obj);
1582            win->img_obj = NULL;
1583         }
1584         break;
1585
1586       case ELM_WIN_SOCKET_IMAGE:
1587         win->ee = ecore_evas_extn_socket_new(1, 1);
1588         break;
1589
1590       default:
1591         if (ENGINE_COMPARE(ELM_SOFTWARE_X11))
1592           {
1593              win->ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 1, 1);
1594 #ifdef HAVE_ELEMENTARY_X
1595              win->client_message_handler = ecore_event_handler_add
1596                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1597 #endif
1598              FALLBACK_TRY("Sofware X11");
1599           }
1600         else if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
1601           {
1602              win->ee = ecore_evas_fb_new(NULL, 0, 1, 1);
1603              FALLBACK_TRY("Sofware FB");
1604           }
1605         else if (ENGINE_COMPARE(ELM_SOFTWARE_DIRECTFB))
1606           {
1607              win->ee = ecore_evas_directfb_new(NULL, 1, 0, 0, 1, 1);
1608              FALLBACK_TRY("Sofware DirectFB");
1609           }
1610         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_X11))
1611           {
1612              win->ee = ecore_evas_software_x11_16_new(NULL, 0, 0, 0, 1, 1);
1613              FALLBACK_TRY("Sofware-16");
1614 #ifdef HAVE_ELEMENTARY_X
1615              win->client_message_handler = ecore_event_handler_add
1616                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1617 #endif
1618      }
1619         else if (ENGINE_COMPARE(ELM_SOFTWARE_8_X11))
1620           {
1621              win->ee = ecore_evas_software_x11_8_new(NULL, 0, 0, 0, 1, 1);
1622              FALLBACK_TRY("Sofware-8");
1623 #ifdef HAVE_ELEMENTARY_X
1624              win->client_message_handler = ecore_event_handler_add
1625                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1626 #endif
1627           }
1628 /* killed
1629         else if (ENGINE_COMPARE(ELM_XRENDER_X11))
1630           {
1631              win->ee = ecore_evas_xrender_x11_new(NULL, 0, 0, 0, 1, 1);
1632              FALLBACK_TRY("XRender");
1633 #ifdef HAVE_ELEMENTARY_X
1634              win->client_message_handler = ecore_event_handler_add
1635                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1636 #endif
1637           }
1638  */
1639         else if (ENGINE_COMPARE(ELM_OPENGL_X11))
1640           {
1641              int opt[10];
1642              int opt_i = 0;
1643
1644              if (_elm_config->vsync)
1645                {
1646                   opt[opt_i] = ECORE_EVAS_GL_X11_OPT_VSYNC;
1647                   opt_i++;
1648                   opt[opt_i] = 1;
1649                   opt_i++;
1650                }
1651              if (opt_i > 0)
1652                 win->ee = ecore_evas_gl_x11_options_new(NULL, 0, 0, 0, 1, 1, opt);
1653              else
1654                 win->ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 1, 1);
1655              FALLBACK_TRY("OpenGL");
1656 #ifdef HAVE_ELEMENTARY_X
1657              win->client_message_handler = ecore_event_handler_add
1658                 (ECORE_X_EVENT_CLIENT_MESSAGE, _elm_win_client_message, win);
1659 #endif
1660           }
1661         else if (ENGINE_COMPARE(ELM_SOFTWARE_WIN32))
1662           {
1663              win->ee = ecore_evas_software_gdi_new(NULL, 0, 0, 1, 1);
1664              FALLBACK_TRY("Sofware Win32");
1665           }
1666         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
1667           {
1668              win->ee = ecore_evas_software_wince_gdi_new(NULL, 0, 0, 1, 1);
1669              FALLBACK_TRY("Sofware-16-WinCE");
1670           }
1671         else if (ENGINE_COMPARE(ELM_SOFTWARE_PSL1GHT))
1672           {
1673              win->ee = ecore_evas_psl1ght_new(NULL, 1, 1);
1674              FALLBACK_TRY("PSL1GHT");
1675           }
1676         else if (ENGINE_COMPARE(ELM_SOFTWARE_SDL))
1677           {
1678              win->ee = ecore_evas_sdl_new(NULL, 0, 0, 0, 0, 0, 1);
1679              FALLBACK_TRY("Sofware SDL");
1680           }
1681         else if (ENGINE_COMPARE(ELM_SOFTWARE_16_SDL))
1682           {
1683              win->ee = ecore_evas_sdl16_new(NULL, 0, 0, 0, 0, 0, 1);
1684              FALLBACK_TRY("Sofware-16-SDL");
1685           }
1686         else if (ENGINE_COMPARE(ELM_OPENGL_SDL))
1687           {
1688              win->ee = ecore_evas_gl_sdl_new(NULL, 1, 1, 0, 0);
1689              FALLBACK_TRY("OpenGL SDL");
1690           }
1691         else if (ENGINE_COMPARE(ELM_OPENGL_COCOA))
1692           {
1693              win->ee = ecore_evas_cocoa_new(NULL, 1, 1, 0, 0);
1694              FALLBACK_TRY("OpenGL Cocoa");
1695           }
1696         else if (ENGINE_COMPARE(ELM_BUFFER))
1697           {
1698              win->ee = ecore_evas_buffer_new(1, 1);
1699           }
1700         else if (ENGINE_COMPARE(ELM_EWS))
1701           {
1702              win->ee = ecore_evas_ews_new(0, 0, 1, 1);
1703           }
1704         else if (ENGINE_COMPARE(ELM_WAYLAND_SHM)) 
1705           {
1706              win->ee = ecore_evas_wayland_shm_new(NULL, 0, 0, 1, 1, 0);
1707
1708              _elm_win_frame_add(win, "default");
1709              _elm_win_pointer_add(win, "default");
1710           }
1711         else if (ENGINE_COMPARE(ELM_WAYLAND_EGL)) 
1712           {
1713              win->ee = ecore_evas_wayland_egl_new(NULL, 0, 0, 1, 1, 0);
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 || !title) 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 }