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