96145d4b68e428de267c3e6c7fa4dadf08b33e6e
[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              win->evas = ecore_evas_get(win->ee);
1708
1709              _elm_win_frame_add(win, "default");
1710              _elm_win_pointer_add(win, "default");
1711           }
1712         else if (ENGINE_COMPARE(ELM_WAYLAND_EGL)) 
1713           {
1714              win->ee = ecore_evas_wayland_egl_new(NULL, 0, 0, 1, 1, 0);
1715              win->evas = ecore_evas_get(win->ee);
1716
1717              _elm_win_frame_add(win, "default");
1718              _elm_win_pointer_add(win, "default");
1719           }
1720         else if (!strncmp(_elm_config->engine, "shot:", 5))
1721           {
1722              win->ee = ecore_evas_buffer_new(1, 1);
1723              ecore_evas_manual_render_set(win->ee, EINA_TRUE);
1724              win->shot.info = eina_stringshare_add(_elm_config->engine + 5);
1725              _shot_init(win);
1726           }
1727 #undef FALLBACK_TRY
1728         break;
1729      }
1730
1731    if (!win->ee)
1732      {
1733         ERR("Cannot create window.");
1734         free(win);
1735         return NULL;
1736      }
1737 #ifdef HAVE_ELEMENTARY_X
1738    _elm_win_xwindow_get(win);
1739 #endif
1740    if ((_elm_config->bgpixmap) && (!_elm_config->compositing))
1741      ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_EXPOSE);
1742    // bg pixmap done by x - has other issues like can be redrawn by x before it
1743    // is filled/ready by app
1744    //     ecore_evas_avoid_damage_set(win->ee, ECORE_EVAS_AVOID_DAMAGE_BUILT_IN);
1745
1746    win->type = type;
1747    win->parent = parent;
1748    if (win->parent)
1749      evas_object_event_callback_add(win->parent, EVAS_CALLBACK_DEL,
1750                                     _elm_win_obj_callback_parent_del, win);
1751
1752    win->evas = ecore_evas_get(win->ee);
1753    win->win_obj = elm_widget_add(win->evas);
1754    elm_widget_type_set(win->win_obj, "win");
1755    ELM_SET_WIDTYPE(widtype, "win");
1756    elm_widget_data_set(win->win_obj, win);
1757    elm_widget_event_hook_set(win->win_obj, _elm_win_event_cb);
1758    elm_widget_on_focus_hook_set(win->win_obj, _elm_win_on_focus_hook, NULL);
1759    elm_widget_can_focus_set(win->win_obj, EINA_TRUE);
1760    elm_widget_highlight_ignore_set(win->win_obj, EINA_TRUE);
1761    elm_widget_focus_next_hook_set(win->win_obj, _elm_win_focus_next_hook);
1762    evas_object_color_set(win->win_obj, 0, 0, 0, 0);
1763    evas_object_move(win->win_obj, 0, 0);
1764    evas_object_resize(win->win_obj, 1, 1);
1765    evas_object_layer_set(win->win_obj, 50);
1766    evas_object_pass_events_set(win->win_obj, EINA_TRUE);
1767
1768    if (win->frame_obj) 
1769      {
1770 //        evas_object_clip_set(win->win_obj, win->frame_obj);
1771         evas_object_stack_below(win->frame_obj, win->win_obj);
1772      }
1773
1774    if (type == ELM_WIN_INLINED_IMAGE)
1775      elm_widget_parent2_set(win->win_obj, parent);
1776    ecore_evas_object_associate(win->ee, win->win_obj,
1777                                ECORE_EVAS_OBJECT_ASSOCIATE_BASE |
1778                                ECORE_EVAS_OBJECT_ASSOCIATE_STACK |
1779                                ECORE_EVAS_OBJECT_ASSOCIATE_LAYER);
1780    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_SHOW,
1781                                   _elm_win_obj_callback_show, win);
1782    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_HIDE,
1783                                   _elm_win_obj_callback_hide, win);
1784    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_DEL,
1785                                   _elm_win_obj_callback_del, win);
1786    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_MOVE,
1787                                   _elm_win_obj_callback_move, win);
1788    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_RESIZE,
1789                                   _elm_win_obj_callback_resize, win);
1790    if (win->img_obj)
1791      evas_object_intercept_move_callback_add(win->win_obj,
1792                                              _elm_win_obj_intercept_move, win);
1793    evas_object_intercept_show_callback_add(win->win_obj,
1794                                            _elm_win_obj_intercept_show, win);
1795
1796    evas_object_smart_callback_add(win->win_obj, "sub-object-del", (Evas_Smart_Cb)_subobj_del, win);
1797    ecore_evas_name_class_set(win->ee, name, _elm_appname);
1798    ecore_evas_callback_delete_request_set(win->ee, _elm_win_delete_request);
1799    ecore_evas_callback_resize_set(win->ee, _elm_win_resize);
1800    ecore_evas_callback_mouse_in_set(win->ee, _elm_win_mouse_in);
1801    ecore_evas_callback_focus_in_set(win->ee, _elm_win_focus_in);
1802    ecore_evas_callback_focus_out_set(win->ee, _elm_win_focus_out);
1803    ecore_evas_callback_move_set(win->ee, _elm_win_move);
1804    evas_image_cache_set(win->evas, (_elm_config->image_cache * 1024));
1805    evas_font_cache_set(win->evas, (_elm_config->font_cache * 1024));
1806    EINA_LIST_FOREACH(_elm_config->font_dirs, l, fontpath)
1807      evas_font_path_append(win->evas, fontpath);
1808    if (!_elm_config->font_hinting)
1809      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_NONE);
1810    else if (_elm_config->font_hinting == 1)
1811      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_AUTO);
1812    else if (_elm_config->font_hinting == 2)
1813      evas_font_hinting_set(win->evas, EVAS_FONT_HINTING_BYTECODE);
1814
1815 #ifdef HAVE_ELEMENTARY_X
1816    _elm_win_xwin_update(win);
1817 #endif
1818
1819    _elm_win_list = eina_list_append(_elm_win_list, win->win_obj);
1820
1821    if (ENGINE_COMPARE(ELM_SOFTWARE_FB))
1822      {
1823         ecore_evas_fullscreen_set(win->ee, 1);
1824      }
1825 #undef ENGINE_COMPARE
1826
1827    if (_elm_config->focus_highlight_enable)
1828      elm_win_focus_highlight_enabled_set(win->win_obj, EINA_TRUE);
1829
1830 #ifdef ELM_DEBUG
1831    Evas_Modifier_Mask mask = evas_key_modifier_mask_get(win->evas, "Control");
1832    evas_object_event_callback_add(win->win_obj, EVAS_CALLBACK_KEY_DOWN,
1833                                   _debug_key_down, win);
1834
1835    Eina_Bool ret = evas_object_key_grab(win->win_obj, "F12", mask, 0,
1836                                         EINA_TRUE);
1837    printf("Ctrl+F12 key combination exclusive for dot tree generation\n");
1838 #endif
1839
1840    evas_object_smart_callbacks_descriptions_set(win->win_obj, _signals);
1841
1842    return win->win_obj;
1843 }
1844
1845 EAPI Evas_Object *
1846 elm_win_util_standard_add(const char *name, const char *title)
1847 {
1848    Evas_Object *win, *bg;
1849
1850    win = elm_win_add(NULL, name, ELM_WIN_BASIC);
1851    if (!win) return NULL;
1852    elm_win_title_set(win, title);
1853    bg = elm_bg_add(win);
1854    if (!bg)
1855      {
1856         evas_object_del(win);
1857         return NULL;
1858      }
1859    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1860    elm_win_resize_object_add(win, bg);
1861    evas_object_show(bg);
1862    return win;
1863 }
1864
1865 EAPI void
1866 elm_win_resize_object_add(Evas_Object *obj, Evas_Object *subobj)
1867 {
1868    Evas_Coord w, h;
1869    Elm_Win *win;
1870    ELM_CHECK_WIDTYPE(obj, widtype);
1871    win = elm_widget_data_get(obj);
1872    if (!win) return;
1873    if (eina_list_data_find(win->subobjs, subobj)) return;
1874    win->subobjs = eina_list_append(win->subobjs, subobj);
1875    elm_widget_sub_object_add(obj, subobj);
1876    evas_object_event_callback_add(subobj, EVAS_CALLBACK_DEL,
1877                                   _elm_win_subobj_callback_del, obj);
1878    evas_object_event_callback_add(subobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1879                                   _elm_win_subobj_callback_changed_size_hints,
1880                                   obj);
1881    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1882    evas_object_move(subobj, 0, 0);
1883    evas_object_resize(subobj, w, h);
1884    _elm_win_eval_subobjs(obj);
1885 }
1886
1887 EAPI void
1888 elm_win_resize_object_del(Evas_Object *obj, Evas_Object *subobj)
1889 {
1890    Elm_Win *win;
1891    ELM_CHECK_WIDTYPE(obj, widtype);
1892    win = elm_widget_data_get(obj);
1893    if (!win) return;
1894    evas_object_event_callback_del_full(subobj,
1895                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1896                                        _elm_win_subobj_callback_changed_size_hints,
1897                                        obj);
1898    evas_object_event_callback_del_full(subobj, EVAS_CALLBACK_DEL,
1899                                        _elm_win_subobj_callback_del, obj);
1900    win->subobjs = eina_list_remove(win->subobjs, subobj);
1901    elm_widget_sub_object_del(obj, subobj);
1902    _elm_win_eval_subobjs(obj);
1903 }
1904
1905 EAPI void
1906 elm_win_title_set(Evas_Object *obj, const char *title)
1907 {
1908    Elm_Win *win;
1909    ELM_CHECK_WIDTYPE(obj, widtype);
1910    win = elm_widget_data_get(obj);
1911    if (!win || !title) return;
1912    ecore_evas_title_set(win->ee, title);
1913    if (win->frame_obj)
1914      edje_object_part_text_set(win->frame_obj, "elm.text.title", title);
1915 }
1916
1917 EAPI const char *
1918 elm_win_title_get(const Evas_Object *obj)
1919 {
1920    Elm_Win *win;
1921    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1922    win = elm_widget_data_get(obj);
1923    if (!win) return NULL;
1924    return ecore_evas_title_get(win->ee);
1925 }
1926
1927 EAPI void
1928 elm_win_autodel_set(Evas_Object *obj, Eina_Bool autodel)
1929 {
1930    Elm_Win *win;
1931    ELM_CHECK_WIDTYPE(obj, widtype);
1932    win = elm_widget_data_get(obj);
1933    if (!win) return;
1934    win->autodel = autodel;
1935 }
1936
1937 EAPI Eina_Bool
1938 elm_win_autodel_get(const Evas_Object *obj)
1939 {
1940    Elm_Win *win;
1941    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1942    win = elm_widget_data_get(obj);
1943    if (!win) return EINA_FALSE;
1944    return win->autodel;
1945 }
1946
1947 EAPI void
1948 elm_win_activate(Evas_Object *obj)
1949 {
1950    Elm_Win *win;
1951    ELM_CHECK_WIDTYPE(obj, widtype);
1952    win = elm_widget_data_get(obj);
1953    if (!win) return;
1954    ecore_evas_activate(win->ee);
1955 }
1956
1957 EAPI void
1958 elm_win_lower(Evas_Object *obj)
1959 {
1960    Elm_Win *win;
1961    ELM_CHECK_WIDTYPE(obj, widtype);
1962    win = elm_widget_data_get(obj);
1963    if (!win) return;
1964    ecore_evas_lower(win->ee);
1965 }
1966
1967 EAPI void
1968 elm_win_raise(Evas_Object *obj)
1969 {
1970    Elm_Win *win;
1971    ELM_CHECK_WIDTYPE(obj, widtype);
1972    win = elm_widget_data_get(obj);
1973    if (!win) return;
1974    ecore_evas_raise(win->ee);
1975 }
1976
1977 EAPI void
1978 elm_win_center(Evas_Object *obj, Eina_Bool h, Eina_Bool v)
1979 {
1980    Elm_Win *win;
1981    int win_w, win_h, screen_w, screen_h, nx, ny;
1982    ELM_CHECK_WIDTYPE(obj, widtype);
1983    win = elm_widget_data_get(obj);
1984    if (!win) return;
1985    ecore_evas_screen_geometry_get(win->ee, NULL, NULL, &screen_w, &screen_h);
1986    if ((!screen_w) || (!screen_h)) return;
1987    evas_object_geometry_get(obj, NULL, NULL, &win_w, &win_h);
1988    if ((!win_w) || (!win_h)) return;
1989    if (h) nx = win_w >= screen_w ? 0 : (screen_w / 2) - (win_w / 2);
1990    else nx = win->screen.x;
1991    if (v) ny = win_h >= screen_h ? 0 : (screen_h / 2) - (win_h / 2);
1992    else ny = win->screen.y;
1993    if (nx < 0) nx = 0;
1994    if (ny < 0) ny = 0;
1995    evas_object_move(obj, nx, ny);
1996 }
1997
1998 EAPI void
1999 elm_win_borderless_set(Evas_Object *obj, Eina_Bool borderless)
2000 {
2001    Elm_Win *win;
2002    ELM_CHECK_WIDTYPE(obj, widtype);
2003    win = elm_widget_data_get(obj);
2004    if (!win) return;
2005    ecore_evas_borderless_set(win->ee, borderless);
2006 #ifdef HAVE_ELEMENTARY_X
2007    _elm_win_xwin_update(win);
2008 #endif
2009 }
2010
2011 EAPI Eina_Bool
2012 elm_win_borderless_get(const Evas_Object *obj)
2013 {
2014    Elm_Win *win;
2015    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2016    win = elm_widget_data_get(obj);
2017    if (!win) return EINA_FALSE;
2018    return ecore_evas_borderless_get(win->ee);
2019 }
2020
2021 EAPI void
2022 elm_win_shaped_set(Evas_Object *obj, Eina_Bool shaped)
2023 {
2024    Elm_Win *win;
2025    ELM_CHECK_WIDTYPE(obj, widtype);
2026    win = elm_widget_data_get(obj);
2027    if (!win) return;
2028    ecore_evas_shaped_set(win->ee, shaped);
2029 #ifdef HAVE_ELEMENTARY_X
2030    _elm_win_xwin_update(win);
2031 #endif
2032 }
2033
2034 EAPI Eina_Bool
2035 elm_win_shaped_get(const Evas_Object *obj)
2036 {
2037    Elm_Win *win;
2038    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2039    win = elm_widget_data_get(obj);
2040    if (!win) return EINA_FALSE;
2041    return ecore_evas_shaped_get(win->ee);
2042 }
2043
2044 EAPI void
2045 elm_win_alpha_set(Evas_Object *obj, Eina_Bool alpha)
2046 {
2047    Elm_Win *win;
2048    ELM_CHECK_WIDTYPE(obj, widtype);
2049    win = elm_widget_data_get(obj);
2050    if (!win) return;
2051    if (win->frame_obj)
2052      {
2053      }
2054    else if (win->img_obj)
2055      {
2056         evas_object_image_alpha_set(win->img_obj, alpha);
2057         ecore_evas_alpha_set(win->ee, alpha);
2058      }
2059    else
2060      {
2061 #ifdef HAVE_ELEMENTARY_X
2062         if (win->xwin)
2063           {
2064              if (alpha)
2065                {
2066                   if (!_elm_config->compositing)
2067                      elm_win_shaped_set(obj, alpha);
2068                   else
2069                      ecore_evas_alpha_set(win->ee, alpha);
2070                }
2071              else
2072                 ecore_evas_alpha_set(win->ee, alpha);
2073              _elm_win_xwin_update(win);
2074           }
2075         else
2076 #endif
2077            ecore_evas_alpha_set(win->ee, alpha);
2078      }
2079 }
2080
2081 EAPI Eina_Bool
2082 elm_win_alpha_get(const Evas_Object *obj)
2083 {
2084    Elm_Win *win;
2085    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2086    win = elm_widget_data_get(obj);
2087    if (!win) return EINA_FALSE;
2088    if (win->frame_obj)
2089      {
2090      }
2091    else if (win->img_obj)
2092      {
2093         return evas_object_image_alpha_get(win->img_obj);
2094      }
2095    return ecore_evas_alpha_get(win->ee);
2096 }
2097
2098 EAPI void
2099 elm_win_transparent_set(Evas_Object *obj, Eina_Bool transparent)
2100 {
2101    Elm_Win *win;
2102    ELM_CHECK_WIDTYPE(obj, widtype);
2103    win = elm_widget_data_get(obj);
2104    if (!win) return;
2105
2106    if (win->frame_obj)
2107      {
2108      }
2109    else if (win->img_obj)
2110      {
2111         evas_object_image_alpha_set(win->img_obj, transparent);
2112      }
2113    else
2114      {
2115 #ifdef HAVE_ELEMENTARY_X
2116         if (win->xwin)
2117           {
2118              ecore_evas_transparent_set(win->ee, transparent);
2119              _elm_win_xwin_update(win);
2120           }
2121         else
2122 #endif
2123            ecore_evas_transparent_set(win->ee, transparent);
2124      }
2125 }
2126
2127 EAPI Eina_Bool
2128 elm_win_transparent_get(const Evas_Object *obj)
2129 {
2130    Elm_Win *win;
2131    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2132    win = elm_widget_data_get(obj);
2133    if (!win) return EINA_FALSE;
2134
2135    return ecore_evas_transparent_get(win->ee);
2136 }
2137
2138 EAPI void
2139 elm_win_override_set(Evas_Object *obj, Eina_Bool override)
2140 {
2141    Elm_Win *win;
2142    ELM_CHECK_WIDTYPE(obj, widtype);
2143    win = elm_widget_data_get(obj);
2144    if (!win) return;
2145    ecore_evas_override_set(win->ee, override);
2146 #ifdef HAVE_ELEMENTARY_X
2147    _elm_win_xwin_update(win);
2148 #endif
2149 }
2150
2151 EAPI Eina_Bool
2152 elm_win_override_get(const Evas_Object *obj)
2153 {
2154    Elm_Win *win;
2155    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2156    win = elm_widget_data_get(obj);
2157    if (!win) return EINA_FALSE;
2158    return ecore_evas_override_get(win->ee);
2159 }
2160
2161 EAPI void
2162 elm_win_fullscreen_set(Evas_Object *obj, Eina_Bool fullscreen)
2163 {
2164    Elm_Win *win;
2165    ELM_CHECK_WIDTYPE(obj, widtype);
2166    win = elm_widget_data_get(obj);
2167    if (!win) return;
2168
2169    // YYY: handle if win->img_obj
2170 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
2171    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
2172        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
2173      {
2174         // these engines... can ONLY be fullscreen
2175         return;
2176      }
2177    else
2178      {
2179         ecore_evas_fullscreen_set(win->ee, fullscreen);
2180 #ifdef HAVE_ELEMENTARY_X
2181         _elm_win_xwin_update(win);
2182 #endif
2183      }
2184 #undef ENGINE_COMPARE
2185 }
2186
2187 EAPI Eina_Bool
2188 elm_win_fullscreen_get(const Evas_Object *obj)
2189 {
2190    Elm_Win *win;
2191    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2192    win = elm_widget_data_get(obj);
2193    if (!win) return EINA_FALSE;
2194
2195 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
2196    if (ENGINE_COMPARE(ELM_SOFTWARE_FB) ||
2197        ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
2198      {
2199         // these engines... can ONLY be fullscreen
2200         return EINA_TRUE;
2201      }
2202    else
2203      {
2204         return ecore_evas_fullscreen_get(win->ee);
2205      }
2206 #undef ENGINE_COMPARE
2207 }
2208
2209 EAPI void
2210 elm_win_maximized_set(Evas_Object *obj, Eina_Bool maximized)
2211 {
2212    Elm_Win *win;
2213    ELM_CHECK_WIDTYPE(obj, widtype);
2214    win = elm_widget_data_get(obj);
2215    if (!win) return;
2216    // YYY: handle if win->img_obj
2217    ecore_evas_maximized_set(win->ee, maximized);
2218 #ifdef HAVE_ELEMENTARY_X
2219    _elm_win_xwin_update(win);
2220 #endif
2221 }
2222
2223 EAPI Eina_Bool
2224 elm_win_maximized_get(const Evas_Object *obj)
2225 {
2226    Elm_Win *win;
2227    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2228    win = elm_widget_data_get(obj);
2229    if (!win) return EINA_FALSE;
2230    return ecore_evas_maximized_get(win->ee);
2231 }
2232
2233 EAPI void
2234 elm_win_iconified_set(Evas_Object *obj, Eina_Bool iconified)
2235 {
2236    Elm_Win *win;
2237    ELM_CHECK_WIDTYPE(obj, widtype);
2238    win = elm_widget_data_get(obj);
2239    if (!win) return;
2240    ecore_evas_iconified_set(win->ee, iconified);
2241 #ifdef HAVE_ELEMENTARY_X
2242    _elm_win_xwin_update(win);
2243 #endif
2244 }
2245
2246 EAPI Eina_Bool
2247 elm_win_iconified_get(const Evas_Object *obj)
2248 {
2249    Elm_Win *win;
2250    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2251    win = elm_widget_data_get(obj);
2252    if (!win) return EINA_FALSE;
2253    return ecore_evas_iconified_get(win->ee);
2254 }
2255
2256 EAPI void
2257 elm_win_layer_set(Evas_Object *obj, int layer)
2258 {
2259    Elm_Win *win;
2260    ELM_CHECK_WIDTYPE(obj, widtype);
2261    win = elm_widget_data_get(obj);
2262    if (!win) return;
2263    ecore_evas_layer_set(win->ee, layer);
2264 #ifdef HAVE_ELEMENTARY_X
2265    _elm_win_xwin_update(win);
2266 #endif
2267 }
2268
2269 EAPI int
2270 elm_win_layer_get(const Evas_Object *obj)
2271 {
2272    Elm_Win *win;
2273    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2274    win = elm_widget_data_get(obj);
2275    if (!win) return -1;
2276    return ecore_evas_layer_get(win->ee);
2277 }
2278
2279 EAPI void
2280 elm_win_rotation_set(Evas_Object *obj, int rotation)
2281 {
2282    Elm_Win *win;
2283    ELM_CHECK_WIDTYPE(obj, widtype);
2284    win = elm_widget_data_get(obj);
2285    if (!win) return;
2286    if (win->rot == rotation) return;
2287    win->rot = rotation;
2288    ecore_evas_rotation_set(win->ee, rotation);
2289    evas_object_size_hint_min_set(obj, -1, -1);
2290    evas_object_size_hint_max_set(obj, -1, -1);
2291    _elm_win_eval_subobjs(obj);
2292 #ifdef HAVE_ELEMENTARY_X
2293    _elm_win_xwin_update(win);
2294 #endif
2295 }
2296
2297 EAPI void
2298 elm_win_rotation_with_resize_set(Evas_Object *obj, int rotation)
2299 {
2300    Elm_Win *win;
2301    ELM_CHECK_WIDTYPE(obj, widtype);
2302    win = elm_widget_data_get(obj);
2303    if (!win) return;
2304    if (win->rot == rotation) return;
2305    win->rot = rotation;
2306    ecore_evas_rotation_with_resize_set(win->ee, rotation);
2307    evas_object_size_hint_min_set(obj, -1, -1);
2308    evas_object_size_hint_max_set(obj, -1, -1);
2309    _elm_win_eval_subobjs(obj);
2310 #ifdef HAVE_ELEMENTARY_X
2311    _elm_win_xwin_update(win);
2312 #endif
2313 }
2314
2315 EAPI int
2316 elm_win_rotation_get(const Evas_Object *obj)
2317 {
2318    Elm_Win *win;
2319    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2320    win = elm_widget_data_get(obj);
2321    if (!win) return -1;
2322    return win->rot;
2323 }
2324
2325 EAPI void
2326 elm_win_sticky_set(Evas_Object *obj, Eina_Bool sticky)
2327 {
2328    Elm_Win *win;
2329    ELM_CHECK_WIDTYPE(obj, widtype);
2330    win = elm_widget_data_get(obj);
2331    if (!win) return;
2332    ecore_evas_sticky_set(win->ee, sticky);
2333 #ifdef HAVE_ELEMENTARY_X
2334    _elm_win_xwin_update(win);
2335 #endif
2336 }
2337
2338 EAPI Eina_Bool
2339 elm_win_sticky_get(const Evas_Object *obj)
2340 {
2341    Elm_Win *win;
2342    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2343    win = elm_widget_data_get(obj);
2344    if (!win) return EINA_FALSE;
2345    return ecore_evas_sticky_get(win->ee);
2346 }
2347
2348 EAPI void
2349 elm_win_keyboard_mode_set(Evas_Object *obj, Elm_Win_Keyboard_Mode mode)
2350 {
2351    Elm_Win *win;
2352    ELM_CHECK_WIDTYPE(obj, widtype);
2353    win = elm_widget_data_get(obj);
2354    if (!win) return;
2355    if (mode == win->kbdmode) return;
2356 #ifdef HAVE_ELEMENTARY_X
2357    _elm_win_xwindow_get(win);
2358 #endif
2359    win->kbdmode = mode;
2360 #ifdef HAVE_ELEMENTARY_X
2361    if (win->xwin)
2362      ecore_x_e_virtual_keyboard_state_set
2363         (win->xwin, (Ecore_X_Virtual_Keyboard_State)win->kbdmode);
2364 #endif
2365 }
2366
2367 EAPI Elm_Win_Keyboard_Mode
2368 elm_win_keyboard_mode_get(const Evas_Object *obj)
2369 {
2370    Elm_Win *win;
2371    ELM_CHECK_WIDTYPE(obj, widtype) ELM_WIN_KEYBOARD_UNKNOWN;
2372    win = elm_widget_data_get(obj);
2373    if (!win) return ELM_WIN_KEYBOARD_UNKNOWN;
2374    return win->kbdmode;
2375 }
2376
2377 EAPI void
2378 elm_win_keyboard_win_set(Evas_Object *obj, Eina_Bool is_keyboard)
2379 {
2380    Elm_Win *win;
2381    ELM_CHECK_WIDTYPE(obj, widtype);
2382    win = elm_widget_data_get(obj);
2383    if (!win) return;
2384 #ifdef HAVE_ELEMENTARY_X
2385    _elm_win_xwindow_get(win);
2386    if (win->xwin)
2387      ecore_x_e_virtual_keyboard_set(win->xwin, is_keyboard);
2388 #else
2389    (void) is_keyboard;
2390 #endif
2391 }
2392
2393 EAPI Eina_Bool
2394 elm_win_keyboard_win_get(const Evas_Object *obj)
2395 {
2396    Elm_Win *win;
2397    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2398    win = elm_widget_data_get(obj);
2399    if (!win) return EINA_FALSE;
2400 #ifdef HAVE_ELEMENTARY_X
2401    _elm_win_xwindow_get(win);
2402    if (win->xwin)
2403      return ecore_x_e_virtual_keyboard_get(win->xwin);
2404 #endif
2405    return EINA_FALSE;
2406 }
2407
2408 EAPI void
2409 elm_win_screen_position_get(const Evas_Object *obj, int *x, int *y)
2410 {
2411    Elm_Win *win;
2412    ELM_CHECK_WIDTYPE(obj, widtype);
2413    win = elm_widget_data_get(obj);
2414    if (!win) return;
2415    if (x) *x = win->screen.x;
2416    if (y) *y = win->screen.y;
2417 }
2418
2419 EAPI Eina_Bool
2420 elm_win_focus_get(const Evas_Object *obj)
2421 {
2422    Elm_Win *win;
2423    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2424    win = elm_widget_data_get(obj);
2425    if (!win) return EINA_FALSE;
2426    return ecore_evas_focus_get(win->ee);
2427 }
2428
2429 EAPI void
2430 elm_win_screen_constrain_set(Evas_Object *obj, Eina_Bool constrain)
2431 {
2432    Elm_Win *win;
2433    ELM_CHECK_WIDTYPE(obj, widtype);
2434    win = elm_widget_data_get(obj);
2435    if (!win) return;
2436    win->constrain = !!constrain;
2437 }
2438
2439 EAPI Eina_Bool
2440 elm_win_screen_constrain_get(Evas_Object *obj)
2441 {
2442    Elm_Win *win;
2443    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2444    win = elm_widget_data_get(obj);
2445    if (!win) return EINA_FALSE;
2446    return win->constrain;
2447 }
2448
2449 EAPI void
2450 elm_win_screen_size_get(const Evas_Object *obj, int *x, int *y, int *w, int *h)
2451 {
2452    Elm_Win *win;
2453    ELM_CHECK_WIDTYPE(obj, widtype);
2454    win = elm_widget_data_get(obj);
2455    if (!win) return;
2456    ecore_evas_screen_geometry_get(win->ee, x, y, w, h);
2457 }
2458
2459 EAPI void
2460 elm_win_conformant_set(Evas_Object *obj, Eina_Bool conformant)
2461 {
2462    Elm_Win *win;
2463    ELM_CHECK_WIDTYPE(obj, widtype);
2464    win = elm_widget_data_get(obj);
2465    if (!win) return;
2466 #ifdef HAVE_ELEMENTARY_X
2467    _elm_win_xwindow_get(win);
2468    if (win->xwin)
2469      ecore_x_e_illume_conformant_set(win->xwin, conformant);
2470 #else
2471    (void) conformant;
2472 #endif
2473 }
2474
2475 EAPI Eina_Bool
2476 elm_win_conformant_get(const Evas_Object *obj)
2477 {
2478    Elm_Win *win;
2479    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2480    win = elm_widget_data_get(obj);
2481    if (!win) return EINA_FALSE;
2482 #ifdef HAVE_ELEMENTARY_X
2483    _elm_win_xwindow_get(win);
2484    if (win->xwin)
2485      return ecore_x_e_illume_conformant_get(win->xwin);
2486 #endif
2487    return EINA_FALSE;
2488 }
2489
2490 EAPI void
2491 elm_win_quickpanel_set(Evas_Object *obj, Eina_Bool quickpanel)
2492 {
2493    Elm_Win *win;
2494    ELM_CHECK_WIDTYPE(obj, widtype);
2495    win = elm_widget_data_get(obj);
2496    if (!win) return;
2497 #ifdef HAVE_ELEMENTARY_X
2498    _elm_win_xwindow_get(win);
2499    if (win->xwin)
2500      {
2501         ecore_x_e_illume_quickpanel_set(win->xwin, quickpanel);
2502         if (quickpanel)
2503           {
2504              Ecore_X_Window_State states[2];
2505
2506              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
2507              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
2508              ecore_x_netwm_window_state_set(win->xwin, states, 2);
2509              ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
2510           }
2511      }
2512 #else
2513    (void) quickpanel;
2514 #endif
2515 }
2516
2517 EAPI Eina_Bool
2518 elm_win_quickpanel_get(const Evas_Object *obj)
2519 {
2520    Elm_Win *win;
2521    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2522    win = elm_widget_data_get(obj);
2523    if (!win) return EINA_FALSE;
2524 #ifdef HAVE_ELEMENTARY_X
2525    _elm_win_xwindow_get(win);
2526    if (win->xwin)
2527      return ecore_x_e_illume_quickpanel_get(win->xwin);
2528 #endif
2529    return EINA_FALSE;
2530 }
2531
2532 EAPI void
2533 elm_win_quickpanel_priority_major_set(Evas_Object *obj, int priority)
2534 {
2535    Elm_Win *win;
2536    ELM_CHECK_WIDTYPE(obj, widtype);
2537    win = elm_widget_data_get(obj);
2538    if (!win) return;
2539 #ifdef HAVE_ELEMENTARY_X
2540    _elm_win_xwindow_get(win);
2541    if (win->xwin)
2542      ecore_x_e_illume_quickpanel_priority_major_set(win->xwin, priority);
2543 #else
2544    (void) priority;
2545 #endif
2546 }
2547
2548 EAPI int
2549 elm_win_quickpanel_priority_major_get(const Evas_Object *obj)
2550 {
2551    Elm_Win *win;
2552    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2553    win = elm_widget_data_get(obj);
2554    if (!win) return -1;
2555 #ifdef HAVE_ELEMENTARY_X
2556    _elm_win_xwindow_get(win);
2557    if (win->xwin)
2558      return ecore_x_e_illume_quickpanel_priority_major_get(win->xwin);
2559 #endif
2560    return -1;
2561 }
2562
2563 EAPI void
2564 elm_win_quickpanel_priority_minor_set(Evas_Object *obj, int priority)
2565 {
2566    Elm_Win *win;
2567    ELM_CHECK_WIDTYPE(obj, widtype);
2568    win = elm_widget_data_get(obj);
2569    if (!win) return;
2570 #ifdef HAVE_ELEMENTARY_X
2571    _elm_win_xwindow_get(win);
2572    if (win->xwin)
2573      ecore_x_e_illume_quickpanel_priority_minor_set(win->xwin, priority);
2574 #else
2575    (void) priority;
2576 #endif
2577 }
2578
2579 EAPI int
2580 elm_win_quickpanel_priority_minor_get(const Evas_Object *obj)
2581 {
2582    Elm_Win *win;
2583    ELM_CHECK_WIDTYPE(obj, widtype) -1;
2584    win = elm_widget_data_get(obj);
2585    if (!win) return -1;
2586 #ifdef HAVE_ELEMENTARY_X
2587    _elm_win_xwindow_get(win);
2588    if (win->xwin)
2589      return ecore_x_e_illume_quickpanel_priority_minor_get(win->xwin);
2590 #endif
2591    return -1;
2592 }
2593
2594 EAPI void
2595 elm_win_quickpanel_zone_set(Evas_Object *obj, int zone)
2596 {
2597    Elm_Win *win;
2598    ELM_CHECK_WIDTYPE(obj, widtype);
2599    win = elm_widget_data_get(obj);
2600    if (!win) return;
2601 #ifdef HAVE_ELEMENTARY_X
2602    _elm_win_xwindow_get(win);
2603    if (win->xwin)
2604      ecore_x_e_illume_quickpanel_zone_set(win->xwin, zone);
2605 #else
2606    (void) zone;
2607 #endif
2608 }
2609
2610 EAPI int
2611 elm_win_quickpanel_zone_get(const Evas_Object *obj)
2612 {
2613    Elm_Win *win;
2614    ELM_CHECK_WIDTYPE(obj, widtype) 0;
2615    win = elm_widget_data_get(obj);
2616    if (!win) return 0;
2617 #ifdef HAVE_ELEMENTARY_X
2618    _elm_win_xwindow_get(win);
2619    if (win->xwin)
2620      return ecore_x_e_illume_quickpanel_zone_get(win->xwin);
2621 #endif
2622    return 0;
2623 }
2624
2625 EAPI void
2626 elm_win_prop_focus_skip_set(Evas_Object *obj, Eina_Bool skip)
2627 {
2628    Elm_Win *win;
2629    ELM_CHECK_WIDTYPE(obj, widtype);
2630    win = elm_widget_data_get(obj);
2631    if (!win) return;
2632 #ifdef HAVE_ELEMENTARY_X
2633    _elm_win_xwindow_get(win);
2634    if (skip)
2635      {
2636         if (win->xwin)
2637           {
2638              Ecore_X_Window_State states[2];
2639
2640              ecore_x_icccm_hints_set(win->xwin, 0, 0, 0, 0, 0, 0, 0);
2641              states[0] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
2642              states[1] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
2643              ecore_x_netwm_window_state_set(win->xwin, states, 2);
2644           }
2645      }
2646 #else
2647    (void) skip;
2648 #endif
2649 }
2650
2651 EAPI void
2652 elm_win_illume_command_send(Evas_Object *obj, Elm_Illume_Command command, void *params __UNUSED__)
2653 {
2654    Elm_Win *win;
2655    ELM_CHECK_WIDTYPE(obj, widtype);
2656    win = elm_widget_data_get(obj);
2657    if (!win) return;
2658 #ifdef HAVE_ELEMENTARY_X
2659    _elm_win_xwindow_get(win);
2660    if (win->xwin)
2661      {
2662         switch (command)
2663           {
2664            case ELM_ILLUME_COMMAND_FOCUS_BACK:
2665               ecore_x_e_illume_focus_back_send(win->xwin);
2666               break;
2667            case ELM_ILLUME_COMMAND_FOCUS_FORWARD:
2668               ecore_x_e_illume_focus_forward_send(win->xwin);
2669               break;
2670            case ELM_ILLUME_COMMAND_FOCUS_HOME:
2671               ecore_x_e_illume_focus_home_send(win->xwin);
2672               break;
2673            case ELM_ILLUME_COMMAND_CLOSE:
2674               ecore_x_e_illume_close_send(win->xwin);
2675               break;
2676            case ELM_ILLUME_COMMAND_INDICATOR_SHOW:
2677               ecore_x_e_illume_indicator_state_set
2678                  (win->xwin, ECORE_X_ILLUME_INDICATOR_STATE_ON);
2679               break;
2680            case ELM_ILLUME_COMMAND_INDICATOR_HIDE:
2681               ecore_x_e_illume_indicator_state_set
2682                  (win->xwin, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
2683               break;
2684            default:
2685               break;
2686           }
2687      }
2688 #else
2689    (void) command;
2690 #endif
2691 }
2692
2693 EAPI Evas_Object *
2694 elm_win_inlined_image_object_get(Evas_Object *obj)
2695 {
2696    Elm_Win *win;
2697    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2698    win = elm_widget_data_get(obj);
2699    if (!win) return NULL;
2700    return win->img_obj;
2701 }
2702
2703 EAPI void
2704 elm_win_focus_highlight_enabled_set(Evas_Object *obj, Eina_Bool enabled)
2705 {
2706    Elm_Win *win;
2707
2708    ELM_CHECK_WIDTYPE(obj, widtype);
2709
2710    win = elm_widget_data_get(obj);
2711    enabled = !!enabled;
2712    if (win->focus_highlight.enabled == enabled)
2713      return;
2714
2715    win->focus_highlight.enabled = enabled;
2716
2717    if (win->focus_highlight.enabled)
2718      _elm_win_focus_highlight_init(win);
2719    else
2720      _elm_win_focus_highlight_shutdown(win);
2721 }
2722
2723 EAPI Eina_Bool
2724 elm_win_focus_highlight_enabled_get(const Evas_Object *obj)
2725 {
2726    Elm_Win *win;
2727
2728    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2729
2730    win = elm_widget_data_get(obj);
2731    return win->focus_highlight.enabled;
2732 }
2733
2734 EAPI void
2735 elm_win_focus_highlight_style_set(Evas_Object *obj, const char *style)
2736 {
2737    Elm_Win *win;
2738
2739    ELM_CHECK_WIDTYPE(obj, widtype);
2740
2741    win = elm_widget_data_get(obj);
2742    eina_stringshare_replace(&win->focus_highlight.style, style);
2743    win->focus_highlight.changed_theme = EINA_TRUE;
2744    _elm_win_focus_highlight_reconfigure_job_start(win);
2745 }
2746
2747 EAPI const char *
2748 elm_win_focus_highlight_style_get(const Evas_Object *obj)
2749 {
2750    Elm_Win *win;
2751
2752    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2753
2754    win = elm_widget_data_get(obj);
2755    return win->focus_highlight.style;
2756 }
2757
2758 typedef struct _Widget_Data Widget_Data;
2759
2760 struct _Widget_Data
2761 {
2762    Evas_Object *frm;
2763    Evas_Object *content;
2764 };
2765
2766 static void _del_hook(Evas_Object *obj);
2767 static void _theme_hook(Evas_Object *obj);
2768 static void _sizing_eval(Evas_Object *obj);
2769 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
2770 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
2771
2772 static const char *widtype2 = NULL;
2773
2774 static void
2775 _del_hook(Evas_Object *obj)
2776 {
2777    Widget_Data *wd = elm_widget_data_get(obj);
2778    if (!wd) return;
2779    free(wd);
2780 }
2781
2782 static void
2783 _theme_hook(Evas_Object *obj)
2784 {
2785    Widget_Data *wd = elm_widget_data_get(obj);
2786    _elm_theme_object_set(obj, wd->frm, "win", "inwin", elm_widget_style_get(obj));
2787    if (wd->content)
2788      edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
2789    _sizing_eval(obj);
2790
2791    evas_object_smart_callback_call(obj, SIG_THEME_CHANGED, NULL);
2792 }
2793
2794 static Eina_Bool
2795 _elm_inwin_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
2796 {
2797    Widget_Data *wd = elm_widget_data_get(obj);
2798
2799    if (!wd)
2800      return EINA_FALSE;
2801
2802    /* Try Focus cycle in subitem */
2803    if (wd->content)
2804      {
2805         elm_widget_focus_next_get(wd->content, dir, next);
2806         if (*next)
2807           return EINA_TRUE;
2808      }
2809
2810    *next = (Evas_Object *)obj;
2811    return EINA_FALSE;
2812 }
2813
2814 static void
2815 _elm_inwin_text_set_hook(Evas_Object *obj, const char *item, const char *text)
2816 {
2817    Widget_Data *wd = elm_widget_data_get(obj);
2818
2819    if (!wd || !item) return;
2820    edje_object_part_text_set(wd->frm, item, text);
2821    _sizing_eval(obj);
2822 }
2823
2824 static const char *
2825 _elm_inwin_text_get_hook(const Evas_Object *obj, const char *item)
2826 {
2827    Widget_Data *wd = elm_widget_data_get(obj);
2828
2829    if (!item || !wd || !wd->frm) return NULL;
2830    return edje_object_part_text_get(wd->frm, item);
2831 }
2832
2833 static void
2834 _sizing_eval(Evas_Object *obj)
2835 {
2836    Widget_Data *wd = elm_widget_data_get(obj);
2837    Evas_Coord minw = -1, minh = -1;
2838
2839    evas_object_size_hint_min_get(wd->content, &minw, &minh);
2840    edje_object_size_min_calc(wd->frm, &minw, &minh);
2841    evas_object_size_hint_min_set(obj, minw, minh);
2842    evas_object_size_hint_max_set(obj, -1, -1);
2843 }
2844
2845 static void
2846 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2847 {
2848    _sizing_eval(data);
2849 }
2850
2851 static void
2852 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
2853 {
2854    Widget_Data *wd = elm_widget_data_get(obj);
2855    Evas_Object *sub = event_info;
2856    if (sub == wd->content)
2857      {
2858         evas_object_event_callback_del_full
2859            (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
2860         wd->content = NULL;
2861         _sizing_eval(obj);
2862      }
2863 }
2864
2865 EAPI Evas_Object *
2866 elm_win_inwin_add(Evas_Object *obj)
2867 {
2868    Evas_Object *obj2;
2869    Widget_Data *wd;
2870    Elm_Win *win;
2871
2872    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
2873    win = elm_widget_data_get(obj);
2874    if (!win) return NULL;
2875    wd = ELM_NEW(Widget_Data);
2876    obj2 = elm_widget_add(win->evas);
2877    elm_widget_type_set(obj2, "inwin");
2878    ELM_SET_WIDTYPE(widtype2, "inwin");
2879    elm_widget_sub_object_add(obj, obj2);
2880    evas_object_size_hint_weight_set(obj2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
2881    evas_object_size_hint_align_set(obj2, EVAS_HINT_FILL, EVAS_HINT_FILL);
2882    elm_win_resize_object_add(obj, obj2);
2883
2884    elm_widget_data_set(obj2, wd);
2885    elm_widget_del_hook_set(obj2, _del_hook);
2886    elm_widget_theme_hook_set(obj2, _theme_hook);
2887    elm_widget_focus_next_hook_set(obj2, _elm_inwin_focus_next_hook);
2888    elm_widget_text_set_hook_set(obj2, _elm_inwin_text_set_hook);
2889    elm_widget_text_get_hook_set(obj2, _elm_inwin_text_get_hook);
2890    elm_widget_can_focus_set(obj2, EINA_TRUE);
2891    elm_widget_highlight_ignore_set(obj2, EINA_TRUE);
2892
2893    wd->frm = edje_object_add(win->evas);
2894    _elm_theme_object_set(obj, wd->frm, "win", "inwin", "default");
2895    elm_widget_resize_object_set(obj2, wd->frm);
2896
2897    evas_object_smart_callback_add(obj2, "sub-object-del", _sub_del, obj2);
2898
2899    _sizing_eval(obj2);
2900    return obj2;
2901 }
2902
2903 EAPI void
2904 elm_win_inwin_activate(Evas_Object *obj)
2905 {
2906    ELM_CHECK_WIDTYPE(obj, widtype2);
2907    Widget_Data *wd = elm_widget_data_get(obj);
2908    if (!wd) return;
2909    evas_object_raise(obj);
2910    evas_object_show(obj);
2911    edje_object_signal_emit(wd->frm, "elm,action,show", "elm");
2912    elm_object_focus_set(obj, EINA_TRUE);
2913 }
2914
2915 EAPI void
2916 elm_win_inwin_content_set(Evas_Object *obj, Evas_Object *content)
2917 {
2918    ELM_CHECK_WIDTYPE(obj, widtype2);
2919    Widget_Data *wd = elm_widget_data_get(obj);
2920    if (!wd) return;
2921    if (wd->content == content) return;
2922    if (wd->content) evas_object_del(wd->content);
2923    wd->content = content;
2924    if (content)
2925      {
2926         elm_widget_sub_object_add(obj, content);
2927         evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2928                                        _changed_size_hints, obj);
2929         edje_object_part_swallow(wd->frm, "elm.swallow.content", content);
2930      }
2931    _sizing_eval(obj);
2932 }
2933
2934 EAPI Evas_Object *
2935 elm_win_inwin_content_get(const Evas_Object *obj)
2936 {
2937    ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
2938    Widget_Data *wd = elm_widget_data_get(obj);
2939    if (!wd) return NULL;
2940    return wd->content;
2941 }
2942
2943 EAPI Evas_Object *
2944 elm_win_inwin_content_unset(Evas_Object *obj)
2945 {
2946    ELM_CHECK_WIDTYPE(obj, widtype2) NULL;
2947    Widget_Data *wd = elm_widget_data_get(obj);
2948    if (!wd) return NULL;
2949    if (!wd->content) return NULL;
2950    Evas_Object *content = wd->content;
2951    elm_widget_sub_object_del(obj, wd->content);
2952    evas_object_event_callback_del_full(wd->content,
2953                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
2954                                        _changed_size_hints, obj);
2955    edje_object_part_unswallow(wd->frm, wd->content);
2956    wd->content = NULL;
2957    return content;
2958 }
2959
2960 EAPI Eina_Bool
2961 elm_win_socket_listen(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys)
2962 {
2963
2964    Elm_Win *win;
2965
2966    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
2967    win = elm_widget_data_get(obj);
2968    if (!win) return EINA_FALSE;
2969    if (!win->ee) return EINA_FALSE;
2970
2971    if(!ecore_evas_extn_socket_listen(win->ee, svcname, svcnum, svcsys))
2972      return EINA_FALSE;
2973
2974    return EINA_TRUE;
2975 }
2976
2977 /* windowing spcific calls - shall we do this differently? */
2978
2979 static Ecore_X_Window
2980 _elm_ee_win_get(const Evas_Object *obj)
2981 {
2982    if (!obj) return 0;
2983 #ifdef HAVE_ELEMENTARY_X
2984    Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
2985    if (ee) return (Ecore_X_Window)ecore_evas_window_get(ee);
2986 #endif
2987    return 0;
2988 }
2989
2990 EAPI Ecore_X_Window
2991 elm_win_xwindow_get(const Evas_Object *obj)
2992 {
2993    Elm_Win *win;
2994    const char *type;
2995
2996    if (!obj) return 0;
2997    type = elm_widget_type_get(obj);
2998    if ((!type) || (type != widtype)) return _elm_ee_win_get(obj);
2999    win = elm_widget_data_get(obj);
3000    if (!win) return 0;
3001 #ifdef HAVE_ELEMENTARY_X
3002    if (win->xwin) return win->xwin;
3003    if (win->parent) return elm_win_xwindow_get(win->parent);
3004 #endif
3005    return 0;
3006 }