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