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