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