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