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